首页 后端开发 php教程 语法:IF判断的实现

语法:IF判断的实现

Jul 29, 2016 am 08:55 AM
break op zend

面试PHP时经常碰到一种判断各种类型的空值是否为true的题:

<code>$a = <span>''</span>;
$a = null
$a = false;

<span>if</span>($a){<span>...</span>}
<span>if</span>(isset($a)){<span>...</span>}
<span>if</span>(empty($a)){<span>...</span>}
<span>...</span></code>
登录后复制

由下面的例子我们来简单看下zend引擎中对if是怎么处理的:

<code><span><span><?php </span><span>$a</span> = <span>''</span>; <span>//array();</span><span>if</span>(<span>$a</span>){
    <span>echo</span><span>"Y"</span>;
}</span></span></code>
登录后复制

这里例子比较简单,结果将什么也不输出。(文中涉及代码均为php-7.0.4版本)

之前的文章介绍过zend执行阶段的入口zend_execute函数,我们直接从这里开始,不熟悉的可以翻一下前面的文章。
编译生成的opcodes如下:
语法:IF判断的实现
其中opcode=38是$a = ”的执行操作,opcode=43是if的操作,下面具体看这一步是如何执行的。
根据opcode及两个操作数类型可以找到对应的handler为:ZEND_JMPZ_SPEC_CV_HANDLER

<code><span>//zend_vm_execute.h #28307</span><span>static</span> ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPZ_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{   
    USE_OPLINE

    zval *<span>val</span>;

    <span>val</span> = _get_zval_ptr_cv_undef(execute_data, opline->op1.var);

    <span>if</span> (Z_TYPE_INFO_P(<span>val</span>) == IS_TRUE) { 
        ZEND_VM_SET_NEXT_OPCODE(opline + <span>1</span>);
        ZEND_VM_CONTINUE();
    } <span>else</span><span>if</span> (EXPECTED(Z_TYPE_INFO_P(<span>val</span>) if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(<span>val</span>) == IS_UNDEF)) {
            SAVE_OPLINE();
            GET_OP1_UNDEF_CV(<span>val</span>, BP_VAR_R);
            ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
        } <span>else</span> {
            ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2));
            ZEND_VM_CONTINUE();
        }
    }

    SAVE_OPLINE();
    <span>if</span> (i_zend_is_true(<span>val</span>)) {
        opline++;
    } <span>else</span> {
        opline = OP_JMP_ADDR(opline, opline->op2);
    }

    <span>if</span> (UNEXPECTED(EG(<span>exception</span>) != NULL)) {
        HANDLE_EXCEPTION();
    }
    ZEND_VM_JMP(opline);
}</code>
登录后复制

从这个函数可以看出if的执行过程:如果条件为true的话则opline++,顺序执行下一条opcode(即if内语句),否则进行跳转,跳过if内语句直接执行if外语句。

i_zend_is_true这个函数就是用来判断各种类型的值是否为真,前面那部分是判断是否为bool型,是的话则直接处理。

<code><span>//</span>zend_operators.h <span>#283</span>
static zend_always_inline int i_zend_is_true(zval *op)
{   
    int result = <span>0</span>;

<span>again</span>:
    <span>switch</span> (Z_TYPE_P(op)) {
        <span>case</span><span>IS_TRUE</span>:
            result = <span>1</span>;
            <span>break</span>;
        <span>//</span>数值类型long、double直接判断即可,与c用法相同
        <span>case</span><span>IS_LONG</span>:
            <span>if</span> (Z_LVAL_P(op)) {
                result = <span>1</span>;
            }
            <span>break</span>;
        <span>case</span><span>IS_DOUBLE</span>:
            <span>if</span> (Z_DVAL_P(op)) {
                result = <span>1</span>;
            }
            <span>break</span>;
        <span>//</span>字符串类型根据长度判断:长度><span>1</span>,或=<span>1</span>且不为<span>'0'</span>为<span>true</span>,所以上面那个例子<span>''</span><span> =></span><span>false</span><span>case</span><span>IS_STRING</span>:
            <span>if</span> (Z_STRLEN_P(op) > <span>1</span> || (Z_STRLEN_P(op) && Z_STRVAL_P(op)[<span>0</span>] != <span>'0'</span>)) {
                result = <span>1</span>;
            }
            <span>break</span>;
        <span>//</span>数组类型根据数组元素的个数判断:大于<span>0</span>即为真
        <span>case</span><span>IS_ARRAY</span>:
            <span>if</span><span><span>(zend_hash_num_elements(Z_ARRVAL_P(op)))</span> { // <span>(Z_ARRVAL_P(op))</span>-></span>nNumOfElements
                result = <span>1</span>;
            }
            <span>break</span>;
        <span>case</span><span>IS_OBJECT</span>:
            result = zend_object_is_true(op);
            <span>break</span>;
        <span>//</span>资源类型实际就是整形(后续会专门介绍资源类型),所以直接判断即可
        <span>case</span><span>IS_RESOURCE</span>:
            <span>if</span> (EXPECTED(Z_RES_HANDLE_P(op))) {
                result = <span>1</span>;
            }
            <span>break</span>;
        <span>//</span>引用类型则根据指向的值判断
        <span>case</span><span>IS_REFERENCE</span>:
            op = Z_REFVAL_P(op);
            goto again;
            <span>break</span>;
        <span>default</span>:
            <span>break</span>;
    }
    <span>return</span> result;
}</code>
登录后复制

isset、empty函数后续补充……

').addClass('pre-numbering').hide(); $(this).addClass('has-numbering').parent().append($numbering); for (i = 1; i ').text(i)); }; $numbering.fadeIn(1700); }); });

以上就介绍了语法:IF判断的实现,包括了方面的内容,希望对PHP教程有兴趣的朋友有所帮助。

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

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
2 周前 By 尊渡假赌尊渡假赌尊渡假赌
仓库:如何复兴队友
4 周前 By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island冒险:如何获得巨型种子
4 周前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

深入探讨 OP Stack 的结构层面与功能 深入探讨 OP Stack 的结构层面与功能 Jan 18, 2024 pm 05:45 PM

OPStack是由Optimism网络背后的开发团体OptimismCollective公布的一个开源区块链框架。它对于Ethereum和Optimism社区都是一个重要的工具。OPStack的主要目标是加强Optimism网络,提供关键的软件工具给OptimismMainnet,以及即将推出的OptimismSuperchain和其治理模型。通过提供一个面向开发者的环境,OPStack的核心思想是促进Ethereum领域的增长和创新。它为前沿发展铺平了道路,使区块链的创建更加简单。OPStac

深入了解OP Mainnet网络: OP Mainnet是哪种链? 深入了解OP Mainnet网络: OP Mainnet是哪种链? Jan 24, 2024 am 11:30 AM

此前Optimism官方宣布,Optimism链现已更名为OPMainnet,可能有人要问了OPMainnet是什么链?根据当前资料显示,OPMainnet是一个开源超级链,致力于以可持续方式为公共产品提供资金,众多L2链之中的一个,可与Base、ZoraNetwork、PGN、Redstone等链无缝通信,但它并不是一条单一的区块链,它代表的二十整个超级链网络。下面小编为大家详细说说这个OPMainnet,帮助大家搞懂OPMainnet网络。OPMainnet是什么链?OPMainnet是以太

如何在Zend框架中使用ACL(Access Control List)进行权限控制 如何在Zend框架中使用ACL(Access Control List)进行权限控制 Jul 29, 2023 am 09:24 AM

如何在Zend框架中使用ACL(AccessControlList)进行权限控制导言:在一个Web应用程序中,权限控制是至关重要的一项功能。它可以确保用户只能访问其有权访问的页面和功能,并防止未经授权的访问。Zend框架提供了一种方便的方法来实现权限控制,即使用ACL(AccessControlList)组件。本文将介绍如何在Zend框架中使用ACL

PHP实现框架:Zend Framework入门教程 PHP实现框架:Zend Framework入门教程 Jun 19, 2023 am 08:09 AM

PHP实现框架:ZendFramework入门教程ZendFramework是PHP开发的一种开源网站框架,目前由ZendTechnologies维护,ZendFramework采用了MVC设计模式,提供了一系列可重用的代码库,服务于实现Web2.0应用程序和Web服务。ZendFramework深受PHP开发者的欢迎和推崇,拥有广泛

Window2003 IIS+MySQL+PHP+Zend环境如何配置 Window2003 IIS+MySQL+PHP+Zend环境如何配置 Jun 02, 2023 pm 09:56 PM

  Windows2003安装包中包含了Zend,PHP5.2.17,PHPWind8.7和PHPMyadmin3.5.2,您可以直接下载安装包,节约搜索资源的时间。  但是,由于MySQL超出了上传限制,您需要另行前往MySQL官网下载。然后解压拷贝到D盘,如下图:  MySQLinDdisk  安装与配置WindowsIIS+FTP  单击开始>控制面板>添加或删除程序。  AddingordeletingaPG  单击添加/删除Windows组件(A)。  Addingorde

PHP无法识别ZendOptimizer,如何解决? PHP无法识别ZendOptimizer,如何解决? Mar 19, 2024 pm 01:09 PM

PHP无法识别ZendOptimizer,如何解决?在PHP开发中,有时可能会遇到PHP无法识别ZendOptimizer的情况,这会导致部分PHP代码无法正常运行。在这种情况下,我们需要采取一些措施来解决这个问题。下面将介绍一些可能的解决方法,并附上具体的代码示例。1.确认ZendOptimizer是否正确安装:首先,我们需要确认ZendOptimize

Go语言break停止语句有什么用 Go语言break停止语句有什么用 Jan 18, 2023 pm 03:46 PM

在Go语言中,break停止语句用于循环语句中跳出循环,并开始执行循环之后的语句。break语句可以结束for、switch和select的代码块,另外break语句还可以在语句后面添加标签,表示退出某个标签对应的代码块,标签要求必须定义在对应的 for、switch和select的代码块上。

如何使用PHP框架Zend开发一个高效的ERP管理平台 如何使用PHP框架Zend开发一个高效的ERP管理平台 Jun 26, 2023 pm 11:00 PM

随着信息技术的飞速发展,越来越多的企业开始意识到信息化管理的必要性。ERP(企业资源计划)管理平台是现代企业管理的重要工具,可以帮助企业实现资源的规划、协同、控制、优化和管理。其中,PHP框架Zend作为一款优秀的开发工具,可以帮助开发者快速高效地实现ERP系统的开发。本文将介绍如何使用Zend开发一个高效的ERP管理平台。一、确定需求分析在开始开发过程之前

See all articles