1.2 基本語法
PHP是一種弱類型、面向對象的編程語言,本節會快速地介紹一下PHP的基本語法,示例代碼可以從ch01/quick_start.php里找到。
1.2.1 基本規范
PHP代碼以<?php作為起始標記,以?>作為結束標記。如果一個文件的內容全部為PHP代碼,或文件的結尾部分是PHP代碼,推薦省略?>結束標記。因為如果加上?>結束標記,無意間在其后增加了空行,那么會在輸出內容里增加這些空行,造成不必要的麻煩。
PHP用分號分割每個語句。代碼段的最后一行可以不用分號結束,但一般不推薦如此使用。
PHP的注釋分為單行注釋和塊注釋。
// This is a line comment # This is a line comment too /* This is a block coment, which can be used in multi lines */
1.2.2 數據類型
PHP中的變量不用事先定義類型,而且運行過程中可以改變其類型。PHP 7.1及以上的版本支持10種數據類型,如表1-4所示。
表1-4 PHP數據類型

1.2.3 變量
PHP定義一個變量的方法是,美元符號$加上變量名。變量名的規則是首字符為數字或下畫線,其余可為數字、字母與下畫線,例如:
$var = 'foo';
變量區分大小寫。例如:
$var = 'foo'; $VAR = 'FOO';
$var與$VAR是不同的變量。
PHP內置了一些預定義變量,這些變量通常為超全局變量,代碼的任何地方都可以直接使用這些變量。常見的預定義變量如表1-5所示。
表1-5 PHP預定義變量

變量的范圍是指變量的生效范圍,即在其上下文背景內能否被訪問、賦值等。PHP的變量范圍分為以下三種。
(1)文件域:定義在兩個不同文件的變量,其作用域限制在文件內部。
例如,文件a.php中定義了$a:
<?php $a = 1;
文件b.php引入a.php,但這時$a在b.php里不生效,所以$a未定義,即$a=NULL。
<?php include a.php; var_dump($a);//$a = NULL
(2)函數域:定義在函數內部的變量,其作用域限制在函數內部。
例如函數foo里定義了$a=1,但其生效范圍僅限于函數foo里,所以函數foo之外的$a=NULL。

(3)全局變量:全局變量可以在任意地方生效,表1-4中的PHP數據類型里的預定義變量就是全部變量。
可以使用global來改變變量的作用域。例如:

1.2.4 常量
常量在定義之后,其值不能改變,而且不能被unset。
常量的定義方式有以下兩種:
1.define
define('FOO','foo');
2.const
const FOO = 'foo';
PHP定義了一些魔術常量,如表1-6所示。
表1-6 PHP魔術常量

1.2.5 運算符
運算是一種給定若干輸入值,通過特定的操作產生輸出值的過程,運算符就是表示特定的操作。根據輸入值的個數不同可以分為幾種情況:一元運算符只能接收一個值,如遞增/遞減運算符;兩元運算符接收兩個值,如常見的加減乘除運算符;三元運算符接收三個值,PHP僅有一個三元運算符?:。
表1-7整理了PHP支持的運算符。
表1-7 PHP運算符

1.2.6 流程控制
PHP的流程控制分為條件控制、循環控制、分支控制和goto語句。
1.條件控制
根據條件執行語句,滿足則執行,不滿足則忽略。例如:

2.循環控制
重復執行語句若干次,可以根據條件是否滿足決定循環是否終止或繼續運行。以下介紹for、foreach、while、do-while、break和continue的使用。
(1)for

(2)foreach

(3)while

(4)do-while

(5)break和continue
在循環控制里,可以使用break和continue改變執行的流程。
● break跳出循環。break可以接受一個可選的數字參數來決定跳出幾重循環。
● continue跳過本次循環,不再執行continue語句之后的剩余代碼。continue也可以接受一個可選的數字參數來決定跳過幾重循環到循環結尾。默認值是1,即跳到當前循環末尾。
3.分支控制
在需要一個變量或表達式與多個不同值比較的場景下,可以用switch代替眾多的if else判斷。例如:

注意break的使用,如果某個case不加break,該case將會向下執行,直到遇到break或所有case執行完畢才停止。
4.goto語句
goto用來跳轉到程序中的另一位置。在各個語言里,goto被視為破壞程序可讀性的罪魁禍首,一般不推薦使用。
1.2.7 函數
PHP的函數分為內置函數和自定義函數。內置函數是PHP標準函數,如strlen為獲取給定字符串長度;用戶可以自行定義一個函數來實現想要的功能。
定義函數的格式如下:

其中$arg1,$arg2為參數,$arg2的類型為int,默認值為0。函數的返回值類型為int。
函數的參數是函數的輸入,默認按值傳遞,也可以通過引用傳遞。函數支持默認參數和可變長度參數。
1.引用傳遞
函數的參數默認傳遞方式為值傳遞,即傳遞的參數的作用域僅限函數內部,在函數內部改變參數的值,不會改變函數外部的值。如下例,盡管在value_demo函數里將$str改變了,但外部輸出的仍然是原值。

引用傳遞是指將參數以引用方式傳遞到函數內部(類似于C語言的指針),函數內的修改會生效。如下例,在reference_demo函數里將$str改變參數值,在外部就生效了。

2.可變長度參數
如果定義函數時無法確定參數的個數,可以使用可變長度參數,語法為…+參數名。例如:

與可變長度參數相關的函數有三個,如表1-8所示。
表1-8 與可變長度參數相關的函數

1.2.8 字符串
字符串是主流語言都支持的一種數據結構,類似于自然語言,程序員的第一個編程任務輸出的“hello world”就是字符串。PHP提供了強大的字符串處理函數。
定義字符串可以使用雙引號或單引號,雙引號支持變量解析,而單引號不支持。示例:
$str = 'hello';//單引號定義字符串 $str2 = "$str world";//雙引號定義字符串
字符串可以用“.”符號進行拼接:
$str3 = $str . ' world';//字符串拼接
PHP甚至提供了大小寫轉換的函數,例如:
strtoupper('Hello World');//將字符串轉化為大寫 strtolower('Hello World');//將字符串轉化為小寫
1.2.9 數組
PHP的數組除了傳統意義的數組(如C語言里的數組)外,還可以起到鏈表、隊列、棧、map的作用。數組可以說是PHP的核心,擁有廣泛的應用場景。
● 遍歷。從MySQL讀出的數據,可以數組方式進行遍歷處理。
● 排序。數組排序,支持自定義排序規則和多維數組排序。
● 格式轉換。與JSON格式相互轉換,以方便使用Restful風格的接口格式。
定義數組有兩種方式:

數組分為兩種,其一是純數組,其下標為數字,叫作壓縮數組(packed array);其二是哈希數組(hash array),類似于其他語言的map。
PHP的數組有豐富的函數庫可供使用,請看下面的幾個示例。
數組遍歷示例:

排序示例:
$nums = [1,3,2,6,4,5]; sort($nums);//正序排序,結果為1,2,3,4,5,6 rsort($nums);//逆序排序,結果為6,5,4,3,2,1
格式轉換:
$json = json_encode($array); $array = json_decode($json,true);
1.2.10 類與對象
PHP是一種面向對象的編程語言,它提供了豐富的面向對象的特性。類是計算機語言對外部世界物體的一個抽象描述,對象是類的實例。
定義一個類的格式如下:

PHP的類是單繼承的,即最多只能有一個父類。可以實現多個接口,用逗號來分隔多個接口的名稱。類有屬性和方法,屬性和方法都有私有、受保護、公有三種訪問控制。
PHP的類和對象的術語解釋如表1-9所示。
表1-9 PHP類和對象

1.2.11 異常處理
在PHP 5中處理異常的流程是try … catch … finally。如果在try中出現可被捕獲(thrown)的異常(Exception),可以在catch里處理此異常(如返回默認值,進行回退操作等),在finally里處理兜底邏輯(如關閉socket、關閉文件等)。

PHP 7的異常處理不同于PHP 5。PHP 7引入了一個與Exception同級別的結構Error,并將一些Fatal Error當作Error異常拋出。這種Error異常也可以像Exception異常一樣被第一個匹配的try/catch塊所捕獲。如果沒有匹配的catch塊,則調用異常處理函數(事先通過set_exception_handler()注冊)進行處理。如果尚未注冊異常處理函數,則按照傳統方式處理:被報告為一個致命錯誤(Fatal Error)。例如:
調用一個未定義的函數:
undefined_func();
這時會輸出類似于以下的錯誤信息并中斷程序的運行:
Fatal error: Uncaught Error: Call to undefined function undefined_func()
使用try/catch之后,可以捕獲這種錯誤,程序也能繼續運行。

PHP 7的Error層次結構如表1-10所示。
表1-10 PHP 7的Error層次結構

當需要處理異常時,應該使用哪種類型呢?一般而言,Error處理與代碼有關的錯誤,如進行取模操作時除數為0引發的錯誤,引用不存在的函數引發的錯誤等;Exception處理與外部環境有關的錯誤,如MySQL連接異常、文件打開異常、網絡訪問異常等。
1.2.12 命名空間
命名空間是一種對類的層級結構的一種封裝方式,類似于操作系統的目錄。在不同的命名空間下,用戶不用擔心類/函數/常量的名字沖突,在引入第三方類庫時,也不用擔心名字沖突。
在引入其他命名空間之下類庫時,如果標識符名稱沖突或過長,可以使用use as來創建別名。使用示例如下:
namesapce David\Name; use Other\Name as OtherName;
- 新一代通用視頻編碼H.266/VVC:原理、標準與實現
- Oracle Database In-Memory(架構與實踐)
- RTC程序設計:實時音視頻權威指南
- HTML5+CSS3網頁設計
- Kotlin從基礎到實戰
- 批調度與網絡問題的組合算法
- Building Android UIs with Custom Views
- Mastering Web Application Development with AngularJS
- Visual Studio 2015高級編程(第6版)
- Programming Microsoft Dynamics? NAV 2015
- Practical Microservices
- 并行編程方法與優化實踐
- 從零開始學Selenium自動化測試:基于Python:視頻教學版
- 大學計算機應用基礎(Windows 7+Office 2010)(IC3)
- Python 快速入門(第3版)