php __autoload() 和动态/运行时类定义 - 有没有一种不用 eval 的方法?
在搜索相关帖子后,我阅读了这篇文章。
我有一个略有不同但相关的问题。
有没有一种方法不使用 EVAL() (因为这是一个坏主意 - 如果有人允许用户提供 eval 等中使用的值,则可能会被滥用),这样您就可以定义类的结构,例如:
if(!class_exists($className) && dao::tableExists($className)) {
class $className extends daoObject {
public function __construct($uid) {
parent::__construct($uid);
}
}
dao::generateClass($className);
}
这样做的原因是因为当新的核心表添加到框架中时,它们可以与通用数据访问对象一起使用来访问相应的字段(通过父级中的 __call 获取器/设置器,添加/插入和更新/删除),而无需为每个表编写一个类,而不需要编码人员编写一个类,然后检查它或为各种类型的表编写自定义代码生成器。 daoObject 为我完成了这一切。
目的是如果类不存在,则使用这种方法定义类,然后将类定义写入文件。
如果对应的表名不存在,则会失败。如果该类存在(例如,下次运行时),则不会定义它。如果它不存在,但是是一个表名,您可以创建它,使用它并在第一次调用它时保存它,这会在插入新表并运行脚本来插入数据时发生。作者将仅通过 csv 定义表字段和示例数据。该脚本将生成类并一次性导入数据。我可以将定义写入文件,然后包含它,这似乎可以工作,但我想在修改对象的属性之后执行此操作,这样我就不必两次写入文件来实现它工作。
这是简化,但是可能吗?
I read this post after doing a search for related posts.
I have a slightly different, but related problem.
Is there a way WITHOUT EVAL() (because this is a bad idea - open for abuse if someone allows a user to supply the value that is used in eval, etc) such that you can define the structure of the class, for example:
if(!class_exists($className) && dao::tableExists($className)) {
class $className extends daoObject {
public function __construct($uid) {
parent::__construct($uid);
}
}
dao::generateClass($className);
}
The reason for this is because when new core tables are added to a framework, they could be used with a generic data access object for accessing the corresponding fields (getters/setters via __call in the parent, add/insert and update/delete) without writing a class for each, without requiring the coder to write a class and then having to inspect it or writing custom code generators for the various types of tables. the daoObject does that all for me.
The intention is to use this kind of method to define a class if it doesn't exist, then write the class definition to a file.
If the corresponding table name doesn't exist, it will fail. If the class exists (e.g. the next time it is run) then it won't define it. If it doesn't exist but is a tablename, you could create it, use it and save it the first time you call it, which would occur when new tables are inserted and a script is run to insert data. The authors will define only the table fields and sample data via csv. This script will generate classes and import the data in one hit. I COULD write the definition to a file, then include it, which seems like it could work, but I want to do that AFTER I've modified the properties of the object so I don't have to write to files twice to make it work.
This is simplified, but is it possible?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我认为这是不可能的;正如您所说,最好的选择可能是将类写入文件,然后自动加载该/那些类。
I don't think it's possible; as you said, the best option is probably to write the class to a file, then autoload that/those classes.
您不能使用变量作为类名(除非如您所说,使用
eval()
)。因此,如果您确实需要在运行时为未定义类的表创建 DAO 对象,也许您应该为“其他表”创建一个 DAO 类,并在构造函数中传递表的名称。
如果您的日志显示您有任何这些用户警告,您应该将其用作提醒,为新表创建适当的类。
回复您的评论:
在运行时为新类生成代码,即使作为后备条件,也不是一个好习惯。风险在于一些不受信任的内容会潜入您的类定义中(例如用户输入,但也可能是其他内容)。那么您就会遇到代码注入安全问题。
您要么需要像我所示的通用任意表 DAO 类,要么最好的解决方案是在开发期间在数据库中创建新表时创建新的 DAO 类。为什么这不是你的解决方案?
You can't use a variable for a class name (unless as you say, with
eval()
).So if you really need to create DAO objects at runtime for tables for which no class is defined, perhaps you should make a DAO class for "other table" and pass the name of the table in the constructor.
If your logs show that you have any of these user-warnings, you should use that as a reminder to go create a proper class for the new table(s).
Re your comment:
Generating code for a new class at runtime, even as a fallback condition, is not a good habit. The risk is that some untrusted content sneaks into your class definition (such as user input, but it can be something else). Then you have a Code Injection security problem.
Either you need a generic any-table DAO class like I showed, or else the best solution is that you create new DAO classes during development, at the time you create new tables in your database. Why is that not your solution?