资源类型
资源类型很多初学者觉得比较难以理解。因为资源类型打印出来只能够看到一个英文的resource。其他的什么在电脑上都不能显示出来,而他有客观存在。
其实,资源类型很简单。我们针对词来进行说明。
电脑里面的资源是指:
1.word,excel等文件
2.有人收藏的美女图片和我们的自拍照片等图片
3.音乐
4.某些人爱看的AVI小电影
5.打开的网页
6.数据库
... ...等等
我们打开一个图片,用PHP来操作它,我们就是操作的一个资源。
我们打开的数据库连接,我们需要连接数据库,数据库就是我们操作的资源。
包括网络连接,连接后发送邮件,我们也可以认为是一个资源。
本章重点:理解资源就提操作我们可见和不可见的文件、网络和数据。我们在以后的章节中**,操作图片和网络的时候大家会有更为深刻的印象。**
<?php //PHP操作图片需打开配置文件中 extension=php_gd2.dll //==================================================生成图片 $imgname = "./test.png"; //根据给定路径图片名或 web 路径创建 png 图片模板对象,图片不存在会报错,需加 @ $im = @imagecreatefrompng ( $imgname ); //对应的创建jpg图片的方法为 imagecreatefromjpeg ,例 //$im = imagecreatefromjpeg("http://wx.qlogo.cn/mmopen/Q3auHgzwzM4fA6602v35iaPhicn4NerIoHhHIsM6uBFjDnbn6saxic3QJBibmibterqicNwiajic1ff8Y2sPhj1ictV0wMw/096"); if (! $im) { //=======================创建图片对象 //如果指定图片不存在,则创建指定大小的空图片模板对象,宽800,高500 $im = ImageCreate ( 800, 500 ); //第二种创建图片方法 $im = ImageCreateTrueColor(800, 500); //=======================创建颜色对象 //依据一个模板对象,生成颜色对象,0为red值,100为green值,30为blue值 //ImageCreate 创建的对象在此会直接将颜色填充至模板对象中,ImageCreateTrueColor 创建的对象则只创建颜色对象,不填充 $bgc = ImageColorAllocate ( $im, 0, 100, 30 ); $tc = ImageColorAllocate ( $im, 0, 0, 0 ); //=======================填充颜色 //为图片对象填充矩形颜色,如果空模板对象不填充颜色则为黑色 //100,50对应矩形填充区域左上角的横纵坐标,150,200对应矩形右下角的横纵坐标 //这里坐标对ImageCreate模板对象不起作用,全局填充,对ImageCreateTrueColor起作用。 ImageFilledRectangle ($im, 100, 50, 150, 200, $bgc); //第二种填充方法200,100同样为左上角横纵坐标,但这里坐标对两种方法创建的模板对象都不起作用,完全填充 ImageFill($im, 200, 100, $bgc); //=======================填充文字 //在模板对象中添加文字两种方法 //40字体粗度,50字体左边距距离,5字体上边距距离,$tc字体颜色,这种方式只能填充英语,填中文乱码 ImageString ( $im, 40, 50, 5, "just is English code", $tc ); //添加中文18为字体大小,0字体旋转程度,100左边距距离,200上边距距离,项目目录下要有"MSYH.TTF"这个字体文件 imagettftext($im, 18, 0, 100, 200, $tc, "MSYH.TTF", "填充中文"); } //==================================================合成图片 // 载入图象 $img1 = imagecreatefromjpeg("image1.jpg"); $img2 = imagecreatefromjpeg("064.jpg"); //方法一合成图象 ,将参数二合成到参数一中,500离主图片左边距,400离主图片上边距,0新合图片内右边距偏移量,10新合图片内下边距偏移量, 243合到参数一后所占位置宽,90合到参数一后所占位置高 //imagecopy($img1,$img2,500,400,0,10,243,90); //得到原始大图片尺寸 $imgage = getimagesize("064.jpg"); $src_W = $imgage[0]; //获取原图片宽度 $src_H = $imgage[1]; //获取原图片高度 //方法二合成图象并改变大小,500,400,0,10,与imagecopy作用一致,200分别是缩小后宽,高,$src_W,$src_H原图宽,高 //imagecopyresampled($img1, $img2, 500,400,0,10, 200, 200, $src_W, $src_H); //方法三,并且合透明图必须用此方法,别的合成方法合成后该透明的地方无法透明 //500,400,0,10, 243,90,与imagecopy作用一致,100表示参数二在参数一中透明程度,范围0~100,0完全透明,100完全不透明 imagecopymerge($img1, $img2, 500,400,0,10, 243,90, 100); //==================================================合成圆角图片 //每次生成圆的四个角中一个角,中心透明,边角有色的图片,用于合成 function get_lt($halfWidth) { //根据圆形弧度创建一个正方形的图像 $img = imagecreatetruecolor($halfWidth, $halfWidth); //图像的背景 $bgcolor = imagecolorallocate($img, 223, 0, 0); //填充颜色 imagefill($img, 0, 0, $bgcolor); //定义圆中心颜色 $fgcolor = imagecolorallocate($img, 0, 0, 0); // $halfWidth,$halfWidth:以图像的右下角开始画弧 // $halfWidth*2, $halfWidth*2:已宽度、高度画弧 // 180, 270:指定了角度的起始和结束点 // fgcolor:指定画弧内的颜色 imagefilledarc($img, $halfWidth, $halfWidth, $halfWidth*2, $halfWidth*2, 180, 270, $fgcolor, IMG_ARC_PIE); //将图片中指定色设置为透明 imagecolortransparent($img, $fgcolor); //变换角度 // $img = imagerotate($img, 90, 0); // $img = imagerotate($img, 180, 0); // $img = imagerotate($img, 270, 0); // header('Content-Type: image/png'); // imagepng($img); return $img; } $img1 = imagecreatefrompng("vote_2.png"); $img2 = imagecreatefromjpeg("064.jpg"); //获取图片尺寸 $imgSize = getimagesize("064.jpg"); $image_width = $imgSize[0]; $image_height = $imgSize[1]; //圆角长度,最好是图片宽,高的一半 $halfWidth = $image_width / 2; //获取四分之一透明圆角 $lt_img = get_lt($halfWidth); //改造$img2 左上角圆角透明 imagecopymerge($img2, $lt_img, 0, 0, 0, 0, $halfWidth, $halfWidth, 100); //旋转图片 $lb_corner = imagerotate($lt_img, 90, 0); //左下角 imagecopymerge($img2, $lb_corner, 0, $image_height - $halfWidth, 0, 0, $halfWidth, $halfWidth, 100); //旋转图片 $rb_corner = imagerotate($lt_img, 180, 0); //右上角 imagecopymerge($img2, $rb_corner, $image_width - $halfWidth, $image_height - $halfWidth, 0, 0, $halfWidth, $halfWidth, 100); //旋转图片 $rt_corner = imagerotate($lt_img, 270, 0); //右下角 imagecopymerge($img2, $rt_corner, $image_width - $halfWidth, 0, 0, 0, $halfWidth, $halfWidth, 100); //生成红色 $red = imagecolorallocate($img2, 223, 0, 0); //去除参数二中红色设成透明 imagecolortransparent($img2, $red); imagecopymerge($img1, $img2, 117,37,0,0, 64, 64, 100); //设定http输出格式 //header ( "Content-type: image/png" ); header("Content-type: image/jpeg"); //将二进制文件流输出到网页 //imagePng ( $im ); //如果是jpg二进制流用 imagejpeg 输出图象,并且后面加路径则直接生成保存图片,不再在页面输出 //如果已有图片则覆盖生成 //imagejpeg($img1, "new.jpg"); imagejpeg($img1); //注销模板对象 ImageDestroy($im); ImageDestroy($img1); ImageDestroy($img2); ?>
查看判断数据类型
函数
我们可以写一个智能的功能(函数),它让有一个功能,就是打开一个装有学生成绩的电子表格。这个函数非常先进。
只有一个人的时候,就返回一个人的成绩,成绩是整型或者浮点型变量。
有2个或两个以上人的时候,返回一个数组类型变量,数组中装有多个人的成绩
如果没有人的时候,则返回布尔值的变量,变量值为false
通过上面的一个场景模拟,我们知道了,一个函数(功能)有可能返回不同的数据类型。因此,我们可以根据不同的类型来做不同的事情。
判断数据类型很重要,我们需要严格掌握。
【默写级知识点】显示类型的函数、得到类型的函数、判断类型的函数
查看数据类型
gettype(传入一个变量) 能够获得变量的类型
var_dump(传入一个变量) 输出变类型和值
<?php //声明一个变量88.8,你可以自己多做几次实验换成其他类型看看$type输出是多少 $float = 88.8; $type = gettype($float); echo $type; ?> <?php //多换几个类型试试 $str = '你喜欢尊上还是喜欢杀仟陌?'; var_dump($str); ?>
判断数据类型
我们使用is_* 系列函数。 is_types这一系列的函数,来进行判断某个东西是不是某个类型。如果是这个类型返回真,不是这个类型返回假。
is_int 是否为整型 is_bool 是否为布尔 is_float 是否是浮点 is_string 是否是字符串 is_array是否是数组 is_object 是否是对象 is_null 是否为空 is_resource 是否为资源 is_scalar 是否为标量 is_numeric 是否为数值类型 is_callable 是否为函数
<?php //is_* 系列函数有个特点,就是如果是这个类型就返回的是真。不是这个数据类型就返回的是假 //声明类型为假 $fo = false; if(is_bool($fo)){ echo '执行真区间'; }else{ echo '执行假区间'; } //检查未声明的变量$p是否为空,为空就执行真区间 if(is_null($p)){ echo '执行真区间'; }else{ echo '执行假区间'; } echo "<br/>"; //字符串类型的数值,看看执行的是真还是假 $str = '18.8'; if(is_numeric($str)){ echo '执行真区间'; }else{ echo '执行假区间'; } echo "<br/>"; //把sca的值换成整型、浮点、布尔和字符串试试 $sca = true; //如果为标量,执行真区间 if(is_scalar($sca)){ echo '执行真区间'; }else{ echo '执行假区间'; } echo "<br/>"; //换成echo,is_int试试,为什么echo执行假区间呢? if(is_callable('var_dump')){ echo '执行真区间'; }else{ echo '执行假区间'; } ?>
注:is_types 很好记。is_ 在前后面跟类型即可。
变量:整型(int) 浮点(float)、布尔(bool)、字符串(string)
混合类型: 数组(array)、对象(object)
特殊类型:空(null)、 资源(resouce)、回调(callback)
为什么最后的实验中echo执行假区间呢?
答:因为echo 不是函数,是基本语法。大家眼前可以不用理解函数和基本语法的区别。了解和不了解在实际开发中没有影响。知道有这个知识点就行
自动转换和强制转换
PHP在PHP 5.x阶段都是完全的弱类型的编程语言。所谓弱类型,就是在声明变量的时候,不需要指定变量的类型。我要声明一个整型的变量,我不用在前面非得写上类型,再写变量。
而PHP 7 的性能有很大的提高。实际测试的结果,PHP 7的性能与PHP5.6相比,提升了性能接近200%。在PHP 7 中有些地方,我们可以强制指定类型,也可以不用强制指定类型来声明变量。
我们接来下来讲强制类型转换和自动类型转换两个部份。
【默写级别】布尔值的自动类型转换、强制类型转换的英文单词
布尔值的自动类型转换
自动类型转换,就是数据类型在某些情况下,自动会变为其他的类型参与运算。自动类型转换的发生时机是:运算和判断的时候某些值会自动进行转换。
下面的情况是布尔值判断时的自动类型转换:
1,整型的0为假,其他整型值全为真
2, 浮点的0.0,布尔值的假。小数点后只要有一个非零的数值即为真。
3,空字符串为假,只要里面有一个空格都算真。
4,字符串的0,也将其看作是假。其他的都为真
5,空数组也将其视为假,只要里面有一个值,就为真。
6,空也为假
7, 未声明成功的资源也为假
<?php //布尔变整型参与运算 $fo = true; $result = $fo + 10; //$result 结果为整型的11,因为$fo布尔的true变为了1 //如果$fo的值为0 var_dump($result); //字符串类型 $str = '419不要爱'; $result = $str + 1; //结果为420。因为将$str变为了整型的419参与运算 //将419放在字符串中间和结尾试试 var_dump($result); ?>
强制类型转换
强制类型转换有三种方式:
1.用后面的三个函数可以完成类型转换,intval()、floatval()、strval()
2.变量前加上()里面写上类型,将它转换后赋值给其他变量
3.settype(变量,类型) 直接改变量本身
我们来进行实验:
intval()、floatval()、strval()转换
<?php $float = 1.23; $result = intval($float); //看看结果是不是变了? var_dump($result); //鸭脖子为整型的5 $yabozi = 5; $re = floatval($yabozi); var_dump($re); //定义整型的变量 $yabozi = 23; $bian = strval($yabozi); //强制变成字符串试试 var_dump($bian); ?>
变量前加上()里面写上类型,将它转换后赋值给其他变量
<?php //定义一个变量,我们来变化一下试试 $transfer = 12.8; //把浮点变为整型 $jieguo = (int)$transfer; var_dump($jieguo); //把浮点变为布尔 $jieguo = (bool) $transfer; var_dump($jieguo); //把布尔变整型 $bool = true; $jieguo = (int)$bool; var_dump($jieguo); //把浮点变数组 $fo = 250; $jieguo = (array)$fo; var_dump($jieguo); //其他的操作方式,按照文字总结的规律你来试试 ?>
settype(变量,类型) 直接改变量本身
<?php //定义浮点变为整型 $fo = 250.18; //settype第二个参数是int,你实验的时候要记得第二个参数要为字符串类型 settype($fo,'int'); //输出看看结果 var_dump($fo); ?>
对象
知道对象是一个复合类型
对象的英文叫object,var_dump一个变量的时候看到的类型为object的,这个变量就是对象类型
所谓复合类型:就是在一个类型中可以同时存入字符串、浮点、整型、布尔等
常量和变量
【重点知识】知识级别我们定义为:默写级
常量的使用范围非常广泛。我们在以后,定义我们的工作目录、定义一些特点的帐户密码、版本号等我们都会使用到常量。所以这一块的知识,非常重要。
常量在代码中的定义、书写方式:
define(常量名,常量值)
注:
1.常量值只能为上一章中我们讲到的标量。
2.常量名可以小写,但是通常大写
3.常量名可以不加引号,但是通常加上引号。
4.在字符串中调用常量的时候,必须在引号外面
5.常量名建议只用字母和下划线
我们用代码来实验一下:
1.定义和调用一次常量试试
<?php define('MY_NAME','PHP中文网'); echo MY_NAME; //下面是错误的调用方式 echo '我的名字是MY_NAME'; //正确的调用方式该这么写 echo '我的名字是' . MY_NAME; ?>
2.注意项目实验
<?php //常量可以在外面不加引号 define(YH,'不要对未来迷茫,迷茫的时候静下心来coding'); echo YH; //只能用标量,我在后面用了一个数组,大家学一下就行,会报错的哟 define('BIAO',array(1,2,3)); ?>
此外,系统还为我们准备了一些内置的常量。这些常量都是规定好的。我们先熟悉几个,还有更多的系统常量我们学习完上册,入门后再慢慢的增加和学习。
常量名 |
说明 |
LINE |
当前所在的行 |
FILE |
当前文件在服务器的路径 |
FUNCTIOIN |
当前函数名 |
CLASS |
当前类名 |
METHOD |
当前成员方法名 |
PHP_OS PHP |
运行的操作系统 |
PHP_VERSION |
当前PHP的版本 |
TRAIT |
Trait 的名字,php5.4新加 |
DIR |
文件所在的目录 |
NAMESPACE |
当前命名空间的名称(区分大小写) |
defined()函数来做安全机制
defined()我们来学习这种用法,主是是为了防止其他人绕过安全检查文件。
函数:defined(常量)
功能:向函数的括号后面传入常量,如果常量定义了就返回true,否则返回false
【情景模拟】假设,我们的这套在线电子商城的软件需要付钱,检查是否付费是通过对软件授权检查来完成的,而文件version.php中就有检查授权的功能,我们在软件中规定,没有授权检查文件version.php就不能使用这个软件。所有的代码都包含了version.php。并且为了防止有人盗版,我还可以把version.php的代码进行了加密。
我们有两个文件:
1.一个文件中间有版本号,版本声明和授权声明。文件名为version.php
2.一个文件中有具体的业务功能。例如:用户注册、登陆等,文件名为users.php
我们该怎么做呢?——也就是说不包含 version.php文件就不让,执行users.php之后的代码。
我们来进行实验:
version.php文件
<?php //此处是检查是否是否授权的业务部份代码xxxx define('AUTH',true); //略过模拟代码xxx行 ?> users.php <?php //尝试将include 'version.php'这一行代码注释后再执行看看,对比结果 include 'version.php'; if(!defined('AUTH')){ echo '非法!非法!你尝试跳过授权文件'; exit; } //模拟后面用户注册和用户登陆的代码xxx行 echo '用户注册'; ?>
实验结果可知:version.php必须要包含 ,不然不会显示后面的echo ‘用户注册’;
可变变量
可变变量其实就是——已声明的变量前,再上变量符。
举例说明:
<?php //定义了一个变量叫作 $shu 将$shu这个变量的值设为字符串的biao $shu = 'biao'; //定义了一个【变量】$biao。将他的值设置为鼠标 $biao = '鼠标'; //$$shu 就是可变变量:在已声明的变量$shu前又加上了一个变量符 echo $$shu; ?>
上面的过程说明:s h u 的值为字符串 的 ′ b i a o ′ 。我在 shu的值为字符串的'biao'。我在shu的值为字符串的 ′ biao ′。我在shu前再加上一个$(美元符号),可以理解成为以下的变形过程:
$$shu
${$shu} 分成两块来看
${'biao'} 把变量$shu解释成了biao
$biao 而$biao也是一个变量对应的值是:鼠标
你可以自己写几个可变变量玩玩,请问以下的代码运行结果是多少?
<?php $shu = 'biao'; $biao = 'wo'; $wo = 'test'; $test = 'sina'; $sina = 'zhongguo'; $zhongguo = 'china'; $china = '我爱你'; //别运行,自己去推理一下代码。也写几个可变变量玩玩吧! echo $$$$$shu; ?>
外部变量
PHP的外部变量是PHP 在使用过程中规定好的一些变量。这个变量的规定是这样规定的,就这样使用。
get传值
我们先讲解几个最常用的例子,我们将下面的表单命名为user.html:
<html> <head> </head> <body> <form action="reg.php" method="get"> <input type="text" name="username" /> <input type="password" name="pwd" /> <input type="submit" value="提交" /> </form> </body> </html>
上现是很基础的一段HTML代码,在这段代码的主要意思是把用户和密码,采用get方法,将数据发送给reg.php(在上面代码的第6行规定的)。reg.php想办法接收用户传过来的username和pwd这两个值。
我们得出我们的第一个外部变量:$_GET。
$_GET 的主要作用是将得到get传值的数据。
我们写一个reg.php,用$_GET来接收值试试:
<?php //$_GET后面加上中括号,将username作为字符串放在中括号里面,就得到了表单里面的<input type="text" name="username" /> 的值 $u = $_GET['username']; echo $u.'<br />'; //$_GET['pwd'] 得到表单<input type="text" name="username" /> 的值 $passwd = $_GET['pwd']; echo $passwd.'<br />'; ?>
你可以输出值看一下结果。通过上面的实验我们知道了,通过$_GET这个外部变量,可以得到从表单输入的值。
reg.php后面跟了一个?(问号)
表单里面的username变在了地址栏里面
表单面username的值输入的是root,在username后面跟了个=(等号)输入的值
username(名字)=root(值) 后面的密码是password(名字)=123123(值),中间有&(and符)分开
post 传值
这个时候我们需要使用到post传值,post传值是在地址栏中不可见的。
同样上面例子的代码我们进行修改,html代码如下:
<html> <head> </head> <body> <!-- 这一行method 对应的值改为了post --> <form action="reg.php" method="post"> <input type="text" name="username" /> <input type="password" name="pwd" /> <input type="submit" value="提交" /> </form> </body> </html>
PHP的代码里面的$_GET全改为了$_POST:
<?php //$_POST后面加上中括号,将username作为字符串放在中括号里面,就得到了表单里面的<input type="text" name="username" /> 的值 $u = $_POST['username']; echo $u.'<br />'; //$_POST['pwd'] 得到表单<input type="text" name="username" /> 的值 $passwd = $_POST['pwd']; echo $passwd.'<br />'; ?>
观察特点:
reg.php后的?(问号)不见了。后面的username和password也不见了。那他怎么传递数据的呢?
他是通过我们看不见的浏览器的请求头文件传递的数据。所以在URL(网址)栏不可见。
注:附录中有如何通过火狐浏览器的firebug查看传递结果的演示过程。这一块都是HTTP协议规定的传送方式。
$_REQUEST接收数据
除此之外,我们还有**$_REQUEST来接收数据**。现在我们这样处理:
将php代码段中的$_POST全改为$_REQUEST,代码如下:
<?php $u = $_REQUEST['username']; echo $u.'<br />'; $passwd = $_REQUEST['pwd']; echo $passwd.'<br />'; ?>
把网页user.html里面的这一行中的method,改为get执行一次,再改为Post再运行一次,看看结果:
<form action="reg.php" method="post">
通过上面的实验你会发现$_REQUEST即可以接收get传值也可以接收post传值。
另外,我们总结一些外部变量,要求知识点的学习级别:了解含义,默写这个单词的写法和作用。
全局变量名 |
功能说明 |
$_COOKIE |
得到会话控制中cookie传值 |
$_SESSION |
得到会话控制中session的值 |
$_FILES |
得到文件上传的结果 |
$_GET |
得到get传值的结果 |
$_POST |
得到post传值的结果 |
$_REQUEST |
即能得到get的传值结果,也能得到Post传值的结果 |
请再记一句话:以上这些变量全是超全局的。(以后讲解超全局的含义)。
注:
1.我们认为从用户输入过来的所有数据都不是可信的。本书的下半部份会专门讲解限制和过滤
2.在提交数据的时候,我们常用的方法有get和post。可以这样理解,get传值在url中可见,而post传值在url中不可见。
而post传值在url中不可见,是通过浏览器的header头部份将数据发送给指定服务器的。需要通过专门的工具才能看到Post发送的值为什么。你可以下载火狐浏览器(firefox)的插件(firebug)来查看。
查看header头传递数据(网络,点击POST reg.php 选择Post),就看到了传递的名字和传递的数据值:
1.若真是使用get传密码,密码在地址栏里面显示过后。浏览器的历史记录会自动记录访问过的地址。恶意用户会,可以通过查看你的浏览器的历史记录,得到你曾经输入的密码。因此,不能使用get方式来作密码的传输方式。
环境变量
环境变量我们主要用的有$_SERVER和$_ENV两个环境变量
不过**,$_ENV逐渐被PHP的新版本给废弃**了。
【重点】知道在哪儿查看环境变量的名字(key)和值(value),记住并默写几个常用的环境变量。
查看环境变量,我们在学习PHP的第一天就学习过:
<?php phpinfo(); ?>
其实环境变量不是不用背的,我了解在哪儿能够找到环境变量的key(键)和值即可。
我们学了phpinfo();打印出来了一批乱乱的东西,我们今天来学习其中的环境变量部份。
你在执行phpinfo();的这个网址中,将网页向下拉动翻页,看看能不能找到截图中的部份:
_SERVER[‘中间的值’]是需要我们了解意思的
如果我们需要显示我们当前访问的这个phpinfo();页面文件放在哪儿,就可以执行:
<?php //我在上图左侧找到的一项,在前面加上了一个$(美元符),就显示出来了当前文件的路径 echo $_SERVER['SCRIPT_FILENAME']; ?>
我们来了解一些常用的环境变量的键名和值对应的意思:
键名 | 含义 |
$_SERVER["REQUEST_METHOD"] | 请求当前PHP页面的方法 |
$_SERVER["REQUEST_URI"] | 请求的URI |
$_SERVER["SERVER_SOFTWARE"] | 用的是哪一种服务器 |
$_SERVER["REMOTE_ADDR"] | 客户的IP地址 |
$_SERVER["SERVER_ADDR"] | 当前服务器的IP地址 |
$_SERVER["SCRIPT_FILENAME"] | 主前请求文件的路径 |
$_SERVER["HTTP_USER_AGENT"] | 当前访问这个网址的电脑和浏览器的情况 |
$_SERVER["HTTP_REFERER"] | 上级来源(用户从哪个地址进入当前网页的) |
$_SERVER["REQUEST_TIME"] | 当前的时间 |
URI 和URL都是网址,但是URL带有了主机地址部份,而URI不带主机地址部份,例如:
http://www.php.cn/abc.php?username=php 上面是一个URL(统一资源定位符),而URI是不带主机和(http://)
协议的部份:
abc.php?username=php
变量引用
变量引用------C语言的指针
<?php $fo = 5; //注意,加上了一个&符哟 $bar = &$fo; $bar = 6; //$bar的结果为6 echo $bar.'<br />'; //$fo的结果为6 echo $fo.'<br />'; ?>
两个结果都变成6了呢?
加上&(and 符后),把变量指向同一个存值空间了
也就是不论f o 或 fo或fo或bar的值如何发生变化,$fo变$bar也变,$bar发生变化,$fo也会发生变化。
注:如果你理解、了解、熟悉C语言的指针。可自行用指针方式来理解,不在本文的讨论范围内。
等于与全等于
接下来的一个重点是演示,等于(==)和全等于也叫判断类型等于(===)。
我们来写一段代码,大家看看两段代码就是符号PHP学院,为什么结果有这么大的差距呢?
下面这段代码执行出来的结果,运行了真区间。
<?php $x = 5; $y = '5'; if($x == $y){ echo '结果为真'; }else{ echo '结果为假'; } ?>
下面这段代码执行出来的结果,运行了假区间。
<?php $x = 5; $y = '5'; if($x === $y){ echo '结果为真'; }else{ echo '结果为假'; } ?>
我们对比区别发现:
下面这段**代码是===(三个等号,**我们说他还有一个名字是判断类型等于)。
逻辑运算
那我们把这些逻辑关于进行了归纳和总结,下面表格中的:$x为条件一,$y 为条件二。进行说明:
逻辑与,中文解释为并且。可理解为,$x 并且 $y 都为真(true)的时候执行。
逻辑或,中文解释为或者。可以理解为,x 或者 x或者x或者y其中一个为真(true)的时候执行。
逻辑非,中文解释取反。如果$x的执为假(false),进行一次非操作。非假(false)就为真了,就可以执行真区间了。反推true,则执行假区间了。
逻辑异或,如果$x和$y相同则为false,不相同则为true。
逻辑与:
<?php $x = true; $y = false; //逻辑与(并且),要求两个都为true才执行真区间,所以代码中执行假区间 if($x && $y){ echo '执行了真区间'; }else{ echo '执行了假区间'; } ?>
逻辑或:
<?php $foo = false; $bar = true; //逻辑或,有一个为真则为真 if($foo || $bar){ echo '执行真区间'; }else{ echo '执行假区间'; } ?>
逻辑非:
<?php $foo = false; //逻辑非,把false变为了true if(!$foo){ echo '执行真区间'; }else{ echo '执行假区间'; } ?>
短路
我们现在把自己想象成一个懒汉,非常非常懒。来思考逻辑与和逻辑或。可不可以这样理解:
逻辑与:如果前面第一个条件为false了,后面就可以不用执行了。
用代码表示:if($x && $y) 如果$x已经为false了,后面的$y 就没有执行必要了。
逻辑或:前面第一个条件为true了,后面就不用执行了。
用代码表示:if($x || y ) 如果 y) 如果y)如果x已经为true了,后面的$y 就没有执行必要了。
我们写段代码来证明一下:
<?php $x = false; $y = 2; if($x && $y++){ echo '真'; }else{ echo '假'; } //结果还为2,说明没有执行$y++ echo $y; ?>
代码如下,将两个&符改为一个&符试试:
<?php $x = false; $y = 2; if($x & $y++){ echo '真'; }else{ echo '假'; } //再看看结果 echo $y; ?>
我们来看看短路的逻辑或:
<?php $x = true; $y = 2; if($x || $y++){ echo '真'; }else{ echo '假'; } //结果,因为$x已经为true了,肯定执行真区间没有必要执行$y++了 echo $y; ?>
改成一个 | 再看看执行结果
<?php $x = true; $y = 2; if($x | $y++){ echo '真'; }else{ echo '假'; } //自己运行对比结果 echo $y; ?>
通过上例我们知道了&&与&的区别,||和 |的区别。我们也了解了什么是短路。那我们在什么地方可以用到短路呢?有一些奇怪的写法,我们必须了清楚。其实就是基础语法的再应用。
回顾3.3.1最后一段内容:
<?php //如果为defined('AUTH')存在AUTH常量则为true,不访问后面的exit了。如果为false则执行exit defined('AUTH') or exit('存在安全因素不准访问'); ?>
上面的一段代码就是典型的短路应用的代码