php __autoload() and dynamic / runtime class definition - is there a way without eval?
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 tabl开发者_C百科es 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?
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.
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.
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);
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?
精彩评论