PHP 的类型转换是比较方便的,但是越是容易使用的东西,底层的实现越是复杂,而且在使用中像我这样的新手也往往不清楚转换后的结果到底是什么。有时候,对于 Java 这种强类型的语言,使用的时候需要强制进行转换,这样多半转换后的结果是可以预料的,至少自己是想这么做的。

通过实例看转换

写个关于 PHP 类型转换的代码测试一下吧,看看大家是否能知道输出结果。把 各种数据类型 都转换为 字符串类型试试。

 <?php

 $var = false;
echo '$var:', $var, "\r\n"; $var = null;
echo '$var:', $var, "\r\n"; $var = true;
echo '$var:', $var, "\r\n"; $var = 1;
echo '$var:', $var, "\r\n"; $var = 1.1;
echo '$var:', $var, "\r\n";
$var1 = &$var;
echo '$var:', $var1, "\r\n"; $var1 = 'string111';
echo '$var:', $var1, "\r\n"; $var = [1, 2, 3];
echo '$var:', $var, "\r\n"; class Obj
{
private $field;
} $var = new Obj();
echo '$var:', $var, "\r\n";

代码很简单,大家可以猜猜输出结果,然后再和运行结果比对一下,运行结果如下:

 $ php string.php
$var:
$var:
$var:1
$var:1
$var:1.1
$var:1.1
$var:string111
$var:
Notice: Array to string conversion in C:\Users\Administrator\Desktop\string.php
on line 24 Call Stack:
0.0010 405568 1. {main}() C:\Users\Administrator\Desktop\string.php:0 Array
$var:
Catchable fatal error: Object of class Obj could not be converted to string in C
:\Users\Administrator\Desktop\string.php on line 32 Call Stack:
0.0010 405568 1. {main}() C:\Users\Administrator\Desktop\string.php:0

不知道是否实际的运行结果和猜测的结果是否一致。

PHP 源码中各类型转换为字符串类型的处理

对于各种类型之间的赋值,并转换为字符串,使用真的是非常的方便。但是,实际的功劳都是 PHP 底层的复杂处理。看一下关于各种类型转换为字符串类型的源代码的处理。

 ZEND_API zend_string* ZEND_FASTCALL _zval_get_string_func(zval *op) /* {{{ */
{
try_again:
switch (Z_TYPE_P(op)) {
case IS_UNDEF:
case IS_NULL:
case IS_FALSE:
return ZSTR_EMPTY_ALLOC();
case IS_TRUE:
return ZSTR_CHAR('1');
case IS_RESOURCE: {
char buf[sizeof("Resource id #") + MAX_LENGTH_OF_LONG];
int len; len = snprintf(buf, sizeof(buf), "Resource id #" ZEND_LONG_FMT, (zend_long)Z_RES_HANDLE_P(op));
return zend_string_init(buf, len, 0);
}
case IS_LONG: {
return zend_long_to_str(Z_LVAL_P(op));
}
case IS_DOUBLE: {
return zend_strpprintf(0, "%.*G", (int) EG(precision), Z_DVAL_P(op));
}
case IS_ARRAY:
zend_error(E_NOTICE, "Array to string conversion");
return zend_string_init("Array", sizeof("Array")-1, 0);
case IS_OBJECT: {
zval tmp;
if (Z_OBJ_HT_P(op)->cast_object) {
if (Z_OBJ_HT_P(op)->cast_object(op, &tmp, IS_STRING) == SUCCESS) {
return Z_STR(tmp);
}
} else if (Z_OBJ_HT_P(op)->get) {
zval *z = Z_OBJ_HT_P(op)->get(op, &tmp);
if (Z_TYPE_P(z) != IS_OBJECT) {
zend_string *str = zval_get_string(z);
zval_ptr_dtor(z);
return str;
}
zval_ptr_dtor(z);
}
zend_error(EG(exception) ? E_ERROR : E_RECOVERABLE_ERROR, "Object of class %s could not be converted to string", ZSTR_VAL(Z_OBJCE_P(op)->name));
return ZSTR_EMPTY_ALLOC();
}
case IS_REFERENCE:
op = Z_REFVAL_P(op);
goto try_again;
case IS_STRING:
return zend_string_copy(Z_STR_P(op));
EMPTY_SWITCH_DEFAULT_CASE()
}
return NULL;
}
/* }}} */

从上面的源码中可以看出,对于类型的转换,PHP 底层的源码使用了 switch ... case 的结构,在进行转换的时候需要对逐个的类型进行匹配后,再进行转换。当然,从源码的角度去看待上面的 PHP 类型转换的代码就非常的清晰明了了。

最后

读 PHP 的源码有一段时间了,进度比较慢,说实话,对于写 PHP 的代码没有什么提高,或者对我来说没有遇到什么让我提高的地方。单纯的出于对知识求甚解的原因吧。


我的微信公众号:“码农UP2U”

从源码角度看 PHP 字符串类型转换的更多相关文章

  1. 从JDK源码角度看Short

    概况 Java的Short类主要的作用就是对基本类型short进行封装,提供了一些处理short类型的方法,比如short到String类型的转换方法或String类型到short类型的转换方法,当然 ...

  2. 从JDK源码角度看Byte

    Java的Byte类主要的作用就是对基本类型byte进行封装,提供了一些处理byte类型的方法,比如byte到String类型的转换方法或String类型到byte类型的转换方法,当然也包含与其他类型 ...

  3. 从JDK源码角度看Object

    Java的Object是所有其他类的父类,从继承的层次来看它就是最顶层根,所以它也是唯一一个没有父类的类.它包含了对象常用的一些方法,比如getClass.hashCode.equals.clone. ...

  4. 从JDK源码角度看Boolean

    Java的Boolean类主要作用就是对基本类型boolean进行封装,提供了一些处理boolean类型的方法,比如String类型和boolean类型的转换. 主要实现源码如下: public fi ...

  5. 从template到DOM(Vue.js源码角度看内部运行机制)

    写在前面 这篇文章算是对最近写的一系列Vue.js源码的文章(https://github.com/answershuto/learnVue)的总结吧,在阅读源码的过程中也确实受益匪浅,希望自己的这些 ...

  6. Android布局性能优化—从源码角度看ViewStub延迟加载技术

    在项目中,难免会遇到这种需求,在程序运行时需要动态根据条件来决定显示哪个View或某个布局,最通常的想法就是把需要动态显示的View都先写在布局中,然后把它们的可见性设为View.GONE,最后在代码 ...

  7. 从源码角度看JedisPoolConfig参数配置

    做一个积极的人 编码.改bug.提升自己 我有一个乐园,面向编程,春暖花开! 你好,JedisPoolConfig Java中使用Jedis作为连接Redis的工具.在使用Jedis的也可以配置Jed ...

  8. 从源码角度看finish()方法的执行流程

    1. finish()方法概览 首先我们来看一下finish方法的无参版本的定义: /** * Call this when your activity is done and should be c ...

  9. 从源码角度看LinkedList一些基本操作(jdk1.7)

    介绍 LinkedList是一个双向链表,就像下图展示那样,每个节点有个指向上个元素和一个指向下个元素的指针. 接下来我会对我们经常使用的方法进行介绍,代码如下 @Test public void t ...

随机推荐

  1. c语言I博客专业06

    问题 答案 这个作业属于那个课程 C语言程序设计II 这个作业要求在哪里 https://edu.cnblogs.com/campus/zswxy/CST2019-2/homework/8655 我在 ...

  2. tensorflow学习笔记——AlexNet

    1,AlexNet网络的创新点 AlexNet将LeNet的思想发扬光大,把CNN的基本原理应用到了很深很宽的网络中.AlexNet主要使用到的新技术点如下: (1)成功使用ReLU作为CNN的激活函 ...

  3. webpack4.0各个击破(6)—— Loader篇【华为云技术分享】

    版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/devcloud/article/detai ...

  4. 更适合Pythoner的标记语言Yaml学习总结

    pythonic的标记语言 之前总结过一篇关于小数据存储文件大比拼,当时着重介绍了json,因为它在各类编程语言的通用性较强.但今天,我想给大家介绍一款更加适合pythoner使用的语言Yaml. Y ...

  5. plsql判断和循环

    if语句 语法1 如果条件成立,执行if和end if 之间的语句. if 条件表达式 then plsql语句; end if; 语法2 if 条件表达式 then 条件成立时执行的语句; else ...

  6. CSS给元素清除浮动影响的方法,--最全四种方法

    代码实例: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF ...

  7. CollectionView常用的布局方式总结

    结合网上的collectionView常用布局整合的collectionView使用工具 下载地址 支持五种布局方式ZFCollectionViewLayoutType有两种ZFCollectionV ...

  8. 《JavaScript 模式》知识点小抄本(上)

    介绍 最近开始给自己每周订个学习任务,学习结果反馈为一篇文章的输出,做好学习记录. 这一周(02.25-03.03)我定的目标是<JavaScript 模式>的第七章学习一遍,学习结果的反 ...

  9. MarkDown快速入门(typora)

    MarkDown快速入门(typora) 1.代码块: //代码块语法: ​```java ​```shell 1.java代码 package com.yjx.jdbc import java.sq ...

  10. Windows10 中的字母映射表

    有很多朋友为寻找特殊字符串而感到烦恼, windows10中的字符映射表有所有字体 包含的特殊符号 windows键 + R键 输入 charmap 点击确定 即可出现 字母映射表 可在字符的下拉按钮 ...