# PHP 7入門：函數的增強

{"type":"doc","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"本文要點"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"要在運行時創建命名的數組常量，我們可以使用新的"},{"type":"codeinline","content":[{"type":"text","text":"define()"}]},{"type":"text","text":"函數。"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"要將對象作用域綁定到一個變量並調用它，我們可以使用新的"},{"type":"codeinline","content":[{"type":"text","text":"Closure::call()"}]},{"type":"text","text":"函數。"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"要通過傳統的"},{"type":"codeinline","content":[{"type":"text","text":"assert()"}]},{"type":"text","text":"使用表達式和\/或自定義"},{"type":"codeinline","content":[{"type":"text","text":"AssertionError"}]},{"type":"text","text":"，那麼我們可以使用expectation。"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"PHP 7支持從Generator函數返回一個值。"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"PHP 7支持將一個Generator函數委託給另一個Generator函數。"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"對於整數除法，使用名爲"},{"type":"codeinline","content":[{"type":"text","text":"intdiv()"}]},{"type":"text","text":"的新函數。"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"要覆蓋"},{"type":"codeinline","content":[{"type":"text","text":"php.ini"}]},{"type":"text","text":"中的會話配置的設置，可以使用新的"},{"type":"codeinline","content":[{"type":"text","text":"session_start"}]},{"type":"text","text":"函數。"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"要使用回調執行正則表達式搜索和替換，使用新的函數"},{"type":"codeinline","content":[{"type":"text","text":"preg_replace_callback_array()"}]},{"type":"text","text":"。"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"PHP 7能夠生成加密安全的整數和字節。"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"PHP 7.1支持將回調轉換爲閉包。"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"箭頭（=>）函數爲匿名函數提供了簡潔的語法。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在"},{"type":"link","attrs":{"href":"https:\/\/www.infoq.com\/articles\/php7-new-type-features\/","title":"","type":null},"content":[{"type":"text","text":"PHP 7系列前面的文章中"}]},{"type":"text","text":"，我們討論了PHP類型系統的新特性。在本文中，我們將會探討PHP 7在函數方面的改善。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"PHP支持多種類型的函數，包括用戶自定義函數、內部函數、變量函數以及匿名函數。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"定義數組常量的新函數"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"PHP 7.0添加了名爲"},{"type":"codeinline","content":[{"type":"text","text":"define()"}]},{"type":"text","text":"的新函數，用來在運行時定義命名的數組常量。define()的語法如下所示："}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"bool define ( string $name , mixed$value [, bool case_insensitive = FALSE ] )"}]},{"type":"text","text":""}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"表1討論了該函數的參數"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":""},{"type":"text","marks":[{"type":"strong"}],"text":"表1 define()函數的參數"},{"type":"text","text":""}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"embedcomp","attrs":{"type":"table","data":{"content":" 參數描述 name常量的名稱。這個名稱可以是保留字，但不建議這樣做。 value常量的值。這個值必須是一個標量值（整型、浮點、字符串、布爾值或NULL）或數組。 case_insensitive常量是否區分大小寫，默認是區分大小寫的。在PHP 7.3.0中，不推薦採用不區分大小寫的方式。"}}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"創建PHP腳本_constant.php_並定義名爲"},{"type":"codeinline","content":[{"type":"text","text":"CONSTANT"}]},{"type":"text","text":"的常量，如下所示。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"define(\"CONSTANT\", \"Hello PHP\");"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我們還可以使用"},{"type":"codeinline","content":[{"type":"text","text":"const"}]},{"type":"text","text":"關鍵字來定義常量："}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"const CONSTANT_2 = 'Hello php';\nconst Constant = 'HELLO PHP';\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"define()"}]},{"type":"text","text":"函數可以用來定義數組常量："}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"define(\"Catalog\", ['Oracle Magazine','Java Magazine']);"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"數組常量的值可以使用數組元素訪問的方式進行輸出。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"echo Catalog[0]\necho Catalog[1]\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"_constant.php_文件如下所示："}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"\"; \nconst CONSTANT_2 = 'Hello php';\necho CONSTANT_2.\" \";\nconst Constant = 'HELLO PHP';\necho Constant.\" \";\ndefine(\"Catalog\", ['Oracle Magazine','Java Magazine']);\necho Catalog[0].\" \";\necho Catalog[1]\n?>\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"運行腳本將會輸出腳本中定義的常量值。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"Hello PHP\nHello php\nHELLO PHP\nOracle Magazine\nJava Magazine\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"全局定義的常量，如"},{"type":"codeinline","content":[{"type":"text","text":"TRUE"}]},{"type":"text","text":"或"},{"type":"codeinline","content":[{"type":"text","text":"FALSE"}]},{"type":"text","text":"，不能進行重定義。爲了闡述這一點，我們創建一個_const.php_腳本，該腳本定義了常量"},{"type":"codeinline","content":[{"type":"text","text":"TRUE"}]},{"type":"text","text":"，並將它的值設置成了"},{"type":"codeinline","content":[{"type":"text","text":"20"}]},{"type":"text","text":"："}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果你運行該腳本的話，它將會輸出的值是"},{"type":"codeinline","content":[{"type":"text","text":"1"}]},{"type":"text","text":"，這也是"},{"type":"codeinline","content":[{"type":"text","text":"TRUE"}]},{"type":"text","text":"全局定義的值。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"綁定對象作用域到閉包的新函數"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"閉包是用來表示匿名函數的類。PHP 7.0引入了新的"},{"type":"codeinline","content":[{"type":"text","text":"Closure::call()"}]},{"type":"text","text":"函數，能夠非常簡便地將對象作用域臨時綁定到一個閉包並調用它。爲了闡述這一點，創建腳本_closure.php_並複製如下清單所示的代碼："}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"getMsg();};\nechogetMsg->call(new Hello);\n?>\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在上述腳本中，Hello是一個具有函數"},{"type":"codeinline","content":[{"type":"text","text":"getMsg()"}]},{"type":"text","text":"的類。"},{"type":"codeinline","content":[{"type":"text","text":"Closure::call()"}]},{"type":"text","text":"函數用來創建一個"},{"type":"codeinline","content":[{"type":"text","text":"Hello"}]},{"type":"text","text":"實例，並綁定它的作用域到一個調用"},{"type":"codeinline","content":[{"type":"text","text":"getMsg"}]},{"type":"text","text":"方法的閉包。運行該腳本將會輸出"},{"type":"codeinline","content":[{"type":"text","text":"Hello"}]},{"type":"text","text":"消息。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"Expectation"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在討論_expectation_之前，我們先看一下傳統的斷言。傳統的"},{"type":"codeinline","content":[{"type":"text","text":"assert()"}]},{"type":"text","text":"方法定義如下所示。它會檢查如果代碼的預期值（稱爲_斷言_）是不是爲"},{"type":"codeinline","content":[{"type":"text","text":"FALSE"}]},{"type":"text","text":"，如果是"},{"type":"codeinline","content":[{"type":"text","text":"FALSE"}]},{"type":"text","text":"的話，它會打印出描述消息，並且默認會中止程序。如果斷言不是"},{"type":"codeinline","content":[{"type":"text","text":"FALSE"}]},{"type":"text","text":"的話，"},{"type":"codeinline","content":[{"type":"text","text":"assert()"}]},{"type":"text","text":"沒有任何效果。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"bool assert ( mixed $assertion [, string$description ] )"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"按照設計，斷言用於開發和測試期的調試，而不是運行期的操作。"},{"type":"codeinline","content":[{"type":"text","text":"assert()"}]},{"type":"text","text":"的行爲可以通過"},{"type":"link","attrs":{"href":"https:\/\/www.php.net\/manual\/en\/function.assert-options.php","title":"","type":null},"content":[{"type":"text","text":"assert_options()"}]},{"type":"text","text":"或者"},{"type":"codeinline","content":[{"type":"text","text":".ini"}]},{"type":"text","text":"文件進行配置。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"傳統上，"},{"type":"codeinline","content":[{"type":"text","text":"assert()"}]},{"type":"text","text":"的第一個參數應該是一個要評估計算的字符串或者作爲斷言進行測試的boolean條件。如果所提供的是一個字符串的話，它會以PHP代碼的形式進行評估計算。如果所提供的是一個boolean條件的話，那麼在傳遞給"},{"type":"codeinline","content":[{"type":"text","text":"assert_options()"}]},{"type":"text","text":"定義的斷言回調函數（如果存在的話）之前，它將會被轉換成字符串。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"斷言在PHP 7中進行了徹底修改，現在被稱爲_expectation_，並且"},{"type":"codeinline","content":[{"type":"text","text":"assert()"}]},{"type":"text","text":"是PHP 7中的一個語言結構。作爲對"},{"type":"codeinline","content":[{"type":"text","text":"assert()"}]},{"type":"text","text":"的增強，expectations被添加了進來，並且具有如下的語法："}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"bool assert ( mixed $assertion [, Throwable$exception ] )"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"有了expectations之後，"},{"type":"codeinline","content":[{"type":"text","text":"assert()"}]},{"type":"text","text":"的第一個參數可能是會返回一個值的表達式，而不再是一個要評估執行的PHP代碼字符串或者要測試的boolean條件。表達式會被執行，得到的結果會被用來確定斷言是否成功。從PHP 7開始，使用字符串作爲第一個參數已經被廢棄掉了。"},{"type":"codeinline","content":[{"type":"text","text":"assert_options()"}]},{"type":"text","text":"依然能夠與expectations協同使用，但是並不推薦這麼做。相反，我們應該使用兩個新的php.ini配置指令，如表2所示。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"表2 Expectations的配置指令"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"embedcomp","attrs":{"type":"table","data":{"content":"

zend.assertionsinteger配置是否要生成斷言代碼並運行。1：生成和運行斷言代碼（開發模式）** 0：生成斷言代碼但是並不會在運行時執行 **-1：不生成斷言代碼（生產模式）。使用該配置以便於使用expectations。1
assert.exception對於失敗的斷言拋出AssertionError或自定義異常1：當斷言失敗的時候，要麼拋出以異常的形式提供的對象，要麼在沒有提供異常的情況下拋出一個新的AssertionError對象。使用該配置以便於使用expectations。** **0：使用或生成上述的Throwable，但是隻生成一個告警，而不拋出異常或AssertionError。0"}}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"藉助expectations，第二個參數可能會是一個"},{"type":"codeinline","content":[{"type":"text","text":"Throwable"}]},{"type":"text","text":"對象，而不再是字符串描述。爲了在斷言失敗的時候拋出"},{"type":"codeinline","content":[{"type":"text","text":"Throwable"}]},{"type":"text","text":"對象或異常，"},{"type":"codeinline","content":[{"type":"text","text":"assert.exception"}]},{"type":"text","text":"指令必須設置爲1。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"相對於傳統的斷言，expectations有如下的優勢，不過爲了向後兼容，傳統的斷言依然是支持的："}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"可以用表達式來評估一個斷言，而不是字符串或boolean值。"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"通過使用"},{"type":"codeinline","content":[{"type":"text","text":"php.ini"}]},{"type":"text","text":"設置，斷言代碼即便已經生成，但可以在運行期跳過它們。甚至可能根本就不生成斷言代碼，對於生產環境的使用來說，推薦這樣做。"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"可以拋出自定義異常。PHP 7新增加了類"},{"type":"codeinline","content":[{"type":"text","text":"AssertionError"}]},{"type":"text","text":"。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"作爲如何使用expectations的樣例，我們創建一個名爲_expectation.php_的腳本，並複製如下的代碼清單到腳本中。這個腳本將這兩個配置指令都設置成了1。"},{"type":"codeinline","content":[{"type":"text","text":"assert"}]},{"type":"text","text":"語言結構將第一個參數設置爲true，第二個參數設置爲一個自定義的"},{"type":"codeinline","content":[{"type":"text","text":"AssertionError"}]},{"type":"text","text":"。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果運行這個腳本的話，將不會拋出"},{"type":"codeinline","content":[{"type":"text","text":"AssertionError"}]},{"type":"text","text":"。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"接下來，將第一個參數設置爲"},{"type":"codeinline","content":[{"type":"text","text":"false"}]},{"type":"text","text":"。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"assert(false, new AssertionError('Assertion failed.'));"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果再次運行腳本的話，expectation將會失敗並拋出"},{"type":"codeinline","content":[{"type":"text","text":"AssertonError"}]},{"type":"text","text":"。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"Uncaught AssertionError: Assertion failed"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"爲了闡述在"},{"type":"codeinline","content":[{"type":"text","text":"assert()"}]},{"type":"text","text":"中藉助表達式和自定義"},{"type":"codeinline","content":[{"type":"text","text":"AssertionError"}]},{"type":"text","text":"使用expectations，我們首先從傳統的使用"},{"type":"codeinline","content":[{"type":"text","text":"assert()"}]},{"type":"text","text":"方式開始，測試一個變量是數字的斷言。這裏使用字符串來測試變量，並在斷言失敗的時候輸出消息。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"$numValue = '123string';\nassert('is_numeric_Value($numValue)' , \"Assertion that numValue is a number failed.\" );\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"接下來，使用表達式作爲"},{"type":"codeinline","content":[{"type":"text","text":"assert()"}]},{"type":"text","text":"的第一個參數。然後，使用"},{"type":"codeinline","content":[{"type":"text","text":"AssertionError"}]},{"type":"text","text":"對象來拋出自定義的錯誤信息。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"num = 10;\nassert($num > 50 , new AssertionError(\"Assertion that$num is greater than 50 failed.\") );\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"Generator支持return表達式"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Generator函數是能夠返回一個迭代對象的函數，比如"},{"type":"codeinline","content":[{"type":"text","text":"foreach"}]},{"type":"text","text":"。Generator函數是簡單的迭代器，它們不需要類實現"},{"type":"codeinline","content":[{"type":"text","text":"Iterator"}]},{"type":"text","text":"接口。Generator函數的語法與普通函數的語法一樣，只不過函數中包含一個或多個"},{"type":"codeinline","content":[{"type":"text","text":"yield"}]},{"type":"text","text":"語句，當Generator函數所返回的迭代器被迭代的時候，每個yield語句都會生成一個值。Generator函數必須要像正常的函數那樣進行調用，並提供所有必要的參數。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"PHP 7.0爲Generator函數添加了一個新的特性，那就是支持在所有的yield語句之後聲明一個return語句。在Generator函數中所返回的值可以通過Generator函數返回對象的"},{"type":"codeinline","content":[{"type":"text","text":"getReturn()"}]},{"type":"text","text":"函數來進行訪問。我們不要將Generator函數返回的迭代器對象與Generator函數返回的值混淆。迭代器對象並不包含返回值，它只包含yield所生成的值。如果Generator函數需要執行某些計算並返回一個最終值的話，那麼能夠返回值就是非常有用的。Generators可以聲明"},{"type":"codeinline","content":[{"type":"text","text":"Generator"}]},{"type":"text","text":"、"},{"type":"codeinline","content":[{"type":"text","text":"Iterator"}]},{"type":"text","text":"、"},{"type":"codeinline","content":[{"type":"text","text":"Traversable"}]},{"type":"text","text":"或"},{"type":"codeinline","content":[{"type":"text","text":"iterable"}]},{"type":"text","text":"返回類型。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"爲了闡述如何使用這個新特性，我們創建名爲"},{"type":"text","marks":[{"type":"italic"}],"text":"gen_return.php"},{"type":"text","text":"的腳本，該腳本定義了帶有多個yield語句的Generator函數並且在調用Generator函數的時候傳入"},{"type":"codeinline","content":[{"type":"text","text":"1"}]},{"type":"text","text":"作爲參數。接下來，使用foreach迭代它的返回值並輸出yield所生成的值。最後，使用"},{"type":"codeinline","content":[{"type":"text","text":"getReturn()"}]},{"type":"text","text":"函數輸出返回值。"},{"type":"text","marks":[{"type":"italic"}],"text":"gen_return.php"},{"type":"text","text":"腳本如下所示："}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"getReturn(), PHP_EOL;\n?>\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果運行腳本的話，將會得到如下的輸出："}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"1 3 5"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"Generator委託"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"PHP 7.0添加了對Generator委託的支持，這意味着一個Generator可以通過_yield from_關鍵字委託給另外一個Generator、"},{"type":"codeinline","content":[{"type":"text","text":"Traversable"}]},{"type":"text","text":"對象或數組。爲了闡述Generator委託功能，我們創建名爲"},{"type":"text","marks":[{"type":"italic"}],"text":"gen_yield_from.php"},{"type":"text","text":"的腳本並定義兩個Generator函數，即"},{"type":"codeinline","content":[{"type":"text","text":"gen($var)"}]},{"type":"text","text":"和"},{"type":"codeinline","content":[{"type":"text","text":"gen2($var)"}]},{"type":"text","text":"，其中"},{"type":"codeinline","content":[{"type":"text","text":"gen($var)"}]},{"type":"text","text":"通過如下的語句委託給了"},{"type":"codeinline","content":[{"type":"text","text":"gen2($var)"}]},{"type":"text","text":"："}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"yield from gen2(var);"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"隨後，在一個"},{"type":"codeinline","content":[{"type":"text","text":"foreach"}]},{"type":"text","text":"循環中遍歷"},{"type":"codeinline","content":[{"type":"text","text":"gen(var)"}]},{"type":"text","text":"所返回的迭代器對象。腳本"},{"type":"text","marks":[{"type":"italic"}],"text":"gen_yield_from.php"},{"type":"text","text":"如下所示："}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"運行腳本將會輸出這兩個Generator函數所生成的值："}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"1 3 1 2"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"整數除法的新函數"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"PHP 7.0爲整數除法添加了一個新函數"},{"type":"codeinline","content":[{"type":"text","text":"intdiv()"}]},{"type":"text","text":"。這個函數會返回一個整數，該整數代表了兩個整數的商，它具有如下的語法。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"int intdiv ( int $dividend , int$divisor )"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"創建名爲"},{"type":"text","marks":[{"type":"italic"}],"text":"int_div.php"},{"type":"text","text":"的腳本以使用"},{"type":"codeinline","content":[{"type":"text","text":"intdiv()"}]},{"type":"text","text":"函數，我們在這裏添加一些整數除法的樣例。像"},{"type":"codeinline","content":[{"type":"text","text":"PHP_INT_MAX"}]},{"type":"text","text":"和"},{"type":"codeinline","content":[{"type":"text","text":"PHP_INT_MIN"}]},{"type":"text","text":"這樣的PHP常量可以用作該函數的參數。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果運行腳本的話，將會得到如下所示的輸出："}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"int(2) int(1) int(-2) int(-2) int(-2) int(-1) int(2) int(2) int(1) int(1)\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果存在"},{"type":"codeinline","content":[{"type":"text","text":"ArithmeticErrors"}]},{"type":"text","text":"的話，它將會輸出到瀏覽器中。爲了闡述這一點，添加如下的函數調用並再次運行腳本。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"var_dump(intdiv(PHP_INT_MIN, -1));"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在本例中，將會生成一個"},{"type":"codeinline","content":[{"type":"text","text":"ArithmeticError"}]},{"type":"text","text":"表明"},{"type":"codeinline","content":[{"type":"text","text":"PHP_INT_MIN"}]},{"type":"text","text":"除以-1的結果不是一個整數："}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"Uncaught ArithmeticError: Division of PHP_INT_MIN by -1 is not an integer"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"添加如下的函數調用到"},{"type":"text","marks":[{"type":"italic"}],"text":"int_div.php"},{"type":"text","text":"腳本中並再次運行該腳本。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"var_dump(intdiv(1, 0));"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"這次，將會拋出"},{"type":"codeinline","content":[{"type":"text","text":"DivisionByZeroError"}]},{"type":"text","text":"："}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"Uncaught DivisionByZeroError: Division by zero"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"新的會話選項"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"session_start"}]},{"type":"text","text":"函數可以用來開始一個新的會話（session）或恢復一個之前已經存在的會話。PHP 7.0添加了對名爲"},{"type":"codeinline","content":[{"type":"text","text":"options"}]},{"type":"text","text":"的新參數的支持，該參數是一個相關選項的數組，它們可以覆蓋"},{"type":"codeinline","content":[{"type":"text","text":"php.ini"}]},{"type":"text","text":"中的會話配置指令。在"},{"type":"codeinline","content":[{"type":"text","text":"php.ini"}]},{"type":"text","text":"中，這些會話配置指令均以"},{"type":"codeinline","content":[{"type":"text","text":"session."}]},{"type":"text","text":"開頭，但是在以函數入參的形式爲"},{"type":"codeinline","content":[{"type":"text","text":"session_start"}]},{"type":"text","text":"提供options參數數組的時候，"},{"type":"codeinline","content":[{"type":"text","text":"session."}]},{"type":"text","text":"前綴要省略。除了會話配置指令，還新增了一個"},{"type":"codeinline","content":[{"type":"text","text":"read_and_close"}]},{"type":"text","text":"選項，如果該選項設置爲"},{"type":"codeinline","content":[{"type":"text","text":"TRUE"}]},{"type":"text","text":"，在讀取之後，該會話會關閉，因爲保持會話處於打開狀態可能沒有必要。作爲樣例，我們創建一個名爲"},{"type":"text","marks":[{"type":"italic"}],"text":"session_start.php"},{"type":"text","text":"的腳本並複製如下所示的代碼清單。在樣例腳本中，"},{"type":"codeinline","content":[{"type":"text","text":"session_start(options)"}]},{"type":"text","text":"函數調用通過數組設置了一些配置指令："}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":" 'PHPSESSID',\n 'cache_limiter' => 'private',\n 'use_cookies' => '0'\n]);\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在運行腳本的時候，腳本中的會話配置選項將會覆蓋掉"},{"type":"codeinline","content":[{"type":"text","text":"php.ini"}]},{"type":"text","text":"中所定義的會話配置指令（如果存在的話）。該腳本不會生成任何輸出。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在PHP 7.1中，如果"},{"type":"codeinline","content":[{"type":"text","text":"session_start()"}]},{"type":"text","text":"開啓會話失敗的話，它將會返回"},{"type":"codeinline","content":[{"type":"text","text":"FALSE"}]},{"type":"text","text":"並且不會初始化"},{"type":"codeinline","content":[{"type":"text","text":"_SESSION"}]},{"type":"text","text":"。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"使用回調執行正則表達式搜索和替換的新函數"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"PHP 7.0增加了一個新的函數"},{"type":"codeinline","content":[{"type":"text","text":"preg_replace_callback_array()"}]},{"type":"text","text":"，以便於使用回調進行正則表達式搜索和替換。這個函數與"},{"type":"codeinline","content":[{"type":"text","text":"preg_replace_callback()"}]},{"type":"text","text":"函數類似，只不過回調是基於每個模式調用的。函數的語法如下所示："}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"mixed preg_replace_callback_array ( arraypatterns_and_callbacks , mixed $subject [, int$limit = -1 [, int &count ]] )"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果"},{"type":"codeinline","content":[{"type":"text","text":"subject"}]},{"type":"text","text":"參數是一個數組的話，它會返回一個字符串組成的數組，如果"},{"type":"codeinline","content":[{"type":"text","text":"subject"}]},{"type":"text","text":"是字符串的話，它會返回一個字符串。如果匹配上了的話，那麼返回的數組和字符串就是新的主題（subject），如果找不到匹配項的話，那麼將會返回未改變的主題。該函數的參數如表3所示。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"表3 preg_replace_callback_array的函數參數"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"embedcomp","attrs":{"type":"table","data":{"content":" 參數類型描述patterns_and_callbacks數組聲明相關的數組，匹配模式（鍵）與回調（值）
$subjectmixed聲明要搜索和替換的字符串或字符串數組$limitint指定每個subject字符串中每個模式的最大替換數的限制。默認是-1，也就是沒有限制。
&$countint替換完成的數量，存儲在$count變量中。"}}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"爲了闡述這個新的功能，創建樣例腳本"},{"type":"text","marks":[{"type":"italic"}],"text":"prereg.php"},{"type":"text","text":"並複製如下的代碼清單到腳本中。主題或要搜索的樣例字符串設置成了'AAaaaaa Bbbbb'。"},{"type":"codeinline","content":[{"type":"text","text":"patterns_and_callbacks"}]},{"type":"text","text":"參數設置成了尋找匹配'A'和'b'的數量。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":" function ($match) {\n echo strlen($match[0]), ' matches for \"A\" found', PHP_EOL;\n },\n '~[b]+~i' => function ($match) {\n echo strlen($match[0]), ' matches for \"b\" found', PHP_EOL;\n }\n ],\n subject\n);\n?>\n\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果運行腳本的話，匹配'A'和'b'的數量將會被打印出來："}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"7 matches for \"A\" found 5 matches for \"b\" found"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"生成加密安全的整數和字節的新函數"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"新增了兩個生成加密安全的整數和字節的新函數。這些函數在表4中進行了討論。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":""},{"type":"text","marks":[{"type":"strong"}],"text":"表4 新的加密函數"},{"type":"text","text":""}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"embedcomp","attrs":{"type":"table","data":{"content":" 函數語法參數返回值描述 random_bytes()string random_bytes ( intlength )int類型的$length，代表了以字節形式返回的任意字符串的長度。返回一個字符串，其中包含了所請求數量的加密安全的隨機字節。生成和返回一個任意的字符串，包含了加密的隨機字節。 random_int()int random_int ( int$min , int $max )$min參數指定了返回值的下限，它必須等於或高於PHP_INT_MIN。$max參數指定了返回值的上限，它必須等於或低於PHP_INT_MAX。加密的安全整數，這個數介於$min和max之間。生成和返回加密的任意整數。"}}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"作爲樣例，我們創建一個名爲"},{"type":"text","marks":[{"type":"italic"}],"text":"random_int.php"},{"type":"text","text":"的腳本，它會生成加密的任意整數。首先，生成一個範圍在1和99之間的整數，然後生成一個範圍在-100到0的整數。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果運行腳本的話，將會打印出兩個整數。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"int(98) int(-84)"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"生成的整數是隨機的，如果相同的腳本再次運行的話，很可能會生成兩個不同的整數。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"接下來，創建另外一個樣例腳本"},{"type":"text","marks":[{"type":"italic"}],"text":"random_bytes.php"},{"type":"text","text":"，它會生成加密的任意字節，其長度爲10。然後，我們使用"},{"type":"codeinline","content":[{"type":"text","text":"bin2hex"}]},{"type":"text","text":"函數將任意的字節轉換成ASCII字符串，其中包含了所返回字節的16進制字符串形式。複製如下的代碼清單到腳本文件中："}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"運行腳本並生成加密的任意字節："}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"string(20) \"ab9ad4234e7c6ceeb70d\""}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"list()函數的修改"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"list()"}]},{"type":"text","text":"函數用來爲一個變量列表像數組那樣進行賦值。PHP 7.0和7.1爲list()帶來了一些變更。在PHP 7中，"},{"type":"codeinline","content":[{"type":"text","text":"list()"}]},{"type":"text","text":"無法像之前的版本那樣解包字符串，如果對字符串進行解包的話，將會返回"},{"type":"codeinline","content":[{"type":"text","text":"NULL"}]},{"type":"text","text":"。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在PHP 5.x中，使用"},{"type":"codeinline","content":[{"type":"text","text":"list()"}]},{"type":"text","text":"解包一個字符串的時候，會將"},{"type":"codeinline","content":[{"type":"text","text":"list()"}]},{"type":"text","text":"中的一個變量賦值爲字符串中的值。我們使用PHP 5.x中的"},{"type":"codeinline","content":[{"type":"text","text":"list()"}]},{"type":"text","text":"來闡述解包字符串。創建腳本_list.php_並複製如下的代碼清單到腳本中。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果運行該腳本的話，與前面的腳本類似，我們會看到輸出的值是"},{"type":"codeinline","content":[{"type":"text","text":"NULL"}]},{"type":"text","text":"。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"實際上，在PHP 7.x中，如果"},{"type":"codeinline","content":[{"type":"text","text":"list()"}]},{"type":"text","text":"要通過字符串進行賦值，那麼必須要使用"},{"type":"codeinline","content":[{"type":"text","text":"str_split"}]},{"type":"text","text":"函數："}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果運行該腳本的話，不會生成錯誤，並且會創建一個具有兩個非空元素和一個空元素的列表。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"Oracle Magazine latest edition is January-February 2018."}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"list()"}]},{"type":"text","text":"函數的另外一個修改就是按照變量定義的順序爲其進行賦值。在此之前，值是按照與定義相反的順序進行賦值的。爲了闡述之前的行爲，使用PHP 5.x運行如下的"},{"type":"text","marks":[{"type":"italic"}],"text":"list.php"},{"type":"text","text":"中的程序清單："}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我們可以探測腳本的輸出（參見圖1），值是按照定義相反的順序進行賦值的。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.infoq.cn\/resource\/image\/bf\/a5\/bf5138105c09a1c0ccd0f3cba53297a5.png","alt":null,"title":"","style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":"center","origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"圖1 值是按照相反的順序賦值的"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在PHP 7.0上運行相同的腳本，我們會發現_list()_會按照與定義相同的順序爲變量賦值："}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"array(3) { [0]=> string(1) \"A\" [1]=> int(2) [2]=> int(3) }"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"PHP 7.1.0支持在列表中指定key以表明賦值的數字順序。作爲樣例，創建"},{"type":"text","marks":[{"type":"italic"}],"text":"list.php"},{"type":"text","text":"腳本幷包含如下的代碼清單。注意，在本例中，所有的key都是數字："}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"journal, 1=> $publisher, 2 =>$edition) = ['Oracle Magazine', 'Oracle Publishing', 'January February 2018'];\necho \"$journal,$publisher, edition. \\n\";\n?>\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果運行腳本的話，將會得到如下的列表值："}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"Oracle Magazine, Oracle Publishing, January February 2018."}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"賦值的數字順序可以交叉，如下面的代碼清單所示，索引0放在了索引1的後面。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"journal, 0=> $publisher, 2=>$edition) = ['Oracle Magazine', 'Oracle\nPublishing', 'January February 2018'];\necho \"$journal,$publisher,edition \\n\";\n?>\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果運行腳本的話，輸出的值表明變量是根據數字的key進行賦值的，而不是列表中key的順序。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"Oracle Publishing, Oracle Magazine,January February 2018"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"key的索引可以使用單括號或雙括號括起來，如下所示："}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"journal, '0'=> $publisher, '2'=>$edition) = ['Oracle Magazine', 'Oracle\nPublishing', 'January February 2018'];\necho \"$journal,$publisher,edition \\n\";\n?>\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"上述腳本會生成與前面的腳本相同的輸出。如果在"},{"type":"codeinline","content":[{"type":"text","text":"list()"}]},{"type":"text","text":"中某個元素使用了key，那麼它的所有元素都應該使用key。例如，創建一個列表，有些元素使用了key進行賦值，有些元素沒有使用key："}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"journal, 1=> $publisher, 2) = ['Oracle Magazine', 'Oracle Publishing', 'January February 2018'];\necho \"$journal, publisher. \\n\";\n?>\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果運行該腳本的話，我們會看到一個錯誤信息，提示在賦值的時候，帶有key和不帶key的數組條目不能混合使用："}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"Cannot mix keyed and unkeyed array entries in assignments"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"字符串偏移支持負數"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"從PHP 7.1開始，像"},{"type":"codeinline","content":[{"type":"text","text":"strpos"}]},{"type":"text","text":"和"},{"type":"codeinline","content":[{"type":"text","text":"substr"}]},{"type":"text","text":"這樣的字符串操作函數引入了對負數偏移量的支持，也就是從字符串的結尾處開始處理偏移。使用[]和{}的字符串索引也支持負數偏移量。例如，\"ABC\"[-2]將會返回字母'B'。現在，我們創建一個腳本"},{"type":"text","marks":[{"type":"italic"}],"text":"str-negative-offset.php"},{"type":"text","text":"並複製如下的代碼清單到腳本中："}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"\";\necho strpos(\"aabbcc\", \"a\", -6);\necho \" \";\necho strpos(\"abcdef\", \"c\", -1);\necho \" \";\necho strpos(\"abcdef\", \"c\", -5);\necho \" \";\necho substr(\"ABCDEF\", -1); \necho \" \"; \necho substr(\"ABCDEF\", -2, 5); \necho \" \";\necho substr(\"ABCDEF\", -7);\necho \" \";\necho substr(\"ABCDEF\", -6);\necho \" \";\necho substr(\"ABCDEF\", -5);\necho \" \";\necho substr(\"ABCDEF\", 6);\necho \" \";\necho substr(\"abcdef\", 1, -3); \necho \" \";\necho substr(\"abcdef\", 3, -2); \necho \" \"; \necho substr(\"abcdef\", 4, -1);\necho \" \"; \necho substr(\"abcdef\", -5, -2); \n?>\n\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"該腳本提供了多個在字符串函數和[]中使用負數偏移量的樣例。如果運行腳本的話，它將會輸出："}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"F\n0\n\n2\nF\nEF\nABCDEF\nABCDEF\nBCDEF\n\nbc\nd\ne\nbcd\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"將回調轉換成閉包的新函數"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"閉包用來以字符串變量的形式傳遞函數（用戶自定義的函數以及除語言構造之外的內置函數）和方法。例如，函數"},{"type":"codeinline","content":[{"type":"text","text":"hello()"}]},{"type":"text","text":"可以以參數的形式傳遞給另外一個函數，或者使用函數名字以字符串的形式從另外一個函數中返回，如'hello'，當然這樣做的前提是參數類型\/返回類型爲callable。我們創建一個樣例腳本"},{"type":"text","marks":[{"type":"italic"}],"text":"callable.php"},{"type":"text","text":"並聲明函數"},{"type":"codeinline","content":[{"type":"text","text":"hello()"}]},{"type":"text","text":"，該函數輸出一個‘hello’消息。聲明另外函數，其參數類型是callable。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"function callFunc(callablecallback) {\n callback();\n}\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"callFunc(callable)"}]},{"type":"text","text":"函數能夠以字符串的形式通過"},{"type":"codeinline","content":[{"type":"text","text":"hello()"}]},{"type":"text","text":"的名字調用該函數："}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"callFunc(\"hello\");"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"另外，內置的"},{"type":"codeinline","content":[{"type":"text","text":"call_user_func ( callablecallback [, mixed ... ] )"}]},{"type":"text","text":"函數以callable作爲其第一個參數，也可以用來根據名字調用"},{"type":"codeinline","content":[{"type":"text","text":"hello()"}]},{"type":"text","text":"函數："}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"call_user_func('hello');"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"腳本_callable.php_如下所示："}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"';\ncallFunc(\"hello\");\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果運行腳本的話，會根據所提供的名稱調用"},{"type":"codeinline","content":[{"type":"text","text":"hello()"}]},{"type":"text","text":"函數。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"hello"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"hello"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"閉包是匿名函數的對象表示形式。那爲什麼要將回調轉換成閉包呢？有多個原因，其中一個就是性能。回調類型相對比較慢，因爲確定一個函數是否爲回調需要一定的成本。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"使用回調的另外一個缺點在於，只有public的函數可以用作回調。相反，將類中的函數轉換成閉包並不需要該函數是public的，例如該函數可以聲明爲private。作爲樣例，我們創建一個腳本_hello.php_並聲明一個類"},{"type":"codeinline","content":[{"type":"text","text":"Hello"}]},{"type":"text","text":"，該類中包含返回一個回調函數的方法"},{"type":"codeinline","content":[{"type":"text","text":"getCallback()"}]},{"type":"text","text":"："}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"public function getCallback() {\n return [this, 'hello_callback_function'];\n }\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"回調函數聲明爲public。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"public function hello_callback_function($name) { var_dump($name); }"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"創建該類的一個實例並調用回調函數。_hello.php_腳本如下所示："}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":" getCallback();\ncallback('Deepak');\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果運行腳本的話，會得到如下的輸出："}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"string(6) \"Deepak\""}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"接下來，使用"},{"type":"codeinline","content":[{"type":"text","text":"Closure::fromCallable"}]},{"type":"text","text":"靜態方法將私有的回調函數轉換成一個閉包。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":" getClosure();\nclosure('Deepak');\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果運行腳本的話，會得到相同的輸出："}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"string(6) \"Deepak\""}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"轉換成閉包的另外一個原因在於能夠在早期探測到錯誤，不必推遲到運行期。考慮如上面所示的樣例，但是這一次我們故意把函數名稱拼錯："}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"public function getCallback() {\n return [this, 'hello_callback_functio'];\n }\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果運行這個腳本的話，當回調函數在如下的語句實際執行的時候，將會拋出"},{"type":"codeinline","content":[{"type":"text","text":"Call to undefined method Hello::hello_callback_functio()"}]},{"type":"text","text":"錯誤："}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"callback('Deepak');"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"相反，如果我們將回調轉換成閉包，錯誤"},{"type":"codeinline","content":[{"type":"text","text":"Failed to create closure from callable: class 'Hello' does not have a method 'hello_callback_function'"}]},{"type":"text","text":"會在如下這行代碼中就能探測出來："}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"return Closure::fromCallable([this, 'hello_callback_functio']);"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"JSON_THROW_ON_ERROR標記"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在PHP 7.3版本之前，對JSON函數json_encode()和json_decode()的錯誤處理功能都是非常少的，有如下的不足之處："}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果出現錯誤的話，"},{"type":"codeinline","content":[{"type":"text","text":"json_decode()"}]},{"type":"text","text":"會返回null，但是null可能是一個合法的值，比如要對JSON “null”進行解碼。判斷是否有錯誤出現的唯一辦法是使用"},{"type":"codeinline","content":[{"type":"text","text":"json_last_error()"}]},{"type":"text","text":"或"},{"type":"codeinline","content":[{"type":"text","text":"json_last_error_msg()"}]},{"type":"text","text":"查看全局的錯誤狀態。"},{"type":"codeinline","content":[{"type":"text","text":"json_encode()"}]},{"type":"text","text":"沒有錯誤的返回值。"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"出現錯誤的時候，程序的運行不會停止，甚至不會拋出警告。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"PHP 7.3在"},{"type":"codeinline","content":[{"type":"text","text":"json_encode()"}]},{"type":"text","text":"和"},{"type":"codeinline","content":[{"type":"text","text":"json_decode()"}]},{"type":"text","text":"方法中添加了對"},{"type":"codeinline","content":[{"type":"text","text":"JSON_THROW_ON_ERROR"}]},{"type":"text","text":"標記的支持。添加了新的異常子類"},{"type":"codeinline","content":[{"type":"text","text":"JsonException"}]},{"type":"text","text":"，用來描述JSON解碼\/編碼。如果爲"},{"type":"codeinline","content":[{"type":"text","text":"json_encode()"}]},{"type":"text","text":"和"},{"type":"codeinline","content":[{"type":"text","text":"json_decode()"}]},{"type":"text","text":"提供"},{"type":"codeinline","content":[{"type":"text","text":"JSON_THROW_ON_ERROR"}]},{"type":"text","text":"標記並拋出了JsonException異常的話，那麼全局的錯誤狀態不會被修改。爲了闡述新的"},{"type":"codeinline","content":[{"type":"text","text":"JSON_THROW_ON_ERROR"}]},{"type":"text","text":"和"},{"type":"codeinline","content":[{"type":"text","text":"JsonException"}]},{"type":"text","text":"，我們創建一個_json.php_腳本，並嘗試使用"},{"type":"codeinline","content":[{"type":"text","text":"json_decode"}]},{"type":"text","text":"解碼一個包含錯誤的數組："}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"getMessage(); \/\/ echoes \"Syntax error\"\n}\n?>\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果運行腳本的話，我們會看到如下所示的"},{"type":"codeinline","content":[{"type":"text","text":"JsonException"}]},{"type":"text","text":"："}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"Maximum stack depth exceeded"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"作爲使用"},{"type":"codeinline","content":[{"type":"text","text":"JSON_THROW_ON_ERROR"}]},{"type":"text","text":"和"},{"type":"codeinline","content":[{"type":"text","text":"json_encode()"}]},{"type":"text","text":"的樣例，我們編碼一個數組，該數組中包含一個值爲 NAN 的元素，如下面的程序清單所示："}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":" 1, 'b' => 2, 'c' => 3, 'd' => 4, 'e' => NAN);\necho json_encode(arr,JSON_THROW_ON_ERROR);\n}\ncatch (\\JsonException $exception) {\n echo$exception->getMessage(); \n}\n?>\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"當運行腳本的時候，會輸出如下的信息："}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"Inf and NaN cannot be JSON encoded"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"從數組中獲取第一個和最後一個key值的新函數"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"從數組中獲取第一個和最後一個key值是很常見的操作，PHP 7.3專門新加了兩個函數："}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"$key = array_key_first($array);\n$key = array_key_last($array);\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如下的代碼清單給出了在相關數組甚至空數組中使用這兩個函數的樣例："}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":" 'A', 2 => 'B', 'c' => 'C'];\n$firstKey =array_key_first($array);\n$lastKey = array_key_last($array);\necho assert($firstKey === 'a');\necho \" \";\n echo$firstKey;\necho \"
\";\n echo $lastKey;\necho \" \";\n\/\/ 在空數組中的應用\n$array = [];\n$firstKey = array_key_first($array);\n$lastKey = array_key_last($array);\n echo \"
\";\necho assert($firstKey === null);\necho \" \";\necho assert($lastKey === null);\n?>\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"腳本的輸入如下所示："}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"1\na\nc\n\n1\n1\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"使用Compact函數報告未定義的變量"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"compact()"}]},{"type":"text","text":"函數在PHP 7.3中有一個新的特性，那就是報告未定義的變量。爲了闡述該功能，運行如下的腳本，該腳本中包含了一些未定義的變量："}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"腳本將會輸出如下的信息："}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"Notice: Undefined variable: array2 on line 9\nNotice: compact(): Undefined variable: a on line 9\nNotice: compact(): Undefined variable: b on line 9\nNotice: compact(): Undefined variable: c on line 9\nNotice: compact(): Undefined variable: var2 on line 9\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"函數調用中的拖尾逗號"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"PHP 7.3添加了在函數調用時使用拖尾逗號的支持。拖尾逗號在有些經常追加參數的場景中是很有用處的，比如可變參數的函數（"},{"type":"codeinline","content":[{"type":"text","text":"array_merge"}]},{"type":"text","text":"、"},{"type":"codeinline","content":[{"type":"text","text":"compact"}]},{"type":"text","text":"和"},{"type":"codeinline","content":[{"type":"text","text":"sprintf"}]},{"type":"text","text":"）。語言構造"},{"type":"codeinline","content":[{"type":"text","text":"unset()"}]},{"type":"text","text":"和"},{"type":"codeinline","content":[{"type":"text","text":"isset()"}]},{"type":"text","text":"也支持拖尾逗號。如下的樣例使用unset函數闡述了拖尾逗號："}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"運行腳本，將會產生如下的輸出："}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"Notice: Undefined variable: A \nNotice: Undefined variable: B \nNotice: Undefined variable: C \n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"array_merge()"}]},{"type":"text","text":"函數是另外一個可以藉助拖尾逗號簡化追加值的樣例。如下的腳本使用在對"},{"type":"codeinline","content":[{"type":"text","text":"array_merge()"}]},{"type":"text","text":"的函數調用中使用了拖尾逗號："}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"方法調用和閉包也允許使用拖尾逗號。在類中，方法就是一個函數。閉包是表示匿名函數的一個對象。拖尾逗號只能用於函數調用，不能用於函數聲明。自由位置的逗號、前導逗號和多個拖尾逗號在該語言中是禁止使用的。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"數學函數bcscale"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"bcscale"}]},{"type":"text","text":"函數的語法是"},{"type":"codeinline","content":[{"type":"text","text":"int bcscale ([ int scale ])"}]},{"type":"text","text":"，它能夠爲所有後續的bc數學函數調用設置默認的小數位數。像"},{"type":"codeinline","content":[{"type":"text","text":"bcadd()"}]},{"type":"text","text":"、"},{"type":"codeinline","content":[{"type":"text","text":"bcdiv()"}]},{"type":"text","text":"和"},{"type":"codeinline","content":[{"type":"text","text":"bcsqrt()"}]},{"type":"text","text":"這樣的bc數學函數能夠用於任意精度的數字計算。PHP 7.3添加了使用bcscale獲取當前小數位數的支持。設置bcscale之後會返回舊的小數位數。作爲樣例，如下的腳本將默認的小數位數設置爲3，隨後輸出了當前的小數位數："}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"上述腳本的輸出是3。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"新函數is_countable"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"PHP 7.3添加了新函數"},{"type":"codeinline","content":[{"type":"text","text":"is_countable"}]},{"type":"text","text":"，如果函數參數爲"},{"type":"codeinline","content":[{"type":"text","text":"array"}]},{"type":"text","text":"類型或"},{"type":"codeinline","content":[{"type":"text","text":"Countable"}]},{"type":"text","text":"實例的話，它會返回true。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"bool is_countable(mixedvar)"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"例如，"},{"type":"codeinline","content":[{"type":"text","text":"is_countable()"}]},{"type":"text","text":"能夠用來判斷給定的參數是不是數組。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"echo is_countable(['A', 'B', 3]);"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"ArrayIterator"}]},{"type":"text","text":"是可數的，"},{"type":"codeinline","content":[{"type":"text","text":"is_countable"}]},{"type":"text","text":"會輸出TRUE，因爲"},{"type":"codeinline","content":[{"type":"text","text":"ArrayIterator"}]},{"type":"text","text":"實現了Countable接口。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"echo is_countable(new ArrayIterator());"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"is_countable"}]},{"type":"text","text":"可以與"},{"type":"codeinline","content":[{"type":"text","text":"if()"}]},{"type":"text","text":"一起使用，確保某個參數時可數的，然後再運行後續的代碼。在如下的代碼片段中，我們測試了類A的實例是不是可數的："}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"class A{}\nif (!is_countable(new A())) {\n echo \"Not countable\";\n}\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"上述代碼片段的結果是"},{"type":"codeinline","content":[{"type":"text","text":"FALSE"}]},{"type":"text","text":"，因爲類A並沒有實現"},{"type":"codeinline","content":[{"type":"text","text":"Countable"}]},{"type":"text","text":"。如果"},{"type":"codeinline","content":[{"type":"text","text":"is_countable"}]},{"type":"text","text":"的參數是一個數組的話，那麼它將會返回"},{"type":"codeinline","content":[{"type":"text","text":"TRUE"}]},{"type":"text","text":"，如下面的代碼片段所示："}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"$array=['A', 'B', 3];\nif (is_countable($array)) {\n var_dump(count(array)); \n}\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"本節所有的代碼片段均放到了"},{"type":"text","marks":[{"type":"italic"}],"text":"is_countable.php"},{"type":"text","text":"腳本中。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"\"; \necho is_countable(new ArrayIterator());\necho \" \"; \nif (!is_countable(new A())) {\n echo \"Not countable\";\n}\necho \" \";\narray=['A', 'B', 3];\nif (is_countable($array)) {\n var_dump(count($array)); \n}\n?>\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"運行該腳本，輸出如下所示："}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"1\n1\nNot countable\nint(3)\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"箭頭函數"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"PHP 7.4引入了_箭頭函數_，從而使匿名函數的語法更加簡潔。箭頭函數的形式如下所示："}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"fn(parameter_list) => expr"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"箭頭函數具有最低的執行優先級，這意味着箭頭 =>右邊的表達式會在箭頭函數之前執行，例如，箭頭函數"},{"type":"codeinline","content":[{"type":"text","text":"fn($x) =>$x + $y"}]},{"type":"text","text":"等價於"},{"type":"codeinline","content":[{"type":"text","text":"fn($x) => ($x +$y)"}]},{"type":"text","text":"，而不是"},{"type":"codeinline","content":[{"type":"text","text":"(fn($x) =>$x) + y"}]},{"type":"text","text":"。在外圍作用域中聲明的且被表達式中使用的變量是隱式按值捕獲的。作爲樣例，考慮如下的腳本，它聲明瞭一個箭頭函數："}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"fn1 = fn($msg) =>$msg.' '.name;"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"變量"},{"type":"codeinline","content":[{"type":"text","text":"name"}]},{"type":"text","text":"會自動從封閉範圍捕獲，上述的箭頭函數等價於："}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"$fn2 = function ($msg) use ($name) {\n return$msg.' '.name;\n};\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"對x的按值綁定等價於對箭頭函數中每次出現"},{"type":"codeinline","content":[{"type":"text","text":"$x"}]},{"type":"text","text":"均執行"},{"type":"codeinline","content":[{"type":"text","text":"use($x)"}]},{"type":"text","text":"。箭頭函數還聲明瞭一個參數"},{"type":"codeinline","content":[{"type":"text","text":"msg"}]},{"type":"text","text":"。在下一個樣例中，"},{"type":"codeinline","content":[{"type":"text","text":"var_export"}]},{"type":"text","text":"調用箭頭函數並提供一個參數，輸出值爲'Hello John'："}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"msg.' '.$name;\nvar_export($fn1(\"Hello\"));\/\/'Hello John'\n?>\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"箭頭函數可以進行嵌套，如下面的腳本所示。外層的腳本函數按值捕獲變量"},{"type":"codeinline","content":[{"type":"text","text":"$name"}]},{"type":"text","text":"，內層的箭頭函數從外層函數捕獲"},{"type":"codeinline","content":[{"type":"text","text":"$name"}]},{"type":"text","text":"："}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":" fn($msg2) =>$msg1.' '.$msg2.' '.$name;\nvar_export(fn(\"Hello\")(\"Hi\")); \n?>\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"當腳本運行的時候，輸出入圖2所示。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.infoq.cn\/resource\/image\/b1\/8a\/b139ee84d00c100560193dea7a28fd8a.png","alt":null,"title":"","style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":"center","origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"圖2 箭頭函數可以進行嵌套"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"因爲箭頭函數使用按值的變量綁定，修改箭頭函數中變量的值不會影響外層作用域中的值。爲了闡述這一點，如下腳本中的箭頭函數遞減了外層代碼塊中變量"},{"type":"katexinline","attrs":{"mathString":"x的值，但是它對"}},{"type":"text","text":"x的值並沒有影響，它依然是"},{"type":"codeinline","content":[{"type":"text","text":"1"}]},{"type":"text","text":"："}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":" x--; \/\/ 沒有影響\nfn();\nvar_export(x); \/\/輸出 1\n?>\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"箭頭函數支持任意的函數簽名，可以包含參數和返回類型、默認值、可變參數以及按引用的變量傳遞和返回。如下的腳本闡述了箭頭函數不同形式簽名的使用。腳本中籤名描述和輸出通過註釋"},{"type":"codeinline","content":[{"type":"text","text":"\/\/"}]},{"type":"text","text":"進行展示。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"msg.' '.$name;\n\/\/包括可變參數的箭頭函數 \n$fn2 = fn(...$x) =>$x;\n \/\/包括按引用參數傳遞的箭頭函數\n$fn3=fn(&$x) => $x++;\n$fn3($x);\necho$x; \/\/ 2\nvar_export($fn(\"Hello\"));\/\/'Hello John'\nvar_export($fn());\/\/'Hi John'\nvar_export(fn2(1,2,3)); \/\/array ( 0 => 1, 1 => 2, 2 => 3, ) \n?>\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"箭頭函數的對象上下文中可能會使用"},{"type":"codeinline","content":[{"type":"text","text":"this"}]},{"type":"text","text":"。如果與帶有static前綴的箭頭函數一起使用，那麼就不能使用"},{"type":"codeinline","content":[{"type":"text","text":"$this"}]},{"type":"text","text":"。爲了闡述這一點，考慮如下的腳本，它在對象上下文和類上下文中使用了"},{"type":"codeinline","content":[{"type":"text","text":"$this"}]},{"type":"text","text":"。如果不在對象上下文中使用的話，將會輸出錯誤信息。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":" var_dump($this);\n$fn(); \/\/ object(A)#1 (0) { }\n $fn = static fn() => var_dump($this);\n $fn(); \/\/Uncaught Error: Using$this when not in object context \n \n }\n}\n$a=new A();\n$a->fn1();\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"總結"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在該系列關於PHP 7新特性的第四篇（也是倒數第二篇）文章中，我們討論了關於PHP函數的新特性。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在本系列的下一篇，也就是最後一篇中，我們將會討論關於數組、操作符、常量和異常處理方面的新特性。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"作者簡介："}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"Deepak Vohra"},{"type":"text","text":"是一位Sun認證的Java程序員和Sun認證的Web組件開發人員。Deepak在WebLogic Developer's Journal、XML Journal、ONJava、java.net、IBM developerWorks、Java Developer’s Journal、Oracle Magazine和devx上都發表過Java和Java EE相關的技術文章。Deepak還出版過五本關於Docker的書，他是Docker導師。Deepak還發表了多篇關於PHP的文章，以及一本面向PHP和Java開發人員的Ruby on Rails圖書。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"原文鏈接："}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https:\/\/www.infoq.com\/articles\/php7-function-improvements\/","title":"","type":null},"content":[{"type":"text","text":"Article: PHP 7 – Functions Improvements"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"相關閱讀："}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https:\/\/www.infoq.cn\/article\/rZZBM2XfaaRr5JviyZqJ","title":"","type":null},"content":[{"type":"text","text":"PHP 7 入門：新特性簡介"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https:\/\/www.infoq.cn\/article\/H5av8rIy5WDy4dUagZWx","title":"","type":null},"content":[{"type":"text","text":"PHP 7 入門：類和接口的增強"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https:\/\/www.infoq.cn\/article\/hpjgR2sLTTFbTA2qcxfu","title":"","type":null},"content":[{"type":"text","text":"PHP 7 入門：數組、運算符、常量及異常處理的改進"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}}]}