从 php 源码看 php 中的对象

从一个简单的例子说起:

class Person
{
    public $name;

    public $age;

    public function __construct($name, $age)
    {
        $this->name = $name;
        $this->age = $age;
    }
}

$person = new Person("php", 20);
echo serialize($person) . PHP_EOL;

$array = [
    'name' => 'php',
    'age'  => 20,
];
echo serialize($array) . PHP_EOL;

  

输出:

O:6:"Person":2:{s:4:"name";s:3:"php";s:3:"age";i:20;}
a:2:{s:4:"name";s:3:"php";s:3:"age";i:20;}

我们通过上面的例子可以看出,person 对象和下面的数组序列化结果值的部分是相同的,只是类型不一样。

 

这就涉及到 php 中对象和普通变量之间的关系问题,实际上,在 php 中,对象也是变量的一种。

php 中 zend_value 的定义:

typedef union _zend_value {
	zend_long         lval;				/* long value */
	double            dval;				/* double value */
	zend_refcounted  *counted;
	zend_string      *str;
	zend_array       *arr;
	zend_object      *obj;
	zend_resource    *res;
	zend_reference   *ref;
	zend_ast_ref     *ast;
	zval             *zv;
	void             *ptr;
	zend_class_entry *ce;
	zend_function    *func;
	struct {
		uint32_t w1;
		uint32_t w2;
	} ww;
} zend_value;

  

而对象的类型是 zend_object:

struct _zend_object {
	zend_refcounted_h gc;
	uint32_t          handle; // TODO: may be removed ???
	zend_class_entry *ce;
	const zend_object_handlers *handlers;
	HashTable        *properties;
	zval              properties_table[1];
};

  

也就是说,对象只是一种结构不一样的变量而已,而其结构中,包含了一个对象的所有属性、方法(甚至还有引用计数)。

其中,ce 是存储该对象的类结构,在对象初始化时保存了类的入口,相当于类指针的作用。

properties 是一个 HashTable,用来存放对象属性。

 从上图可以看出,对象和数组存在一定的相似,只不过对象还有一个类指针,通过该指针我们可以实现很多数组不具备的功能。

 

对象与数组:

对象可以转化为数组(get_object_vars()),数组也可以转化为对象(stdClass)。

 

posted @ 2018-05-06 17:48  佚名000  阅读(186)  评论(0编辑  收藏  举报