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
精彩评论