Making a PHP object behave like an array?

前端 未结 2 603
忘了有多久
忘了有多久 2020-12-23 22:12

I\'d like to be able to write a PHP class that behaves like an array and uses normal array syntax for getting & setting.

For example (where Foo is a PHP class of

相关标签:
2条回答
  • 2020-12-23 22:30

    If you extend ArrayObject or implement ArrayAccess then you can do what you want.

    • ArrayObject
    • ArrayAccess
    0 讨论(0)
  • 2020-12-23 22:37

    Nope, casting just results in a normal PHP array -- losing whatever functionality your ArrayObject-derived class had. Check this out:

    class CaseInsensitiveArray extends ArrayObject {
        public function __construct($input = array(), $flags = 0, $iterator_class =     'ArrayIterator') {
            if (isset($input) && is_array($input)) {
                $tmpargs = func_get_args();
                $tmpargs[0] = array_change_key_case($tmpargs[0], CASE_LOWER);
                return call_user_func_array(array('parent', __FUNCTION__), $tmp    args);
            }
            return call_user_func_array(array('parent', __FUNCTION__), func_get_args());
        }
    
        public function offsetExists($index) {
            if (is_string($index)) return parent::offsetExists(strtolower($index));
            return parent::offsetExists($index);
        }
    
        public function offsetGet($index) {
            if (is_string($index)) return parent::offsetGet(strtolower($index));
            return parent::offsetGet($index);
        }
    
        public function offsetSet($index, $value) {
            if (is_string($index)) return parent::offsetSet(strtolower($index, $value));
            return parent::offsetSet($index, $value);
        }
    
        public function offsetUnset($index) {
            if (is_string($index)) return parent::offsetUnset(strtolower($index));
            return parent::offsetUnset($index);
        }
    }
    
    $blah = new CaseInsensitiveArray(array(
        'A'=>'hello',
        'bcD'=>'goodbye',
        'efg'=>'Aloha',
    ));
    
    echo "is array: ".is_array($blah)."\n";
    
    print_r($blah);
    print_r(array_keys($blah));
    
    echo $blah['a']."\n";
    echo $blah['BCD']."\n";
    echo $blah['eFg']."\n";
    echo $blah['A']."\n";
    

    As expected, the array_keys() call fails. In addition, is_array($blah) returns false. But if you change the constructor line to:

    $blah = (array)new CaseInsensitiveArray(array(
    

    then you just get a normal PHP array (is_array($blah) returns true, and array_keys($blah) works), but all of the functionality of the ArrayObject-derived subclass is lost (in this case, case-insensitive keys no longer work). Try running the above code both ways, and you'll see what I mean.

    PHP should either provide a native array in which the keys are case-insensitive, or make ArrayObject be castable to array without losing whatever functionality the subclass implements, or just make all array functions accept ArrayObject instances.

    0 讨论(0)
提交回复
热议问题