- URL: https://www.laruence.com/en/2010/05/18/1482.html
- Please include attribution when republishing.
Before PHP4, PHP had no support for object orientation. With PHP4, PHP introduced a set of OOP keywords — and note that I say "keywords", because an object in PHP4 was nothing more than an array (the properties) plus an array of functions (the methods): no access control, no destructor (you could emulate one, of course), and so on.
Then came PHP5, and with the release of Zend Engine 2:
1. Access control 2. Interfaces 3. Magic methods (PHP4 could emulate these to a limited extent through overloading) 4. Applying interfaces 5. Built-in interfaces and so on.
PHP5 could finally be called a fairly complete object-oriented implementation.
Yet all these seemingly complex features have never fundamentally departed from the property array + method array basics. Next I will uncover the secrets hidden in the source code.
The Structure of an Object
In PHP5 an object is still carried by a zval. Do you still remember what a zval is (Deep dive into PHP internals: variables).
typedef union _zvalue_value {
long lval;
double dval;
struct {
char *val;
int len;
} str;
HashTable *ht;
zend_object_value obj;
} zvalue_value;
If a zval holds an object, then the obj member of zvalue_value points to a zend_object_value instance.
A zend_object_value has two members: one is an identifier (an integer handle) telling where the object currently sits in the global object list, and the other is a zend_object_handlers pointer, pointing to the handlers (the set of standard operations) of the class the object belongs to.
The real object entity, zend_object, holds the following key entry points:
1. ce, zend_class_entry the class entry 2. properties, hashTable the set of ordinary properties
Object Properties
As described above, ordinary properties live in a HashTable. PHP5 introduced access control, and a property's access level is distinguished by its name (to this end Zend introduced zend_mangle_property_name).
1. public property name 2. private class name property name 3. protected * property name
PHP marks property access levels with this rather ugly but simple and efficient trick. Knowing it, we can do some quite unreasonable things, such as reaching an object's private/protected properties (see: Bug #44273 access to private and protected class variables allowed when casting to array):
class Foo {
private $_name = "laruence";
protected $_age = 28;
}
$foo = new Foo();
$arr = (array) $foo;
var_dump($arr["