震惊!if else 竟然同时输出!

简介: 震惊!if else 竟然同时输出!

首先,大家看看这个代码,应该输出什么:

//示例1
<?php
if(pcntl_fork()){
    echo 1;
}else{
    echo 2;
}
//示例2
<?php
if (1) {
    echo 1;
} else label:{
    echo 2;
}

输出1?还是输出2?

但它其实输出的是1和2:

image.png

为什么呢?

在这边,最主要一点在于pcntl_fork函数:

pcntl_fork

pcntl_fork 函数是php多进程扩展的一个函数,用于创建一个新进程执行,其返回值为 主进程id和0 或者 -1(错误)

那么,很多人就会奇怪了,为什么一个函数的返回值有2个呢?原因就在于此函数将会创建一个新进程,新进程作为调用函数进程的子进程,将复制主进程所有状态.

image.png

如图,对应代码如下:

<?php
$a = 1;
$b = 2;
$pid = pcntl_fork();//在这之后,已经变成了2个进程在执行,所以下面的输出都将输出2次
echo "返回值:{$pid}\\n";
if ($pid > 0) {
    echo "返回值:$pid,最后修改值:a:{$a},b:{$b}\\n"; //主进程
    $a = 3;
    $b = 4;
} elseif ($pid == 0) {
    echo "返回值:$pid,最后修改值:a:{$a},b:{$b}\\n"; //子进程
    $a = 2;
    $b=1;
}
echo "返回值:$pid,最后修改值:a:{$a},b:{$b}\\n";
echo "返回值:$pid,最后修改值:a:{$a},b:{$b}\\n";

将输出:

返回值:13879
返回值:13879,最后修改值:a:1,b:2
返回值:13879,最后修改值:a:3,b:4
返回值:0
返回值:0,最后修改值:a:1,b:2
返回值:0,最后修改值:a:2,b:1

可看到,在pcntl_fork后,子进程将会继承主进程所有变量,状态,但和主进程并非共用,在fork后,2个进程互相隔离,变量互不相干.

通过这个说明,是不是顿时了解了上面为什么会输出1,2呢?其实并不是同时走了if,else,只是不同进程走了不同的判断罢了.

很好,我们已经知道了第一个if else 都走的原理了,那么看看第二个:

<?php
if (1){
    echo 1;
}else label:{
    echo 2;
}

这个输出什么呢?没错!也是1和2,这个又是因为什么呢?

首先,我们需要了解一下, label:  是什么鬼?

goto 语句

php的goto语句可以标记一个程序的位置,并通过goto 进行跳转,例如:

<?php
$i = 1;
testGOTO:
echo  $i;
$i++;
if ($i<=10){
    goto testGOTO;
}

再例如:

<?php
$i = 1;
testGOTO:{
    echo  $i;
}
$i++;

当没有goto时,标记仍然可以使用,但是失去了goto语法的效果,当成了正常语句执行,同时标识可增加 {} 用于标记代码块

看出什么了嘛?上面的label,其实是goto写法的一个标记而已,那么为什么会走if,else呢?

goto 语句可以用来跳转到程序中的另一个位置。该目标位置可以用目标名称加上冒号来标记,而跳转指令是 goto 之后接上目标位置的标记。

PHP 中对 goto 语句有一定限制,即目标位置只能位于同一个文件和作用域,也就是说无法跳出一个函数或类方法,也无法跳入另一个函数、其他循环或者 switch 结构中。

goto 也可以跳出循环或者 switch,所以可以用来代替多层的 break 语句。

同时,goto 标识,代表着独立的语句,并不能跟之前的代码有关联

在上面的例子中,else label: {}  其实最后解析的代码块为:

<?php
if (1){
    echo 1;
}else;label:{
    echo 2;
}

格式化一下:

<?php
if (1) {
    echo 1;
} else;
label:{
    echo 2;
}

label作为独立语句块,并不能跟前面的语句关联,else 将直接中断,相当于else后面没有执行语句,else后面的2个括号,也只是goto标记的代码块,跟else毫无关联

好了,今天的2个装逼知识小技巧,你学会了吗?

目录
相关文章
|
Shell
shell脚本的“奇迹暖暖“之行 -- printf彩色输出
shell脚本的“奇迹暖暖“之行 -- printf彩色输出
44 0
|
存储 编解码 运维
让数据说话,获得“原来如此”的答案
随着数据分析和人工智能技术的快速发展,让数据说话已经成为了一种新的趋势。数据不仅可以帮助我们发现问题,解决问题,还可以让我们获得“原来如此”的答案。尤其是在日常生活中,数据无处不在,而且我们生活中的点点滴滴都脱离不了数据,通过数据可以知道自己的消费情况,通过数据可以知道自己喜欢的电影类型,通过数据可以知道自己在日常工作中的任务进度,等等这些通过数据分析和洞察,可以让某些困惑“真相大白”。
188 0
让数据说话,获得“原来如此”的答案
|
存储 Java
无聊小知识.04 以下代码会输出什么?
今天同事给我看了一段代码,然后这段简单的代码,我却陷入了沉思。
无聊小知识.04 以下代码会输出什么?
|
编解码 人工智能 文字识别
连百年梗图都整明白了!微软多模态「宇宙」搞定IQ测试,仅16亿参数
连百年梗图都整明白了!微软多模态「宇宙」搞定IQ测试,仅16亿参数
158 0
【perl】老司机的再一次翻车:没有想到加了一句打印,会影响结果输出
【perl】老司机的再一次翻车:没有想到加了一句打印,会影响结果输出
第六届蓝桥杯JavaC组省赛真题——详细答案对照(包含垒骰子)-2
第六届蓝桥杯JavaC组省赛真题——详细答案对照(包含垒骰子)
121 0
第六届蓝桥杯JavaC组省赛真题——详细答案对照(包含垒骰子)-2
|
机器学习/深度学习
第六届蓝桥杯JavaC组省赛真题——详细答案对照(包含垒骰子)-1
第六届蓝桥杯JavaC组省赛真题——详细答案对照(包含垒骰子)
136 0
第六届蓝桥杯JavaC组省赛真题——详细答案对照(包含垒骰子)-1
|
Java
Java锤子剪刀布大家应该都会玩“锤子剪刀布”的游戏: 现给出两人的交锋记录,请统计双方的胜、平、负次数,并且给出双方分别出什么手势的胜算最大。
Java锤子剪刀布大家应该都会玩“锤子剪刀布”的游戏: 现给出两人的交锋记录,请统计双方的胜、平、负次数,并且给出双方分别出什么手势的胜算最大。
161 0
7-24 悄悄关注 (10 分)
7-24 悄悄关注 (10 分)
128 0