The confusion about recounting PHP 7

<?php $s = "foobar"; $t = $s; $u = $s; echo PHP_VERSION . "\n"; debug_zval_dump($s); xdebug_debug_zval('s'); 

Running in PHP 5.6.16

php 5 refcount

Running in PHP 7.0.2

php 7 refcount

I think the result (PHP 7) should be:

 string(6) "foobar" refcount(4) s: (refcount=3, is_ref=0)="foobar" 

I wonder what is the difference? You need an explanation. Thank you very much.

------ update ------

Nikita Popov - PHP 7 - What Has Changed Inside? (P41)

http://www.slideshare.net/nikita_ppv/php-7-what-changed-internally

slideshare

+6
source share
1 answer

In PHP 7, zval can refer to a link or not. A flag is specified in the zval structure.

There are some types that are never recounted. These types are: null, bool, int and double.

There are other types that are always recounted. These are objects, resources, and links.

And then there are types that are sometimes recounted. These are strings and arrays.

For strings, the non-refcounted option is called the "intern string". If you use the NTS (non-thread safe) PHP 7 assembly that you usually use, all string literals in your code will be interned. These interned strings are deduplicated (i.e. there is only one interned row with specific content) and are guaranteed to exist throughout the duration of the request, so there is no need to use reference counting for them. If you use opcache, these lines will live in shared memory, and in this case you cannot use reference counting for them (since our recount mechanism is non-atomic). Interned strings have a dummy recount of 1, which you see here.

For non-refcounted arrays, the option is called an "immutable array". If you use opcache, constant literals in your code will be converted to immutable arrays. Once again, they live in shared memory and as such should not use refcounting. Immutable arrays have a fictitious recount of 2, since this allows us to optimize certain separation paths.

+8
source

All Articles