PHP定义的第二个参数使用方法
标量和空是允许的。标量的类型是整数、浮点数、字符串或布尔值。常量的类型也可以定义为资源,但不推荐,这可能导致未知条件的发生。
阅读PHP的源代码,发现第二个定义参数实际上可以是一个对象。
首先举个例子:
复制代码代码如下所示:
类{
公共功能__tostring(){
return'bar;
}
}
美元=新的A();
定义('foo,美元);
回声Foo;
输出
接下来,看看PHP中的定义是如何实现的。
复制代码代码如下所示:
zend_function(定义)
{
char *名称;
国际name_len;
*值变量;
zval * val_free = null;
zend_bool non_cs = 0;
国际case_sensitive = const_cs;
zend_constant C;
接收 / / 3参数,字符串,布尔变量,
如果(zend_parse_parameters(zend_num_args(tsrmls_cc)、深圳| B
返回;
}
/区分大小写
如果(non_cs){
case_sensitive = 0;
}
如果定义错误是常数。
如果(zend_memnstr(名称,::
zend_error(e_warning,类常量不能定义或重新定义了);
return_false;
}
获取真正的值,使用保存的
重复:
开关(z_type_p(Val)){
案例is_long:
案例is_double:
案例is_string:
案例is_bool:
案例is_resource:
案例is_null:
打破;
案例is_object:
如果(!val_free){
如果(z_obj_ht_p(Val)->得到){
val_free = = z_obj_ht_p缬氨酸(Val)->得到(Val tsrmls_cc);
去重复;
} else if(z_obj_ht_p(Val)-> cast_object){
alloc_init_zval(val_free);
如果(z_obj_ht_p(Val)-> cast_object(Val,val_free,is_string,tsrmls_cc)= =成功){
val_free val =;
打破;
}
}
}
没有中断/ ***
违约:
zend_error(e_warning,常数只能评估标量值);
如果(val_free){
zval_ptr_dtor(val_free);
}
return_false;
}
构建常量
c.value =×Val;
zval_copy_ctor(c.value);
如果(val_free){
zval_ptr_dtor(val_free);
}
c.flags = case_sensitive非持久性; / * * /
c.name = zend_strndup(名称、name_len);
c.name_len = name_len + 1;
c.module_number = php_user_constant;
注册/常量
如果(zend_register_constant(C tsrmls_cc)= =成功){
return_true;
{人}
return_false;
}
}
注意一个循环开始,重复,和使用goto语句t_t
此代码的功能是:
对于int,float,字符串,布尔,资源,null,使用这些值直接当实际常量定义
对于对象,您需要将对象转换为上面提到的6种类型之一(如果转换后仍然是对象,则继续转换)
如何使对象成为这6种类型中的一种有2种方法可以查看代码:
复制代码代码如下所示:
如果(z_obj_ht_p(Val)->得到){
val_free = = z_obj_ht_p缬氨酸(Val)->得到(Val tsrmls_cc);
去重复;
}
/ / __tostring()方法是在cast_object叫
如果(z_obj_ht_p(Val)-> cast_object){
alloc_init_zval(val_free);
如果(z_obj_ht_p(Val)-> cast_object(Val,val_free,is_string,tsrmls_cc)=成功)
{
val_free val =;
打破;
}
}
1、z_obj_ht_p(Val)->得到,在宏扩展(* Val)。价值。对象句柄->得到
2、z_obj_ht_p(Val)-> cast_object,在宏扩展(* Val)。价值。对象句柄-> cast_object
句柄是一个结构,包含了大量的函数指针,它专门定义的结构_zend_object_handlers.the函数指针来操作对象,如阅读或修改对象的属性,获取和调用对象的方法,等等…得到和cast_object也是其中之一。
对于一般的物体,PHP提供了一个标准的cast_object功能,zend_std_cast_object_tostring,位于src / / Zend PHP Zend对象句柄。C:
复制代码代码如下所示:
zend_api int zend_std_cast_object_tostring(zval * readobj,zval * writeobj,int型tsrmls_dc) / / *
{
*用zval;
zend_class_entry *;
开关(类型){
案例is_string:
CE = z_objce_p(readobj);
/ /如果用户定义的类__tostring,试着打
如果(CE -> __tostring
(zend_call_method_with_0_params(readobj,CE,CE -> __tostring,__tostring,retval)| | EG(例外))){
......
}
返回失败;
......
}
返回失败;
}
从具体实现,默认cast_object是找到__tostring类然后调用方法…
回到最初的示例,定义()