题
我希望能够编写一个行为类似于数组的 PHP 类,并使用正常的数组语法来获取和设置。
例如(其中 Foo 是我制作的 PHP 类):
$foo = new Foo();
$foo['fooKey'] = 'foo value';
echo $foo['fooKey'];
我知道 PHP 有 _get 和 _set 魔术方法,但这些方法不允许您使用数组表示法来访问项目。Python 通过重载 __getitem__ 和 __setitem__ 来处理它。
有没有办法在 PHP 中做到这一点?如果有影响的话,我正在运行 PHP 5.2。
其他提示
不,强制转换只会产生普通的 PHP 数组——丢失 ArrayObject 派生类所具有的任何功能。看一下这个:
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";
正如预期的那样,array_keys() 调用失败。此外,is_array($blah) 返回 false。但如果将构造函数行更改为:
$blah = (array)new CaseInsensitiveArray(array(
那么你只会得到一个普通的 PHP 数组(is_array($blah) 返回 true,并且 array_keys($blah) 起作用),但是 ArrayObject 派生子类的所有功能都丢失了(在这种情况下,不区分大小写的键不再工作)。尝试以两种方式运行上面的代码,您就会明白我的意思。
PHP 应该提供一个本机数组,其中键不区分大小写,或者使 ArrayObject 可转换为数组而不丢失子类实现的任何功能,或者只是使所有数组函数接受 ArrayObject 实例。
不隶属于 StackOverflow