Weźmy ten kod jako podstawa: (refcounting documentation)
$a = new ArrayObject();
$a['ID'] = 42;
$b = &$a['ID'];
$c = $a;
xdebug_debug_zval('a');
xdebug_debug_zval('b');
xdebug_debug_zval('c');
Daje:
a:
(refcount=2, is_ref=0),
object(ArrayObject)[1]
public 'ID' => (refcount=2, is_ref=1),int 42
b:
(refcount=2, is_ref=1),int 42
c:
(refcount=2, is_ref=0),
object(ArrayObject)[1]
public 'ID' => (refcount=2, is_ref=1),int 42
jak mówisz : $a
to obiekt, $b
jest numerem referencyjnym: $a['ID']
($a['ID']
i $b
: refcount=2, is_ref=1
) i $ c is copy as a reference (since PHP5), więc $ c jest odniesienie $ a (to już ten sam obiekt: refcount=2, is_ref=0
)
Jeśli mamy: $c['ID'] = 37;
Dostajemy:
a:
(refcount=2, is_ref=0),
object(ArrayObject)[1]
public 'ID' => (refcount=1, is_ref=0),int 37
b:
(refcount=1, is_ref=0),int 42
c:
(refcount=2, is_ref=0),
object(ArrayObject)[1]
public 'ID' => (refcount=1, is_ref=0),int 37
$c['ID']
jest przypisany nowy int
, więc =>
$b
staje się niezależny (refcount=1
i is_ref=0
), a także $a['ID']
i $c['ID']
ale jako $c
i $a
są zależne od $a['ID']
i $c['ID']
mieć taką samą wartość 37.
Teraz rzućmy kod bazowy i robimy: $c['ID'] &= 0;
UPDATE: Niespodziewanie, otrzymujemy:
a:
(refcount=2, is_ref=0),
object(ArrayObject)[1]
public 'ID' => (refcount=2, is_ref=1),int 0
b:
(refcount=2, is_ref=1),int 0
c:
(refcount=2, is_ref=0),
object(ArrayObject)[1]
public 'ID' => (refcount=2, is_ref=1),int 0
zamiast: (jeżeli: $c['ID'] = $c['ID'] & 0;
)
a:
(refcount=2, is_ref=0),
object(ArrayObject)[1]
public 'ID' => (refcount=1, is_ref=0),int 0
b:
(refcount=1, is_ref=0),int 42
c:
(refcount=2, is_ref=0),
object(ArrayObject)[1]
public 'ID' => (refcount=1, is_ref=0),int 0
ArrayObject realizuje ArrayAccess sposób:
Jak wspomniano w komentarzu i documented here:
bezpośrednia zmiana jest, że zastępuje całkowicie wartość wymiar tablicy, jak w $ obj [6] = 7. Z drugiej strony, modyfikacja pośrednia zmienia jedynie część wymiaru lub próbuje przypisać wymiar przez odniesienie do innej zmiennej, jak w $ obj [6] [7] = 7 lub $ var = & $ obj [ 6]. Przyrosty ++ i dekrety z - są również implementowane w sposób, który wymaga pośredniej modyfikacji.
Ewentualna odpowiedź:
"Combined Operator (+ =, - =, & =, | =) może być pracował jako ten sam sposób (modyfikacja pośredni.)":
refcount
i is_ref
nie mają wpływu, dlatego (w naszym przypadku) wartości wszystkich zmiennych związanych z są modyfikowane. ($c['ID']
=>$a['ID']
=>$b)
Tak, nie sądzę, że jest to udokumentowane. Instrukcja mówi tylko, że ++ i - wykonuje pośrednie modyfikacje i tym samym wyzwala 'ArrayAccess :: offsetGet()', a nie 'ArrayAccess :: offsetSet()'. Ze względu na spójność, myślę, że + =, - = i kuzyni zostali zaimplementowani w ten sam sposób. – cleong
@cleong Nie mogę znaleźć tego w dokumentach. Czy możesz wskazać gdzie? – webmaster777