implements ArrayAccess

Opik

Новичок
implements ArrayAccess

Есть некий класс:
PHP:
  class Data implements ArrayAccess
 ....
       // $this->data экземпляр класса User
       function offsetSet($offset, $value)
       {
            $this->data->$offset = $value;
       }
$data - экземпляр класса: data
$plugin_info - свойство класса User
// ниженаписанное почему то не меняет свойство класса, а добавляет новое к классу Data
$data->plugin_info['silence_start'] = 2;


Перепробовал всё, но никак не то что нужно
 

Opik

Новичок
Есть :)

-~{}~ 12.11.05 23:07:

Если я конечно правильно понял,но этот пример работает:
PHP:
 class Data implements ArrayAccess
  {
       protected $data = array();
       protected function __construct($mid)
       {
            $this->data // bla bla getting info
       }

       function getUser($id)
       {
            return new Data($id);
       }

       function userExists()
       {
            return $this->data == false ? false : true;
       }

       function offsetUnset($offset)
       {
            //   throw new Exception("User.offsetUnset: user property '{$offset}' can not be unset!");
       }

       function offsetGet($offset)
       {
            return isset($this->data[$offset])? $this->data[$offset]: null;
       }

       function offsetExists($offset)
       {
            return isset($this->data[$offset]) ? true : false;
       }

       function offsetSet($offset, $value)
       {
            $this->data[$offset] = $value;
       }
}
$data = data::getUser(100);
if($data->userExists())
{
print $data['login'];
}
 

svetasmirnova

маленький монстрик
PHP:
<?php
class Data implements ArrayAccess
  {
       protected $data = array();
	   
       public function __construct($last)
       {
            $this->data = range(0, $last);
       }

       // остальные методы реализованы как и выше

       function offsetSet($offset, $value)
       {
            $this->data[$offset] = $value;
       }
}

$data = new Data(5);
$data[3] = 10;
echo $data[3];
?>
Простой пример работает: давай-ка приводи код с инициализацией члена plugin_info.
 

Opik

Новичок
PHP:
  class Data implements ArrayAccess
  {
       protected $data = array();
       protected function __construct($mid)
       {
            $this->data  = $this->getDataFile($mid);
       }

       static function getData($mid)
       {
 // инфа
       }

       public function isUserExists()
       {
            return $this->data == false ? false : true;
       }

       function offsetUnset($offset)
       {
            //   throw new Exception("User.offsetUnset: user property '{$offset}' can not be unset!");
       }

       function offsetGet($offset)
       {
            return isset($this->data->$offset)? $this->data->$offset: null;
       }

       function offsetExists($offset)
       {
            return isset($this->data->$offset) ? true : false;
       }

       function offsetSet($offset, $value)
       {
            $this->data->$offset = $value;
       }
  }
так ПХП ругается чуть ли не матом
$data = Data::getData(598);
$data['plugin_info']['silence_time'] = 2;
а так работает:

$data = Data::getData(598);
$new = $data['plugin_info'];
$new['silence_time'] = 2;
$data['plugin_info'] = $new;
 

itprog

Cruftsman
Попробовал
$data = Data::getData(598);
$data['plugin_info']['silence_time'] = 2;

Результат:
Array ( [plugin_info] => Array ( [silence_time] => 2 ) )

Версия PHP: 5.1.0RC5-dev
 

white phoenix

Новичок
интересно экспериментировать...

-~{}~ 13.11.05 04:15:

честно говоря не очень понял почему
PHP:
$data = Data::getData(598);
$data['plugin_info']['silence_time'] = 2;
ругается матом, это работает:
PHP:
$data = Data::getData(598);
$new = $data['plugin_info'];
$new['silence_time'] = 2;
$data['plugin_info'] = $new;
в чем принципиальное отличие
PHP:
$data['plugin_info']['silence_time'] = 2;
и
PHP:
$data['plugin_info'] = $new;
?
 

Opik

Новичок
Может бага PHP? у меня 5.0.4

-~{}~ 13.11.05 12:30:

Раз у itprog работает
 

Profic

just Profic (PHP5 BetaTeam)
Для того, чтобы работало
PHP:
$objectOfClassImplementingArrayAccess['dim1']['dim2'] = 'something';
в php5 нужно, чтобы offsetGet возвращал reference, о чем собственно и повествует "мат", которым ругается php.
 

Opik

Новичок
PHP:
       function &offsetGet($offset)
       {
            return isset($this->data->$offset)? $this->data->$offset: null;
       }
так? пробовал уже.
 

Profic

just Profic (PHP5 BetaTeam)
Оказывается все вообще странно :)
E:\>type test10.1.php
PHP:
<?php
class SuperArray implements ArrayAccess {
        private $store = NULL;

        public function __construct() {
                $this->store = new StdClass();
        }

        public function offsetExists($offset) {
                return isset($this->store->$offset);
        }

        public function offsetGet($offset) {
                if (!isset($this->store->$offset)) {
                        $this->store->$offset = NULL;
                }
                return $this->store->$offset;
        }

        public function offsetSet($offset, $value) {
                $this->store->$offset = $value;
                return true;
        }

        public function offsetUnset($offset) {
                unset($this->store->$offset);
                return true;
        }
}

$arr = new SuperArray();
$arr['dim1']['dim2'] = 'ok';
var_dump($arr);
?>
E:\>type test10.2.php
PHP:
<?
// тоже самое, только offsetGet() возвращает reference
?>
E:\>php -v
PHP 5.1.0RC4-dev (cli) (built: Oct 28 2005 14:00:22)
Copyright (c) 1997-2005 The PHP Group
Zend Engine v2.1.0-dev, Copyright (c) 1998-2005 Zend Technologies

E:\>php test10.1.php

Fatal error: Objects used as arrays in post/pre increment/decrement must return values by reference in E:\test10.1.php on line 34

E:\>php test10.2.php

Fatal error: Declaration of SuperArray::eek:ffsetGet() must be compatible with that of ArrayAccess::eek:ffsetGet() in E:\test10.2.php on line 2

E:\>"c:\web files\php50\php.exe" -v
PHP 5.0.6-dev (cli) (built: Oct 11 2005 02:25:10)
Copyright (c) 1997-2004 The PHP Group
Zend Engine v2.0.5, Copyright (c) 1998-2004 Zend Technologies
with Xdebug v2.0.0beta5-dev, Copyright (c) 2002, 2003, 2004, 2005, by Derick Rethans

E:\>"c:\web files\php50\php.exe" test10.1.php

Fatal error: Objects used as arrays in post/pre increment/decrement must return values by reference in E:\test10.1.php on line 34

Call Stack:
0.0005 1. {main}() E:\test10.1.php:0

E:\>"c:\web files\php50\php.exe" test10.2.php
Код:
object(SuperArray)#1 (1) {
  ["store:private"]=>
  object(stdClass)#2 (1) {
    ["dim1"]=>
    &array(1) {
      ["dim2"]=>
      string(2) "ok"
    }
  }
}
E:\>
PS. Собрать более свежую версию php5.1 никак руки не дойдут.
 

Opik

Новичок
Profic
аналогичная ситуёвина и на:

C:\php>php -v
PHP 5.1.0RC5-dev (cli) (built: Nov 11 2005 00:23:52)
Copyright (c) 1997-2005 The PHP Group
Zend Engine v2.1.0-dev, Copyright (c) 1998-2005 Zend Technologies
 

svetasmirnova

маленький монстрик
Мда... Зря я пост itprog внимательно не прочитала. Он же ссылку на массив получает, после чего пользуется синтаксисом []
 

Opik

Новичок
itprog
Ты пробовал второй вариант класса? они различаются.
 

Profic

just Profic (PHP5 BetaTeam)
svetasmirnova
Он скорее всего воспользовался кодом один в один, как приведен был, а в нем Data::getData() ничего не возвращает, т.е. возвращает NULL. Такой вариант будет работать в любой версии php.
 

itprog

Cruftsman
Я пробовал
PHP:
class Data implements ArrayAccess
  {
       protected $data = array();
       protected function __construct($mid)
       {
            $this->data  = $this->getDataFile($mid);
       }

       static function getData($mid)
       {
       }

       public function isUserExists()
       {
            return $this->data == false ? false : true;
       }

       function offsetUnset($offset)
       {
            //   throw new Exception("User.offsetUnset: user property '{$offset}' can not be unset!");
       }

       function offsetGet($offset)
       {
            return isset($this->data->$offset)? $this->data->$offset: null;
       }

       function offsetExists($offset)
       {
            return isset($this->data->$offset) ? true : false;
       }

       function offsetSet($offset, $value)
       {
            $this->data->$offset = $value;
       }
  }

$data = Data::getData(598);
$data['plugin_info']['silence_time'] = 2;
-~{}~ 13.11.05 21:18:

ArrayObject/ArrayIterator simply implement the ArrayAccess imnterface
which doesn't handle multi dimensional array syntax. As you pointer out
already you could have ArrayObject store ArrayObjects itself. Thus the
solution is to overwrite ArrayObject.
(c) bugs.php.net

PS: Действительно фигня какая-то..
 

svetasmirnova

маленький монстрик
Да не фигня Profic прав совершенно:
PHP:
//getData вернула null
$data = Data::getData(598);
//присвоили переменной $data массив с одним элементом
$data['plugin_info']['silence_time'] = 2;
 
Сверху