Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can PHP Perform Magic Instantiation?

Tags:

php

Given a class class RandomName extends CommonAppBase {} is there any way to automatically create an instance of any class extending CommonAppBase without explicitly using new?

As a rule there will only be one class definition per PHP file. And appending new RandomName() to the end of all files is something I would like to eliminate. The extending class has no constructor; only CommonAppBase's constructor is called. CommonAppBase->__construct() kickstarts the rest of the apps execution.

Strange question, but would be nice if anyone knows a solution.

Edit

Further to the below comment. The code that does the instantiation won't be in the class file. The class file will be just that, I want some other code to include('random.class.php') and instantiate whatever class extending CommonAppBase is in there.

For anyone unsure what I am after my hackish answer does what I want, but not in the sanest way.

Thanks in advance, Aiden

(btw, my PHP version is 5.3.2) Please state version restrictions with any answer.

Answers

The following can all be appended to a file (through php.ini or with Apache) to auto launch a class of a specific parent class.

First (thanks dnagirl)

$ca = get_declared_classes();
foreach($ca as $c){
    if(is_subclass_of($c, 'MyBaseClass')){
        $inst = new $c();
    }
}

and (the accepted answer, as closest answer)

auto_loader();
function auto_loader() {
    // Get classes with parent MyBaseClass
    $classes = array_filter(get_declared_classes(), function($class){
        return get_parent_class($class) === 'MyBaseClass';
    });
    // Instantiate the first one
    if (isset($classes[0])) {
        $inst = new $classes[0];
    }
}
like image 706
Aiden Bell Avatar asked May 11 '10 18:05

Aiden Bell


2 Answers

I'm not sure if the following is precisely what you are looking for, but it's an idea. The code should be pretty self-explanatory.

auto_loader();
function auto_loader() {
    // Get classes with parent MyBaseClass
    $classes = array_filter(get_declared_classes(), function($class){
        return get_parent_class($class) === 'MyBaseClass';
    });
    // Instantiate the first one
    if (isset($classes[0])) {
        $inst = new $classes[0];
    }
}

Note: the functions are available since early in the life of PHP 4 but the anonymous function syntax used with array_filter was only introduced in PHP 5.3.0.

like image 126
salathe Avatar answered Sep 22 '22 04:09

salathe


I may be misinterpreting your problem but if you're looking for a single instantiation of a class to use throughout the application (like a database class) I would suggest you use a factory pattern. Then, anytime you need the class you can do something like....

$obj = &MyFactory::getClass('mysql_database_class');

I would definitely rule out instantiating your classes at the end of your class files. If you're trying to follow standard OOP principles then you should avoid this at all costs, as it can cause collisions elsewhere in your code.

like image 40
Jarrod Nettles Avatar answered Sep 23 '22 04:09

Jarrod Nettles