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 開始輸出這些空白,而腳本中此時並無輸出的意圖。

【示例】

<?php
echo "Hello World";

// ... more code

echo "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:_REQUEST:包含用戶所有輸入內容的數組(包括_GET、POST_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;		// 浮點型 float

echo gettype($a_bool);		// 輸出: boolean
echo gettype($a_str);		// 輸出: string
echo gettype($a_str2);		// 輸出: string
echo gettype($an_int);		// 輸出: integer
echo gettype($a_float);		// 輸出: double

// 如果是整型,就加上4
if (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 = <<<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': \x41
EOT;
?>

以上代碼會輸出:

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

也可以把Heredoc結構用在函數參數中來傳遞數據:

<?php
var_dump(array(<<<EOD
foobar!
EOD
));
?>

以上代碼會輸出

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

在PHP5.3.0以後,也可以用Heredoc結構來初始化靜態變量和類的屬性和常量:

<?php
// 靜態變量
function foo()
{
	static $bar = <<<LABEL
Nothing in here...
LABEL;
}

// 類的常量、屬性
class foo
{
	const BAR = <<<FOOBAR
Constant example
FOOBAR;
	
	public $baz = <<<FOOBAR
Property example
FOOBAR;
}
?>

自PHP5.3.0起還可以在Heredoc結構中用雙引號來聲明標識符:

<?php
echo <<<"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': \x41
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': \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 work
echo "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 fantastic
echo "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()}";

還可以在字符串中用這種語法通過變量來調用類的屬性。
示例

<?php
class 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 & W
echo "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也可以用花括號訪問,比如str42str{42},效果和str[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 起可以直接對一個數組原型進行數組解引用。

示例

<?php
function 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語句實例化一個類:

<?php
class 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 值賦給變量 varvar,var 就成了一個 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! ***

<?php
var_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)scalarValuearray(scalarValue 與 array(scalarValue) 完全一樣。

如果一個 object 類型轉換爲 array,則結果爲一個數組,其單元爲該對象的屬性。鍵名將爲成員變量名,不過有幾點例外:整數屬性不可訪問;私有變量前會加上類名作前綴;保護變量前會加上一個 ‘*’ 做前綴。這些前綴的前後都各有一個 NULL 字符。這會導致一些不可預知的行爲:

<?php
class A {
	private $A;		// 這將變成'\0A\0A'
}

class B extends A {
	private $A;		// 它將變成'\0B\0A'
	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 + 加法運算符 aa和b的和
$a - $b - 減法運算符 aa和b的差
$a * $b * 乘法運算符 aa和b的積
$a / $b / 除法運算符 aa和b的商
$a % $b % 取摸運算符 aa除以b的餘數
$a ** $b ** 乘方運算符 該運算符自PHP5.6新增,結果爲aa的b次方

除法運算符總是返回浮點數。只有在下列情況例外:兩個操作數都是整數(或字符串轉換成的整數)並且正好能整除,這時它返回一個整數。

取模運算符的操作數在運算之前都會轉換成整數(除去小數部分)。

取模運算符 % 的結果和被除數的符號(正負號)相同。即 $a % $b 的結果和 $a 的符號相同。

賦值運算符

基本賦值運算符(=),作用是把一定的數據值加載給特定變量,即把右邊表達式的值賦給左邊的運算數。
組合賦值運算符,可以在一個表達式中使用它的值並把表達式的結果賦給它,例如$a += 5,相當於$a = $a + 5.

賦值運算符的含義

賦值運算符 含義
= 將右邊的值賦值給左邊的變量
+= 將左邊的值加上右邊的值賦給左邊的變量
-= 將左邊的值減去右邊的值賦給左邊的變量
*= 將左邊的值乘以右邊的值賦給左邊的變量
/= 將左邊的值除以右邊的值賦給左邊的變量
.= 將左邊的字符串連接到右邊
%= 將左邊的值對右邊的值取餘賦給左邊的變量

位運算符

位運算符允許對整型數中指定的位進行求值和操作。常見的位運算符如下表:

例子 按位運算符 名稱 結果
$a & $b & And(按位與) 將把aa和b中都爲1的位設爲1
$a | $b | Or(按位或) 將把aa和b中任何一個爲1的位設爲1
$a ^ $b ^ Xor(按位抑或) 將把aa和b鍾一個爲1另一個爲0的位設爲1
~$a ~ Not(按位取反) 將$a中爲0的位設爲1,爲1的位設爲0
$a << $b << Shift left(左移) aa中的位向左移動b次(每一次移動都表示“乘以2”)。
$a >> $b >> Shift right(右移) aa中的位向右移動b次(每一次移動都表示“除以2”)

位移在 PHP 中是數學運算。向任何方向移出去的位都被丟棄。左移時右側以零填充,符號位被移走意味着正負號不被保留。右移時左側以符號位填充,意味着正負號被保留。

比較運算符

比較運算符用來比較兩端數據值的大小。比較運算符的具體含義如下表:

例子 運算符 名稱 結果
$a == $b == 等於 如果類型轉換後aa等與b,結果爲TRUE
$a === $b === 全等 如果aa等於b,並且他們的類型也相同,則結果爲TRUE
$a != $b != 不等 如果類型轉換後aa不等於b,結果爲TRUE
$a <> $b <> 不等 如果類型轉化後aa不等於b,結果爲TRUE
$a !== $b !== 不全等 如果aa不等於b,或者他們的類型不同,結果爲TRUE
$a < $b < 小於 如果aa嚴格小於b,結果爲TRUE
$a > $b > 大於 如果aa嚴格大於b,結果爲TRUE
$a <= $b <= 小於等於 如果aa小於或者等於b,結果爲TRUE
$a >= $b >= 大於等於 如果aa大於或者等於b,結果爲TRUE
$a <=> $b <=> 太空船運算符(組合比較符) aa小於、等於、大於b時,分別返回一個小於、等於、大於0的integer值。PHP7開始提供。
$a ?? $b ?? $c ?? ?? NULL合併操作符 從左往右第一個存在且不爲NULL的操作數。如果都沒有定義且不爲NULL,則返回NULL。PHP7開始提供

如果比較一個數字和字符串或者比較涉及到數字內容的字符串,則字符串會被轉換爲數值並且比較按照數值來進行。此規則也適用於 switch 語句。當用 === 或 !== 進行比較時則不進行類型轉換,因爲此時類型和數值都要比對。

<?php
// Integers
echo 1 <=> 1;		// 0
echo "<br />";
echo 1 <=> 2;		// -1
echo "<br />";
echo 2 <=> 1;		//1
echo "<br />";

// Floats
echo 1.5 <=> 1.5;	// 0
echo "<br />";
echo 1.5 <=> 2.5;	// -1
echo "<br />";
echo 2.5 <=> 1.5;	// 1
echo "<br />";

// Strings
echo "a" <=> "a";	//0
echo "<br />";
echo "a" <=> "b";	// -1
echo "<br />";
echo "b" <=> "a";	// 1
echo "<br />";
echo "a" <=> "aa";	// -1
echo "<br />";
echo "zz" <=> "aa";	// 1
echo "<br />";

// Arrays
echo [] <=> [];		// 0
echo "<br />";
echo [1, 2, 3] <=> [1, 2, 3];	// 0
echo "<br />";
echo [1, 2, 3] <=> [];	// 1
echo "<br />";
echo [1, 2, 3] <=> [1, 2, 1];	// 1
echo "<br />";
echo [1, 2, 3] <=> [1, 2, 4];	// -1
echo "<br />";

// Objects
$a = (object)["a" => "b"];
$b = (object)["a" => "b"];
echo $a <=> $b;		// 0
echo "<br />";

$a = (object)["a" => "b"];
$b = (object)["a" => "c"];
echo $a <=> $b;		// -1
echo "<br />";

$a = (object)["a" => "c"];
$b = (object)["a" => "b"];
echo $a <=> $b;		// 1
echo "<br />";

// 只進行值的比較
$a = (object)["a" => "b"];
$b = (object)["b" => "b"];
echo $a <=> $b;		// 1
echo "<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 前加 a1a的值加1,然後返回a
$a++ 後加 返回aa,然後將a的值加1
–$a 前減 a1a的值減1,然後返回a
$a– 後減 返回aa,然後將a的值減1

增/遞減運算符不影響布爾值。遞減 NULL 值也沒有效果,但是遞增 NULL 的結果是 1。
除了數值可以進行自增運算外,字符也可以進行自增運算。例如b++,結果等於c.注意字符變量只能遞增,不能遞減,並且只支持純字母(a-z 和 A-Z)。遞增/遞減其他字符變量則無效,原字符串沒有變化。

邏輯運算符

編程語言最重要的功能之一,就是進行邏輯判斷和運算。邏輯運算符的含義如下表所示:

例子 運算符 名稱 結果
$a and $b and And(邏輯與) 如果aa和b都爲true,結果爲true
$a or $b or Or(邏輯或) 如果aa或b任一爲true,結果爲true
$a xor $b xor Xor(邏輯亦或) 如果aa不同於b,結果爲true
!$a ! Not(邏輯非) 如果$a不爲true,結果爲true
$a && $b && And(邏輯與) 如果aa和b都爲true,結果爲true
$a || $b || (邏輯或) 如果aa或b任一爲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 聯合 aa和b的聯合。
$a == $b 相等 如果aa和b具有相同的鍵/值對則爲TRUE
$a === $b 全等 如果aa和b具有相同的鍵/值對並且順序和類型都相同則爲TRUE
$a != $b 不等 如果aa不等於b則爲TRUE
$a <> $b 不等 如果aa不等於b則爲TRUE
$a !== $b 不全等 如果aa不全等於b則爲TRUE

+運算符把右邊的數組元素附加到左邊的數組後面,兩個數組中都有的鍵名,則只用左邊數組中的,右邊的被忽略。

數組中的單元如果具有相同的鍵名和值則比較時相等。

類型運算符

instanceof用於確定一個PHP變量是否屬於某一類class的實例:

<?php
class MyClass {
}
class NotMyClass {
}

$a = new MyClass;

var_dump($a instanceof MyClass);
var_dump($a instanceof NotMyClass);
?>

以上程序會輸出:

bool(true)
bool(false)

instanceof 也可用來確定一個變量是不是繼承自某一父類的子類的實例:

<?php
class ParentClass{
}
class MyClass extends ParentClass{
}

$a = new MyClass;

var_dump($a instanceof MyClass);
var_dump($a instanceof ParentClass);
?>

以上程序會輸出:

bool(true)
bool(true)

檢查一個對象是否不是某個類的實例,可以使用邏輯運算符 not。

<?php
class MyClass{
}

$a = new MyClass;
var_dump(!($a instanceof stdClass));
?> 

以上程序輸出:

bool(true)

instanceof也可用於確定一個變量是不是實現了某個接口的對象的實例:

<?php
interface 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 = (b = $c)。

沒有結合的相同優先級的運算符不能連在一起使用,例如 1 < 2 > 1 在PHP是不合法的。但另外一方面表達式 1 <= 1 == 1 是合法的, 因爲 == 的優先級低於 <=。

括號的使用,哪怕在不是必要的場合下,通過括號的配對來明確標明運算順序,而非靠運算符優先級和結合性來決定,通常能夠增加代碼的可讀性。

運算符優先級

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

表達式

表達式是在特定語言中表達一個特定的操作或動作的語句。一個表達式包含“操作數”和“操作符”。操作數可以是變量也可以是常量。操作符體現了要表達的行爲,如邏輯判斷、賦值、運算等。

在PHP代碼中,使用“;”號來區分表達式,即一個表達式和一個分號組成了一條PHP語句。

PHP 是一種面向表達式的語言,從這一方面來講幾乎一切都是表達式。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章