Lifesign's Blog

php中的stdClass

今天在打印某个对象的时候发现是stdClass object,找了找资料发现原来是php的一个预定义类。

Reference

stdClass类在初始时没有成员变量也没有成员方法,所有的魔术方法都被设置为NULL,所以用new stdClass()的变量,不会出现成员方法的调用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Reflection::export(new ReflectionClass('stdClass'));
/* 输出结果
Class [ <internal> class stdClass ] {
- Constants [0] {
}
- Static properties [0] {
}
- Static methods [0] {
}
- Properties [0] {
}
- Methods [0] {
}
}
</internal>
*/

值得注意的是 有些地方写stdClass是PHP的一个基类,所有的类几乎都继承这个类,这些说法是不正确的。举例如下
//新建一个空的类

1
2
class demo {}
echo ( new demo instance of stdClass) ? 'yes' : 'no'; //output no

可以看出这一说法并不正确。
从源码的维度看看stdClass类的实现,它注册的位置在 Zend/zend_buildin_functions.c文件中。

1
2
3
4
5
6
7
8
9
10
11
ZEND_MINIT_FUNCTION(core) { /*
zend_class_entry class_entry;
/* 注册stdClass 类 */
INIT_CLASS_ENTRY(class_entry, &quot;stdClass&quot;, NULL);
zend_standard_class_def = zend_register_internal_class(&amp;class_entry TSRMLS_CC);
/* 注册默认类,接口,如Exception类,SPL中的一些类等 */
zend_register_default_classes(TSRMLS_C);
return SUCCESS;}/*

这是zend_builtin_module的模块初始化函数,在PHP内核进行模块初始化操作时会自动加载这个函数, 这样,stdClass类的注册操作也就会被执行了。从这段代码可以看出,stdClass类是一个没有成员变量也没有成员方法的类。 它的所有的魔术方法,父类、接口等在初始化时都被设置成NULL。由于在PHP中对于一个类我们无法动态的添加方法, 所以这个类只能用来处理动态属性,这也是我们一种常见的用法。

参考:http://www.phppan.com/2011/05/php-stdclass/

stdClass的几种生成方式及应用

①显示的定义

如果想创建一个对象,并在其中添加一些属性,但是却不想把它作为一个明确的类正式地定义它。这时候stdClass就比较有用了

创建一个匿名的对象

实例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
$room = new stdClass();
$room->name = 'caddy';
$room->type = 'kitchen';
class Room
{
public $owner;
public function __construct($owner)
{
$this->owner = $owner;
}
public function show_room()
{
echo 'this is ' . $this->owner->name . ''s ' . $this->owner->type;
}
}
$demo = new Room($room);
$demo->show_room();//this is caddy's kitchen

②通过类型强转成object

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
$str = '云袭';
$arr = array('a' => 'www', 'b' => 'yunsea.com');
$num = 1;
$bool = true;
$null = null;
function to_object($something) {
return (object) $something;
}
var_dump(to_object($str));
var_dump(to_object($arr));
var_dump(to_object($num));
var_dump(to_object($bool));
var_dump(to_object($null));

php-stdClass

如果将一个对象转换成对象,它将不会有任何变化。如果其它任何类型的值被转换成对象,将会实例化一个内置类 stdClass 的对象。如果该值为 NULL,则新的实例为空。数组转换成对象将使键名成为属性名并具有相对应的值。对于任何其它的值,名为 scalar 的成员变量将包含该值。
③json_decode

1
2
3
<?php
$str = json_encode(array('a' => 'www', 'b' => 'yussea', 'c' => '.me'));
print_r(json_decode($str));//stdClass Object ( [a] => www [b] => yussea [c] => .me )

PHP5中,对象的调用和赋值都是引用地址型的,所以相对消耗的资源会少一点。在其它页面为它赋值时是直接修改,而不是引用一个拷贝。

1
2
3
4
5
6
$person = new stdClass();
$person->name = 'Yunsea';
$another = $person;
$another->name = '云袭';
print_r($person);//stdClass Object ( [name] => 云袭 )
print_r($another);//stdClass Object ( [name] => 云袭 )