【问题标题】:How do I create a PHP static class property at runtime (dynamically)?如何在运行时(动态)创建 PHP 静态类属性?
【发布时间】:2012-04-08 06:12:34
【问题描述】:

我想做这样的事情:

public static function createDynamic(){
    $mydynamicvar = 'module'; 
    self::$mydynamicvar = $value;
}

并且能够从类中访问属性

$value = self::$module;

【问题讨论】:

    标签: php function dynamic static creation


    【解决方案1】:

    我不知道你为什么要这样做,但这很有效。您必须像函数一样访问动态“变量”,因为 PHP 中还没有 __getStatic() 魔术方法。

    class myclass{
        static $myvariablearray = array();
    
        public static function createDynamic($variable, $value){
            self::$myvariablearray[$variable] = $value;
        }
    
        public static function __callstatic($name, $arguments){
            return self::$myvariablearray[$name];
        }
    }
    
    myclass::createDynamic('module', 'test');
    echo myclass::module();
    

    【讨论】:

      【解决方案2】:

      静态变量必须是类定义的一部分,因此您不能动态地创建它们。甚至没有Reflection

      chuck at manchuck dot com                                             2 years ago
      

      请务必注意,调用 ReflectionClass::setStaticPropertyValue 将不允许您向类添加新的静态属性。

      但这看起来很像XY Problem。您可能真的不想在运行时向 PHP 类添加静态属性;您有一些用例可以以这种方式实现。或者这种方式将是最快的方式,如果它可用,来完成一些用例。可能还有其他方法。

      实际上,下面的用例又是一些更高层次问题的可能解决方案。重新检查高级问题并以不同的方式重构/重新思考它可能是值得的,也许完全不需要干预静态属性。

      我想要一个类中的属性字典。

      trait HasDictionary {
          private static $keyValueDictionary = [ ];
      
          public static function propget($name) {
              if (!array_key_exists($name, static::$keyValueDictionary) {
                  return null;
              }
              return static::$keyValueDictionary[$name];
          }
      
          public static function propset($name, $value) {
              if (array_key_exists($name, static::$keyValueDictionary) {
                  $prev = static::$keyValueDictionary[$name];
              } else {
                  $prev = null;
              }
              static::$keyValueDictionary[$name] = $value;
              return $prev;
          }
      }
      
      
      class MyClass
      {
          use Traits\HasDictionary;
      
          ...$a = self::propget('something');
      
          self::propset('something', 'some value');
      }
      

      我想将一些值关联到一个类,或者:我想要一个其他人的类中的属性字典。

      这实际上发生在我身上,我在调查方法时发现了这个问题。我需要在我的工作流程的 B 点中查看给定类的哪一点(“A”)已定义,以及代码的其他部分。最后,我将这些信息存储到我的自动加载器提供的数组中,并最终能够在类第一次加载时存储debug_backtrace()

      // Solution: store values somewhere else that you control.
      
      class ClassPropertySingletonMap {
          use Traits\HasDictionary; // same as before
      
          public static function setClassProp($className, $prop, $value) {
              return self::propset("{$className}::{$prop}", $value);
          }
      
          public static function getClassProp($className, $prop) {
              return self::propget("{$className}::{$prop}");
          }
      }
      
      // Instead of
      // $a = SomeClass::$someName;
      // SomeClass::$someName = $b;
      
      // we'll use
      // $a = ClassPropertySingletonMap::getClassProp('SomeClass','someName');
      // ClassPropertySingletonMap::setClassProp('SomeClass','someName', $b);
      

      我想更改而不是创建一个类的现有属性。

      // Use Reflection. The property is assumed private, for were it public
      // you could do it as Class::$property = $whatever;
      
      function setPrivateStaticProperty($class, $property, $value) {
          $reflector = new \ReflectionClass($class);
          $reflector->getProperty($property)->setAccessible(true);
          $reflector->setStaticPropertyValue($property, $value);
          $reflector->getProperty($property)->setAccessible(false);
      }
      

      【讨论】:

        【解决方案3】:

        静态属性必须在类定义中定义。因此,真正的静态属性不能像常规属性那样动态创建。

        例如,如果你运行这个:

        <?php
        
        class MyClass
        {
            public static function createDynamic()
            {
                $mydynamicvar = 'module';
                self::$mydynamicvar = $value;
            }
        }
        
        MyClass::createDynamic();
        
        var_dump(MyClass::$mydynamicvar);
        var_dump(MyClass::$module);
        

        ...你会得到这个错误

        Fatal error: Access to undeclared static property: MyClass::$mydynamicvar test.php on line 8
        

        请注意,在尝试设置属性而不是第 14 或 15 行时,错误是如何在第 8 行发生的(如果您只是做错了并且实际上可以动态创建静态属性,您可能会想到)。

        【讨论】:

          【解决方案4】:

          一个可能的相关问题(在 PHP 5.4.0 及更高版本中)是包含各种不同的静态变量或常量声明组,并将它们组合到一个类声明中。

          这是一个例子:

          trait Added1 // This can be located in one Include file
              {
              static
              $x="hello"; // Can declare more variables here
              }
          trait Added2 // This can be located in another Include file
              {
              static
              $y="world"; // Can declare more variables here
              }
          class G // Global constant and variable declarations class
              {
              use Added1, Added2; // Combines all variable declarations
              }
          
          echo G::$x." ".G::$y; // Shows "hello world" on the web page
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-01-08
            • 2014-01-03
            • 1970-01-01
            相关资源
            最近更新 更多