代码之家  ›  专栏  ›  技术社区  ›  chiborg Alessandro Minoccheri

具有不存在索引的默认值的PHP数组

  •  9
  • chiborg Alessandro Minoccheri  · 技术社区  · 15 年前

    我喜欢Ruby的散列实现,在这里可以用默认值初始化散列对象。目前,我正努力在PHP中实现类似的对象。这是我第一次(非工作)拍摄这个。

    class DefaultArray extends ArrayObject {
    
      protected $_defaultValue;
    
      public function setDefault($defaultValue) {
        $this->_defaultValue  = $defaultValue;
      }
    
      public function offsetExists($index) {
        return true;
      }
    
      public function offsetGet($index) {
        if(!parent::offsetExists($index)) {
          if(is_object($this->_defaultValue))
            $default = clone $this->_defaultValue;
          else 
            $default = $this->_defaultValue;
    
          parent::offsetSet($index, $default);
        }
        return parent::offsetGet($index);
      }
    }
    
    $da = new DefaultArray();
    assert($da["dummy"] == null);
    $da->setDefault = 1;
    assert($da["dummy2"] == 1);
    

    第二个断言将失败。单步执行代码表明调用了offsetget并执行了if子句。然而,任何数组值都为空。有其他实施方案的想法吗?

    我厌倦了写作

    if(!isset($myarr['value']))
        $myarr['value'] = new MyObj();
    $myarr['value']->myVal=5;
    

    而不仅仅是写作

    $myarr['value']->myVal=5;
    
    4 回复  |  直到 9 年前
        1
  •  6
  •   erenon    14 年前
    $da->setDefault(1);
    

    您还可以使用uu construct magic函数:

    class DefaultArray extends ArrayObject
    {
        public function __construct($value = null){
            if(is_null($value))
            {
                $this->value = 'default';
            } else {
                $this->value = $value;
            }
        }
    }
    
        2
  •  3
  •   Gumbo    15 年前

    试试 magic methods __get .

    class DefaultArray extends ArrayObject {
        protected $_defaultValue;
    
        public function setDefault($defaultValue) {
            $this->_defaultValue  = $defaultValue;
        }
    
        public function __get($index) {
            return $this->offsetGet($index);
        }
    
        public function offsetGet($index) {
            if(!parent::offsetExists($index)) {
                if (is_object($this->_defaultValue)) {
                    $default = clone $this->_defaultValue;
                } else {
                    $default = $this->_defaultValue;
                }
                parent::offsetSet($index, $default);
            }
            return parent::offsetGet($index);
        }
    }
    

    现在您只需要使用不同的键,因为读访问将初始化该数组项:

    $da = new DefaultArray();
    assert($da['foo'] == null);
    $da->setDefault(1);
    assert($da['bar'] == 1);
    
        3
  •  0
  •   Victor Bocharsky    9 年前

    你可以用我的小图书馆 ValueResolver 在这种情况下,例如:

    class DefaultArray extends ArrayObject
    {
        public function __construct($value = null){
            $this->value = ValueResolver::resolve($value, 'default'); // returns 'default' if $value is null
        }
    }
    

    别忘了使用名称空间 use LapaLabs\ValueResolver\Resolver\ValueResolver;

    例如,如果变量的值应该是 integer 所以用这个:

    $id = ValueResolver::toInteger('6 apples', 1); // returns 6
    $id = ValueResolver::toInteger('There are no apples', 1); // returns 1 (used default value)
    

    检查 docs 更多示例

        4
  •  -3
  •   cimnine    15 年前

    为什么这么复杂?

    function initVal($value) {
        global $myarr;
        if(!isset($myarr['value']))
            $myarr['value'] = new MyObj();
    }
    

    现在你只需要打电话:

    initVal('bla');
    $myarr['bla']->bla = 'bla';
    

    但我明白了,你的要干净得多。