Intereting Posts
Создание эскиза из загруженного изображения Получить поврежденный файл xls при загрузке с помощью PHPExcel сжать / архивировать папку с помощью php-скрипта PHP preg_match с регулярным выражением: только отдельные дефисы и пробелы между словами mysqli и AJAX Предупреждение: встречено нечисловое значение Как вставить данные json в таблицу? codeigniter возвращает "Message: Undefined property: Welcome :: $ load" пытается загрузить вспомогательную библиотеку lib PHP Неустранимая ошибка: вызов неопределенной функции password_verify () Как включить образ из относительного каталога в корневой каталог в php Анализ комментариев PHP Doc в структуру данных Yii CDbConnection не удалось открыть соединение с БД: не удалось найти драйвер с облаком Google sql JSONP и GET с обратными вызовами – помощь в исправлении ошибок Почему я не могу передавать пользовательские сеансы между субдоменами? В чем разница между расширением и zend_extension в php.ini?

Создание объекта PHP ведет себя как массив?

Я бы хотел написать PHP-класс, который ведет себя как массив и использует обычный синтаксис массива для получения и настройки.

Например (где Foo – класс PHP для моего создания):

$foo = new Foo(); $foo['fooKey'] = 'foo value'; echo $foo['fooKey']; 

Я знаю, что PHP имеет методы _get и _set magic, но они не позволяют использовать нотацию массива для доступа к элементам. Python обрабатывает его, перегружая __getitem__ и __setitem__.

Есть ли способ сделать это в PHP? Если это имеет значение, я запускаю PHP 5.2.

Если вы расширяете ArrayObject или реализуете ArrayAccess вы можете делать то, что хотите.

  • ArrayObject
  • ArrayAccess

Нет, кастинг просто приводит к нормальному массиву 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.