可用看出如果字符串链接的两个操作数如果不是字符串的话, 则调用zend_make_printable_zval函数将操作数转换为"printable_zval"也就是字符串。ZEND_API void zend_make_printable_zval(zval *expr, zval *expr_copy, int *use_copy)
{if (Z_TYPE_P(expr)==IS_STRING) {*use_copy = 0;return;}switch (Z_TYPE_P(expr)) {case IS_NULL:Z_STRLEN_P(expr_copy) = 0;Z_STRVAL_P(expr_copy) = STR_EMPTY_ALLOC();break;case IS_BOOL:if (Z_LVAL_P(expr)) {Z_STRLEN_P(expr_copy) = 1;Z_STRVAL_P(expr_copy) = estrndup("1", 1);} else {Z_STRLEN_P(expr_copy) = 0;Z_STRVAL_P(expr_copy) = STR_EMPTY_ALLOC();}break;case IS_RESOURCE:// ...省略case IS_ARRAY:Z_STRLEN_P(expr_copy) = sizeof("Array") - 1;Z_STRVAL_P(expr_copy) = estrndup("Array", Z_STRLEN_P(expr_copy));break;case IS_OBJECT:// ... 省略case IS_DOUBLE:*expr_copy = *expr;zval_copy_ctor(expr_copy);zend_locale_sprintf_double(expr_copy ZEND_FILE_LINE_CC);break;default:*expr_copy = *expr;zval_copy_ctor(expr_copy);convert_to_string(expr_copy);break;}Z_TYPE_P(expr_copy) = IS_STRING;*use_copy = 1;
}

ZEND_API void convert_to_null(zval *op) /* {{{ */
{if (Z_TYPE_P(op) == IS_OBJECT) {if (Z_OBJ_HT_P(op)->cast_object) {zval *org;TSRMLS_FETCH();ALLOC_ZVAL(org);*org = *op;if (Z_OBJ_HT_P(op)->cast_object(org, op, IS_NULL TSRMLS_CC) == SUCCESS) {zval_dtor(org);return;}*op = *org;FREE_ZVAL(org);}}zval_dtor(op);Z_TYPE_P(op) = IS_NULL;
}转换为NULL非常简单,对变量进行析构操作,然后将数据类型设为IS_NULL即可。 可能读者会好奇(unset)$a和unset($a)这两者有没有关系,其实并没有关系, 前者是将变量$a的类型变为NULL,这只是一个类型的变化,而后者是将这个变量释放,释放后当前作用域内该变量就不存在了。除了上面提到的与C语言很像,在其它语言中也经常见到的强制数据转换,PHP中有一个极具PHP特色的强制类型转换。 PHP的标准扩展中提供了两个有用的方法settype()以及gettype()方法,前者可以动态的改变变量的数据类型, gettype()方法则是返回变量的数据类型。在ext/standard/type.c文件中找到settype的实现源码:
PHP_FUNCTION(settype)
{zval **var;char *type;int type_len = 0;if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Zs", &var, &type, &type_len) == FAILURE) {return;}if (!strcasecmp(type, "integer")) {convert_to_long(*var);} else if (!strcasecmp(type, "int")) {convert_to_long(*var);} else if (!strcasecmp(type, "float")) {convert_to_double(*var);} else if (!strcasecmp(type, "double")) { /* deprecated */convert_to_double(*var);} else if (!strcasecmp(type, "string")) {convert_to_string(*var);} else if (!strcasecmp(type, "array")) {convert_to_array(*var);} else if (!strcasecmp(type, "object")) {convert_to_object(*var);} else if (!strcasecmp(type, "bool")) {convert_to_boolean(*var);} else if (!strcasecmp(type, "boolean")) {convert_to_boolean(*var);} else if (!strcasecmp(type, "null")) {convert_to_null(*var);} else if (!strcasecmp(type, "resource")) {php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot convert to resource type");RETURN_FALSE;} else {php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid type");RETURN_FALSE;}RETVAL_TRUE;
}这个极具PHP特色的强制类型转换就是这个函数,而这个函数是作为一个代理方法存在, 具体的转换规则由各个类型的处理函数处理,不管是自动还是强制类型转换,最终都会调用这些内部转换方法, 这和前面的强制类型转换在本质上是一样的。

http://www.php-internals.com/book/?p=chapt03/03-07-type-cast

33. 数据类型转换相关推荐

  1. Python基本语法_强制数据类型转换

    目录 目录 前言 软件环境 Python数据类型的显式转换 显式转换的多种类型 Non-String转换为String str函数 repr str和repr的区别 eval Non-int转换为in ...

  2. 3、常用关键字,变量赋值,多个变量赋值,标准数据类型,数字,字符串,列表,元组,字典,数据类型转换

    3Python变量类型 3.1常用关键字 系统中有一些常用关键字不可以用来当做标识符. and lambda except while del return import or class try i ...

  3. 5.单行函数,多行函数,字符函数,数字函数,日期函数,数据类型转换,数字和字符串转换,通用函数(case和decode)

     1  多行函数(理解:有多个输入,但只输出1个结果) SQL>select count(*) from emp; COUNT(*) ------------- 14 B 字符函数Lower ...

  4. java数组类型转换_java数据类型转换和数组总结

    流程控制 分支 循环语句 if...else... if...else if...else switch(值0) {          ------------值0是什么类型, case后面的值就要是 ...

  5. python学习笔记5—数据类型转换

    数据类型转换 16进制和10进制之间转换 In [18]: int('a',16) 把16进制的a转换为10进制的10,16说明a是16进制数 Out[18]: 10 In [13]: int('0x ...

  6. c++ 数据类型转换: static_cast dynamic_cast reinterpret_cast const_cast

    c++ 数据类型转换: static_cast dynamic_cast reinterpret_cast const_cast [版权声明]转载请注明出处 http://www.cnblogs.co ...

  7. java数据类型转换和数组总结

    流程控制 分支 循环语句 if...else... if...else if...else switch(值0) {          ------------值0是什么类型, case后面的值就要是 ...

  8. python变量类型之间转换_python学习笔记5—数据类型转换

    数据类型转换 16进制和10进制之间转换In [18]: int('a',16) 把16进制的a转换为10进制的10,16说明a是16进制数 Out[18]: 10 In [13]: int('0xa ...

  9. 转:VC++常用数据类型转换

      留着方便自查 VC++数据类型转换 int i = 100; long l = 2001; float f=300.2; double d=12345.119; char username[]=& ...

  10. %02 java_Java基础02—变量、运算符和数据类型转换(示例代码)

    Java语言基础 参考资料:<Java从入门到精通>/明日科技编著. 4版. 北京:清华大学出版社,2016 一.变量与常量 常量:在程序执行过程中,其值不能改变的量称为常量. 变量:在程 ...

最新文章

  1. Spring boot 忽略对mybatis的配置
  2. Tensorflow—变量
  3. Xshell远程登录Ubuntu
  4. Nginx 图片防盗链
  5. WebSocket 1.0的学习和简单使用
  6. tcpdump 不显示指定ip_wordpress首页不显示指定分类文章的方法
  7. SharedCache分析:服务端程序
  8. kitti2bag将KITTI原始数据转换为rosbag
  9. 集成腾讯信鸽推送遇到的大坑
  10. 安装了360安全卫士和瑞星杀毒,看迅雷电影很卡,谁有知道的
  11. 21. 合并两个有序链表 C语言
  12. Linux 开始IntelCPU节能模式
  13. linux 内核回调,Linux 内核通知链随笔【下】
  14. python爬取物流信息_手把手教你用Python爬取快递100查询你的物流信息
  15. 计算机c盘是内存还是外存,rom是内存还是外存?
  16. 学习总结——按下按键灯亮,再次按下按键,灯灭
  17. 蓝牙款血氧仪单片机开发
  18. 2.4gwifi最高下载速度_2.4gwifi最高下载速度
  19. mmdetection3d基于kitti数据集训练pointpillars模型
  20. RK3308实现usb webcamera功能

热门文章

  1. docker python3环境搭建
  2. 2017年2月24号课堂笔记
  3. mydbtest文档
  4. 一对一单双向主键关联
  5. 和菜鸟一起深入学习国嵌实验之vim常用命令
  6. 利用NSFileManager获取文件(文件夹)列表
  7. Asp.Net细节性问题技巧精萃
  8. 七夕出手,这本情话秘籍请收好
  9. 送书《数据库系统概念》,送课,SQL必备!!
  10. Mysql 锁定 读情况