- function __autoload($classname) {
- require_once("{$classname}.php")
- }
復(fù)制代碼
但該函數(shù)已經(jīng)不被建議使用,原因是一個(gè)項(xiàng)目中僅能有一個(gè)這樣的 __autoload() 函數(shù),因?yàn)?PHP 不允許函數(shù)重名。但當(dāng)你使用一些類庫(kù)的時(shí)候,難免會(huì)出現(xiàn)多個(gè) autoload 函數(shù)的需要,于是 spl_autoload_register() 取而代之: - spl_autoload_register(function($classname)
- {
- require_once("{$classname}.php")
- });
復(fù)制代碼
spl_autoload_register() 會(huì)將一個(gè)函數(shù)注冊(cè)到 autoload 函數(shù)列表中,當(dāng)出現(xiàn)未定義的類的時(shí)候,SPL [注] 會(huì)按照注冊(cè)的倒序逐個(gè)調(diào)用被注冊(cè)的 autoload 函數(shù),這意味著你可以使用 spl_autoload_register() 注冊(cè)多個(gè) autoload 函數(shù). - // 連接到服務(wù)器,選擇數(shù)據(jù)庫(kù)
- $conn = mysql_connect("localhost", "user", "password");
- mysql_select_db("database");
-
- // 執(zhí)行 SQL 查詢
- $type = $_POST['type'];
- $sql = "SELECT * FROM `table` WHERE `type` = {$type}";
- $result = mysql_query($sql);
-
- // 打印結(jié)果
- while($row = mysql_fetch_array($result, MYSQL_ASSOC))
- {
- foreach($row as $k => $v)
- print "{$k}: {$v}\n";
- }
-
- // 釋放結(jié)果集,關(guān)閉連接
- mysql_free_result($result);
- mysql_close($conn);
復(fù)制代碼
為了能夠讓代碼實(shí)現(xiàn)數(shù)據(jù)庫(kù)無(wú)關(guān),即一段代碼同時(shí)適用于多種數(shù)據(jù)庫(kù)(例如以上代碼僅僅適用于MySQL),PHP 官方設(shè)計(jì)了 PDO. - // 連接到數(shù)據(jù)庫(kù)
- $conn = new PDO("mysql:host=localhost;dbname=database", "user", "password");
-
- // 預(yù)編譯SQL, 綁定參數(shù)
- $query = $conn->prepare("SELECT * FROM `table` WHERE `type` = :type");
- $query->bindParam("type", $_POST['type']);
-
- // 執(zhí)行查詢并打印結(jié)果
- foreach($query->execute() as $row)
- {
- foreach($row as $k => $v)
- print "{$k}: {$v}\n";
- }
復(fù)制代碼
PDO 是官方推薦的,更為通用的數(shù)據(jù)庫(kù)訪問(wèn)方式,如果你沒(méi)有特殊需求,那么你最好學(xué)習(xí)和使用 PDO. - // 限制第一個(gè)參數(shù)為 MyClass, 第二個(gè)參數(shù)為可執(zhí)行類型,第三個(gè)參數(shù)為數(shù)組
- function MyFunction(MyClass $a, callable $b, array $c)
- {
- // ...
- }
復(fù)制代碼
- $array = array("key" => "value", "array" => array(1, 2, 3, 4));
- $json = json_encode($array);
- echo "{$json}\n";
-
- $object = json_decode($json);
- print_r($object);
復(fù)制代碼
輸出: - {"key":"value","array":[1,2,3,4]}
- stdClass Object
- (
- [key] => value
- [array] => Array
- (
- [0] => 1
- [1] => 2
- [2] => 3
- [3] => 4
- )
- )
復(fù)制代碼
值得注意的是 json_decode() 默認(rèn)會(huì)返回一個(gè)對(duì)象而非數(shù)組,如果需要返回?cái)?shù)組需要將第二個(gè)參數(shù)設(shè)置為 true. - if(isAuth())
- $authorized = true;
- if($authorized)
- include("page.php");
復(fù)制代碼
這段代碼在通過(guò)驗(yàn)證時(shí),將 $authorized 設(shè)置為 true. 然后根據(jù) $authorized 的值來(lái)決定是否顯示頁(yè)面. - $func = function($arg)
- {
- print $arg;
- };
-
- $func("Hello World");
復(fù)制代碼
以上代碼定義了一個(gè)匿名函數(shù),并賦值給了 $func. - function arrayPlus($array, $num)
- {
- array_walk($array, function(&$v) use($num){
- $v += $num;
- });
- }
復(fù)制代碼
上面的代碼定義了一個(gè) arrayPlus() 函數(shù)(這不是匿名函數(shù)), 它會(huì)將一個(gè)數(shù)組($array)中的每一項(xiàng),加上一個(gè)指定的數(shù)字($num). - class A
- {
- public function __invoke($str)
- {
- print "A::__invoke(): {$str}";
- }
- }
-
- $a = new A;
- $a("Hello World");
復(fù)制代碼
輸出毫無(wú)疑問(wèn)是: - A::__invoke(): Hello World
復(fù)制代碼
__callStatic() 則會(huì)在調(diào)用一個(gè)不存在的靜態(tài)方法時(shí)被調(diào)用。 - <?php
- // 命名空間的分隔符是反斜杠,該聲明語(yǔ)句必須在文件第一行。
- // 命名空間中可以包含任意代碼,但只有 **類, 函數(shù), 常量** 受命名空間影響。
- namespace XXOO\Test;
-
- // 該類的完整限定名是 \XXOO\Test\A , 其中第一個(gè)反斜杠表示全局命名空間。
- class A{}
-
- // 你還可以在已經(jīng)文件中定義第二個(gè)命名空間,接下來(lái)的代碼將都位于 \Other\Test2 .
- namespace Other\Test2;
-
- // 實(shí)例化來(lái)自其他命名空間的對(duì)象:
- $a = new \XXOO\Test\A;
- class B{}
-
- // 你還可以用花括號(hào)定義第三個(gè)命名空間
- namespace Other {
- // 實(shí)例化來(lái)自子命名空間的對(duì)象:
- $b = new Test2\B;
-
- // 導(dǎo)入來(lái)自其他命名空間的名稱,并重命名,
- // 注意只能導(dǎo)入類,不能用于函數(shù)和常量。
- use \XXOO\Test\A as ClassA
- }
復(fù)制代碼
更多有關(guān)命名空間的語(yǔ)法介紹請(qǐng)參見(jiàn)官網(wǎng) [注]. - spl_autoload_register(
- function ($class) {
- spl_autoload(str_replace("\\", "/", $class));
- }
- );
復(fù)制代碼
當(dāng)你實(shí)例化一個(gè)類 \XXOO\Test\A 的時(shí)候,這個(gè)類的完整限定名會(huì)被傳遞給 autoload 函數(shù),autoload 函數(shù)將類名中的命名空間分隔符(反斜杠)替換為斜杠,并包含對(duì)應(yīng)文件。 - class A
- {
- public function callFuncXXOO()
- {
- print $this->funcXXOO();
- }
-
- public function funcXXOO()
- {
- return "A::funcXXOO()";
- }
- }
-
- class B extends A
- {
- public function funcXXOO()
- {
- return "B::funcXXOO";
- }
- }
-
- $b = new B;
- $b->callFuncXXOO();
復(fù)制代碼
輸出是: - B::funcXXOO
復(fù)制代碼
可以看到,當(dāng)在 A 中使用 $this->funcXXOO() 時(shí),體現(xiàn)了“虛函數(shù)”的機(jī)制,實(shí)際調(diào)用的是 B::funcXXOO(). - class A
- {
- static public function callFuncXXOO()
- {
- print self::funcXXOO();
- }
-
- static public function funcXXOO()
- {
- return "A::funcXXOO()";
- }
- }
-
- class B extends A
- {
- static public function funcXXOO()
- {
- return "B::funcXXOO";
- }
- }
-
- $b = new B;
- $b->callFuncXXOO();
復(fù)制代碼
情況就沒(méi)這么樂(lè)觀了,輸出是: - A::funcXXOO()
復(fù)制代碼
這是因?yàn)?self 的語(yǔ)義本來(lái)就是“當(dāng)前類”,所以 PHP5.3 給 static 關(guān)鍵字賦予了一個(gè)新功能:后期靜態(tài)綁定: - class A
- {
- static public function callFuncXXOO()
- {
- print static::funcXXOO();
- }
-
- // ...
- }
-
- // ...
復(fù)制代碼
這樣就會(huì)像預(yù)期一樣輸出了: - B::funcXXOO
復(fù)制代碼
- $name = "MyName";
- echo <<< TEXT
- My name is "{$name}".
- TEXT;
復(fù)制代碼
Heredoc 以三個(gè)左尖括號(hào)開(kāi)始,后面跟一個(gè)標(biāo)識(shí)符(TEXT), 直到一個(gè)同樣的頂格的標(biāo)識(shí)符(不能縮進(jìn))結(jié)束。 - var_dump(<<<EOD
- Hello World
- EOD
- );
-
- class A
- {
- const xx = <<< EOD
- Hello World
- EOD;
-
- public $oo = <<< EOD
- Hello World
- EOD;
- }
復(fù)制代碼
Nowdoc 的行為像一個(gè)單引號(hào)字符串,不能在其中嵌入變量,和 Heredoc 唯一的區(qū)別就是,三個(gè)左尖括號(hào)后的標(biāo)識(shí)符要以單引號(hào)括起來(lái): - $name = "MyName";
- echo <<< 'TEXT'
- My name is "{$name}".
- TEXT;
復(fù)制代碼
輸出: - My name is "{$name}".
復(fù)制代碼
- define("XOOO", "Value");
復(fù)制代碼
新式風(fēng)格: - const XXOO = "Value";
復(fù)制代碼
const 形式僅適用于常量,不適用于運(yùn)行時(shí)才能求值的表達(dá)式: - // 正確
- const XXOO = 1234;
- // 錯(cuò)誤
- const XXOO = 2 * 617;
復(fù)制代碼
- echo $a ? $a : "No Value";
復(fù)制代碼
可簡(jiǎn)寫成: - echo $a ?: "No Value";
復(fù)制代碼
即如果省略三元運(yùn)算符的第二個(gè)部分,會(huì)默認(rèn)用第一個(gè)部分代替。 - require("xxoo.phar");
- require("phar://xxoo.phar/xo/ox.php");
復(fù)制代碼
更多信息請(qǐng)參見(jiàn)官網(wǎng) [注]. - <?php
- // Code...
- ?>
復(fù)制代碼
通常就是上面的形式,除此之外還有一種簡(jiǎn)寫形式: - <? /* Code... */ ?>
復(fù)制代碼
還可以把 - <?php echo $xxoo;?>
復(fù)制代碼
簡(jiǎn)寫成: - <?= $xxoo;?>
復(fù)制代碼
這種簡(jiǎn)寫形式被稱為 Short Open Tag, 在 PHP5.3 起被默認(rèn)開(kāi)啟,在 PHP5.4 起總是可用。 - // 原來(lái)的數(shù)組寫法
- $arr = array("key" => "value", "key2" => "value2");
- // 簡(jiǎn)寫形式
- $arr = ["key" => "value", "key2" => "value2"];
復(fù)制代碼
- // Traits不能被單獨(dú)實(shí)例化,只能被類所包含
- trait SayWorld
- {
- public function sayHello()
- {
- echo 'World!';
- }
- }
-
- class MyHelloWorld
- {
- // 將SayWorld中的成員包含進(jìn)來(lái)
- use SayWorld;
- }
-
- $xxoo = new MyHelloWorld();
- // sayHello() 函數(shù)是來(lái)自 SayWorld 構(gòu)件的
- $xxoo->sayHello();
復(fù)制代碼
Traits還有很多神奇的功能,比如包含多個(gè)Traits, 解決沖突,修改訪問(wèn)權(quán)限,為函數(shù)設(shè)置別名等等。 - php -S localhost:8000
復(fù)制代碼
這樣就在當(dāng)前目錄建立起了一個(gè)Web服務(wù)器,你可以通過(guò) http://localhost:8000/ 來(lái)訪問(wèn)。 - php -S localhost:8000 index.php
復(fù)制代碼
這樣一來(lái),所有的請(qǐng)求都會(huì)由index.php來(lái)處理。 - $func = "funcXXOO";
- A::{$func}();
復(fù)制代碼
新增在實(shí)例化時(shí)訪問(wèn)類成員的特征: - (new MyClass)->xxoo();
復(fù)制代碼
新增支持對(duì)函數(shù)返回?cái)?shù)組的成員訪問(wèn)解析(這種寫法在之前版本是會(huì)報(bào)錯(cuò)的): - print func()[0];
復(fù)制代碼
- function number10()
- {
- for($i = 1; $i <= 10; $i += 1)
- yield $i;
- }
復(fù)制代碼
該函數(shù)的返回值是一個(gè)數(shù)組: - $array = [
- [1, 2, 3],
- [4, 5, 6],
- ];
-
- foreach ($array as list($a, $b, $c))
- echo "{$a} {$b} {$c}\n";
復(fù)制代碼
結(jié)果: - 1 2 3
- 4 5 6
復(fù)制代碼
- const A = 2;
- const B = A + 1;
-
- class C
- {
- const STR = "hello";
- const STR2 = self::STR + ", world";
- }
復(fù)制代碼
允許常量作為函數(shù)參數(shù)默認(rèn)值: - function func($arg = C::STR2)
復(fù)制代碼
- function add(...$args)
- {
- $result = 0;
- foreach($args as $arg)
- $result += $arg;
- return $result;
- } 復(fù)制代碼
同時(shí)可以在調(diào)用函數(shù)時(shí),把數(shù)組展開(kāi)為函數(shù)參數(shù): - $arr = [2, 3];
- add(1, ...$arr);
- // 結(jié)果為 6 復(fù)制代碼
- namespace Name\Space {
- const FOO = 42;
- function f() { echo __FUNCTION__."\n"; }
- }
-
- namespace {
- use const Name\Space\FOO;
- use function Name\Space\f;
-
- echo FOO."\n";
- f();
- } 復(fù)制代碼
聯(lián)系客服