PHP.mk документација

Основи на броење на референци

Почист и полокален преглед на PHP референцата, со задржана структура од PHP.net и подобра читливост за примери, секции и белешки.

features.gc.refcounting-basics.php PHP.net прокси Преводот е вчитан
Оригинал на PHP.net
Патека features.gc.refcounting-basics.php Локална патека за оваа страница.
Извор php.net/manual/en Оригиналниот HTML се реупотребува и локално се стилизира.
Режим Прокси + преведен приказ Кодовите, табелите и белешките остануваат читливи во истиот тек.
Основи на броење на референци

Референца за `features.gc.refcounting-basics.php` со подобрена типографија и навигација.

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
)

Или графички

Zvals for a simple array

Трите 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'
)

Или графички

Zvals for a simple array with a reference

Од горенаведениот 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)=...
)

Или графички

Zvals for an array with a circular reference

Пример #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)=...
)

Или графички

Zvals after removal of array with a circular reference demonstrating the memory leak

Можете да видите дека променливата на низата (

) како и вториот елемент (по референца".

) сега покажуваат на контејнер на променлива што има "refcount" од

Белешки од корисници 6 белешки

Анонимен
пред 11 години
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');
. "..." во приказот погоре покажува дека е вклучена рекурзија, што, се разбира, во овој случај значи дека "..." покажува назад кон оригиналната низа.
пред 8 години
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.html
Анонимен
пред 11 години
If a variable is not present in the current scope xdebug_debug_zval will return null.
по извршувањето на горниот код, бројот на референци на контејнерот на променливата на кој
пред 7 години
my 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.
и елементот "1" покажуваат се намалува за еден, од "2" на "1". Ова може да се претстави како:
пред 6 години
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
На оваа страница

Автоматски outline од активната документација.

Насловите ќе се појават тука по вчитување.

Попрегледно читање

Примерите, changelog табелите и user notes се визуелно издвоени за да не се губат во долгата содржина.

Брз совет Користи го outline-от Скокни директно на главните секции од активната страница.
Извор Оригиналниот линк останува достапен Кога ти треба целосен upstream context, отвори го PHP.net во нов tab.