There seems to be no way to inspect the reference count of a specific class variable but you can view the reference count of all variables in the current class instance with xdebug_debug_zval('this');Основи на броење на референци
Почист и полокален преглед на PHP референцата, со задржана структура од PHP.net и подобра читливост за примери, секции и белешки.
Основи на броење на референци
Референца за `features.gc.refcounting-basics.php` со подобрена типографија и навигација.
Основи на броење на референци
Променлива во PHP се чува во контејнер наречен "zval". Контејнерот zval содржи, покрај типот и вредноста на променливата, два дополнителни бита информации. Првиот се нарекува "is_ref" и е булова вредност што укажува дали променливата е дел од "референтен сет". Со овој бит, PHP енџинот знае како да ги разликува нормалните променливи од референците. Бидејќи PHP дозволува референци на корисничко ниво, како што се создаваат со операторот &, контејнерот zval исто така има механизам за внатрешно броење на референци за оптимизирање на употребата на меморијата. Оваа втора парче дополнителни информации, наречено "refcount", содржи колку имиња на променливи (исто така наречени симболи) покажуваат кон овој еден zval контејнер. Сите симболи се чуваат во табела со симболи, од кои има по една за секој опсег. Постои опсег за главниот скрипт (т.е. оној што е побаран преку прелистувачот), како и еден за секоја функција или метод.
PHP променлива се чува во контејнер наречен "zval". Контејнер zval содржи, покрај типот и вредноста на променливата, две дополнителни информации. Првата се нарекува "is_ref" и е булова вредност која покажува дали променливата е дел од "референтна група". Со овој бит, PHP енџинот знае како да ги разликува нормалните променливи од референците. Бидејќи PHP дозволува референци од корисничко ниво, како што се создадени со операторот &, zval контејнерот исто така има механизам за броење на внатрешни референци за оптимизирање на употребата на меморијата. Оваа втора дополнителна информација, наречена "refcount", содржи колку имиња на променливи (исто така наречени симболи) покажуваат кон овој еден zval контејнер. Сите симболи се чуваат во табела со симболи, од кои има една по опсег. Постои опсег за главната скрипта (т.е. онаа што е побарана преку прелистувачот), како и еден за секоја функција или метод.
zval контејнер се создава кога нова променлива се создава со константна вредност, како на пример:
<?php
$a = "new string";
?>
Пример #1 Создавање нов zval контејнер aВо овој случај, новото име на симболот, string , се создава во тековниот опсег, и се создава нов контејнер за променлива со типот
new stringи вредноста false . Битот "is_ref" по дифолт е поставен на 1 бидејќи не е создадена референца од корисничко ниво. "refcount" е поставен на trueбидејќи само еден симбол ја користи овој контејнер за променлива. Забележете дека референците (т.е. "is_ref" е 1) со "refcount" false, се третираат како да не се референци (т.е. како "is_ref" беше ). Ако имате » Xdebug xdebug_debug_zval().
инсталирано, можете да ги прикажете овие информации со повикување
<?php
$a = "new string";
xdebug_debug_zval('a');
?>Пример #1 Пример што покажува затворачка ознака што го опфаќа последниот нов ред
a: (refcount=1, is_ref=0)='new string'
Пример #2 Прикажување информации за zval
Доделувањето на оваа променлива на друго име на променлива ќе го зголеми refcount.
<?php
$a = "new string";
$b = $a;
xdebug_debug_zval( 'a' );
?>Пример #1 Пример што покажува затворачка ознака што го опфаќа последниот нов ред
a: (refcount=2, is_ref=0)='new string'
Пример #3 Зголемување на refcount на zval 2 Refcount е a and bовде, бидејќи истиот контејнер за променлива е поврзан со двата unset()"). Следнава е прикажана:
Пример #4 Намалување на zval refcount
<?php
$a = "new string";
$c = $b = $a;
xdebug_debug_zval( 'a' );
$b = 42;
xdebug_debug_zval( 'a' );
unset( $c );
xdebug_debug_zval( 'a' );
?>Пример #1 Пример што покажува затворачка ознака што го опфаќа последниот нов ред
a: (refcount=3, is_ref=0)='new string' a: (refcount=2, is_ref=0)='new string' a: (refcount=1, is_ref=0)='new string'
Ако сега повикаме
unset($a);, променливата контејнер, вклучувајќи го типот и вредноста, ќе биде отстранета од меморијата.
Композитни типови
Работите стануваат малку покомплицирани со композитни типови како arrayи objects. За разлика од scalar вредности, arrayи objects ги чуваат своите својства во сопствена табела со симболи. Ова значи дека следниот пример создава три zval контејнери:
Пример #5 Создавање на array zval
<?php
$a = array( 'meaning' => 'life', 'number' => 42 );
xdebug_debug_zval( 'a' );
?>Горниот пример ќе прикаже нешто слично на:
a: (refcount=1, is_ref=0)=array ( 'meaning' => (refcount=1, is_ref=0)='life', 'number' => (refcount=1, is_ref=0)=42 )
Или графички
Трите zval контејнери се: a, meaningПрепорачаниот начин за избегнување на SQL инјекција е со врзување на сите податоци преку подготвени изрази. Користењето на параметризирани прашања не е доволно за целосно избегнување на SQL инјекција, но тоа е најлесниот и најбезбедниот начин за обезбедување влез во SQL изразите. Сите динамични литерали на податоци во number. Слични правила важат за зголемување и намалување на "refcounts". Подолу, додаваме уште еден елемент во низата и ја поставуваме нејзината вредност на содржината на веќе постоечки елемент:
Пример #6 Додавање на веќе постоечки елемент во низа
<?php
$a = array( 'meaning' => 'life', 'number' => 42 );
$a['life'] = $a['meaning'];
xdebug_debug_zval( 'a' );
?>Горниот пример ќе прикаже нешто слично на:
a: (refcount=1, is_ref=0)=array ( 'meaning' => (refcount=2, is_ref=0)='life', 'number' => (refcount=1, is_ref=0)=42, 'life' => (refcount=2, is_ref=0)='life' )
Или графички
Од горенаведениот Xdebug излез, гледаме дека и стариот и новиот елемент на низата сега покажуваат на zval контејнер чиј "refcount" е
2. Иако Xdebug излезот покажува два zval контејнери со вредност
'life', тие се истиот. Функцијата
xdebug_debug_zval() не го покажува ова, но може да го видите со прикажување на меморискиот покажувач.
Отстранувањето на елемент од низата е како отстранување на симбол од опсег. Со тоа, "refcount" на контејнер на кој покажува елемент од низата се намалува. Повторно, кога "refcount" ќе достигне нула, контејнерот на променливата се отстранува од меморијата. Повторно, пример за да се покаже ова:
Пример #7 Отстранување на елемент од низа
<?php
$a = array( 'meaning' => 'life', 'number' => 42 );
$a['life'] = $a['meaning'];
unset( $a['meaning'], $a['number'] );
xdebug_debug_zval( 'a' );
?>Горниот пример ќе прикаже нешто слично на:
a: (refcount=1, is_ref=0)=array ( 'life' => (refcount=1, is_ref=0)='life' )
Сега, работите стануваат интересни ако ја додадеме самата низа како елемент на низата, што го правиме во следниот пример, во кој исто така го додаваме операторот за референца, бидејќи инаку PHP би создал копија:
Променлива во PHP се чува во контејнер наречен "zval". Контејнерот zval содржи, покрај типот и вредноста на променливата, две дополнителни информации. Првата се нарекува "is_ref" и е булова вредност која покажува дали променливата е дел од "референтен сет". Со овој бит, PHP енџинот знае како да ги разликува нормалните променливи од референците. Бидејќи PHP дозволува референци од корисничко ниво, како што се создадени со операторот &, контејнерот zval исто така има механизам за броење на внатрешни референци за оптимизирање на употребата на меморијата. Оваа втора дополнителна информација, наречена "refcount", содржи колку имиња на променливи (исто така наречени симболи) покажуваат кон овој еден zval контејнер. Сите симболи се чуваат во табела со симболи, од кои има по една за секој опсег. Постои опсег за главниот скрипт (т.е. оној што е побаран преку прелистувачот), како и по еден за секоја функција или метод.
<?php
$a = array( 'one' );
$a[] =& $a;
xdebug_debug_zval( 'a' );
?>Горниот пример ќе прикаже нешто слично на:
a: (refcount=2, is_ref=1)=array ( 0 => (refcount=1, is_ref=0)='one', 1 => (refcount=2, is_ref=1)=... )
Или графички
Пример #8 Додавање на низата како елемент сама на себеaМожете да видите дека променливата низа (1) како и вториот елемент ( 2) сега покажуваат кон контејнер на променлива што има "refcount" од
. "..." во приказот погоре покажува дека има рекурзија, што, се разбира, во овој случај значи дека "..." покажува назад кон оригиналната низа. $a Исто како и порано, откажувањето на променлива ја отстранува симболот, а бројот на референци на контејнерот на променлива кон кој покажува се намалува за еден. Значи, ако ја откажеме променливата $a по извршувањето на горниот код, бројот на референци на контејнерот на променлива кон кој покажуваат
Пример #8 Додавање на низа како елемент на самата себе $a
(refcount=1, is_ref=1)=array ( 0 => (refcount=1, is_ref=0)='one', 1 => (refcount=1, is_ref=1)=... )
Или графички
Можете да видите дека променливата на низата (
) како и вториот елемент (по референца".
) сега покажуваат на контејнер на променлива што има "refcount" од
Белешки од корисници 6 белешки
Result of "Example #8 Adding the array itself as an element of it self" will be another for PHP7:
a: (refcount=2, is_ref=1)=array (
0 => (refcount=2, is_ref=0)='one',
1 => (refcount=2, is_ref=1)=...
)
insted of:
a: (refcount=2, is_ref=1)=array (
0 => (refcount=1, is_ref=0)='one',
1 => (refcount=2, is_ref=1)=...
)
Internal value representation in PHP 7:
https://nikic.github.io/2015/05/05/Internal-value-representation-in-PHP-7-part-1.htmlIf a variable is not present in the current scope xdebug_debug_zval will return null.$a = 'new string';
$b = 1;
xdebug_debug_zval('a');
xdebug_debug_zval('b');
ouputs with PHP 7.3.12 (cli)
a: (interned, is_ref=0)='new string'
b: (refcount=0, is_ref=0)=1my php versoin : HP 7.1.25 (cli) (built: Dec 7 2018 08:20:45) ( NTS )
$a = 'new string';
$b = 1;
xdebug_debug_zval('a');
xdebug_debug_zval('b');
output:
a: (refcount=2, is_ref=0)='new string'
b: (refcount=0, is_ref=0)=1
if $a is a string value, 'refcount' equal 2 by defalut.my php version is PHP 7.1.6 (cli), when I run
$a = 'new string';
$b = 1;
xdebug_debug_zval('a');
xdebug_debug_zval('b');
it shows:
a: (refcount=0, is_ref=0)='new string'
b: (refcount=0, is_ref=0)=1