详解PHP7语言基础

 

文章目录

  • PHP标记
  • PHP指令分隔符
  • PHP注释
  • 常量
  • PHP变量
  • 数据类型
    • Boolean布尔类型
    • Integer整型
    • 浮点型
    • NaN
    • 字符串型
      • 存取和修改字符串中的字符
    • 数组型
      • 数组元素的访问
      • 数组元素值的修改与新建
    • Object对象型
      • 对象初始化
    • Resource资源类型
      • 释放资源
    • NULL类型
    • Callback / Callable 类型
    • 数据类型之间的相互转换
      • 转换为布尔值
      • 转换为整型
      • 转换为浮点数
      • 转换为字符串
      • 转换为数组
      • 转换为对象
      • 转换为资源
      • 转换到NULL
  • 标量类型的声明
  • 运算符
    • 算术运算符
    • 赋值运算符
    • 位运算符
    • 比较运算符
    • 递增/递减运算符
    • 逻辑运算符
    • 字符串运算符
    • 错误控制运算符
    • 执行运算符
    • 数组运算符
    • 类型运算符
    • 三元运算符
    • 运算符优先级
  • 表达式

推荐(免费):PHP7

PHP标记

php服务器会寻找php起始和结束标记,也就是<?php?>之间的部分,而任务起始和结束标记之外的部分会被php解析器忽略。
PHP也允许使用短标记<??>,但已经不推荐使用了。如果要使用短标记需要在php.ini中将短标记配置选项short_open_tag的值设置为true,或者在编译php时使用配置选项--enable-short-tags

自 PHP 5.4 起,短格式的 echo 标记 <?= 总会被识别并且合法,而不管 short_open_tag 的设置是什么。

PHP还支持<script language="php"></script>这样的开始和结束标记,并且这种标记不需要任何配置就可以使用,效果与<?php ?>相同。

PHP还可以使用ASP风格标记<% %>,需要在php.ini中打开asp_tags选项,但由于移植性等原因不推荐使用此种标记。

如果文件内容是纯 PHP 代码,最好在文件末尾删除 PHP 结束标记。这可以避免在 PHP 结束标记之后万一意外加入了空格或者换行符,会导致 PHP 开始输出这些空白,而脚本中此时并无输出的意图。

【示例】

<?phpecho "Hello World";// ... more codeecho "Last statement";// 脚本至此结束,不使用结束标记

在 PHP 5.2 和之前的版本中,解释器不允许一个文件的全部内容就是一个开始标记 <?php。自 PHP 5.3 起则允许此种文件,但要开始标记后有一个或更多白空格符。

PHP指令分隔符

php代码以;作为语句结束指令。在一个PHP代码段中的最后一行可以不用分号结束。如果前面还有新行,则代码段的结束标记包含了行结束。
【以下都是合法的php语句】

    <?php
    	echo "This is a test";
    ?>
    
    <?php echo "This is a test" ?>
    
    <?php echo 'We omitted the last closing tag';

文件末尾的 PHP 代码段结束标记可以不要,有些情况下当使用 include 或者 require 时省略掉会更好些,这样不期望的空白符就不会出现在文件末尾,之后仍然可以输出响应标头。在使用输出缓冲时也很便利,就不会看到由包含文件生成的不期望的空白符。

PHP注释

PHP支持C、C++和Unix Shell风格(Perl风格)的注释。
单行注释//仅仅注释到行末或者当前的PHP代码块。
多行注释/* */,以/*开始,直到碰到第一个*/时结束,多行注释不能嵌套多行注释。

常量

在PHP中,常量是一旦声明就无法改变的值。

  1. 声明和使用常量
    PHP通过define()命令来声明常量,格式如下:
define("常量名", 常量值);

常量名是一个字符串,通常在PHP的编码规范指导下使用大写英文字母表示,如:CLASS_NAME、MYAGE等。
常量值可以是很多种PHP的数据类型,可以是数组,可以是对象,也可以是字符和数字。
【示例】

<?php
	define("WELCOME", "欢迎来到PHP的世界");			// 定义常量WELCOME
	echo WELCOME;									// 输出常量值?>
  1. 内置常量

PHP的内置常量是指PHP在系统建立之初定义好的一些值。PHP中预定义了很多系统内置常量,这些产量可以被随时调用。
常用内置常量

  • _FILE_:这个默认常量是文件的完整路径和文件名。若引用文件(include或require),则在引用文件内的该常量为引用文件名,而不是引用它的文件名。
  • _LINE_:这个默认常量是PHP程序行数。若引用文件(include或require)则在引用文件内的该常量为引用文件的行,而不是引用它的文件行。
  • PHP_VERSION:这个内置常量是PHP程序的版本。
  • PHP_OS:这个内置常量是指执行PHP解析器的操作系统名称。
  • TRUE:代表真值true
  • FALSE:代表假值false
  • E_ERROR:这个常量指到最近的错误处。
  • E_WARNING:这个常量指导最近的警告处。
  • E_PARSE:这个常量指到解析语法有潜在问题处。
  • E_NOTICE:这个常量为发生不寻常但不一定是错误处。
  • _DIR_:这个常量为文件所在的目录。该常量在PHP 5.3.0版本中新增。
  • _FUNCTION_:这个常量为函数的名称。从PHP5开始,此常量返回该函数被定义时的名字,区分大小写。
  • _CLASS_:这常量为类的名称。从PHP5开始,此常量返回该类被定义时的名字,区分大小写。

PHP变量

变量像一个贴有名字标签的空盒子。不同的变量类型对应不同种类的数据,就像不同种类的东西要放入不同种类的盒子。

  1. PHP中的变量声明
    PHP中的变量一般以$作为前缀,然后以字母a~z的大小写或者“_”下划线开头。这是变量的一般表示。
    PHP中不需要显式地声明变量,但是定义变量前进行声明并带有注释,是一个好程序员应该养成的习惯。
    PHP的赋值有两种:

    • 传值赋值:使用“=”直接将赋值表达式的值赋给另一个变量。
    • 引用赋值:将赋值表达式内存空间的引用赋给另一个变量。需要在“=”左后的变量前面加上一个“&”符号。
      【示例】
        <?php
        echo "使用传值方式赋值:<br/>";			// 输出 使用传值方式赋值:
        $a = "变量的名字为a";
        $b = $a;								// 将变量$a的值赋给$b,两个变量指向不同内存空间
        echo "变量a的值为".$a."<br/>";			// 输出变量a的值
        echo "变量b的值为".$b."<br/>";			// 输出变量b的值
        $a = "修改变量a的值";					// 改变变量a的值,变量b的值不受影响
        echo "变量a的值为".$a."<br/>";			// 输出变量a的值
        echo "变量b的值为".$b."<p>";			// 输出变量b的值
        
        echo "使用引用方式赋值:<br/>";			// 输出 使用引用方式赋值:
        $a = "引用赋值测试";
        $b = &$a;								// 将变量$a的引用赋给$b,两个变量指向同一块内存
        echo "变量a的值为".$a."<br/>";			// 输出变量a的值
        echo "变量b的值为".$b."<br/>";			// 输出变量b的值
        $a = "修改变量a的值";
        /*
        改变变量a的内存空间中存储的内容,变量b也指向该空间,b的值也发生变化
        */
        echo "变量a的值为".$a."<br/>";			// 输出变量a的值
        echo "变量b的值为".$b."<p>";			// 输出变量b的值
        ?>

    运行结果:
    在这里插入图片描述

  2. 可变变量与变量引用
    首先来看一个例子:
	    <?php
	    $value0 = "guest";		// 定义变量$value0并赋值
	    $$value0 = "customer";	// 再次给变量赋值
	    echo $guest."<br />";	// 输出变量
	    $guest = "ib-top.com";		// 定义变量$guest并赋值
	    echo $guest."t".$$value0."<br />";
	    
	    $value1 = "ib-top.cn";		// 定义变量$value1
	    $value2 = &$value1;			// 引用变量并传递变量
	    echo $value1."t".$value2."<br />";	//输出变量
	    $value2 = "冰蓝工作室";
	    echo $value1."t".$value2;
	    ?>
运行结果:

在这里插入图片描述

【代码分析】
首先,$value0被赋值guest。因此,$value0相当于guest,于是$$value0相当于$guest。所以当$$value0被复制为customer时,打印$guest就得到customer。当$guest被赋值为ib-top.com时,打印$$value0得到的就是ib-top.com,这就是可变变量。
其次在代码的第二部分里,$value1被赋值ib-top.cn,然后通过“&”引用变量$value1并赋值给$value2.实际上就是将变量$value1添加了一个别名$value2.由于$value2是别名,因此和$value1指向同一个变量。因此当$value2被赋值“冰蓝工作室”后,$value1$value2都得到了新值。
可变变量其实是允许改变一个变量的变量名,允许使用一个变量的值作为另一个变量的名。
变量引用相当于给变量添加了一个别名,使用“&”来引用变量。在计算机内部,两个变量名指向同一个变量。

  1. 变量作用域
    变量作用域(variable scope),是指特定变量在代码中可以被访问到的位置。在PHP中有6种基本的变量作用域法则:

    • 内置超全局变量(Built-in superglobal variables),在代码中的任意位置都可以访问到。
      • 超全局变量,sperglobal或autoglobal,这些超全局变量是由PHP预先定义好以方便使用的。
        • $GLOBALS:包含全局变量的数组。
        • $_GET:包含所有通过GET方法传递给代码的变量的数组。
        • $_POST:包含所有通过POST方法传递给代码的变量的数组。
        • $_FILES:包含文件上传变量的数组。
        • $_COOKIES:包含cookie变量的数组。
        • $_SERVER:包含服务器环境变量的数组。
        • $_ENV:包含环境变量的数组。
        • $_REQUEST:包含用户所有输入内容的数组(包括G

          E

          T

          _GET、

           

          GET_POST和$_COOKIE)。

        • $_SESSION:包含会话变量的数组。
    • 常量(constants),一旦声明,就是全局性的,可以在函数内外使用。
      可以用define()函数来定义常量,在PHP5.3.0后,可以使用const关键字在类定义之外定义常量。一个常量一旦被定义,就不能再改变或者取消定义。
    • 全局变量(global variables),在代码间声明,可在代码间访问,但是不能在函数内访问。
      【示例1】
    <?php
	$room = 20;				// 定义全局变量
	function showrooms() {
		echo $room;			// 函数内部访问全局变量
	}
	showrooms();			// 访问全局变量
	echo $room.'间房间。';
	?>

运行结果:
在这里插入图片描述
出现上述结果,是因为函数无法访问外部全局变量,但是在代码间可以访问全局变量。
【示例2】

    <?php
    $room = 20;				// 定义全局变量
    function showrooms() {
    	global $room;		// 函数内部调用全局变量
    	echo $room.'间新房间。<br />';
    }
    showrooms();			// 访问全局变量
    echo $room.'间房间。';
    ?>

运行结果:
在这里插入图片描述
除了使用global在函数内部调用全局变量外,还可以通过“超全局变量”中的$GLOBALS数组进行访问。
【示例3】

    <?php
    $room = 20;				// 定义全局变量
    function showrooms() {
    	$room = $GLOBALS['room']	// 通过$GLOBALS数组访问全局变量
    	echo $room.'间新房间。<br />';
    }
    showrooms();			// 访问全局变量
    echo $room.'间房间。';
    ?>
* 在函数中声明为全局变量的变量就是同名的全局变量。
* 在函数中创建和声明为静态变量的变量在函数外是无法访问的,但这个静态变量的值可以保留。
* 在函数中创建和声明的局部变量在函数外是无法访问的,并且在本函数终止时失效。
* 静态变量

静态变量只是在函数内存在,在函数外无法访问。但是执行后,其值保留,也就是说这一次执行完毕后,静态变量的值保留,下一次再执行此函数,这个值还可以调用。
【示例】

    <?php
    $person = 20;
    function showpeople(){
    	static $person = 5;
    	$person++;
    	echo '再增加一位,将会有'.$person.'位static人员。<br />';
    }
    showpeople();
    echo $person.' 人员。<br />';
    showpeople();
    ?>

运行效果:
在这里插入图片描述

  1. 变量的销毁
    当用户创建一个变量时,相应地在内存中有一个空间专门用于存储该变量,该空间引用计数加i。当变量与该空间的联系被断开时,空间引用计数减1,直到引用计数为0,则成为垃圾。
    PHP有自动回收垃圾的机制,用户也可以手动销毁变量,通常使用unset()函数来实现。该函数的语法格式如下:
void unset (变量)

其中,变量类型为局部变量,则变量被销毁;如果变量类型为全局变量,则变量不会被销毁。
【示例】

<?php
function xiaohui() {
	global $b;		// 函数内使用global关键字声明全局变量$b
	unset ($b);		// 使用unset()销毁不再使用的变量$b 
}
$b = '冰蓝工作室';	// 函数外声明全局变量
xiaohui();			// 调用函数
echo $b;			// 查看全局变量是否发生变化
?>

运行效果:
在这里插入图片描述

数据类型

PHP支持9种原始数据类型。

  • 四种标量类型
    • boolean(布尔型)
    • integer(整型)
    • float(浮点型,也称作double)
    • string(字符串)
  • 三种复合类型:
    • array(数组)
    • object(对象)
    • callable(可调用)
  • 两种特殊类型:
    • resource(资源)
    • NULL(无类型)

如果想查看某个表达式的值和类型,用var_dump()函数。如果只是想得到一个易读懂的类型的表达方式用于调试,用gettype()函数。要检验某个类型,不要用gettype(),而用is_type函数。

【示例】

<?php$a_bool = TRUE;			// 布尔值 boolean$a_str = "foo";			// 字符串 string$a_str2 = 'foo';		// 字符串 string$an_int = 12;			// 整型 integer$a_float = 3.14;		// 浮点型 floatecho gettype($a_bool);		// 输出: booleanecho gettype($a_str);		// 输出: stringecho gettype($a_str2);		// 输出: stringecho gettype($an_int);		// 输出: integerecho gettype($a_float);		// 输出: double// 如果是整型,就加上4if (is_int($an_int)) {
	$an_int += 4;}// 如果 $bool 是字符串,就打印出来// 未打印任何信息if (is_string($a_bool)) {
	echo "String: $a_bool";}?>

Boolean布尔类型

标量类型。表达了真值,可以为TRUE或FALSE。

  • 语法
    要指定一个布尔值,使用常量TRUE或FALSE。两个都不区分大小写。
    通常运算符所返回的boolean值结果会被传递给控制流程。
    当运算符,函数或控制结构需要一个boolean参数时,会将结果自动转换为一个boolean值,也可以显式的将一个值强制转换成boolean,用(bool)或者(boolean)来强制转换。
    自动转换规则:
  • 整型,为0时,布尔值为false,为非零时,布尔值为true。
  • 浮点型,为0.0时,布尔值为false,为非零时,布尔值为true。
  • 字符串型,为空字符串””或者零字符串“0”时,布尔值为false,包含除此以外的字符串时其布尔值为true。
  • 数组型,若不含任何元素,其布尔值为false,只要包含元素,其布尔值为true。
  • 对象型,资源型,布尔值永远为true。
  • NULL型,布尔值永远为false。

Integer整型

整型值可以使用十进制,十六进制,八进制或二进制表示,前面可以加上可选的符号(- 或者 +)。
二进制表达的 integer 自 PHP 5.4.0 起可用。
要使用八进制表达,数字前必须加上 0(零)。要使用十六进制表达,数字前必须加上 0x。要使用二进制表达,数字前必须加上 0b。
integer 语法的结构形式是:
decimal: [1-9][0-9]*
| 0
hexadecimal : 0[xX][0-9a-fA-F]+
octal: 0[0-7]+
binary: 0b[01]+
integer: [±]?decimal
| [±]?hexadecimal
| [±]?octal
| [±]?binary

整型数的字长和平台有关,尽管通常最大值是大约二十亿(32 位有符号)。64 位平台下的最大值通常是大约 9E18,除了 Windows 下 PHP 7 以前的版本,总是 32 位的。 PHP 不支持无符号的 integer。Integer 值的字长可以用常量 PHP_INT_SIZE来表示,自 PHP 4.4.0 和 PHP 5.0.5后,最大值可以用常量 PHP_INT_MAX 来表示,最小值可以在 PHP 7.0.0 及以后的版本中用常量 PHP_INT_MIN 表示。

PHP 7 以前的版本里,如果向八进制数传递了一个非法数字(即 8 或 9),则后面其余数字会被忽略。PHP 7 以后,会产生 Parse Error。

如果给定的一个数超出了 integer 的范围,将会被解释为 float。同样如果执行的运算结果超出了 integer 范围,也会返回 float。

PHP 中没有整除的运算符。1/2 产生出 float 0.5。值可以舍弃小数部分,强制转换为 integer,或者使用 round() 函数可以更好地进行四舍五入。

浮点型

浮点型(也叫浮点数 float,双精度数 double 或实数 real)可以用以下任一语法定义:

<?php$a = 1.234;$b = 1.2e3;$c = 7E-10;?>

浮点数的字长和平台相关,尽管通常最大值是 1.8e308 并具有 14 位十进制数字的精度(64 位 IEEE 格式)。

浮点数的精度有限。尽管取决于系统,PHP 通常使用 IEEE 754 双精度格式,则由于取整而导致的最大相对误差为 1.11e-16。非基本数学运算可能会给出更大误差,并且要考虑到进行复合运算时的误差传递。
此外,以十进制能够精确表示的有理数如 0.1 或 0.7,无论有多少尾数都不能被内部所使用的二进制精确表示,因此不能在不丢失一点点精度的情况下转换为二进制的格式。这就会造成混乱的结果:例如,floor((0.1+0.7)*10) 通常会返回 7 而不是预期中的 8,因为该结果内部的表示其实是类似 7.9999999999999991118…。
所以永远不要相信浮点数结果精确到了最后一位,也永远不要比较两个浮点数是否相等。如果确实需要更高的精度,应该使用任意精度数学函数或者 gmp 函数。

NaN

某些数学运算会产生一个由常量 NAN 所代表的结果。此结果代表着一个在浮点数运算中未定义或不可表述的值。任何拿此值与其它任何值(除了 TRUE)进行的松散或严格比较的结果都是 FALSE。
由于 NAN 代表着任何不同值,不应拿 NAN 去和其它值进行比较,包括其自身,应该用 is_nan() 来检查。

字符串型

一个字符串string就是由一系列的字符组成,其中每个字符等同于一个字节,PHP只支持256的字符集,因此不支持Unicode。

一个字符串最大可以达到2GB。

字符串型(string)的数据是表示在引号之间的。引号分为双引号(””)和单引号(’’)。双引号几乎可以包含所有的字符,但是在其中的变量显示变量的值,而不是变量的变量名,而有些特殊字符加上””符号就可以了;单引号内的字符是直接表示出来的。

第三种表达字符串的方法是用heredoc语法结构:<<<。在该运算符之后要提供一个标识符,然后换行,接下来是字符串string本身,最后要用前面定义的标识符作为结束标志。结束时所引用的标识符必须在该行的第一列,而且标识符的命名也要像其它标签一样遵守PHP命名规则:只能包含字母、数字和下划线,并且必须以字母和下划线作为开头。

要注意的是结束标识符这行除了可能有一个分号(;)外,绝对不能包含其它字符。也就是说结束标识符不能缩进,分号的前后也不能有任何空白或制表符。更重要的是结束标识符的前面必须是个被本地操作系统认可的换行,而结束标识符(可能其后有个分号)之后也必须紧跟一个换行。
Heredoc结构不能用来初始化类的属性。自PHP 5.3起,此限制仅对heredoc包含变量时有效。

heredoc结构就像是没有使用双引号的双引号字符串,在heredoc结构中单引号不用转义,并且变量将被替换为变量值。
示例

<?php$str = <<<EODExample of string
spanning multiple lines
using heredoc syntax.EOD;/* 含有变量的更复杂示例 */class foo{
    var $foo;
    var $bar;

    function __construct()
    {
        $this->foo = 'Foo';
        $this->bar = array('Bar1', 'Bar2', 'Bar3');
    }}$foo = new foo();$name = 'MyName';echo <<<EOTMy name is "$name". I am printing some $foo->foo.
Now, I am printing some {$foo->bar[1]}.
This should print a capital 'A': x41EOT;?>

以上代码会输出:

My name is "MyName". I am printing some Foo. Now, I am printing some Bar2. This should print a capital 'A': A

也可以把Heredoc结构用在函数参数中来传递数据:

<?phpvar_dump(array(<<<EODfoobar!EOD));?>

以上代码会输出

array(1) { [0]=> string(7) "foobar!" }

在PHP5.3.0以后,也可以用Heredoc结构来初始化静态变量和类的属性和常量:

<?php// 静态变量function foo(){
	static $bar = <<<LABELNothing in here...LABEL;}// 类的常量、属性class foo{
	const BAR = <<<FOOBARConstant exampleFOOBAR;
	
	public $baz = <<<FOOBARProperty exampleFOOBAR;}?>

自PHP5.3.0起还可以在Heredoc结构中用双引号来声明标识符:

<?phpecho <<<"FOOBAR"Hello world!FOOBAR;?>

第四种表示方式是Nowdoc结构,与Heredoc结构类似,使用标记<<<开头,但是在后边的标识符要用单引号括起来,即<<<‘EOT’。Heredoc的所有规则也同样适用于nowdoc结构,尤其是结束标识符的规则。
heredoc结构类似于双引号字符串,Nowdoc结构类似于单引号字符串,因此nowdoc中不进行解析操作。这种结构很适合用于嵌入PHP代码或其它大段文本而无需对其中的特殊字符进行转义。
示例

<?php$str = <<<'EOD'Example of string
spanning multiple lines
using heredoc syntax.EOD;/* 含有变量的更复杂示例 */class foo{
    var $foo;
    var $bar;

    function __construct()
    {
        $this->foo = 'Foo';
        $this->bar = array('Bar1', 'Bar2', 'Bar3');
    }}$foo = new foo();$name = 'MyName';echo <<<'EOT'My name is "$name". I am printing some $foo->foo.
Now, I am printing some {$foo->bar[1]}.
This should print a capital 'A': x41EOT;?>

以上代码会输出

My name is "$name". I am printing some $foo->foo. Now, I am printing some {$foo->bar[1]}. This should print a capital 'A': x41

Nowdoc结构是在PHP5.3.0中加入的。

** 变量解析 **
当字符串用双引号或 heredoc 结构定义时,其中的变量将会被解析。
共有两种语法规则:一种简单规则,一种复杂规则。简单的语法规则是最常用和最方便的,它可以用最少的代码在一个 string 中嵌入一个变量,一个 array 的值,或一个 object 的属性。

复杂规则语法的显著标记是用花括号包围的表达式。

简单语法
当 PHP 解析器遇到一个美元符号($)时,它会和其它很多解析器一样,去组合尽量多的标识以形成一个合法的变量名。可以用花括号来明确变量名的界线。
示例

<?php$juice = "apple";echo "He drank some $juice juice.".PHP_EOL;// Invalid. "s" is a valid character for a variable name, but the variable is $juice.echo "He drank some juice made of $juices.";?>

以上代码输出如下
在这里插入图片描述

同样,一个array索引或一个object属性也可以被解析。
示例

<?php$juices = array("apple", "orange", "koolaid1"=>"purple");echo "He drank some $juices[0] juice.".PHP_EOL;echo "He drank some $juices[1] juice.".PHP_EOL;echo "He drank some juice made of $juice[0]s.".PHP_EOL;  //Won't workecho "He drank some $juices[koolaid1] juice.".PHP_EOL;class people {
	public $john = "John Smith";
	public $jane = "Jame Smith";
	public $robert = "Robert Paulsen";
	
	public $smith = "Smith";}$people = new people();echo "$people->john drank some $juices[0] juice.".PHP_EOL;echo "$people->john then said hello to $people->jane.".PHP_EOL;echo "$people->john's wife greeted $people->robert.".PHP_EOL;echo "$people->robert greeted the two $people->simths."; //Won't work?>

以上代码输出如下
在这里插入图片描述

复杂(花括号)语法
复杂语法不是因为其语法复杂而得名,而是因为它可以使用复杂的表达式。只需简单地像在 string 以外的地方那样写出表达式,然后用花括号 { 和 } 把它括起来即可。由于 { 无法被转义,只有 $ 紧挨着 { 时才会被识别。可以用 {$ 来表达 {$。
示例

<?php// 显示所有错误error_reporting(E_ALL);$great = 'fantastic';// 无效,输出:This is { fantastic}echo "This is { $great}";// 有效,输出:This is fantasticecho "This is {$great}";echo "This is ${great}";// 有效echo "This square is {$square->width} 00 centimeters broad.";// 有效,只有通过花括号语法才能正确解析带引号的键名echo "This works:{$arr['key']}";// 有效 echo "This works:{$arr[4][3]}";// 这是错误的表达式,因为就像$foo[bar]的格式在字符串以外也是错的一样。// 换句话说,只有在PHP能找到常量foo的前提下才会正常工作;这里会产生一个E_NOTICE(undefined constant)级别的错误。echo "This is wrong:{$arr[foo][3]}";// 有效,当在字符串中使用多重数组时,一定要用括号将它括起来echo "This works:{$arr['foo'][3]}";echo "This works too:{$obj->values[3]->name}";echo "This is the value of the var named $name: {${$name}}";echo "This is the value of the var named by the return value of getName():{${$getName()}}";echo "This is the value of the var named by the return value of $object->getName():{${$object->getName()}}";// 无效,输出:This is the return value of getName():{getName()}echo "This is the return value of getName():{getName()}";

还可以在字符串中用这种语法通过变量来调用类的属性。
示例

<?phpclass foo {
	var $bar = "I am bar.";}$foo = new foo();$bar = 'bar';$baz = array('foo', 'bar', 'baz', 'quux');echo "{$foo->$bar}n";echo "{$foo->{$baz[1]}}n";?>

函数、方法、静态类变量和类常量只有在 PHP 5 以后才可在 {$} 中使用。然而,只有在该字符串被定义的命名空间中才可以将其值作为变量名来访问。只单一使用花括号 ({}) 无法处理从函数或方法的返回值或者类常量以及类静态变量的值。

<?php// 显示所有错误error_reporting(E_ALL);class beers {
	const softdrink = 'rootbeer';
	public static $ale = 'ipa';}$rootbeer = 'A & W';$ipa = 'Alexander Keith's';//有效, 输出: I'd like an A & Wecho "I'd like an {${beers::softdrink}}n";//也有效,输出:I'd like an Alexander Kerith's
echo "I'd like an {${beers::$ale}}n";?>

存取和修改字符串中的字符

string 中的字符可以通过一个从 0 开始的下标,用类似 array 结构中的方括号包含对应的数字来访问和修改,比如 $str[42]。可以把 string 当成字符组成的 array。函数 substr() 和 substr_replace() 可用于操作多于一个字符的情况。

string也可以用花括号访问,比如

s

t

r

42

str{42},效果和

str42str[42]一样


用超出字符串长度的下标写入将会增加字符串长度并以空格填充。非整数类型下标会被转换为整数。非法下标类型将会产生一个E_NOTICE级别的错误。用负数下标写入字符串时会产生一个E_NOTICE级别的错误,用负数下标读取字符串时返回空字符串。写入时只用到了赋值字符串的第一个字符,用空字符串赋值则赋给的值是NULL字符。


PHP的字符串在内部是字节组成的数组,因此用花括号访问或修改字符串对多字节字符集很不安全。仅应对单字节编码例如ISO-8859-1的字符进行此类操作。

自 PHP 5.4 起字符串下标必须为整数或可转换为整数的字符串,否则会发出警告。之前类似 “foo” 的下标会无声地转换成 0。

用 [] 或 {} 访问任何其它类型(不包括数组或具有相应接口的对象实现)的变量只会无声地返回 NULL。 PHP 5.5 增加了直接在字符串原型中用 [] 或 {} 访问字符的支持。

数组型

数组(array)是PHP变量的集合,是按照“键”与“值”的对应关系组织数据的。数组的键值既可以是整数,也可以是字符串。数组不显式声明键值的默认情况下,数组元素的键值从零开始。
PHP中的数组实际上是一个有序映射。映射是一种把values关联到keys的类型。
可以使用list()函数或array()函数来创建数组,也可以直接进行赋值。
示例

<?php$arr = array		// 定义数组并赋值(0 => 15,2 => 1E+05,1 => "PHP数组语法",);for ($i = 0; $i < count($arr); $i++)	// 使用for循环输出数组内容{
	$arr1 = each($arr);
	echo "$arr1[value]<br />";}?>

以上代码中用”=>”为数组元素赋值,数组的下标只是存储的标识,没有任何意义,数组元素的排列以加入的先后顺序为准。

可以用 array() 语言结构来新建一个数组。它接受任意数量用逗号分隔的 键(key) => 值(value)对。最后一个数组单元之后的逗号可以省略。通常用于单行数组定义中,例如常用 array(1, 2) 而不是 array(1, 2, )。对多行数组定义通常保留最后一个逗号,这样要添加一个新单元时更方便。

自 5.4 起可以使用短数组定义语法,用 [] 替代 array()。

示例

<?php$arr = array("foo" => "bar","bar" => "foo",);// 自PHP5.4起$arr = ["foo" => "bar","bar" => "foo",];?>

其中key 可以是 integer 或者 string。value 可以是任意类型。
关于key还有如下转换规则

  • 包含有合法整型值的字符串会被转换为整型。 例如键名 “8” 实际会被储存为 8。但是 “08” 则不会强制转换,因为其不是一个合法的十进制数值。
  • 浮点数也会被转换为整型,意味着其小数部分会被舍去。例如键名 8.7 实际会被储存为 8。
  • 布尔值也会被转换成整型。即键名 true 实际会被储存为 1 而键名 false 会被储存为 0。
  • Null 会被转换为空字符串,即键名 null 实际会被储存为 “”。
  • 数组和对象不能被用作键名。坚持这么做会导致警告:Illegal offset type。

如果在数组定义中多个单元都使用了同一个键名,则只使用了最后一个,之前的都被覆盖了。

示例

<?php$arr = array(1 => "a","1" => "b",1.5 => "c",true => "d",);var_dump($arr);?>

以上代码会输出:

array(1) { [1]=> string(1) "d" }

因为以上代码中的所有键名都被强制转换为1,则每一个新单元都会覆盖前一个的值。

PHP 数组可以同时含有 integer 和 string 类型的键名,因为 PHP 实际并不区分索引数组和关联数组。

如果对给出的值没有指定键名,则取当前最大的整数索引值,而新的键名将是该值加一。如果指定的键名已经有了值,则该值会被覆盖。

key 为可选项。如果未指定,PHP 将自动使用之前用过的最大 integer 键名加上 1 作为新的键名。

数组元素的访问

数组单元可以通过 array[key] 语法来访问。

方括号和花括号可以互换使用来访问数组单元(例如 $array[42] 和 $array{42} 在上例中效果相同)。

自 PHP 5.4 起可以用直接对函数或方法调用的结果进行数组解引用,在此之前只能通过一个临时变量。

自 PHP 5.5 起可以直接对一个数组原型进行数组解引用。

示例

<?phpfunction getArray() {
	return array(1, 2, 3);}// PHP5.4$secondElement = getArray()[1]// PHP5.4之前$tmp = getArray();$secondElement = $tmp[1];// 或者list(, $secondElement) = getArray();?>

试图访问一个未定义的数组键名与访问任何未定义变量一样:会导致 E_NOTICE 级别错误信息,其结果为 NULL。

数组元素值的修改与新建

可以显式的指定数组的下标来修改一个已有数组。通过在方括号内指定键名来给数组赋值。也可以省略键名,在这种情况下给变量名加上一对空的方括号([])。

$arr[key] = value;
$arr[] = value;
// key可以是integer或string类型
// value可以是任意类型

以上代码中,如果$arr不存在,将会新建一个,这也是另一种新建数组的方法。但并不推荐这样做,因为如果$arr已经有值,则此值会保留而[]实际上代表着字符串访问运算符。

要修改某个值,通过其键名给该单元赋一个新值即可。要删除某键值对,对齐调用unset()函数。

Object对象型

对象(object)就是类的实例。当一个类被实例化以后,这个被生成的对象被传递给一个变量,这个变量就是对象型变量。对象型变量也属于资源型变量。

对象初始化

要创建一个新的对象object,使用new语句实例化一个类:

<?phpclass foo {
	function do_foo() {
		echo "Doing foo.";
	}}$bar = new foo;$bar->do_foo();?>

以上代码中$bar的类型就是object类型。

Resource资源类型

资源 resource 是一种特殊变量,保存了到外部资源的一个引用。资源是通过专门的函数来建立和使用的。(get_resource_type())
资源类型是十分特殊的数据类型。它表示PHP的扩展资源,可以是一个打开的文件,也可以是一个数据库连接,甚至可以是其他的数据类型。

释放资源

引用计数系统是 Zend 引擎的一部分,可以自动检测到一个资源不再被引用了(和 Java 一样)。这种情况下此资源使用的所有外部资源都会被垃圾回收系统释放。因此,很少需要手工释放内存。

持久数据库连接比较特殊,它们不会被垃圾回收系统销毁。

NULL类型

NULL类型是仅拥有NULL这个值的类型,表示一个变量没有值。这个类型用来标记一个变量为空。一个空字符串与NULL是不同的。在数据库存储时会把空字符串和NULL区分处理。NULL型在布尔判断时永远为false。很多情况下,在声明一个变量的时候可以直接赋值为NULL。
在下列情况下一个变量被认为是NULL:

  • 被赋值为NULL
  • 尚未被赋值
  • 被unset()

Callback / Callable 类型

自PHP5.4起,可以用callable类型指定回调类型callback。
一些函数如 call_user_func() 或 usort() 可以接受用户自定义的回调函数作为参数。回调函数不止可以是简单函数,还可以是对象的方法,包括静态类方法。

数据类型之间的相互转换

数据从一种类型转换到另一种类型,就是数据类型转换。在PHP中,有两种常见的转换方式:自动数据类型转换和强制数据类型转换。
PHP 在变量定义中不需要(或不支持)明确的类型定义;变量类型是根据使用该变量的上下文所决定的。也就是说,如果把一个 string 值赋给变量

v

a

r

var,

varvar 就成了一个 string。如果又把一个integer 赋给 $var,那它就成了一个integer。

  1. 自动数据类型转换
    这种转换方法最为常用,直接输入数据的转换类型即可。例如,float型转换为整型int型,小数点后面的数将被舍弃。如果float数值超过了整数的取值范围,则结果可能是0或者整数的最小负数。

自动转换为 数组 的行为目前没有定义。

示例

<?php$foo = "1";  // $foo 是字符串 (ASCII 49)$foo *= 2;   // $foo 现在是一个整数 (2)$foo = $foo * 1.3;  // $foo 现在是一个浮点数 (2.6)$foo = 5 * "10 Little Piggies"; // $foo 是整数 (50)$foo = 5 * "10 Small Pigs";     // $foo 是整数 (50)?>
  1. 强制数据类型转换
    PHP 中的类型强制转换和 C 中的非常像:在要转换的变量之前加上用括号括起来的目标类型。
<?php$foo = 10;   // 定义一个整型变量$bar = (boolean) $foo;   // 强制转换为布尔型?>

允许的强制转换有:

  • (int), (integer) – 转换为整形 integer
  • (bool), (boolean) – 转换为布尔类型 boolean
  • (float), (double), (real) – 转换为浮点型 float
  • (string) – 转换为字符串 string
  • (array) – 转换为数组 array
  • (object) – 转换为对象 object
  • (unset) – 转换为 NULL (PHP 5)

(binary) 转换和 b 前缀转换支持为 PHP 5.2.1 新增。

<?php$binary = (binary)$string;$binary = b"binary string";?>

可以将变量放置在双引号中的方式来代替将变量转换成字符串:

<?php$foo = 10;	//定义整型变量$str = "$foo";	// 强制转换为string类型$fst = (string)$foo;	//强制转换为string类型// 输出 "they are the same"if ($fst === $str) {
	echo "they are the same";}?>

在PHP中,如果要改变一个变量的类型,可以使用settype函数强制转换数据类型,基本语法如下:

Bool settype(var, string type)

其中type的可能值不能包含资源类型数据。
示例

<?php$var1 = 1.86;	// 定义浮点型数据echo settype($var1, "int");	// 强制转换为整数输出?>

转换为布尔值

要明确地将一个值转换成 boolean,用 (bool) 或者 (boolean) 来强制转换。但是很多情况下不需要用强制转换,因为当运算符,函数或者流程控制结构需要一个 boolean 参数时,该值会被自动转换。
当转换为 boolean 时,以下值被认为是 FALSE:

  • 布尔值 FALSE 本身
  • 整型值 0(零)
  • 浮点型值 0.0(零)
  • 空字符串,以及字符串 “0”
  • 不包括任何元素的数组
  • 特殊类型 NULL(包括尚未赋值的变量)
  • 从空标记生成的 SimpleXML 对象

所有其它值都被认为是 TRUE(包括任何资源 和 NAN)。
*** -1 和其它非零值(不论正负)一样,被认为是 TRUE! ***

<?phpvar_dump((bool) "");	// bool(false)var_dump((bool) 1);		// bool(true)var_dump((bool) -1);	// bool(true)var_dump((bool) -2);	// bool(true)var_dump((bool) "foo");	// bool(true)var_dump((bool) 2.3e5);	// bool(true)var_dump((bool) array(12));	// bool(true)var_dump((bool) array());	// bool(false)var_dump((bool) "false");	// bool(true)?>

转换为整型

要明确地将一个值转换为 integer,用 (int) 或 (integer) 强制转换。不过大多数情况下都不需要强制转换,因为当运算符,函数或流程控制需要一个 integer 参数时,值会自动转换。还可以通过函数 intval() 来将一个值转换成整型。

将 resource 转换成 integer 时,结果会是 PHP 运行时为 resource 分配的唯一资源号。

  1. 从布尔值转换
    FALSE 将产生出 0(零),TRUE 将产生出 1(壹)。
  2. 从浮点型转换
    当从浮点数转换成整数时,将向下取整。
    如果浮点数超出了整数范围(32 位平台下通常为 +/- 2.15e+9 = 2^31,64 位平台下,除了 Windows,通常为 +/- 9.22e+18 = 2^63),则结果为未定义,因为没有足够的精度给出一个确切的整数结果。在此情况下没有警告,甚至没有任何通知!
    PHP 7.0.0 起,NaN 和 Infinity 在转换成 integer 时,不再是 undefined 或者依赖于平台,而是都会变成零。
  3. 从字符串转换
    当一个字符串被当作一个数值来取值,其结果和类型如下:
    如果该字符串没有包含 ‘.’,‘e’ 或 ‘E’ 并且其数字值在整型的范围之内(由 PHP_INT_MAX 所定义),该字符串将被当成 integer 来取值。其它所有情况下都被作为 float 来取值。
    该字符串的开始部分决定了它的值。如果该字符串以合法的数值开始,则使用该数值。否则其值为 0(零)。合法数值由可选的正负号,后面跟着一个或多个数字(可能有小数点),再跟着可选的指数部分。指数部分由 ‘e’ 或 ‘E’ 后面跟着一个或多个数字构成。
  4. 从其他类型转换
    没有定义从其它类型转换为整型的行为。不要依赖任何现有的行为,因为它会未加通知地改变。

转换为浮点数

对于任何除字符串类型外的其它类型的值,其情况类似于先将值转换成整型,然后再转换成浮点。自 PHP 5 起,如果试图将对象转换为浮点数,会发出一条 E_NOTICE 错误消息。

转换为字符串

一个值可以通过在其前面加上 (string) 或用 strval() 函数来转变成字符串。在一个需要字符串的表达式中,会自动转换为 string。比如在使用函数 echo 或 print 时,或在一个变量和一个 string 进行比较时,就会发生这种转换。

一个布尔值 boolean 的 TRUE 被转换成 string 的 “1”。Boolean 的 FALSE 被转换成 “”(空字符串)。这种转换可以在 boolean 和 string 之间相互进行。

一个整数 integer 或浮点数 float 被转换为数字的字面样式的 string(包括 float 中的指数部分)。使用指数计数法的浮点数(4.1E+6)也可转换。

数组 array 总是转换成字符串 “Array”,因此,echo 和 print 无法显示出该数组的内容。要显示某个单元,可以用 echo $arr[‘foo’] 这种结构。

在 PHP 4 中对象 object 总是被转换成字符串 “Object”,为了得到对象的类的名称,可以用 get_class() 函数。自 PHP 5 起,适当时可以用 __toString 方法。

资源 resource 总会被转变成 “Resource id #1” 这种结构的字符串,其中的 1 是 PHP 在运行时分配给该 resource 的唯一值。不要依赖此结构,可能会有变更。要得到一个 resource 的类型,可以用函数 get_resource_type()。

NULL 总是被转变成空字符串。

直接把 array,object 或 resource 转换成 string 不会得到除了其类型之外的任何有用信息。可以使用函数 print_r() 和 var_dump() 列出这些类型的内容。

大部分的 PHP 值可以转变成 string 来永久保存,这被称作串行化,可以用函数 serialize() 来实现。如果 PHP 引擎设定支持 WDDX,PHP 值也可被串行化为格式良好的 XML 文本。

转换为数组

对于任意 integer,float,string,boolean 和 resource 类型,如果将一个值转换为数组,将得到一个仅有一个元素的数组,其下标为 0,该元素即为此标量的值。换句话说,(array)

s

c

a

l

a

r

V

a

l

u

e

a

r

r

a

y

(

scalarValue 与 array(

scalarValuearray(scalarValue) 完全一样。

如果一个 object 类型转换为 array,则结果为一个数组,其单元为该对象的属性。键名将为成员变量名,不过有几点例外:整数属性不可访问;私有变量前会加上类名作前缀;保护变量前会加上一个 ‘*’ 做前缀。这些前缀的前后都各有一个 NULL 字符。这会导致一些不可预知的行为:

<?phpclass A {
	private $A;		// 这将变成'AA'}class B extends A {
	private $A;		// 它将变成'BA'
	public $AA;		// 它将变成‘AA’}var_dump((array) new B());?>

以上代码输出结果为:
在这里插入图片描述

将 NULL 转换为 array 会得到一个空的数组。

可以用 array_diff() 和数组运算符来比较数组。

转换为对象

如果将一个对象转换成对象,它将不会有任何变化。如果其它任何类型的值被转换成对象,将会创建一个内置类stdClass的实例。如果该值为NULL,则新的实例为空。 array转换成object将使键名成为属性名并具有相对应的值。

<?php$obj = (object)array('1' => 'foo');// PHP7.2之后的版本输出'bool(tru)',之前版本会输出'bool(false)'var_dump(isset($obj->{'1'}));var_dump(key($obj));  //PHP7.2后输出'string(1) "1"',之前输出'int(1)'?>

对于其他值,会包含进成员变量名 scalar。

<?php$obj = (object)'ciao';echo $obj->scalar;    // 输出'ciao'?>

转换为资源

由于资源类型变量保存有为打开文件、数据库连接、图形画布区域等的特殊句柄,因此将其它类型的值转换为资源没有意义。

转换到NULL

使用(unset)$var将一个变量转换为NULL将不会删除该变量或者unset其值。仅是返回NULL值而已。

标量类型的声明

在默认情况下,所有的PHP文件都处于弱类型校验模式。PHP7加了标量类型声明特性,标量类型声明有两种模式:强制模式(默认)和严格模式。
标量类型声明语法格式如下:

declare(strict_types=1);

PHP默认情况下是弱类型校验模式,在php7下declare新增了strict_types指令,通过设置strict_types的值(1或者0),1表示严格类型校验模式,作用于函数调用和返回语句;0表示弱类型校验模式。默认为强制模式,即弱类型校验模式

可以声明标量类型的参数类型包括int、float、bool、string、interfaces、array和callable。

注意:declare(strict_types=1)必须是文件的第一个语句。如果这个语句出现在文件的其他地方,将会产生一个编译错误,块模式是被严格禁止的。

  1. 强制模式(弱类型校验模式)
<?php// 默认情况function sum(int $ints){
	return array_sum($ints);}print(sum(2, '3', 4.1));

以上程序输出结果为9.代码中的4.1先转换为整数4,然后再进行相加操作。

  1. 严格模式
<?php// 严格模式declare(strict_types=1);function sum(int $ints) {
	return array_sum($ints);}print(sum(2, '3', 4.1));?>

以上程序采用了严格模式,因此如果参数中出现的不是整数类型,程序执行时就会报错。

运算符

算术运算符

算术运算符是最简单、最常用的的运算符。常见的算术运算符如下表:

例子 运算符 名称 结果
-$a 取反运算符 $a的负值
$a + $b + 加法运算符  

a

a和

ab的和

$a – $b 减法运算符  

a

a和

ab的差

$a * $b * 乘法运算符  

a

a和

ab的积

$a / $b / 除法运算符  

a

a和

ab的商

$a % $b % 取摸运算符  

a

a除以

ab的余数

$a ** $b ** 乘方运算符 该运算符自PHP5.6新增,结果为

a

a的

ab次方

除法运算符总是返回浮点数。只有在下列情况例外:两个操作数都是整数(或字符串转换成的整数)并且正好能整除,这时它返回一个整数。

取模运算符的操作数在运算之前都会转换成整数(除去小数部分)。

取模运算符 % 的结果和被除数的符号(正负号)相同。即 $a % $b 的结果和 $a 的符号相同。

赋值运算符

基本赋值运算符(=),作用是把一定的数据值加载给特定变量,即把右边表达式的值赋给左边的运算数。
组合赋值运算符,可以在一个表达式中使用它的值并把表达式的结果赋给它,例如$a += 5,相当于$a = $a + 5.

赋值运算符的含义

赋值运算符 含义
= 将右边的值赋值给左边的变量
+= 将左边的值加上右边的值赋给左边的变量
-= 将左边的值减去右边的值赋给左边的变量
*= 将左边的值乘以右边的值赋给左边的变量
/= 将左边的值除以右边的值赋给左边的变量
.= 将左边的字符串连接到右边
%= 将左边的值对右边的值取余赋给左边的变量

位运算符

位运算符允许对整型数中指定的位进行求值和操作。常见的位运算符如下表:

例子 按位运算符 名称 结果
$a & $b & And(按位与) 将把

a

a和

ab中都为1的位设为1

$a | $b | Or(按位或) 将把

a

a和

ab中任何一个为1的位设为1

$a ^ $b ^ Xor(按位抑或) 将把

a

a和

ab钟一个为1另一个为0的位设为1

~$a ~ Not(按位取反) 将$a中为0的位设为1,为1的位设为0
$a << $b << Shift left(左移)

a

a中的位向左移动

ab次(每一次移动都表示“乘以2”)。

$a >> $b >> Shift right(右移)

a

a中的位向右移动

ab次(每一次移动都表示“除以2”)

位移在 PHP 中是数学运算。向任何方向移出去的位都被丢弃。左移时右侧以零填充,符号位被移走意味着正负号不被保留。右移时左侧以符号位填充,意味着正负号被保留。

比较运算符

比较运算符用来比较两端数据值的大小。比较运算符的具体含义如下表:

例子 运算符 名称 结果
$a == $b == 等于 如果类型转换后

a

a等与

ab,结果为TRUE

$a === $b === 全等 如果

a

a等于

ab,并且他们的类型也相同,则结果为TRUE

$a != $b != 不等 如果类型转换后

a

a不等于

ab,结果为TRUE

$a <> $b <> 不等 如果类型转化后

a

a不等于

ab,结果为TRUE

$a !== $b !== 不全等 如果

a

a不等于

ab,或者他们的类型不同,结果为TRUE

$a < $b < 小于 如果

a

a严格小于

ab,结果为TRUE

$a > $b > 大于 如果

a

a严格大于

ab,结果为TRUE

$a <= $b <= 小于等于 如果

a

a小于或者等于

ab,结果为TRUE

$a >= $b >= 大于等于 如果

a

a大于或者等于

ab,结果为TRUE

$a <=> $b <=> 太空船运算符(组合比较符)

a

a小于、等于、大于

ab时,分别返回一个小于、等于、大于0的integer值。PHP7开始提供。

$a ?? $b ?? $c ?? ?? NULL合并操作符 从左往右第一个存在且不为NULL的操作数。如果都没有定义且不为NULL,则返回NULL。PHP7开始提供

如果比较一个数字和字符串或者比较涉及到数字内容的字符串,则字符串会被转换为数值并且比较按照数值来进行。此规则也适用于 switch 语句。当用 === 或 !== 进行比较时则不进行类型转换,因为此时类型和数值都要比对。

<?php// Integersecho 1 <=> 1;		// 0echo "<br />";echo 1 <=> 2;		// -1echo "<br />";echo 2 <=> 1;		//1echo "<br />";// Floatsecho 1.5 <=> 1.5;	// 0echo "<br />";echo 1.5 <=> 2.5;	// -1echo "<br />";echo 2.5 <=> 1.5;	// 1echo "<br />";// Stringsecho "a" <=> "a";	//0echo "<br />";echo "a" <=> "b";	// -1echo "<br />";echo "b" <=> "a";	// 1echo "<br />";echo "a" <=> "aa";	// -1echo "<br />";echo "zz" <=> "aa";	// 1echo "<br />";// Arraysecho [] <=> [];		// 0echo "<br />";echo [1, 2, 3] <=> [1, 2, 3];	// 0echo "<br />";echo [1, 2, 3] <=> [];	// 1echo "<br />";echo [1, 2, 3] <=> [1, 2, 1];	// 1echo "<br />";echo [1, 2, 3] <=> [1, 2, 4];	// -1echo "<br />";// Objects$a = (object)["a" => "b"];$b = (object)["a" => "b"];echo $a <=> $b;		// 0echo "<br />";$a = (object)["a" => "b"];$b = (object)["a" => "c"];echo $a <=> $b;		// -1echo "<br />";$a = (object)["a" => "c"];$b = (object)["a" => "b"];echo $a <=> $b;		// 1echo "<br />";// 只进行值的比较$a = (object)["a" => "b"];$b = (object)["b" => "b"];echo $a <=> $b;		// 1echo "<br />";?>

对于多种类型,比较运算符根据下表比较(按顺序)。

运算数1类型 运算数2类型 结果
null或string string 将NULL转换为””,进行数字或词汇比较
bool或null 任何其他类型 转换为bool,FALSE < TRUE
object object 内置类可以定义自己的比较,不同类不能比较,相同类和数组同样方式比较属性(PHP4),PHP5中当使用比较运算符()比较两个对象变量时,比较的原则是:如果两个对象的属性和属性值都相等,而且两个对象是同一个类的实例,那么这两个对象变量相等。 而如果使用全等运算符(=),这两个对象变量一定要指向某个类的同一个实例(即同一个对象)。
string,resource或number string,resource或number 将字符串和资源转换成数字,按普通数学比较
array array 具有较少成员的数组较小,如果运算数1中的键不存在与运算数2中则数组无法比较,否则挨个值比较
object 任何其他类型 object总是更大
array 任何其他类型 array总是更大

递增/递减运算符

PHP支持C风格的前/后递增与递减运算符。

例子 名称 效果
++$a 前加  

a

1

a的值加1,然后返回

a1a

$a++ 后加 返回

a

a,然后将

aa的值加1

–$a 前减  

a

1

a的值减1,然后返回

a1a

$a– 后减 返回

a

a,然后将

aa的值减1

增/递减运算符不影响布尔值。递减 NULL 值也没有效果,但是递增 NULL 的结果是 1。
除了数值可以进行自增运算外,字符也可以进行自增运算。例如b++,结果等于c.注意字符变量只能递增,不能递减,并且只支持纯字母(a-z 和 A-Z)。递增/递减其他字符变量则无效,原字符串没有变化。

逻辑运算符

编程语言最重要的功能之一,就是进行逻辑判断和运算。逻辑运算符的含义如下表所示:

例子 运算符 名称 结果
$a and $b and And(逻辑与) 如果

a

a和

ab都为true,结果为true

$a or $b or Or(逻辑或) 如果

a

a或

ab任一为true,结果为true

$a xor $b xor Xor(逻辑亦或) 如果

a

a不同于

ab,结果为true

!$a ! Not(逻辑非) 如果$a不为true,结果为true
$a && $b && And(逻辑与) 如果

a

a和

ab都为true,结果为true

$a || $b || (逻辑或) 如果

a

a或

ab任一为true,结果为true

“与”和”或”有两种不同形式运算符的原因是它们运算的优先级不同。

字符串运算符

有两个字符串(string)运算符。第一个是连接运算符(”.”),它返回其左右参数连接后的字符串。第二个是连接赋值运算符(”.=”),它将右边参数附加到左边的参数之后。

错误控制运算符

PHP 支持一个错误控制运算符:@。当将其放置在一个 PHP 表达式之前,该表达式可能产生的任何错误信息都被忽略掉。

如果用set_error_handler()设定了自定义的错误处理函数,仍然会被调用,但是此错误处理函数可以调用error_reporting(),而该函数在出错语句前有@时将返回0。

如果激活了track_errors特性,表达式所产生的任何错误信息都被存放在变量 $php_errormsg中。此变量在每次出错时都会被覆盖,所以如果想用它的话就要尽早检查。

@运算符只对表达式有效。一个简单的规则就是:如果能从某处得到值,就能在它前面加上@运算符。例如,可以把它放在变量,函数和include调用,常量,等等之前。不能把它放在函数或类的定义之前,也不能用于条件结构例如 if 和 foreach 等。
***目前的”@“错误控制运算符前缀甚至使导致脚本终止的严重错误的错误报告也失效。这意味着如果在某个不存在或者敲错了字母的函数调用前用了”@”来抑制错误信息,那脚本会没有任何迹象显示原因而死在那里。 ***

执行运算符

PHP 支持一个执行运算符:反引号(“)。注意这不是单引号!PHP 将尝试将反引号中的内容作为 shell 命令来执行,并将其输出信息返回(即,可以赋给一个变量而不是简单地丢弃到标准输出)。使用反引号运算符”`”的效果与函数 shell_exec() 相同。

反引号运算符在激活了安全模式或者关闭了 shell_exec() 时是无效的。
与其它某些语言不同,反引号不能在双引号字符串中使用。

<?php$output = `ping 127.0.0.1`;echo "<pre>$output</pre>";?>

数组运算符

数组支持的运算符如下表所示:

例子 名称 结果
$a + $b 联合  

a

a和

ab的联合。

$a == $b 相等 如果

a

a和

ab具有相同的键/值对则为TRUE

$a === $b 全等 如果

a

a和

ab具有相同的键/值对并且顺序和类型都相同则为TRUE

$a != $b 不等 如果

a

a不等于

ab则为TRUE

$a <> $b 不等 如果

a

a不等于

ab则为TRUE

$a !== $b 不全等 如果

a

a不全等于

ab则为TRUE

+运算符把右边的数组元素附加到左边的数组后面,两个数组中都有的键名,则只用左边数组中的,右边的被忽略。

数组中的单元如果具有相同的键名和值则比较时相等。

类型运算符

instanceof用于确定一个PHP变量是否属于某一类class的实例:

<?phpclass MyClass {}class NotMyClass {}$a = new MyClass;var_dump($a instanceof MyClass);var_dump($a instanceof NotMyClass);?>

以上程序会输出:

bool(true)
bool(false)

instanceof 也可用来确定一个变量是不是继承自某一父类的子类的实例:

<?phpclass ParentClass{}class MyClass extends ParentClass{}$a = new MyClass;var_dump($a instanceof MyClass);var_dump($a instanceof ParentClass);?>

以上程序会输出:

bool(true)
bool(true)

检查一个对象是否不是某个类的实例,可以使用逻辑运算符 not。

<?phpclass MyClass{}$a = new MyClass;var_dump(!($a instanceof stdClass));?>

以上程序输出:

bool(true)

instanceof也可用于确定一个变量是不是实现了某个接口的对象的实例:

<?phpinterface MyInterface{}class MyClass implements MyInterface{}$a = new MyClass;var_dump($a instanceof MyClass);var_dump($a instanceof MyInterface);?>

以上程序输出:

bool(true)
bool(true)

如果被检测的变量不是对象,instanceof 并不发出任何错误信息而是返回 FALSE。不允许用来检测常量。

三元运算符

三元运算符作用在三个操作数之间,这样的操作符在PHP中只有一个,即“?:”,语法形式如下:

(expr1)?(expr2):(expr3)

表达式(expr1) ? (expr2) : (expr3) 在 expr1 求值为 TRUE 时的值为 expr2,在 expr1 求值为 FALSE 时的值为 expr3。

自PHP5.3起,可以省略三元运算符中间那部分。表达式 expr1 ?: expr3 在 expr1 求值为 TRUE 时返回 expr1,否则返回 expr3。

建议避免将三元运算符堆积在一起使用。当在一条语句中使用多个三元运算符时会造成 PHP 运算结果不清晰.
三元运算符是个语句,因此其求值不是变量,而是语句的结果。在一个通过引用返回的函数中语句 return $var == 42 ? $a : $b; 将不起作用。

运算符优先级

运算符的优先级和结合规则与正常的数学运算十分相似。

如果运算符优先级相同,那运算符的结合方向决定了该如何运算。例如,”-“是左联的,那么 1 – 2 – 3 就等同于 (1 – 2) – 3 并且结果是 -4. 另外一方面,”=”是右联的,所以 $a = $b = $c 等同于

a

=

(

a = (

a=(b = $c)。

没有结合的相同优先级的运算符不能连在一起使用,例如 1 < 2 > 1 在PHP是不合法的。但另外一方面表达式 1 <= 1 == 1 是合法的, 因为 == 的优先级低于 <=。

括号的使用,哪怕在不是必要的场合下,通过括号的配对来明确标明运算顺序,而非靠运算符优先级和结合性来决定,通常能够增加代码的可读性。

运算符优先级

结合方向 运算符
clone、new
[
**
++、–、~、(int)、(float)、(string)、(array)、(object)、(bool)、 @
instanceof
!
*、/、%
+、-、.
<<、>>
<、<=、>、>=
、!=、=、!==、<>、<=>
&
^
|
&&
||
??
?:
=、+=、-+、*=、**=、/=、.=、%=、&=、|=、^=、<<=、>>=
and
xor
or

表达式

表达式是在特定语言中表达一个特定的操作或动作的语句。一个表达式包含“操作数”和“操作符”。操作数可以是变量也可以是常量。操作符体现了要表达的行为,如逻辑判断、赋值、运算等。

在PHP代码中,使用“;”号来区分表达式,即一个表达式和一个分号组成了一条PHP语句。

PHP 是一种面向表达式的语言,从这一方面来讲几乎一切都是表达式。