PHP中的动态类名

时间:2013-04-05 08:55:08

标签: php dynamic autoload

我正在尝试创建一个具有GeneralObj的系统。 GeneralObj允许用户使用表名的String启动数据库表的特殊对象。到目前为止,它完美无缺。

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

然而,每次输入新的GeneralObj(XXX)太累了。 我想知道是否可以简化流程以喜欢新的XXX(),它实际上与新的GeneralObj(XXX)运行相同? 我发现PHP在设置include_path中为动态加载文件提供了__autoload方法,但它需要一个实际的定义文件。我真的不想复制和复制相同的定义文件,只是改变了一点。

因为原因,eval不是一种选择。

4 个答案:

答案 0 :(得分:2)

也许您可以在自动加载器中自动创建文件:

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;
    }
}

答案 1 :(得分:1)

使用继承。使GeneralObj成为表特定类的超类。这样,您可以动态派生类名并实例化对象。例如:

class someTable extends GeneralObj {

}


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

$obj = new $className;

答案 2 :(得分:0)

不,这是不可能的。

runkit扩展允许对PHP运行时环境进行编程操作,但它无法执行此操作。即使它可以,恕我直言也是一个非常糟糕的主意,极大地影响了应用程序的要求和复杂性,以换取节省一些按键。

在不相关的说明中,您的GeneralObj类的功能听起来与dependency injection container的功能相似。也许您应该考虑用一个替换它?

答案 3 :(得分:0)

像这样的自动加载器:

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()

}

如果表类无法实例化,那么GeneralObj会抛出异常