1.对于(=和!=)、(==和!==)、(isset)、(if($var)语句)来说,0和null值有什么区别
1.1值为0的情况
<?php
$flag = 0;
//$flag = $_REQUEST['flag'];
if($flag === 0) echo "flag === 0</br>\n";
if ( $flag) echo "flag</br>\n";
if ( $flag == 0 ) echo "flag == 0</br>\n";
if( isset($flag)) echo "flag isset</br>\n";
if($flag == null) echo "flag == null</br>\n";
if($flag === null) echo "flag === null</br>\n";
?>
输出 :
flag === 0
!flag
flag == 0
flag isset
flag == null
1.2如果$flag是null呢?
$flag = null;
//$flag = $_REQUEST['flag'];
if($flag === 0) echo "flag === 0</br>\n";
if ( $flag) echo "flag</br>\n";
if ( $flag == 0 ) echo "flag == 0</br>\n";
if( isset($flag)) echo "flag isset</br>\n";
if($flag == null) echo "flag == null</br>\n";
if($flag === null) echo "flag === null</br>\n";
输出:
!flag
flag == 0
flag == null
flag === null
1.3如果$flag压根就没赋值呢
$flag;
//$flag = $_REQUEST['flag'];
if($flag === 0) echo "flag === 0</br>\n";
if ( $flag) echo "flag</br>\n";
if ( $flag == 0 ) echo "flag == 0</br>\n";
if( isset($flag)) echo "flag isset</br>\n";
if($flag == null) echo "flag == null</br>\n";
if($flag === null) echo "flag === null</br>\n";
输出:
!flag
flag == 0
flag == null
flag === null
或者,直接就没“声明”
//$flag;
//$flag = $_REQUEST['flag'];
if($flag === 0) echo "flag === 0</br>\n";
if ( $flag) echo "flag</br>\n";
if ( $flag == 0 ) echo "flag == 0</br>\n";
if( isset($flag)) echo "flag isset</br>\n";
if($flag == null) echo "flag == null</br>\n";
if($flag === null) echo "flag === null</br>\n";
输出:
!flag
flag == 0
flag == null
flag === null
结论如下:
- 首先明确什么是null:如果变量“声明”后没有赋值(或者压根就没“声明”),以及变量赋值为null是一样的
- 附加结论:变量赋值为null,也就是$flag = null可以清除变量
- 有且仅有以下三种情况0值和null是一样的:(flag == 0以及flag!=0)、(flag == null)和(if ( $flag))
- 对于精确等于和精确不等于(flag === 0以及flag!==0),0值和null值只可以跟他们本身相同,这里跟强数据类型语言是一样的
- 0值和null值一个最明显的不同是,赋值0时,isset为真;而变量为null时,isset为假
2.PHP从URL参数中获取0值和null值
你要说了,上面那些我都懂啊,ok,那来一些你可能没想到的。下面的代码中,变量的值不再从代码中赋值,而从URL中获取。
代码如下:
<?php
$flag = $_REQUEST['flag'];
if($flag === 0) echo "flag === 0</br>\n";
if ( !$flag) echo "!flag</br>\n";
if ( $flag == 0 ) echo "flag == 0</br>\n";
if( isset($flag)) echo "flag isset</br>\n";
if($flag == null) echo "flag == null</br>\n";
if($flag === null) echo "flag === null</br>\n";
?>
2.1输入为0的情况
http://127.0.0.1:8081/test.php?flag=0
输出为:
!flag
flag == 0
flag isset
神马?flag===0不管用啦!flag==null也不管用啦,说好的0值和null是一样的呢
2.2输入赋值为null的情况
http://127.0.0.1:8081/test.php?flag=null
输出为:
flag == 0
flag isset
这里更是醉了,isset说明null值被识别成了字符串,但是!!怎么会不等于null了,而是0呢。这里注意的是,isset了,实际上if($flag)
是成立的,因为这里if(!$flag)
没有打印嘛。
对比一下在程序中赋值为null的结果:
!flag
flag == 0
flag == null
flag === null
是不是差距好大!
这里只能理解为,flag确实传了(isset)了。至于那个0值,特么没法理解的。
2.3输入为空(真空)的情况
http://127.0.0.1:8081/test.php?flag=
输入:
!flag
flag == 0
flag isset
flag == null
我去,flag isset了,if($flag)
居然取不到,if(!$flag)
居然打印出来了!!不过这里接近于程序里赋值null了。写代码,“接近”没有卵用。
这里可以理解为,flag是传了(isset了),但是传的是null。
2.4压根就没传这个值呢
http://127.0.0.1:8081/test.php
输出为:
!flag
flag == 0
flag == null
flag === null
对比程序中赋值null的输出:
!flag
flag == 0
flag == null
flag === null
没错,这里跟程序中赋值null是一样的。
对于URL中0值和null值得问题我们的结论是:没有结论,记着,或者收藏本文每次查照。
3.研究这个问题的现实意义或应用场景
问题场景
假设数据库中A B C三个字段默认是null,我们要写一个接口,接收其中A字段的数据并更新。传来的数据恰好是0。而我们更新数据库的一般操所是使用数据作为多个键值来储存的。
比如:
$data['A'] = $_REQUEST['A'];
$data['B'] = $_REQUEST['B'];
$data['C'] = $_REQUEST['C'];
$server->where(1)->setField($data);
那么问题来了,这个时候我如何取到A=0,并且不让B和C原来的null值改变呢?
3.1直接套用上述程序
程序:
$data['A'] = $_REQUEST['A'];
$data['B'] = $_REQUEST['B'];
$data['C'] = $_REQUEST['C'];
print_r($data);
$server->where(1)->setField($data);
输入:
http://127.0.0.1:8081/testurl.php?A=0
输出:
Array ( [A] => 0 [B] => [C] => )
这样符合要求吗?结论是不!符!合!数组中$data['B']
和$data['C']
创建了,在写入数据库时B和C字段会被写入0。所以,我们必须保证,传入A值0时,$data['B']
和$data['C']
是不可以被创建的。
3.2所以我们修改一下代码
<?php
if($_REQUEST['A'])
$data['A'] = $_REQUEST['A'];
if($_REQUEST['B'])
$data['B'] = $_REQUEST['B'];
if($_REQUEST['C'])
$data['C'] = $_REQUEST['C'];
print_r($data);
输入:
http://127.0.0.1:8081/testurl.php?A=0
根据上面2.1的结论,没错,没有任何输出。
3.3所以我们要上一些条件,我们再修改一下代码
怎么修改呢?我们回顾一下2.4的输出:
!flag
flag == 0
flag == null
flag === null
注意,2.4的输入是真空,由于只能传A的值,B和C输入就是真空。所以,需要排除2.4的所有结果才能保证$data['B']
和$data['C']
不被创建,但是同时,只能从2.1的输出中选择:
!flag
flag == 0
flag isset
答案就只有一个了,isset。
3.4故而3中问题场景可以转化为以下模型,输入A=0,B和C直接不输入。其判断语句是的逻辑是
3.5因此,3中问题的最佳实践有且仅有一个:
代码:
<?php
if($_REQUEST['A'] || isset($_REQUEST['A']))
$data['A'] = $_REQUEST['A'];
if($_REQUEST['B'] || isset($_REQUEST['B']))
$data['B'] = $_REQUEST['B'];
if($_REQUEST['C'] || isset($_REQUEST['C']))
$data['C'] = $_REQUEST['C'];
print_r($data);
$server->where(1)->setField($data);
输出为:
Array ( [A] => 0 )
没有问题啦,记住即可。