我正在为我的某个项目开展ORM工作,并且我试图避免不必要的"硬编码"这些类通过使用匿名类来扩展基本的抽象模型的默认功能。
现在,所有查询都基于我想在匿名类中覆盖的静态属性$table_name
。但是,当我尝试这样做时,匿名类的所有其他实例都会获得相同的值,尽管理想情况下它们会获得自己的不同值。我只是在类中使用非静态属性,但是有静态函数使用静态属性。
我看到的选项是
这两种解决方案都有效,但似乎并不像我希望的那样优雅。有什么建议吗?
以下是示例代码示例
模型类
<?php
class Model{
protected static $table_name;
public static function query_table(){
[...use static::$table_name]
}
扩展匿名类
(new class() extends TableModel {
protected static $table_name = null;
public function setTableName($table_name) {
static::$table_name = $table_name;
}
});
答案 0 :(得分:0)
我有相同的想法和相同的问题。我快到了,但是还有一个问题。 PHP引擎将我的匿名类处理为同一类型。这里是演示该问题的代码。
测试1导致两个类都具有相同的类型,并且Ids被覆盖。 测试2导致第二个匿名类成为不同的类型,但每个id都需要另一个函数。
<?php
//define('TEST',1); //Uncomment to show Test1
class Foo
{
public static function getID()
{
return static::$ID;
}
};
function getClass($classID)
{
$class = new class extends Foo
{
public static $ID;
};
$class::$ID = $classID;
return $class;
}
function getAnotherClass($classID)
{
$class = new class extends Foo
{
public static $ID;
};
$class::$ID = $classID;
return $class;
}
if (defined('TEST')) { //Test 1 - Doesn't Works
$class1 = getClass(1); //Expected 1 - Actual 5
$class5 = getClass(5); //Expected 5 - Actual 5
} else { //Test 2 - Work
$class1 = getClass(1); //Expected 1 - Actual 1
$class5 = getAnotherClass(5); //Expected 5 - Actual 5
}
print "ClassID 1: " . $class1::getID() . PHP_EOL;
print "ClassID 5: " . $class5::getID() . PHP_EOL;
print "\tBecause the types are " . (get_class($class1) === get_class($class5) ? "" : "not ") . "equal." . PHP_EOL;
也许任何人都可以给我们提示。
更新解决方法
我发现使用eval
的丑陋但可行的解决方案。
<?php
class Foo
{
public static function getID()
{
return static::$ID;
}
};
/**
* Create a new class declaration
*
* @return string Returning the name of the new class.
*/
function createClass($classID): string
{
eval('class Foo' . $classID . ' extends Foo
{
public static $ID = ' . $classID . ';
};');
return "Foo$classID";
}
$class1 = createClass(1);
$class5 = createClass(5);
$object1 = new $class1;
$object5 = new $class5;
print "ClassID 1 (" . get_class($object1) . "): " . $class1::getID() . PHP_EOL;
print "ClassID 5 (" . get_class($object5) . "): " . $class5::getID() . PHP_EOL;
print "\tBecause the types are " . (get_class($object1) === get_class($object5) ? "" : "not ") . "equal." . PHP_EOL;