【问题标题】:Static Properties in PHP7 Anonymous ClassesPHP7 匿名类中的静态属性
【发布时间】:2017-04-11 12:28:43
【问题描述】:

我正在为我的一个项目开发 ORM,并且我试图通过使用匿名类来扩展基本抽象模型的默认功能,从而避免不必要地“硬编码”这些类。

现在,所有查询都基于我想在匿名类中覆盖的静态属性 $table_name。但是,当我尝试这样做时,匿名类的所有其他实例都会收到相同的值,尽管理想情况下它们会获得自己不同的值。我只会在类中使用非静态属性,但是有些静态函数使用静态属性。

我看到的选项是

  1. 手动创建每个类并硬编码每个模型的表名
  2. 重新编写代码以使用非静态属性和参数

这两种解决方案都有效,但似乎不像我希望的那样优雅。有什么建议吗?

这是一个示例代码示例

模型类

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

【问题讨论】:

    标签: php anonymous-class


    【解决方案1】:

    我有同样的想法和同样的问题。我快到了,但还有一个问题。 PHP 引擎将我的匿名类作为相同类型处理。这里有一个代码来演示这个问题。

    测试 1 导致两个类的类型相同,并且 Id 被覆盖。 测试 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;
    

    【讨论】:

      猜你喜欢
      • 2016-12-31
      • 2021-06-13
      • 1970-01-01
      • 2017-07-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多