user2248249
user2248249

Reputation: 3

Dynamic class name in PHP

I'm trying to create a system that it has a GeneralObj. The GeneralObj allows user to initiate special objects for database's tables with a String of the table name. So far, it works perfect.

class GeneralObj{
    function __construct($tableName) {
        //...
    }
}

However, it is too tired to type new GeneralObj(XXX) every time. I am wondering is that possible to simplify the process to like new XXX(), which is actually running the same as new GeneralObj(XXX)? I spot PHP provided __autoload method for dynamic loading files in the setting include_path but it requires a the actually definition file existing. I really don't want to copy and copy the same definition files only changing a little.

For cause, eval is not an option.

Upvotes: 0

Views: 427

Answers (4)

marekful
marekful

Reputation: 15351

Use inheritance. Make GeneralObj the superclass of the table specific classes. This way you can dynamically derive class names and instantiate objects. Example:

class someTable extends GeneralObj {

}


$tableName = 'some';
$className = $tableName . 'Table';

$obj = new $className;

Upvotes: 1

sroes
sroes

Reputation: 15053

Maybe you can just auto-create the files in the autoloader:

function __autoload($class_name) {
    // check for classes ending with 'Table'
    if (preg_match('/(.*?)Table/', $class_name, $match)) {
        $classPath = PATH_TO_TABLES . '/' . $match[1] . '.php';
        // auto-create the file
        if (!file_exists($classPath)) {
            $classContent = "
class $class_name extends GeneralObj {
    public __construct() {
        parent::__construct('{$match[1]}');
    }
}";
            file_put_contents($classPath, $classContent);
        }
        require_once $classPath;
    }
}

Upvotes: 2

Mark Baker
Mark Baker

Reputation: 212402

Something like this autoloader:

myAutoloader::Register();


class myAutoloader
{
    /**
     * Register the Autoloader with SPL
     *
     */
    public static function Register() {
        if (function_exists('__autoload')) {
            //  Register any existing autoloader function with SPL, so we don't get any clashes
            spl_autoload_register('__autoload');
        }
        //  Register ourselves with SPL
        return spl_autoload_register(array('myAutoloader', 'Load'));
    }   //  function Register()


    /**
     * Autoload a class identified by name
     *
     * @param   string  $pClassName     Name of the object to load
     */
    public static function Load($pClassName){
        if (class_exists($pClassName,FALSE)) {
            //  Already loaded
            return FALSE;
        }

        $pClassFilePath = str_replace('_',DIRECTORY_SEPARATOR,$pClassName) . '.php';

        if (file_exists($pClassFilePath) === FALSE) {
            //  Not a class file
            return new GeneralObj($pClassName);
        }

        require($pClassFilePath);
    }   //  function Load()

}

And it's up to GeneralObj to throw an exception if the table class can't be instantiated

Upvotes: 0

Jon
Jon

Reputation: 437336

No, this is not possible.

The runkit extension allows programmatic manipulation of the PHP runtime environment, but it cannot do this. Even if it could, it would IMHO be a very bad idea, greatly impacting the requirements and complexity of the application in exchange for saving a few keystrokes.

In an unrelated note, your GeneralObj class has functionality that sounds suspiciously like that of a dependency injection container. Perhaps you should consider replacing it with one?

Upvotes: 0

Related Questions