Skip to content

Instantly share code, notes, and snippets.

@hellofromtonya
Created March 19, 2019 17:15
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hellofromtonya/53ca2cd768238eed86421c3fe0b55763 to your computer and use it in GitHub Desktop.
Save hellofromtonya/53ca2cd768238eed86421c3fe0b55763 to your computer and use it in GitHub Desktop.
Exploring PHP Variables, recount, and copy on write.
<?php
add_action( 'init', function() {
/**
* 1. PHP adds the variable into the symbols table.
* 2. PHP adds the value into the data table, which is called zval.
* 3. PHP points the value location to the variable location, binding them together.
* 4. refcount is incremented to 1.
*/
$item_1 = 'something';
/**
* Let's look at the zval for the variable $item_1:
*
* The output is:
*
* item_1:
* (refcount=1, is_ref=0),string 'something' (length=9)
*
* Notice the value is 'something' and the refcount is 1, meaning 1 variable is pointing to that memory location.
*/
xdebug_debug_zval( 'item_1' );
/**
* 1. PHP adds the variable into the symbols table.
* 2. PHP points the variable to the existing zval, i.e. value in memory.
* Why? To optimize memory usage. Instead of creating a new memory location (zval) for the value, it points
* to the same value that $item_1 is pointing to.
* 3. refcount for the value is incremented to 2.
*/
$item_2 = $item_1;
/**
* Let's look at the zval for the variable $item_1. The output is:
*
* item_1:
* (refcount=2, is_ref=0),string 'something' (length=9)
*
* Notice the value is 'something' and the refcount is 2, meaning 2 variables are pointing to that memory location,
* i.e. $item_1 and $item_2.
*/
xdebug_debug_zval( 'item_1' );
/**
* Let's look at the zval for the variable $item_2. The output is:
*
* item_2:
* (refcount=2, is_ref=0),string 'something' (length=9)
*
* Notice that's the same as $item_1. Why? They are both pointing to the exact same value memory location.
*/
xdebug_debug_zval( 'item_2' );
/**
* Now let's change the value in one of the variables and see what happens.
*
* 1. PHP creates a new memory location in the data table, i.e. creates a new zal container.
* 2. It then points $item_1's memory location in the symbols table to the new location of where the value
* lives in memory (the new zval).
* 3. It increments the new value's refcount to 1, as only one variable is pointing to it.
* 4. It decrements the old value's refcount by 1, as $item_1 is no longer pointing to it.
*
* This process is known as Copy on Write. It's used to optimize memory.
*/
$item_1 = 'something else';
/**
* Let's look at the zval for the variable $item_1. The output is:
*
* item_1:
* (refcount=1, is_ref=0),string 'something else' (length=14)
*
* Notice the recount and value match what we'd expect.
*/
xdebug_debug_zval( 'item_1' );
/**
* Let's look again at the zval for the variable $item_2. The output is:
*
* item_2:
* (refcount=1, is_ref=0),string 'something' (length=9)
*
* Notice that the refcount is 1 and the value didn't change.
*/
xdebug_debug_zval( 'item_2' );
die();
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment