Data Storage

You've used PHP from the userspace side of things, so you're already familiar with the concept of an array. Any number of PHP variables (zvals) can be dropped into a single container (array) and be given names (labels) in the form of numbers or strings.

What's hopefully not surprising is that every single variable in a PHP script can be found in an array. When you create a variable, by assigning a value to it, Zend stores that value into an internal array known as a symbol table.

One symbol table, the one that defines the global scope, is initialized upon request startup just before extension RINIT methods are called, and then destroyed after script completion and subsequent RSHUTDOWN methods have executed.

When a userspace function or object method is called, a new symbol table is allocated for the life of that function or method and is defined as the active symbol table. If current script execution is not in a function or method, the global symbol table is considered active.

Taking a look at the execution globals structure (defined in Zend/zend_globals.h), you'll find the following two elements defined:

struct _zend_execution_globals {
 HashTable symbol_table;
 HashTable *active_symbol_table;

The symbol_table, accessed as EG(symbol_table), is always the global variable scope much like the $GLOBALS variable in userspace always corresponds to the global scope for PHP scripts. In fact, the $GLOBALS variable is just a userspace wrapper around the EG(symbol_table) variable seen from the internals.

The other part of this pair, active_symbol_table, is similarly accessed as EG(active_symbol_table), and represents whatever variable scope is active at the time.

The key difference to notice here is that EG(symbol_table), unlike nearly every other HashTable you'll use and encounter while working with the PHP and Zend APIs, is a direct variable. Nearly all functions that operate on HashTables, however, expect an indirect HashTable* as their parameter. Therefore, you'll have to dereference EG(symbol_table) with an ampersand when using it.

Consider the following two code blocks, which are functionally identical:


In C:

 zval *fooval;

 ZVAL_STRING(fooval, "bar", 1);
 ZEND_SET_SYMBOL(EG(active_symbol_table), "foo", fooval);

First, a new zval was allocated using MAKE_STD_ZVAL() and its value was initialized to the string "bar". Then a new macro, which roughly equates with the assignment operator (=), combines that value with a label (foo), and adds it to the active symbol table. Because no userspace function is active at the time, EG(active_symbol_table) == &EG(symbol_table), which ultimately means that this variable is stored in the global scope.

The PHP Life Cycle

Variables from the Inside Out

Memory Management

Setting Up a Build Environment

Your First Extension

Returning Values

Accepting Parameters

Working with Arrays and HashTables

The Resource Data Type

PHP4 Objects

PHP5 Objects

Startup, Shutdown, and a Few Points in Between

INI Settings

Accessing Streams

Implementing Streams

Diverting the Stream

Configuration and Linking

Extension Generators

Setting Up a Host Environment

Advanced Embedding

Appendix A. A Zend API Reference

Appendix B. PHPAPI

Appendix C. Extending and Embedding Cookbook

Appendix D. Additional Resources

Extending and Embedding PHP
Extending and Embedding PHP
ISBN: 067232704X
EAN: 2147483647
Year: 2007
Pages: 175
Authors: Sara Golemon © 2008-2020.
If you may any questions please contact us: