php __autoload()和动态/运行时类定义 - 有没有eval的方法?

时间:2010-09-26 22:18:24

标签: php class runtime autoload

我在搜索相关帖子后阅读了this post

我有一个稍微不同但相关的问题。

有没有一种方法WITHOUT EVAL()(因为这是一个坏主意 - 如果有人允许用户提供eval中使用的值等,则打开滥用),以便您可以定义类的结构,例如:

if(!class_exists($className) && dao::tableExists($className)) {
   class $className extends daoObject {
     public function __construct($uid) {
      parent::__construct($uid);
     }
   }
   dao::generateClass($className);
}

这是因为当新的核心表添加到框架时,它们可以与通用数据访问对象一起使用以访问相应的字段(通过父级的__call获取/ getter,添加/插入和更新/删除)而不需要为每个编写一个类,而不需要编码器编写一个类,然后必须检查它或为各种类型的表编写自定义代码生成器。 daoObject为我做了这一切。

目的是使用这种方法来定义一个类(如果它不存在),然后将类定义写入文件。

如果相应的表名不存在,则会失败。如果该类存在(例如下次运行),那么它将不会定义它。如果它不存在但是是表名,则可以创建它,使用它并在第一次调用时保存它,这将在插入新表并运行脚本以插入数据时发生。作者将通过csv仅定义表字段和样本数据。该脚本将生成类并在一次命中中导入数据。我可以将定义写入文件,然后包含它,看起来它可以工作,但我想在我修改对象的属性后这样做,所以我不必写两次文件来使它工作

这是简化,但有可能吗?

2 个答案:

答案 0 :(得分:0)

我不认为这是可能的;如你所说,最好的选择可能是将类写入文件,然后自动加载那些/那些类。

答案 1 :(得分:0)

您不能将变量用于类名(除非您说eval())。

因此,如果你真的需要在运行时为没有定义类的表创建DAO对象,也许你应该为“其他表”创建一个DAO类,并在构造函数中传递表的名称。

class OtherTable extends daoObject {
  public function __construct($uid, $tableName) {
   $this->table = $tableName;
   parent::__construct($uid);
  }
}

$FootballTable = new OtherTable($uid, 'football'); 
trigger_error("You need a new table class!", E_USER_WARNING);

如果您的日志显示您有任何这些用户警告,则应将其用作提醒,为新表创建正确的类。


重新评论:

在运行时为新类生成代码,即使作为后备条件,也不是一个好习惯。风险在于一些不受信任的内容潜入您的类定义(例如用户输入,但它可能是其他内容)。然后您遇到Code Injection安全问题。

要么像我展示的那样需要一个通用的任意表DAO类,要么最好的解决方案是在开发过程中创建新的DAO类,在数据库中创建新表时。为什么这不是你的解决方案?