【问题标题】:Can class default public variables be defined dynamically from an array in php?可以从php中的数组动态定义类默认公共变量吗?
【发布时间】:2012-09-24 21:45:43
【问题描述】:

我有一个事件类,用于将数据插入/更新到我的数据库中。有没有办法可以从我的 db_fields 数组创建公共变量,这样我就不必复制数据?

这是我目前有效的结构......

class event{
    protected static $table_name='tName';
    protected static $db_fields = array('field1','field2','field3','field4','field5');

    public $field1;
    public $field2;
    public $field3;
    public $field4;
    public $field5;
}

我想要这样的东西..

class event{
    protected static $table_name='tName';
    protected static $db_fields = array('field1','field2','field3','field4','field5');

    function __construct() {
        create_public_vars_here($db_fields);
    }

}

谢谢!

【问题讨论】:

    标签: php class properties mutators


    【解决方案1】:

    您可以尝试以下方法:

    class event{
    
        protected static $table_name='tName';
        protected static $db_fields = array('field1','field2','field3','field4','field5');
    
        function __construct() {
            foreach (self::$db_fields as $var) {
                $this->$var = $whateverDefaultValue;
            }
            // After the foreach loop, you'll have a bunch of properties of this object with the variable names being the string values of the $db_fiels.
            // For example, you'll have $field1, $field2, etc and they will be loaded with the value $whateverDefaultValue (probably want to set it to null).
        }
    
    }
    

    【讨论】:

    • 非常好。有没有办法显式声明变量“公共”,而不是依赖默认行为或未声明的变量是公共的?
    • @L0j1k 我相信这是可能的,但我之前还没有真正做到过。有人说反射可以做到这一点:php.net/manual/en/reflectionproperty.setaccessible.php 也可以查看这篇文章:stackoverflow.com/questions/5274348/…
    • 所以如果我使用它,变量默认是公共的,而不是这样声明?
    • 我很震惊(并且有点不安)PHP 允许您这样做。 +1 提醒我注意。
    • 之所以这样,是因为依赖这种隐式功能会导致一些错误非常非常难以发现。你这样做是在混淆你的代码,所以最好不要这样做。
    【解决方案2】:

    你可以使用魔法设置器/获取器:

    class event{
    
        protected static $table_name='tName';
        protected static $db_fields = array('field1','field2','field3','field4','field5');
    
        public function __get($key)
        {
    
            if(!in_array($key, static::$db_fields))
                throw new Exception( $key . " doesn't exist.");
    
            return $this -> $key;
    
        }
    
        public function __set($key, $value)
        {
    
            if(!in_array($key, static::$db_fields))
                throw new Exception( $key . " doesn't exist.");
    
            $this -> $key = $value;
    
        }   
    
    }
    

    这样你肯定不会点击列表之外的值:

    $event -> field1 = 'hello';  // --> OK
    $event -> field17 = 'hello'; // --> Exception: field17 doesn't exist
    
    echo $event -> field1;  // --> OK
    echo $event -> field17; // --> Exception: field17 doesn't exist
    

    至于在你的代码中有一个显式的公共变量声明,你不需要迭代你的对象——但在这种情况下你会根据你的静态字段实现Iterator 接口.

    【讨论】:

      【解决方案3】:

      使用修改器:

      class event{
        protected static $table_name='tName';
        protected static $db_fields = array('field1','field2','field3','field4','field5');
      
        function getVars($var) {
          if(!in_arrary($this->db_fields[$var])) {
            return false;
          } else {
            return $this->db_fields[$var];
          }
        }
      }
      

      然后你可以像这样访问它:

      $eventObject->getVars('field3');
      

      或者,如果您不创建类之外的对象:

      event::getVars('field3');
      

      编辑:本着使事情复杂化的精神,以便您不会违反边界,添加了代码。

      【讨论】:

      • 我不知道。这是一种方法。我只是这样写了我的答案。 :P +1
      猜你喜欢
      • 1970-01-01
      • 2011-10-11
      • 2023-03-17
      • 1970-01-01
      • 1970-01-01
      • 2011-12-07
      • 1970-01-01
      • 2012-03-22
      • 1970-01-01
      相关资源
      最近更新 更多