Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: ArrayAccess
Forum PHP.pl > Forum > PHP > Object-oriented programming
Athlan
Witam,

Mam klasę, która dziedziczy z ArrayAccess, mimo tego nie mogę użyć obiektu jako tablicy. Metoda offsetGet() returnuje wartość z __get():

  1. <?php
  2.  public function offsetGet($sParam)
  3.  {
  4.    return $this->__get($sParam);
  5.  }
  6.  ?>


Otrzymuję błąd:
Kod
Fatal error: Objects used as arrays in post/pre increment/decrement must return values by reference [...]


Kawałek kodu, który wywołuje błąd:
  1. <?php
  2. $oConfig = new Vframe_Config('Account', 'Validator');
  3. if($oConfig['image_process']['thumb']['width'] > 100) // tutaj jest błąd
  4. ?>


Wszystkie klucze istnieją, aby to działało, muszę zebrać wartości instancji jako tablicę (wtedy mogę czytać z $aConfig) i zapisać w zmiennej, co jest dla mnie niewygodne:
  1. <?php
  2.  
  3. $oConfig = new Vframe_Config('Account', 'Validator');
  4. $aConfig = $oConfig->dump();
  5.  
  6. ?>


Serdecznie dziękuję za support.

P.S. Szukałem, ale znalazłem jeden wątek, w którym nie do końca wyjaśniono co jest nie tak.
mike
1. W PHP nie ma takiej klasy jak ArrayAccess, więc nie możesz po niej dziedziczyć (no chyba, że masz swoją). Jeśli jednak to wynik Twojej pomyłki i miałeś na myśli to, że implementujesz interfejs ArrayAccess to ...
2. ... interfejs ArrayAccess posiada cztery metody. Jak masz zaimplementowane pozostałe poza offsetGet()?
Morkai
... i co zwraca __get()?
dr_bonzo
Moze dodaj & jako znaczik ze zwracasz przez referencje do offsetGet i __get().
Bo komunikat bledu ... hmm... troche dziwny z ta inkrementacja.

$oCostam->x ++; to by pasowalo ale do porownania??
Athlan
Dodam jeszcze, że problem jest tylko na Linuxie (ale to standard, win to wiadomo jakie g* tongue.gif).

Cytat
1. W PHP nie ma takiej klasy jak ArrayAccess, więc nie możesz po niej dziedziczyć (no chyba, że masz swoją). Jeśli jednak to wynik Twojej pomyłki i miałeś na myśli to, że implementujesz interfejs ArrayAccess to ...

Dzięki za poprawkę, chodziło mi oczywiście o interfejs.
Cytat
2. ... interfejs ArrayAccess posiada cztery metody. Jak masz zaimplementowane pozostałe poza offsetGet()?

Wszystkie odnoszą się do metod magicznych __. Np: offsetGet() z __get() (i analogicznie pozostałe: set, isset [exists], unset).

Wycinka klasy, z której dziedziczy Vframe_Config, w zasadzie Vframe_Config odpowiada tylko za zainicjownaie silnika i pobranie danych, wkłada je w formie tablicy do atrybutu $_aAttributes:

  1. <?php
  2.  
  3. class Vframe_Attribute implements Countable, Serializable, ArrayAccess, Iterator
  4. {
  5.  protected $_aAttributes = array();
  6.  
  7.  public function dump()
  8.  {
  9.    return $this->_aAttributes;
  10.  }
  11.  
  12.  public function __get($sParam)
  13.  {
  14.    return $this->__isset($sParam) ? $this->_aAttributes[$sParam] : null;
  15.  }
  16.  
  17.  public function __set($sParam, $mValue)
  18.  {
  19.    return $this->_aAttributes[$sParam] = $mValue;
  20.  }
  21.  
  22.  public function __isset($sParam)
  23.  {
  24.    return isset($this->_aAttributes[$sParam]);
  25.  }
  26.  
  27.  public function __unset($sParam)
  28.  {
  29.    if($this->__isset($sParam))
  30.      unset($this->_aAttributes[$sParam]);
  31.  }
  32.  
  33.  public function __sleep()
  34.  {
  35.    
  36.  }
  37.  
  38.  public function __wakeUp()
  39.  {
  40.    
  41.  }
  42.  
  43.  /**
  44.    * Serializable
  45.    */
  46.  
  47.  public function serialize()
  48.  {
  49.    return serialize($this->_aAttributes);
  50.  }
  51.  
  52.  public function unserialize($sString)
  53.  {
  54.    if(is_array($aAttributes = unserialize($sString)))
  55.      return $this->_aAttributes = $aAttributes;
  56.    
  57.    return false;
  58.  }
  59.  
  60.  /**
  61.    * Countable
  62.    */
  63.  public function count()
  64.  {
  65.    return count($this->_aAttributes);
  66.  }
  67.  
  68.  /**
  69.    * Iterator
  70.    */
  71.  
  72.  public function rewind()
  73.  {
  74.    reset($this->_aAttributes);
  75.  }
  76.  
  77.  public function key()
  78.  {
  79.    return key($this->_aAttributes);
  80.  }
  81.  
  82.  public function next()
  83.  {
  84.    return next($this->_aAttributes);
  85.  }
  86.  
  87.  public function current()
  88.  {
  89.    return current($this->_aAttributes);
  90.  }
  91.  
  92.  public function valid()
  93.  {
  94.    return ($this->current() !== false);
  95.  }
  96.  
  97.  // ArrayAccess
  98.  
  99.  public function offsetGet($sParam)
  100.  {
  101.    return $this->__get($sParam);
  102.  }
  103.  
  104.  public function offsetSet($sParam, $mValue)
  105.  {
  106.    return $this->__set($sParam, $mValue);
  107.  }
  108.  
  109.  public function offsetExists($sParam)
  110.  {
  111.    return $this->__isset($sParam);
  112.  }
  113.  
  114.  public function offsetUnset($sParam)
  115.  {
  116.    $this->__unset($sParam);
  117.  }
  118. }
  119.  
  120. ?>


Zrobiłem więc mały test poza środowiskiem frameworka, żeby być pewien na 100%, że to jest nie jest jego wina:

  1. <?php
  2.  
  3. class Vframe_Attribute implements ArrayAccess
  4. {
  5.  protected $_aAttributes = array();
  6.  
  7.  public function __get($sParam)
  8.  {
  9.    return $this->__isset($sParam) ? $this->_aAttributes[$sParam] : null;
  10.  }
  11.  
  12.  public function __set($sParam, $mValue)
  13.  {
  14.    return $this->_aAttributes[$sParam] = $mValue;
  15.  }
  16.  
  17.  public function __isset($sParam)
  18.  {
  19.    return isset($this->_aAttributes[$sParam]);
  20.  }
  21.  
  22.  public function __unset($sParam)
  23.  {
  24.    if($this->__isset($sParam))
  25.      unset($this->_aAttributes[$sParam]);
  26.  }
  27.  
  28.  public function offsetGet($sParam)
  29.  {
  30.    return $this->__get($sParam);
  31.  }
  32.  
  33.  public function offsetSet($sParam, $mValue)
  34.  {
  35.    return $this->__set($sParam, $mValue);
  36.  }
  37.  
  38.  public function offsetExists($sParam)
  39.  {
  40.    return $this->__isset($sParam);
  41.  }
  42.  
  43.  public function offsetUnset($sParam)
  44.  {
  45.    $this->__unset($sParam);
  46.  }
  47. }
  48.  
  49. class Vframe_Config extends Vframe_Attribute
  50. {
  51.  public function __construct()
  52.  {
  53.    $this->_aAttributes = array('a' => 1, 'b' => 2, 'c' => array(1,2));
  54.  }
  55. }
  56.  
  57. $oConfig = new Vframe_Config();
  58.  
  59. echo ($oConfig['a'] == $oConfig->b) ? 'Yes' : 'No';
  60. echo ($oConfig['not_exists']) ? 'Exists' : 'Not extsis';
  61.  
  62. foreach($oConfig['c'] as $iNumber)
  63.  echo 'Number ' . $iNumber;
  64.  
  65. ?>


Nie działa pętla foreach. (przepraszam za wprowadzenie w błąd w pierwszym poście). Dzieje się tylko przy pętlach.
Morkai
Apache 2.2 i PHP 5.3a2 na XP:
Kod
No
Not extsis
Number 1
Number 2

Apache 1.3.37 i PHP 5.2.2 na jakikolwiek-linux-jest-na lap.pl:
Kod
No
Not extsis
Number 1
Number 2


Musisz mieć zbugowaną wersję PHP winksmiley.jpg
Athlan
Wersja PHP 5.2.0-8+etch11 jest zbugowana. Na serwie mam juz 5.2.2 i śmiga. Otrzymujesz jak najbardziej zasłużone pomógł.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.