0

0

PHP类型转换的面试题与答案解析

php中文网

php中文网

发布时间:2016-06-08 17:20:30

|

1565人浏览过

|

来源于php中文网

原创

面试题对于我们要去找工作的朋友多少都会要看一下的,这里一聚教程小伙伴为各位整理PHP类型转换的面试题与答案解析,希望本文章能够对各位有帮助。


最近在为公司面试新人,经常会问到的一道题目就是PHP类型转换的值,例如:
 
var_dump((int)true);
var_dump((string)true);
var_dump((string)false);
var_dump((bool)"1");
var_dump((bool)"0");
var_dump((bool)"");
var_dump((bool)"false");

我印象中最早见到这道题目是在英极的php高级开发工程师岗位的笔试题里面,看似很基础,但是依然可以难住不少phper。先来看一下运行结果:

int(1)
string(1) "1"
string(0) ""
bool(true)
bool(false)
bool(false)
bool(true)

对于大多数人来说,第1、2、4行通常是没有问题的。但是为什么false转换为字符串是空字符串呢?在处理请求值时,通常会传一个字符串类型的false,但是“false”(字符串)并非false(布尔),这有点令人疑惑了。

为什么会这样呢?

关于这个问题,我们从PHP内核入手,看看在类型转换时系统内部到底发生了什么。

首先补充一些关于PHP弱类型实现方式的背景知识。PHP解释器是使用C语言写成的,当然最终对变量的处理,也会使用C语言构造数据结构来实现。在Zend引擎中,一个PHP变量对应的类型是zval。

立即学习PHP免费学习笔记(深入)”;

打开Zend/zend_types.h文件,我们可以看到zval类型的定义,php-5.5.23版本大约在第55行左右:

秘塔写作猫
秘塔写作猫

秘塔写作猫是一个集AI写作、校对、润色、配图等为一体的创作平台

下载

typedef struct _zval_struct zval;


这样我们发现,zval其实是一个名为_zval_struct的结构体类型,我们在Zend/zend.h文件中找到这个结构体的定义,大约在320行左右开始:


 
typedef union _zvalue_value {
long lval; /* long value */
double dval; /* double value */
struct {
char *val;
int len;
} str;
HashTable *ht; /* hash table value */
zend_object_value obj;
} zvalue_value;
 
struct _zval_struct {
/* Variable information */
zvalue_value value; /* value */
zend_uint refcount__gc;
zend_uchar type; /* active type */
zend_uchar is_ref__gc;
};

大家可以看到,_zval_struct中包含两个重要的成员,一个是zvalue_value类型的value,一个是zend_uchar类型的type。注意zvalue_value类型是一个联合体,它用来存储一个PHP变量的值的信息。(如果你忘记了什么是联合体,我来解释一下。联合体类似结构体,但是联合体的中的成员,存储时有且只能有一个,而且联合体占用的空间是联合体中长度最长的那个成员,这样做是为了节省内存的使用。)在zvalue_value中,包括了long、double、struct、HashTable、zend_object_value五个类型的成员。他们分别用来存储PHP变量不同类型的值:
C类型  PHP类型
long  bool
int
resource
double  float
struct  string
HashTable  array
zend_object_value  object

看到这个结构体之后,想必也就明白了常问的诸如PHP中int类型的取值范围,以及php中strlen的时间复杂度之类的问题。

由此可见,PHP的变量类型转换,或者说是弱类型实现,本质上是实现zval类型在不同类型之间的转换。除了完成zvalue_value的数值转换,还需要将_zval_struct中的type设置成当前变量的type类型。在Zend引擎中实现了convert_to_*系列函数完成这一转换,我们在Zend/zend_operators.c中可以看到这些转换函数,在大约511行左右,可以找到转换为布尔类型的函数:


 
ZEND_API void convert_to_boolean(zval *op) /* {{{ */
{
int tmp;
 
switch (Z_TYPE_P(op)) {
case IS_BOOL:
break;
case IS_NULL:
Z_LVAL_P(op) = 0;
break;
case IS_RESOURCE: {
TSRMLS_FETCH();
 
zend_list_delete(Z_LVAL_P(op));
}
/* break missing intentionally */
case IS_LONG:
Z_LVAL_P(op) = (Z_LVAL_P(op) ? 1 : 0);
break;
case IS_DOUBLE:
Z_LVAL_P(op) = (Z_DVAL_P(op) ? 1 : 0);
break;
case IS_STRING:
{
char *strval = Z_STRVAL_P(op);
 
if (Z_STRLEN_P(op) == 0
|| (Z_STRLEN_P(op)==1 && Z_STRVAL_P(op)[0]=='0')) {
Z_LVAL_P(op) = 0;
} else {
Z_LVAL_P(op) = 1;
}
STR_FREE(strval);
}
break;
case IS_ARRAY:
tmp = (zend_hash_num_elements(Z_ARRVAL_P(op))?1:0);
zval_dtor(op);
Z_LVAL_P(op) = tmp;
break;
case IS_OBJECT:
{
zend_bool retval = 1;
TSRMLS_FETCH();
 
convert_object_to_type(op, IS_BOOL, convert_to_boolean);
 
if (Z_TYPE_P(op) == IS_BOOL) {
return;
}
 
zval_dtor(op);
ZVAL_BOOL(op, retval);
break;
}
default:
zval_dtor(op);
Z_LVAL_P(op) = 0;
break;
}
Z_TYPE_P(op) = IS_BOOL;
}
/* }}} */

case IS_STRING这段代码即是将一个字符串类型变量转换为布尔型的操作。可以看到,只有空字符串,或者字符串长度为1,并且此字符为0时,字符串的布尔值才为1,也就是true,其他为0,也就是false。

同样的,我们也就明白了布尔值如何转换为字符串的,可以从_convert_to_string函数的实现中了解。

看似简单并且基础的PHP问题,究其根源是对PHP实现机制的把握。个人觉得,这道题也不失为鉴别PHPer知识边界的一道好题目。

PHP速学教程(入门到精通)
PHP速学教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
java连接字符串方法汇总
java连接字符串方法汇总

本专题整合了java连接字符串教程合集,阅读专题下面的文章了解更多详细操作。

4

2026.02.05

java中fail含义
java中fail含义

本专题整合了java中fail的含义、作用相关内容,阅读专题下面的文章了解更多详细内容。

8

2026.02.05

控制反转和依赖注入区别
控制反转和依赖注入区别

本专题整合了控制反转和依赖注入区别、解释、实现方法相关内容。阅读专题下面的文章了解更多详细教程。

7

2026.02.05

钉钉脑图插图教程合集
钉钉脑图插图教程合集

本专题整合了钉钉脑图怎么插入图片、钉钉脑图怎么用相关教程,阅读专题下面的文章了解更多详细内容。

16

2026.02.05

python截取字符串方法汇总
python截取字符串方法汇总

本专题整合了python截取字符串方法相关合集,阅读专题下面的文章了解更多详细内容。

2

2026.02.05

Java截取字符串方法合集
Java截取字符串方法合集

本专题整合了Java截取字符串方法汇总,阅读专题下面的文章了解更多详细操作教程。

1

2026.02.05

java 抽象方法
java 抽象方法

本专题整合了java抽象方法定义、作用教程等内容,阅读专题下面的文章了解更多详细内容。

2

2026.02.05

Eclipse创建jsp文件教程合集
Eclipse创建jsp文件教程合集

本专题整合了Eclipse创建jsp文件、创建jsp项目等等内容,阅读专题下面的文章了解更多详细教程。

21

2026.02.05

java 字符串转数字
java 字符串转数字

本专题整合了java如何字符串转数字相关内容,阅读专题下面的文章了解更多详细教程。

4

2026.02.05

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
zend框架2视频教程
zend框架2视频教程

共79课时 | 14万人学习

深入剖析redis教程
深入剖析redis教程

共55课时 | 8.2万人学习

Redis中文开发手册
Redis中文开发手册

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号