Press "Enter" to skip to content

PHP Internals — Variable Scope in PHP

My earlier article (Understanding PHP Internals: Variables Inside PHP) covered the internal representation of PHP variables. But that raises a question: how are those internal representations tied to the variables in a user script? In other words, if I write this in a script:

<?php
  $var = "laruence";
  echo $var;
?>

how does the ZE connect my variable var to the internal structure, the zval?
As I explained in the variables article, PHP internally represents every variable with a zval, but in the script above our variable has a name, var, and zval has no field that carries the variable name.
If you guessed that PHP must have some internal mechanism that maps variable names to zvals, then you are really clever 😉
In PHP, all variables are stored in an array (a hash table, to be precise), and PHP also uses different arrays to implement variable scope.
When you create a variable, PHP allocates a zval for it, fills in the value, and then puts the variable's name and a pointer to that zval into an array. Later, when you access the variable, PHP looks up that array and gets the corresponding zval.
Take a look at the _zend_executor_globals structure (this structure holds some execution context in the PHP executor):

struct _zend_executor_globals {
	....
    HashTable *active_symbol_table;/*active symbol table*/
    HashTable symbol_table;     /*global symbol table*/
    HashTable included_files;
    jmp_buf *bailout;
    int error_reporting;
	.....
}
 

Among these, the global symbol table holds the variables in the top-level scope (that is, not inside any function or object). Every time a function (or an object's method) is called, an active symbol table is created for that function, and all variables defined inside the function are kept in this active symbol table.
Right, this is how PHP implements variable scope! Here is an example:

  <?php
	$var = "I am in the global symbol table";
    function sample($para){
        $var = "I am in the active symbol table";
		echo $var;
 	}
    sample($var);
    echo $var;
  ?>

The variable $var outside the function sample goes into the global symbol table, and it has a corresponding zval pointer; that zval holds the string "I am in the global symbol table".
The $var inside the function goes into the active symbol table belonging to sample, and likewise its corresponding zval holds the string "I am in the active symbol table
".
The special case is the parameter $para of sample. This $para is kept in sample's active symbol table, but its corresponding zval pointer points to a zval that holds a copy of the global variable $var (strictly speaking it is not a copy but a reference; this involves the copy-on-write mechanism of variables, which I will cover later).
We all know that PHP passes simple variables by value, but what I want to tell you is that PHP does not implement pass-by-value simply by copying a zval. Hehe, I will leave you in suspense and explain next time.

Be First to Comment

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.