开发者

Find the class with a specific class const

开发者 https://www.devze.com 2023-03-18 17:25 出处:网络
I\'ve got a number of product classes which extend a parent product class. Each of these imp开发者_运维百科lements its own version of a PRODUCT_ID const. A method in a customer object will pull the PR

I've got a number of product classes which extend a parent product class. Each of these imp开发者_运维百科lements its own version of a PRODUCT_ID const. A method in a customer object will pull the PRODUCT_ID 's from the DB. I'd then like to instanciate the relevant product object and add it to an array.

Any ideas how I can dynamically find out which product object has the specific PRODUCT_ID const?

Sorry if that is a bit confusing!


The only way to do this would be to first loop through all of the declared classes, then check if they're a subclass of the parent product and finally to check if the PRODUCT_ID constant is defined and equal to the product you're looking for.

Here an example:

<?php

class Product
{
}

class Stack extends Product
{
  const PRODUCT_ID = 1;
}

class Overflow extends Product
{
  const PRODUCT_ID = 2;
}

function getSubclasses($parentClassName)
{
    $classes = array();
    foreach (get_declared_classes() as $className)
    {
        if (is_subclass_of($className, $parentClassName))
            $classes[] = $className;
    }

    return $classes;
}

function find_product($product_id)
{
  foreach ( get_declared_classes() as $class )
    if ( is_subclass_of($class, 'Product') )
      if ( constant($class . '::PRODUCT_ID') == $product_id )
        return $class;
}

echo find_product(1); // Outputs "Stack"


Create class with field $product_id and accessors:

class Product
{
    protected $product_id;

public function __construct($id)
{
    $this->id = $id;
}

    public function getProductId()
    {
        return $this->product_id;
    }

    public function setProductId($product_id)
    {
        $this->product_id = $product_id;
    }
}

And then:

$t = new Product(1254899);


Each PRODUCT_ID value corresponds to a unique product class name, right ? So you can't have a PRODUCT_ID without a class associated ? So, in this case, you know how many product class you have. If everything is true, I think the best solution is to create an array like this

$pairs = array(
    PRODUCT_ID_VALUE_ONE => 'classNameOne',
    PRODUCT_ID_VALUE_TWO => 'classNameTwo',
    // [...]
);

Then, when you want to retrieve the class name associated with a specific PRODUCT_ID, you have to do

    $className = $pairs[ $myProductId ];

You have two solutions to construct that array:

  • build it manually,
  • build it using automatically PHP reflexion (as shown by Francois)

If you have few class and if they don't change a lot, the first solution is better: its faster, easy to read/change values, easy to understand the code, and you have a better control over the array values => you set them manually so you won't have wrong values.

The problem with the first solution is you may have inconsistencies between the array and all the products class: if you change a PRODUCT_ID value into a class, you'll have to change it manually into the array.

The second solution is better if you have a lot of classes or if they change often. However, PHP reflexion may slow down your application. To limit that side effect, you can:

  • build the array once and only once,
  • build the array once only when needed,

You can create a method like getProductClassById which will:

  • check the existence of the array above,
  • created the array if necessary,
  • search in that array,
  • return the value,

Hope this will help,

Cheers

0

精彩评论

暂无评论...
验证码 换一张
取 消