[php4變化日志](https://www.php.net/ChangeLog-4.php)(主要是修復bug方面)
[php5變化日志](http://php.net/ChangeLog-5.php) (主要是修復bug方面)
[php7變化日志](http://php.net/ChangeLog-7.php)(主要是修復bug方面)
[更新日志](https://www.php.net/manual/zh/doc.changelog.php)(綁定的擴展的函數更新內容)
[遷移日志(包含新增或廢棄的特性和函數等)](https://www.php.net/manual/zh/appendices.php)
[TOC]
主要新特性一覽,詳情查看遷移日志
# **php5.4新特性**
## **增加短數組支持如:[1, 2, 3, 4]**
## **新增Trait**
# **php5.5新特性**
## **新增yield關鍵字簡化生成器**
**新增密碼加密及驗證**
```
//之前
//模擬input提交的密碼
$user_input = '12+#?345';
//crypt()函數不能正確處理加號。請首先對密碼使用urlencode,以確保登錄過程可以處理任何字符
$pass = urlencode($user_input));
$pass_crypt = crypt($pass);
if ($pass_crypt == crypt($pass, $pass_crypt)) {
echo "成功!有效的密碼";
} else {
echo "無效的密碼";
}
//當校驗密碼時,應該使用一個不容易被時間攻擊的字符串比較函數來比較crypt()的輸出與之前已知的哈希。出于這個目的,PHP5.6開始提供了hash_equals()
$hashed_password = crypt('mypassword'); // 自動生成鹽值
/* 你應當使用 crypt() 得到的完整結果作為鹽值進行密碼校驗,以此來避免使用不同散列算法導致的問題。(如上所述,基于標準 DES 算法的密碼散列使用 2 字符鹽值,但是基于 MD5 算法的散列使用 12 個字符鹽值。)*/
if (hash_equals($hashed_password, crypt($user_input, $hashed_password))) {
echo "Password verified!";
}
//新特性
/**
* 我們想要使用默認算法散列密碼
* 當前是 BCRYPT,并會產生 60 個字符的結果。
*
* 請注意,隨時間推移,默認算法可能會有變化,
* 所以需要儲存的空間能夠超過 60 字(255字不錯)
* 強烈建議不要自己為這個函數生成鹽值(salt)。只要不設置,它會自動創建安全的鹽值
* password_hash 參數2有三個加密算法:PASSWORD_DEFAULT(默認),PASSWORD_BCRYPT ,PASSWORD_ARGON2I(php7.2加入)
*/
$hash=password_hash("rasmuslerdorf", PASSWORD_DEFAULT);//$2y$10$.vGA1O9wmRjrwAVXD98HNOgsNpDczlqm3Jq7KnEd1rVAGv3Fykk1a
if (password_verify('rasmuslerdorf', $hash)) {
echo 'Password is valid!';
} else {
echo 'Invalid password.';
}
print_r(password_get_info ($hash));
//Array ( [algo] => 1 [algoName] => bcrypt [options] => Array ( [cost] => 10 ) )
```

password_hash方法我們無需關注salt,只需要將password_hash返回的hash保存在數據庫就ok
```
$_POST['pwd']== 'rasmuslerdorf';
$password =$_POST['pwd'];
//數據庫沒有就使用password_hash,數據庫有則查查出數據庫的hash
if(!empty($res=findPwdToMysql($_POST['user'], $_POST['pwd']))){
$hash=$res;
}else{
$hash=password_hash($password);//$2y$10$YCFsG6elYca568hBi2pZ0.3LDL5wjgxct1N8w/oLR/jfHsiQwCqTS
savePwdTosql($hash);
}
// 當硬件性能得到改善時,cost 參數可以再修改(默認10)
$options = array('cost' => 11);
// 根據明文密碼驗證儲存的散列
if (password_verify($password, $hash)) {
// 檢測是否有更新的可用散列算法
// 或者 cost 發生變化
if (password_needs_rehash($hash, PASSWORD_DEFAULT, $options)) {
// 如果是這樣,則創建新散列,替換舊散列
$newHash = password_hash($password, PASSWORD_DEFAULT, $options);
}
// 使用戶登錄setcookie()
}
```
**訪問單個元素和字符**
```
//之前
$arr=[123];
$str='abc';
$arr[0];
$str[0];
//新特性:
[123][0];
'abc'[0];
```
foreach控制結構現在支持通過[list()](https://www.php.net/manual/zh/function.list.php)構造將嵌套數組分離到單獨的變量
```
//之前
$arr1=[1,2];
$arr2=[3,4];
list ($a, $b)=$arr1;
list ($a, $b)=$arr2;
//新特性:
$array = [
[1, 2],
[3, 4],
];
foreach ($array as list($a, $b)) {
echo "A: $a; B: $b\n";
}
輸出:
A: 1; B: 2
A: 3; B: 4
```
## **異常處理新增finally塊,`try{}catch{}finally{}`**
finally塊中的代碼總是在try和catch塊之后執行,不管是否拋出了異常,也不管正常的執行是否繼續
# **php5.6 新特性**
## **可變數量的參數**
可變參數由 ... 語法實現;在 PHP 5.5 及更早版本中,使用函數 func_num_args(),func_get_arg(),和 func_get_args()
```
//5.6以前實現可變參數
function sum() {
$acc = 0;
foreach (func_get_args() as $n) {
$acc += $n;
}
return $acc;
}
echo sum(1, 2, 3, 4);
//新特性
function f($req, $opt = null, ...$params) {
// $params 是一個包含了剩余參數的數組
printf('$req的值: %d; $opt的值: %d; $params的個數: %d;', $req, $opt, count($params));
echo gettype($params)."<br>";
}
f(1);//$req的值: 1; $opt的值: 0; $params的個數: 0;array
f(1, 2);//$req的值: 1; $opt的值: 2; $params的個數: 0;array
f(1, 2, 3);//$req的值: 1; $opt的值: 2; $params的個數: 1;array
f(1, 2, 3, 4);//$req的值: 1; $opt的值: 2; $params的個數: 2;array
f(1, 2, 3, 4, 5);//$req的值: 1; $opt的值: 2; $params的個數: 3;array
```
在調用函數的時候,使用...運算符, 將**數組**和**可遍歷**對象展開為函數參數。 在其他編程語言,比如 Ruby中,這被稱為連接運算符
```
function add($a, $b, $c) {
return $a + $b + $c;
}
//add(1,...[2,?3])
$operators = [2, 3];
echo add(1, ...$operators);//6 與add(1,2,3)效果一樣
```
## **使用表達式定義常量**
```
//之前只能使用靜態值定義常量
const?ONE?=?1;
//現在可以用表達式定義常量
const?TWO?=?ONE?*?2;
```
## **新增冪運算**
加入右連接運算符`**`來進行冪運算。 同時還支持簡寫的`**=`運算符,表示進行冪運算并賦值
```
printf("2的3次方等于?%d\n",?2?**?3);//2的3次方等于 8
```
## **新增__debugInfo()魔術方法 當使用vardump打印類對象時觸發**
## **擴展了use 以前可以導入命名空間的類現在還可以導入函數及常量**
```
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";//42
f();//Name\Space\f
}
```
# **php7新特性**
php7有三種方式創建空對象
```
$obj1 = new \stdClass; // Instantiate stdClass object
$obj2 = new class{}; // Instantiate anonymous class
$obj3 = (object)[]; // Cast empty array to object
var_dump($obj1); // object(stdClass)#1 (0) {}
var_dump($obj2); // object(class@anonymous)#2 (0) {}
var_dump($obj3); // object(stdClass)#3 (0) {}
```
$obj1和$obj3類型一樣但是不相等
## **1.在use語句增加了group支持**
~~~
use FooLibrary\Bar\Baz\{ ClassA, ClassB, ClassC, ClassD as Fizbo };
~~~
php7.2末尾可以留,而不會報錯
```
use FooLibrary\Bar\Baz\{ ClassA, ClassB, ClassC, ClassD as Fizbo, };
```
## **2.類型約束與標量類型聲明(標量string、int、float和 bool)**
現在可在參數前加上參數類型,支持:具體類名接口名(php5.0),self(php5.0),array(php5.1),callable(php5.4),string(php7.0),int(php7.0),float(php7.0),bool(php7.0),iterable(php7.1),object(php7.2)
>[info]特別注意 Closure類型約束的是匿名函數,匿名函數本身就是個Closure對象
>[danger]php有兩種模式強制模式(默認)和嚴格模式
>聲明嚴格模式`declare(strict_types=1);`后,如果形參聲明為int那么參數是其他類型比如string時就會拋出致命錯誤,強制模式下的話會將string轉換為int而不會報錯
>由上可知php5有可以約束array 類和接口 可調用函數 self 類型,我們可以簡單的認為php5類型約束是嚴格模式如`function foo(array $arr) {} foo(null)`會報錯提示給的參數不是指定的類型,但是參數為null時還是會報這個錯,解決辦法是將默認參數給個null`function foo(array $arr = null) {}`這樣fool(null)就不會報錯了
```
class A{
public $name=null;
public function demo(self $a){
var_dump($a);
}
public function __construct(){
$this->demo($this);
//$this->demo(new stdClass()); // 致命錯誤 A::demo() must be an instance of A
}
}
class B implements Iterator{//Iterator繼承Traversable
public function current (){} //返回當前產生的值
public function key (){} //返回當前產生的鍵
public function next (){} // 生成器繼續執行
public function rewind (){} //重置迭代器
public function valid (){} //檢查迭代器是否被關閉
}
new A();
//字符串
function demo(string $param){
var_dump(is_string($param));
}
demo(1);//true
demo(2.2); //true
//整數
function demo1(int $param){
echo $param;
var_dump(is_integer($param));
}
demo1('1.1');//1 true
demo1(1.1); //1 true
//浮點數
function demo2(float $param){
echo $param;
var_dump(is_float($param));
}
demo2('1.2');//1.2 true
demo2(1); //1 true
//布爾值
function demo3(bool $param){
var_dump($param);
var_dump(is_bool($param));
}
demo3('a');// true true
demo3(3.3);// true true
//數組
function demo4(array $param){
var_dump($param);
var_dump(is_array($param));
}
demo4(['a']);//['a'] true
//demo4('a');//demo4() must be of the type array
//函數
function demo5(callable $param){
$param();
var_dump(is_callable($param,true));
}
demo5(function(){echo 111;});// 111 true
//對象
function demo6(object $param){
var_dump(is_object($param));
}
demo6(new A());//true
//迭代對象
function demo7(iterable $param){
var_dump($param instanceof Traversable);
//var_dump(is_iterable($param));
}
demo7(new B());//true
demo7([1,2]);//false php7.2以前致命錯誤demo6() must be an instance of iterable
//具體類名或接口名
function demo9(Exception $param){
print_r($param);
}
//demo9(new Exception('哈哈'));
//demo9(new A());//致命錯誤 demo3() must be an instance of Exception,
```
## **3.返回值類型聲明**
可用的類型與參數聲明中可用的類型相同。即支持:具體類名接口名(php5.0),self(php5.0),array(php5.1),callable(php5.4),string(php7.0),int(php7.0),float(php7.0),bool(php7.0),iterable(php7.1),void(php7.1),object(php7.2)
>[danger]注意指定類型后不能返回null,php7.1在類型前加?可解決此問題
```
function demo($param):int{
return $param;
}
demo(null);//7.0致命錯誤
function demo1($param):?int{
return $param;
}
demo1(null);//php7.1類型前加上?就能接受及返回null
function demo(?int $param):?int{
return $param;
}
demo(null);//php7.1類型前加上?就能接受及返回null
```
## **4.三元運算新增null合并運算符??**
當第一個表達式的值不存在或者為null時返回第二個表達式的值,否則返回第一個表達式的值,詳情參看其他--三元運算章節
```
$username = $_GET['user'] ?? 'nobody';
echo $username;//nobody
```
## **5.太空船操作符<=>(組合比較符)**
太空船操作符用于比較兩個表達式。當$a小于、等于或大于$b時它分別返回-1、0或1。 比較的原則是沿用 PHP 的常規比較規則進行的。
```
// 整數
echo 1 <=> 1; // 0
echo 1 <=> 2; // -1
echo 2 <=> 1; // 1
// 浮點數
echo 1.5 <=> 1.5; // 0
echo 1.5 <=> 2.5; // -1
echo 2.5 <=> 1.5; // 1
// 字符串
echo "a" <=> "a"; // 0
echo "a" <=> "b"; // -1
echo "b" <=> "a"; // 1
```
## **6.define支持定義數組**
自從PHP5.6后,使用const數組也能被定義為常量,define在PHP7中被實現
## **7.支持[匿名類](https://www.php.net/manual/zh/language.oop5.anonymous.php)**
現在支持通過new class來實例化一個匿名類,這可以用來替代一些“用后即焚”的完整類定義
```
interface Logger {
public function log(string $msg);
}
class Application {
private $logger;
public function getLogger(): Logger {
return $this->logger;
}
public function setLogger(Logger $logger) {
$this->logger = $logger;
}
}
$app = new Application;
$app->setLogger(new class implements Logger {
public function log(string $msg) {
echo $msg;
}
});
var_dump($app->getLogger());//object(class@anonymous)#2 (0) {}
```
## [**8.Unicode字符編碼表**](https://www.cnblogs.com/chris-oil/p/8677309.html)
中日韓統一表意文字(CJK Unified Ideographs),外加一些特殊的字符;用 [ \u2E80-\uFE4F]
```
echo '\u{2E80}';//\u{2E80} 必須雙引號
echo "\u{2E80}";//?
```
## **9.增強之前的[assert()](https://www.php.net/manual/zh/function.assert.php)的方法**
簡單但卻最精確的定義一個*表達式*的方式就是“任何有值的東西”
早期assert是一個函數,php7是一個語法結構(在php語言中是用來判斷一個表達式是否成立。返回true or false;)
老版本的API出于兼容目的將繼續被維護,assert()現在是一個語言結構,
斷言在PHP 5,這必須是一個字符串或者一個布爾計算測試。在PHP 7中,這也可以是**返回值的任何表達式**,該值將被執行,其結果用于指示斷言是否成功或失敗
**php7新增的的ini配置如下:**
**zend.assertions**
1:生成并執行代碼(開發模式)
0:生成代碼,但在運行時繞過它
-1:不生成代碼(生產模式)
>[info]**zend.assertions=1**
## **assert.exception**
//1:當斷言失敗時拋出,方法是拋出作為異常提供的對象,或者在沒有提供異常時拋出一個新的AssertionError對象
//0:使用或生成一個Throwable,如前所述,但只生成一個基于該對象的警告,而不是拋出它(兼容PHP 5行為)
>[info]**assert.exception=0**
```
assert(true?==?false);
echo?'Hi!';
zend.assertions=0時輸出:
Hi!
zend.assertions=1并且assert.exception=0時輸出:
Warning: assert(): assert(true == false) failed in - on line 2
Hi!
zend.assertions=1并且assert.exception=1時輸出:
Fatal error: Uncaught AssertionError: assert(true == false) in -:2
Stack trace:
#0 -(2): assert(false, 'assert(true == ...')
#1 {main}
thrown in - on line 2
```
## **10.為unserialize()提供過濾**
~~~
//將所有對象分為__PHP_Incomplete_Class對象
$data = unserialize($foo, ["allowed_classes" => false]);
//將所有對象分為__PHP_Incomplete_Class 對象 除了ClassName1和ClassName2
$data = unserialize($foo, ["allowed_classes" => ["ClassName1", "ClassName2"]);
//默認行為,和 unserialize($foo)相同
$data = unserialize($foo, ["allowed_classes" => true]);
~~~
## **11.增加Closure::call支持**
?Closure::call將一個閉包函數動態綁定到一個新的對象實例并調用執行該函數,
~~~
class Value {
protected $value;
public function __construct($value) {
$this->value = $value;
}
public function getValue() {
return $this->value;
}
}
$three = new Value(3);
$four = new Value(4);
$closure = function ($delta) {
var_dump($this->getValue() + $delta);
};
$closure->call($three, 4);
$closure->call($four, 4);
// outputs int(7),int(8)
~~~
~~~
class Test
{
public $name = "lixuan";
}
//PHP7和PHP5.6都可以
$getNameFunc = function () {
return $this->name;
};
$name = $getNameFunc->bindTo(new Test, 'Test');
echo $name();
//PHP7可以,PHP5.6報錯
$getX = function () {
return $this->name;
};
echo $getX->call(new Test);
~~~
## **12.新增整數除法函數**
intdiv?接收兩個參數作為被除數和除數,返回他們相除結果的整數部分。
~~~
// 7/2=3余1 值保留整數部分3
var_dump(intdiv(7, 2));//int(3)
~~~
## **13.新增加的 IntlChar 類**
旨在暴露出更多的 ICU 功能。這個類自身定義了許多靜態方法用于操作多字符集的 unicode 字符。Intl是Pecl擴展,使用前需要編譯進PHP中,也可apt-get/yum/port install php5-intl
~~~
printf('%x', IntlChar::CODEPOINT_MAX);
echo IntlChar::charName('@');
var_dump(IntlChar::ispunct('!'));
~~~
以上例程會輸出:?
10ffff?
COMMERCIAL AT?
bool(true)
CSPRNG
## **14.新增兩個跨平臺函數:** 可用于生成salt、密鑰或初始化向量
兼容windows,linux或者其他大多數平臺,如果不兼容拋出異常
**random_bytes** — 生成加密安全的偽隨機字節
```
//隨機字節的長度設置為5
$bytes = random_bytes(5);
print_r($bytes);
//轉換為十六進制值
$hexadecimal = bin2hex($bytes);
var_dump($hexadecimal);//類似8c7c0481d6的字符串
```
使用下面的函數來創建隨機的令牌,并且還從令牌中創建了一個salt。我在我的應用程序中使用它來防止CSRF攻擊
```
function RandomToken($length = 32){
if(!isset($length) || intval($length) <= 8 ){
$length = 32;
}
if (function_exists('random_bytes')) {
return bin2hex(random_bytes($length));
}
if (function_exists('mcrypt_create_iv')) {
return bin2hex(mcrypt_create_iv($length, MCRYPT_DEV_URANDOM));
}
if (function_exists('openssl_random_pseudo_bytes')) {
return bin2hex(openssl_random_pseudo_bytes($length));
}
}
function Salt(){
return substr(strtr(base64_encode(hex2bin(RandomToken(32))), '+', '.'), 0, 44);
}
echo (RandomToken());
echo '<br>';
echo Salt();
/*
調試上面的幾個函數
*/
function RandomTokenDebug($length = 32){
if(!isset($length) || intval($length) <= 8 ){
$length = 32;
}
$randoms = array();
if (function_exists('random_bytes')) {
$randoms['random_bytes'] = bin2hex(random_bytes($length));
}
if (function_exists('mcrypt_create_iv')) {
$randoms['mcrypt_create_iv'] = bin2hex(mcrypt_create_iv($length, MCRYPT_DEV_URANDOM));
}
if (function_exists('openssl_random_pseudo_bytes')) {
$randoms['openssl_random_pseudo_bytes'] = bin2hex(openssl_random_pseudo_bytes($length));
}
return $randoms;
}
echo '<br>';
print_r (RandomTokenDebug());
```
**random_int**(int`$min`,int`$max`) :int —生成加密安全的偽隨機整數
生成適合在非常重要的公正的結果情況下使用的加密隨機整數,例如在撲克游戲中洗牌時
```
var_dump(random_int(100, 999));//int(248)
var_dump(random_int(-1000, 0));//int(-898)
```
## **15.新增preg_replace_callback_array()函數,比preg_replace_callback()函數簡潔**
在 PHP 7 之前,當使用 preg_replace_callback() 函數的時候, 由于針對每個正則表達式都要執行回調函數,可能導致過多的分支代碼。 而使用新加的 preg_replace_callback_array() 函數, 可以使得代碼更加簡潔。 現在,可以使用一個關聯數組來對每個正則表達式注冊回調函數, 正則表達式本身作為關聯數組的鍵, 而對應的回調函數就是關聯數組的值。
## **16.session_start()可以接受一個array作為參數**
現在,session\_start()函數可以接收一個數組作為參數,可以覆蓋php.ini中session的配置項。?
比如,把cache\_limiter設置為私有的,同時在閱讀完session后立即關閉
~~~
session_start(['cache_limiter' => 'private',
'read_and_close' => true,
]);
~~~
## **17.生成器中引入其他生成器**
在生成器中可以引入另一個或幾個生成器,只需要寫yield from functionName1
~~~
function generator1()
{
yield 1;
yield 2;
yield from generator2();
yield from generator3();
}
function generator2()
{
yield 3;
yield 4;
}
function generator3()
{
yield 5;
yield 6;
}
foreach (generator1() as $val) {
echo $val, " ";
}
~~~
## **18.生成器可以返回表達式**
生成器(讀取超大文件很有用,節約內存)
它允許在生成器函數中通過使用 return 語法來返回一個表達式 (但是不允許返回引用值), 可以通過調用 Generator::getReturn() 方法來獲取生成器的返回值, 但是這個方法只能在生成器完成產生工作以后調用一次
```
$gen = (function() {
yield 1;
yield 2;
return 3;
})();
foreach ($gen as $val) {
echo $val, PHP_EOL;// 1 2
}
//首先執行函數 該函數遇到yield停止并將該yied的值發送給foreach
echo $gen->getReturn(), PHP_EOL;//3
結果:
1 2 3
```
php全局保留字可以聲明使用
~~~
class View {
public function include(View $view) {
//...
//include關鍵字可以當普通字符串關鍵字一樣被使[其他](%E5%85%B6%E4%BB%96.md)用
}
}
~~~
允許在克隆表達式上訪問對象成員,例如:*(clone $foo)->bar()*。
# **php7.1新特性**
## **參數和返回類型支持null,前提是在類型前加?**
```
function test1(?string $name)
{
var_dump($name);
}
//在默認非嚴格模式下,標量string、int、float和 bool 之間會強制轉化,與php7相比php7.1可接受null
test1('dash');//'dash'
test1(null);//NULL
test1(30);//'30'
test1(30.1);//'30.1'
test1(true);//'1'
test1([1,2]);//致命錯誤
test1(new stdClass);//致命錯誤
function test1($name):?string
{
return $name;
}
echo gettype(test1('dash'));//string
echo gettype(test1(null));//NULL
echo gettype(test1(30));//string
echo gettype(test1(30.1));//string
echo gettype(test1(true));//string
test1([1,2]);//致命錯誤
test1(new stdClass);//致命錯誤
```
## **php7.1返回類型新增void**
```
function test(): void
{
return 'hello';
}
test();//致命錯誤
function test1(): void
{
return null;
}
test1();//致命錯誤
function test2(): void
{
return '';
}
test2();//致命錯誤
function test3(): void
{
return;
}
test3();//正常
function test4(): void
{
//無返回值
}
test4();//正常
```
## **短數組語法(*\[\]*)現在作為list()語法的一個備選項,可以用于將數組的值賦給一些變量(包括在*foreach*中)**
```
$data = [
[1, 'Tom'],
[2, 'Fred'],
];
//php之前支持格式
list($id1, $name1) = $data[0];
foreach ($data as list($id, $name)) {
// logic here with $id and $name
}
//php7新增的短數組[]格式
[$id1, $name1] = $data[0];
foreach ($data as [$id, $name]) {
// logic here with $id and $name
}
```
PHP 5 里,list() 從最右邊的參數開始賦值; PHP 7 里,list() 從最左邊的參數開始賦值
```
$info = array('coffee', 'brown', 'caffeine');
list($a[0], $a[1], $a[2]) = $info;
print_r($a);
php5輸出:[2=>'caffeine',1=>'brown',0=>'coffee']
php7輸出:[0=>'coffee',1=>'brown',2=>'caffeine']
```
在 PHP 7.1.0 之前的版本,list() 僅能用于數字索引的數組,并假定數字索引從 0 開始
從 PHP 7.1.0 開始,list() 可以包含顯式的鍵,可賦值到任意表達式。 可以混合使用數字和字符串鍵。但是不能混合有鍵和無鍵不能混用
```
$data = [
["id" => 1, "name" => 'Tom'],
["id" => 2, "name" => 'Fred'],
];
foreach ($data as ["id" => $id, "name" => $name]) {
echo "id: $id, name: $name\n";//id: 1, name: Tom id: 2, name: Fred
}
echo PHP_EOL;
list(1 => $second, 3 => $fourth) = [1, 2, 3, 4];
echo $second.$fourth.PHP_EOL;//2 4
```
## **字符串偏移量可以為負,表示為一個從字符串結尾開始的偏移量**
```
var_dump("abcdef"[-2]);//e
//b在abcdef首次出現的位置 從結尾倒數第5個偏移開始查找
echo strpos('abcdef','b', -5);//1
a b c d e f
0 1 2 3 4 5
-6 -5 -4 -3 -2 -1
```
## **字符串負偏移在簡單的變量解析語法中也支持能了**
```
$string = 'bar';
echo "The last character of '$string' is '$string[-1]'.\n";//The last character of 'bar' is 'r'.
```
## **對服務器推送的支持現在已經被加入到 CURL 擴展(v7.46)中**
```
$transfers = 1;
$callback = function($parent_ch, $pushed_ch, array $headers) use (&$transfers) {
$transfers++; // 增量,以跟蹤并發請求的數量
return CURL_PUSH_OK;
};
$mh = curl_multi_init();
curl_multi_setopt($mh, CURLMOPT_PIPELINING, CURLPIPE_MULTIPLEX);
curl_multi_setopt($mh, CURLMOPT_PUSHFUNCTION, $callback);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://localhost:8080/index.html");
curl_setopt($ch, CURLOPT_HTTP_VERSION, 3);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
// 調式/局部填充
//curl_setopt($ch, CURLOPT_VERBOSE, 1); // 是否會輸出curl調試信息
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); // self-signed cert
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); // self-signed cert
curl_multi_add_handle($mh, $ch);
$active = null;
do {
$status = curl_multi_exec($mh, $active);
do {
$info = curl_multi_info_read($mh);
if (false !== $info && $info['msg'] == CURLMSG_DONE) {
$handle = $info['handle'];
if ($handle !== null) {
$transfers--; // 減量 剩余請求
$out = curl_multi_getcontent($info['handle']); // 響應體
curl_multi_remove_handle($mh, $handle);
curl_close($handle);
}
}
} while ($info);
} while ($transfers);
curl_multi_close($mh);
```
## **異步信號處理**
一個新的名為 pcntl_async_signals() 的方法現在被引入, 用于啟用無需 ticks (這會帶來很多額外的開銷)的異步信號處理。
```
pcntl_async_signals(true); // 打開異步信號
pcntl_signal(SIGHUP, function($sig) {
echo "SIGHUP\n";
});
posix_kill(posix_getpid(), SIGHUP);
以上例程會輸出:
SIGHUP
```
## **新增Closure::fromCallable() 將callables轉為閉包**
Closure新增了一個靜態方法,用于將callable快速地 轉為一個Closure 對象。
```
class Test
{
public function exposeFunction()
{
return Closure::fromCallable([$this, 'privateFunction']);
}
private function privateFunction($param)
{
var_dump($param);
}
}
//((new Test)->exposeFunction())('some value');
$privFunc = (new Test)->exposeFunction();
$privFunc('some value');//some value
```
# **php7.2新特性**
## **新的對象類型**
這種新的對象類型, object, 引進了可用于逆變(contravariant)參數輸入和協變(covariant)返回任何對象類型
~~~
function test(object $obj) : object
{
return new SplQueue();
}
test(new StdClass());
~~~
## **既可以通過 php.ini 也可以運行時通過 dl(string $library): bool載入一個 PHP 擴展**
在 安全模式(php5.4廢除),總是無法使用 dl()
不推薦,存在安全風險
如果加載模塊的功能是無效或者禁用的(既可以通過設置關閉 enable_dl(僅對 Apache 模塊版本的 PHP 有效) 設置
~~~
// 加載一個擴展的例子,基于操作系統
if (!extension_loaded('sqlite')) {//檢查一個擴展是否已經加載
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
dl('php_sqlite.dll');
} else {
dl('sqlite.so');
}
}
// 或者,使用常量 PHP_SHLIB_SUFFIX
if (!extension_loaded('sqlite')) {
$prefix = (PHP_SHLIB_SUFFIX === 'dll') ? 'php_' : '';
dl($prefix . 'sqlite.' . PHP_SHLIB_SUFFIX);
}
~~~
## **允許重寫抽象方法**
當一個抽象類繼承于另外一個抽象類的時候,繼承后的抽象類可以重寫被繼承的抽象類的抽象方法
~~~
abstract class A
{
abstract function test(string $s);
}
abstract class B extends A
{
// 覆蓋 - still maintaining contravariance for parameters and covariance for return
abstract function test($s) : int;
}
~~~
## **重寫方法和接口實現的參數類型現在可以省略**
~~~
interface A
{
public function Test(array $input);
}
class B implements A
{
public function Test($input){} // 省略了$input的類型
}
~~~
# **php7.3新特性**
## **更靈活的`Heredoc`和`Nowdoc`語法**
```
//heredoc可以解析變量,nowdoc則不能解析變量
$name='dash';
//原heredoc
$str=<<<STR
這是文本第一行
這是文本第二行.{$name}over!
STR;
echo $str;//這是文本第一行 這是文本第二行.dashover!
//原nowdoc
$str = <<<'EOD'
Example of string
spanning multiple lines
using nowdoc syntax.{$name}over!
EOD;
echo $str;//Example of string spanning multiple lines using nowdoc syntax.{$name}over!
//可以使用縮進,使用縮進時doc內容的每行都會跳過相應的縮進
(下例兩行的縮進都被剝除了)
$str=<<<STR
這是文本第一行 |
這是文本第二行 STR; |
STR;
echo $str;// 這是文本第一行 | 這是文本第二行 STR; |
兩行的縮進都被剝除了
//結束標記不再需要獨立一行
$str=<<<STR
這是文本第一行
這是文本第二行
STR;echo $str;//這是文本第一行 這是文本第二行
//在某些情況下不用緊跟分號了
$data = ["元素", <<<STR
這是文本第一行
這是文本第二行
STR, 42,];
print_r($data);//Array ( [0] => 元素 [1] => 這是文本第一行 這是文本第二行 [2] => 42 )
$str=<<<STR
這是文本第一行
這是文本第二行
STR
echo $str;//這中情況就會報錯
```
## **數組析構與list結構支持引用賦值**
$v = [10, 20];
[$a, &$b] = $v;//短語法等同list($a, &$b)=$v;
$b += 10;
var_dump($v, $a, $b);//array(2) { [0]=> int(10) [1]=> &int(30) } int(10) int(30)
## ** instanceof 運算符支持字面量語法**
instanceof 的第一個運算數支持字面量,非對象型字面量檢測的結果為 false
var_dump("literal" instanceof stdClass);//false
var_dump(42 instanceof stdClass);//false
var_dump(new stdClass() instanceof stdClass);//true
## **支持調用時參數的末尾跟隨逗號,但是定義是不行的**
function methodName($p1, $p2)
{
var_dump($p1, $p2);
}
methodName(10, 20, );//10 20
## **BC 數學函數**
bcscale() 函數支持獲取當前任意BC(精度的數學擴展)函數所使用的 scale。
bcscale(3);//設置所有bc數學函數的默認小數點保留位數
var_dump(bcscale());//3
## **廢棄大小寫不敏感的常量**
將 TRUE 作為第三個參數傳遞給 define() 會導致一個廢棄警告
## **命名捕獲支持**
mb_ereg_ *系列函數現在支持命名捕獲。類似于mb_ereg()的匹配函數現在將使用其組號和名稱返回命名捕獲,類似于PCRE:
```
mb_ereg('(?<word>\w+)', '國', $matches);
print_r($matches);//Array ( [0] => [0 => "國", 1 => "國", "word" => "國"];
mb_ereg('(?<word>\w+)', '國<=>家', $matches);
print_r($matches);//Array ( [0] => [0 => "國", 1 => "國", "word" => "國"];
mb_ereg('(?<word>\w+)', '國家', $matches);
print_r($matches);//Array ( [0] => 國家 [1] => 國家 [word] => 國家 )
```
此外,mb_ereg_replace()現在支持 \k<>和\k''表示法來引用替換字符串中的命名捕獲:
```
//mb_ereg_replace ($pattern , $replacement , $string中匹配) //在string中匹配pattern,匹配成功則替換成replacement
$str=mb_ereg_replace('\s*(?<word>\w+)\s*', "_\k<word>_\k'word'_", ' foo ');
echo $str;// => "_foo_foo_"
```
# **php7.4新特性**
## **預加載**
`PHP`預加載可以極大的提高性能
* 優點:在`PHP 7.4`以前,如果你使用了框架來開發,每次請求文件就必須加載和重新編譯。預加載在框架啟動時在內存中加載文件,而且在后續請求中永久有效。
* 缺點:性能的提升會在其他方面花費很大的代價,每次預加載的文件發生改變時,框架需要重新啟動。
## **類屬性現在支持類型聲明**
除了`void`和`callable`外,所有的類型都支持
因此,我們可以放心使用`bool`,`int`,`float`,`string`,`array`,`object`,`iterable`,`self`,`parent`
```
class?User?{
????public?int?$id;
????public?string?$name;
public ?Foo $foo;
}
```
## **短閉包函數**
```
array_map (function($arr1_value, $arr2_value, $arrN_value){
//return $arr1_value.$arr2_value.$arrN_value;
},
$arr1,
$arr2,
$arrN
);
//原有特性
function cube($n){
return ($n * $n * $n);
}
$a = [1, 2, 3, 4, 5];
$b = array_map('cube', $a);
print_r($b);
//新特性
$a = [1, 2, 3, 4, 5];
$res = array_map(fn($n) => $n * $n * $n, $a);
print_r($res);
$a = [1, 2];
$b = [3, 4, 5];
$res = array_map(fn($av,$bv) => $av*$bv, $a,$b);
print_r($res);
$a = [1, 2];
$b = [3, 4, 5];
$res = array_map(fn(?int $av,?int $bv): int => $av*$bv, $a,$b);
print_r($res);
//如果你想通過引用返回一個值,應該使用以下語法
fn&($x) => $x
//總結:
//它們以fn關鍵字開始
//它們只能有一個表達式,即return語句
//不允許return關鍵字
//參數和返回類型可以是限定類型
```
## **Null 合并運算符**
~~~
$data['date'] ??= new DateTime();
//相當于之前的
$data['date'] = $data['date'] ?? new DateTime();
或:
if (!isset($data['date'])) {
$data['date'] = new DateTime();
}
~~~
## **數組擴展運算符(展開運算符)**
現在你可以在數組中使用展開運算符:
**注意**:只對數字索引有效
~~~
$arrayA = [1, 2, 3];
$arrayB = [4, 5];
$result = [0, ...$arrayA, ...$arrayB, 6 ,7];
// [0, 1, 2, 3, 4, 5, 6, 7]
~~~
## **自定義對象序列化**
添加了兩個新的魔術方法:`__serialize`?和`__unserialize`
## **數字分隔符**
允許使用下劃線更直觀的分隔數值
~~~
$unformattedNumber = 107925284.88;
//新特性
$formattedNumber = 107_925_284.88;
~~~
## **支持反射引用**
`PHP 7.4`將會新增`ReflectionReference`類
## **改進的類型差異(協變返回和逆變參數)**
[協變和逆變](https://link.zhihu.com/?target=https%3A//zh.wikipedia.org/wiki/%25E5%258D%258F%25E5%258F%2598%25E4%25B8%258E%25E9%2580%2586%25E5%258F%2598)
[百度百科的解釋](https://link.zhihu.com/?target=https%3A//baike.baidu.com/item/%25E5%258D%258F%25E5%258F%2598)
協變與逆變(Covariance and contravariance )是在計算機科學中,描述具有父/子型別關系的多個型別通過型別構造器、構造出的多個復雜型別之間是否有父/子型別關系的用語。
* Invariant (不變): 包好了所有需求類型
* Covariant (協變):類型從通用到具體
* Contravariant (逆變): 類型從具體到通用目前,PHP 主要具有`Invariant`的參數類型,并且大多數是`Invariant`的返回類型,這就意味著當我是 T 參數類型或者返回類型時,子類也必須是 T 的參數類型或者返回類型。但是往往會需要處理一些特殊情況,比如具體的返回類型,或者通用的輸入類型。而[RFC](https://link.zhihu.com/?target=https%3A//wiki.php.net/rfc/covariant-returns-and-contravariant-parameters)的這個提案就提議,PHP7.4 添加協變返回和逆變參數,以下是提案給出來的例子:協變返回:
```
class Parent {}
class Child extends Parent {}
class A
{
public function covariantReturnTypes(): Parent
{ /* … */ }
}
class B extends A
{
public function covariantReturnTypes(): Child
{ /* … */ }
}
```
## **箭頭函數**
匿名函數和箭頭函數都是[](https://www.php.net/manual/zh/class.closure.php)[Closure](https://www.php.net/manual/zh/class.closure.php)類的實現
箭頭函數的基本語法為`fn (argument_list) => expr`
```
$y?=?1;
$fn1?=?fn($x)?=>?$x?+?$y;
//?相當于?using?$y?by?value:
$fn2?=?function?($x)?use?($y)?{
????return?$x?+?$y;
};
var_export($fn1(3));
//箭頭函數自動捕捉變量的值,即使在嵌套的情況下
$z?=?1;
$fn?=?fn($x)?=>?fn($y)?=>?$x?*?$y?+?$z;
var_export($fn(5)(10));//?輸出?51
//合法的箭頭函數例子
fn(array $x) => $x;
static fn(): int => $x;
fn($x = 42) => $x;
fn(&$x) => $x;
fn&($x) => $x;
fn($x, ...$rest) => $rest;
//示例 #4 來自外部范圍的值不能在箭頭函數內修改
$x = 1;
$fn = fn() => $x++; // 不會影響 x 的值
$fn();
var_export($x); // 輸出 1
```
# **php8**
## **參數最后可尾隨`,`**
```
function demo($a,$b,){}
```
## 不推薦在可選參數之后傳遞強制參數,但null除外
如果帶有默認值的參數后面跟著一個必要的參數,那么默認值就會無效。這在 PHP 8.0.0 中已被廢棄,通常可以通過刪除默認值,不影響現有功能:
```
//不推薦
function demo($a=[],$b){}
demo(1);//$a為可選參數,他后面跟的是一個必要參數$b,k可選參數$a的默認值則在8.0之前是無效的
//可行替代方案
function demo($a, $b){}
//null時除外
function demo($a=null,$b){}
//官方推薦
function demo(?array $a){}
```
## **新增注解功能**
https://www.php.net/manual/zh/language.attributes.overview.php
## **在構造函數中聲明類的屬性**
```
class Point {
protected int $x;
protected int $y;
public function __construct(int $x, int $y = 0) {
$this->x = $x;
$this->y = $y;
}
//8.0構造器提升類屬性
public function __construct(protected int $x, protected int $y = 0) {
}
}
// 兩個參數都傳入
$p1 = new Point(4, 5);
// 僅傳入必填的參數。 $y 會默認取值 0。
$p2 = new Point(4);
// 使用命名參數(PHP 8.0 起):
$p3 = new Point(y: 5, x: 4);
```
## **新增聯合類型**
[mixed](https://www.php.net/manual/zh/language.types.declarations.php#language.types.declarations.mixed)等同于[聯合類型](https://www.php.net/manual/zh/language.types.declarations.php#language.types.declarations.union)object|resource|array|string|int|float|bool|null。PHP 8.0.0 起可用。
## **新增`match`表達式**
`match`表達式跟`switch`語句相似,但是有以下關鍵區別:
* 它會像三元表達式一樣求值
* `match`比較分支值,使用了嚴格比較 (`===`), 而 switch 語句使用了松散比較。
* `match`表達式會返回一個值。
* `match`的分支不會像`switch`語句一樣, 落空時執行下個 case。
* `match`表達式必須徹底列舉所有情況。如果主體表達式不能被任意分支條件處理, 會拋出**UnhandledMatchError**
```
$food = 'cake';
$return_value = match ($food) {
'apple' => 'This food is an apple',
'bar' => 'This food is a bar',
'cake' => 'This food is a cake',
};
var_dump($return_value);//This food is a cake
//逐個檢測匹配分支。一開始不會執行代碼。 只有在所有之前的條件不匹配主體表達式時,才會執行剩下的條件表達式。 只會執行返回的表達式所對應的匹配條件表達式
$result = match ($x) {
foo() => ...,
$this->bar() => ..., // 如果 foo() === $x,不會執行 $this->bar()
$this->baz => beep(), // 只有 $x === $this->baz 時才會執行 beep()
// 等等
};
//`match`表達式分支可以通過逗號分隔,包含多個表達式。 這是一個邏輯 OR,當多個分支表達式右側相同時,就可以用這種縮寫
$result = match ($x) {
// 匹配分支:
$a, $b, $c => 5,
// 等同于以下三個分支:
$a => 5,
$b => 5,
$c => 5,
};
//`default`模式是個特殊的條件。 當之前的條件都不匹配時,會匹配到該模式
//多個 default 模式將會觸發**`E_FATAL_ERROR`**錯誤
$expressionResult = match ($condition) {
1, 2 => foo(),
3, 4 => bar(),
default => baz(),
};
//**針對整數范圍,使用寬泛的表達式匹配分支**
$age = 23;
$result = match (true) {
$age >= 65 => 'senior',
$age >= 25 => 'adult',
$age >= 18 => 'young adult',
default => 'kid',
};
var_dump($result);//young adult
//**針對字符串內容,使用寬泛的表達式匹配分支**
$text = 'Bienvenue chez nous';
$result = match (true) {
str_contains($text, 'Welcome') || str_contains($text, 'Hello') => 'en',
str_contains($text, 'Bienvenue') || str_contains($text, 'Bonjour') => 'fr',
// ...
};
var_dump($result);//fr
//表達式存在未處理的示例
$condition = 5;
try {
match ($condition) {
1, 2 => foo(),
3, 4 => bar(),
};
} catch (\UnhandledMatchError $e) {
var_dump($e);
}
```
## **新增Nullsafe 運算符(`?->`)**
nullsafe 操作符和->原來的屬性、方法訪問是一致的: 對象引用解析(dereference)為**`null`**時不拋出異常,而是返回**`null`**。 并且如果是鏈式調用中的一部分,剩余鏈條會直接跳過.此操作的結果,類似于在每次訪問前使用 is_null() 函數判斷方法和屬性是否存在,但更加簡潔
```
// 自 PHP 8.0.0 起可用
$result = $repository?->getUser(5)?->name;
// 上邊那行代碼等價于以下代碼
if (is_null($repository)) {
$result = null;
} else {
$user = $repository->getUser(5);
if (is_null($user)) {
$result = null;
} else {
$result = $user->name;
}
}
```
## 新增[WeakMap](https://www.php.net/manual/zh/class.weakmap.php)類
## 新增**ValueError**類
## 任意數量的函數參數都可以用一個可變參數替換(只要類型兼容)
```
class A {
public function method(int $many, string $parameters, $here) {}
}
class B extends A {
public function method(...$everything) {}
}
```
## static("后期靜態綁定"中) 可以作為返回類型
```
class?Test?{
?????public?function?create():?static?{
??????????return?new?static();
?????}
}
```
## 可以通過`$object::class`獲取類名,返回的結果和`get_class($object)`一致
## 可作為表達式使用`throw`
```
$fn = fn() => throw new Exception('Exception in arrow function');
$user = $session->user ?? throw new Exception('Must have user');
```
## 在父類上聲明的私有方法不再對子類的方法強制執行任何繼承規則(最終私有構造函數除外)。 以下示例說明了哪些限制已被刪除:
```
class ParentClass {
private function method1() {}
private function method2() {}
private static function method3() {}
// Throws a warning, as "final" no longer has an effect:
private final function method4() {}
}
class ChildClass extends ParentClass {
// All of the following are now allowed, even though the modifiers aren't
// the same as for the private methods in the parent class.
public abstract function method1() {}
public static function method2() {}
public function method3() {}
public function method4() {}
}
```
## 其他
* [`new`](https://www.php.net/manual/zh/language.oop5.basic.php#language.oop5.basic.new)、[`instanceof`](https://www.php.net/manual/zh/language.operators.type.php)可用于任何表達式, 用法為`new (expression)(...$args)`和`$obj instanceof (expression)`。
* 添加對一些變量語法一致性的修復,例如現在能夠編寫`Foo::BAR::$baz`。
* 添加[Stringable](https://www.php.net/manual/zh/class.stringable.php)interface, 當一個類定義[\_\_toString()](https://www.php.net/manual/zh/language.oop5.magic.php#object.tostring)方法后會自動實現該接口。
* Trait 可以定義私有抽象方法(abstract private method)。 類必須實現 trait 定義的該方法。
* 新增 [get\_resource\_id()](https://www.php.net/manual/zh/function.get-resource-id.php)
## 不向后兼容的變更
| Comparison | Before | After |
| --- | --- | --- |
| `0 == "0"` | **`true`** | **`true`** |
| `0 == "0.0"` | **`true`** | **`true`** |
| `0 == "foo"` | **`true`** | **`false`** |
| `0 == ""` | **`true`** | **`false`** |
| `42 == " 42"` | **`true`** | **`true`** |
| `42 == "42foo"` | **`true`** | **`false`** |
`(real)`和`(unset)`轉換已被移除。
# **php8.1**
- php更新內容
- PHP PSR 標準規范
- 輔助查詢(*)
- composer項目的創建
- composer安裝及設置
- composer自動加載講解
- phpsdudy的composer操作
- git
- Git代碼同時上傳到GitHub和Gitee(碼云)
- Git - 多人協同開發利器,團隊協作流程規范與注意事項
- 刪除遠程倉庫的文件
- github查詢方法
- 錯誤
- 其他
- php.ini
- php配置可修改范圍
- php超時
- 防跨目錄設置
- 函數可變參數
- 【時間】操作
- 時間函數例子
- Date/Time 函數(不包含別名函數)
- DateTime類別名函數
- 【數字】操作
- 【字符串】操作
- 【數組】操作
- 排序
- 合并案例
- empty、isset、is_null
- echo 輸出bool值
- if真假情況
- 流程控制代替語法【if (條件): endif;】
- 三元運算
- 運算符優先級
- 常量
- define與const(php5.3) 類常量
- 遞歸
- 單元測試
- 面向對象
- 對象(object) 與 數組(array) 的轉換
- php網絡相關
- 支持的協議和封裝協議(如http,php://input)
- php://協議
- file://協議
- http(s)://協議
- ftp(s)://協議
- zip://, bzip2://, zlib://協議
- data://協議
- glob://協議
- expect://協議
- phar://
- ssh2
- rar://
- ogg://
- 上下文(Context)選項和參數
- 過濾器
- http請求及模擬登錄
- 常用的header頭部定義匯總
- HTTP響應頭和請求頭信息對照表
- HTTP請求的返回值含義說明
- content-type對照表
- Cache-Control對照
- curl函數
- 防止頁面刷新
- telnet模擬get、post請求
- 三種方式模擬表單發布留言
- 模擬登陸
- 防盜鏈
- php+mysql模擬隊列發送郵件
- socket
- 使用websocket實現php消息實時推送完整示例
- streams
- Stream函數實現websocket
- swoole
- 網絡編程基本概念
- 全局變量域超全局變量
- 超全局變量
- $_ENV :存儲了一些系統的環境變量
- $_COOKIE
- $_SESSION
- $_FILES
- $_SERVER
- 正則
- php正則函數
- 去除文本中的html、xml的標簽
- 特殊符號
- \r\n
- 模式修正符
- 分組
- 斷言(環視?)
- 條件表達式
- 遞歸表達式 (?R)
- 固化分組
- 正則例子
- 提取類文件的公共方法
- 抓取網頁內容
- 匹配中文字符
- 提取sql日志文件
- 框架
- 文件操作
- 自動加載spl_autoload_register
- 文件加載
- 文件的上傳下載
- 常見的mimi類型
- 文件斷點續傳
- 下載文件防盜鏈
- 破解防盜鏈
- 將字節轉為人可讀的單位
- 無限分類
- 短信驗證碼
- 短信寶
- 視頻分段加載
- 隱藏地址
- MPEG DASH視頻分片技術
- phpDoc注釋
- @錯誤抑制符
- 字符編碼
- PHP CLI模式開發
- CGI、FastCGI和PHP-FPM關系圖解
- No input file specified的解決方法
- SAPI(PHP常見的四種運行模式)
- assert斷言
- 輪詢(Event Loop)
- 異常處理
- 異常分類
- php系統異常
- 錯誤級別
- set_error_handler
- set_exception_handler
- register_shutdown_function
- try catch
- tp5異常處理類解析
- 文件上傳相關設置
- 進程/線程/協程
- 協程
- 什么是協程
- 引用&
- Heredoc和Nowdoc語法
- 類基礎
- 系統預定義類
- pdo
- 類的三大特性:封裝,繼承,多態
- 魔術方法
- extends繼承
- abstract 抽象類
- interface 接口(需要implements實現)
- 抽象類和接口的區別
- 多態
- static
- final
- serialize與unserialize
- instanceof 判斷后代子類
- 類型約束
- clone克隆
- ::的用法
- static::class、self::class
- new self()與new static()
- this、self、static、parent、super
- self、static、parent:后期靜態綁定
- PHP的靜態變量
- php導入
- trait
- 動態調用類方法
- 參數及類型申明
- 方法的重載覆蓋
- return $a && $b
- 類型聲明
- 設計思想
- 依賴注入與依賴倒置
- MVC模式與模板引擎
- 模版引擎
- smarty模版
- 系統變量、全局變量
- 語言切換
- 函數-給函數默認值
- 流程控制-遍歷
- 模版加載
- 模版繼承
- blade
- twig
- Plates
- 創建型模式(創建類對象)--單原二廠建
- (*)單例模式(保證一個類僅有一個實例)
- (*)工廠模式(自動實例化想要的類)
- 原型模式(在指定方法里克隆this)
- 創建者模式(建造者類組裝近似類屬性)
- 結構型模式 --橋(幫)組享外帶裝適
- 適配器模式(Adapter 用于接口兼容)
- 橋接模式(方法相同的不同類之間的快速切換)
- 裝飾模式(動態增加類對象的功能 如游戲角色的裝備)
- 組合模式(用于生成類似DOMDocument這種節點類)
- 外觀模式(門面(Facade)模式 不同類的統一調用)
- 享元模式
- 代理模式
- 行為型模式--觀摩職命狀-備爹在房中潔廁
- (*)觀察者模式
- (*)迭代器模式(Iterator)
- 模板方法模式 Template
- 命令模式(Command)
- 中介者模式(Mediator)
- 狀態模式(State)
- 職責鏈模式 (Chainof Responsibility)
- 策略模式(Strategy)
- 已知模式-備忘錄模式(Memento)
- 深度模式-解釋器模式(Interpreter)
- 深度模式-訪問者模式(Visitor)
- (*)注冊樹(注射器、注冊表)模式
- PHP擴展庫列表
- 函數參考
- 影響 PHP 行為的擴展
- APC擴展(過時)
- APCu擴展
- APD擴展(過時)
- bcompiler擴展(過時)
- BLENC擴展 (代碼加密 實驗型)
- Componere擴展(7.1+)
- Componere\Definition
- Componere\Patch
- Componere \ Method
- Componere\Value
- Componere函數
- 錯誤處理擴展(PHP 核心)
- FFI擴展
- 基本FFI用法
- FFI api
- htscanner擴展
- inclued擴展
- Memtrack擴展
- OPcache擴展(5.5.0內部集成)
- Output Control擴展(核心)
- PHP Options/Info擴展(核心)
- 選項、 信息函數
- phpdbg擴展(5.6+內部集成)
- runkit擴展
- runkit7擴展
- scream擴展
- uopz擴展
- Weakref擴展
- WeakRef
- WeakMap
- WinCache擴展
- Xhprof擴展
- Yac(7.0+)
- 音頻格式操作
- ID3
- KTaglib
- oggvorbis
- OpenAL
- 身份認證服務
- KADM5
- Radius
- 針對命令行的擴展
- Ncurses(暫無人維護)
- Newt(暫無人維護)
- Readline
- 壓縮與歸檔擴展
- Bzip2
- LZF
- Phar
- Rar
- Zip
- Zlib
- 信用卡處理
- 加密擴展
- Crack(停止維護)
- CSPRNG(核心)
- Hash擴展(4.2內置默認開啟、7.4核心)
- Mcrypt(7.2移除)
- Mhash(過時)
- OpenSSL(*)
- 密碼散列算法(核心)
- Sodium(+)
- 數據庫擴展
- 數據庫抽象層
- DBA
- dbx
- ODBC
- PDO(*)
- 針對各數據庫系統對應的擴展
- CUBRID
- DB++(實驗性)
- dBase
- filePro
- Firebird/InterBase
- FrontBase
- IBM DB2
- Informix
- Ingres
- MaxDB
- Mongo(MongoDB老版本)
- MongoDB
- mSQL
- Mssql
- MySQL
- OCI8(Oracle OCI8)
- Paradox
- PostgreSQL
- SQLite
- SQLite3
- SQLSRV(SQL Server)
- Sybase
- tokyo_tyrant
- 日期與時間相關擴展
- Calendar
- 日期/時間(核心)
- HRTime(*)
- 文件系統相關擴展
- Direct IO
- 目錄(核心)
- Fileinfo(內置)
- 文件系統(核心)
- Inotify
- Mimetype(過時)
- Phdfs
- Proctitle
- xattr
- xdiff
- 國際化與字符編碼支持
- Enchant
- FriBiDi
- Gender
- Gettext
- iconv(內置默認開啟)
- intl
- 多字節字符串(mbstring)
- Pspell
- Recode(將要過時)
- 圖像生成和處理
- Cairo
- Exif
- GD(內置)
- Gmagick
- ImageMagick
- 郵件相關擴展
- Cyrus
- IMAP
- Mail(核心)
- Mailparse
- vpopmail(實驗性 )
- 數學擴展
- BC Math
- GMP
- Lapack
- Math(核心)
- Statistics
- Trader
- 非文本內容的 MIME 輸出
- FDF
- GnuPG
- haru(實驗性)
- Ming(實驗性)
- wkhtmltox(*)
- PS
- RPM Reader(停止維護)
- RpmInfo
- XLSWriter Excel操作(*)
- php第三方庫非擴展
- 進程控制擴展
- Eio
- Ev
- Expect
- Libevent
- PCNTL
- POSIX
- 程序執行擴展(核心)
- parallel
- pthreads(*)
- pht
- Semaphore
- Shared Memory
- Sync
- 其它基本擴展
- FANN
- GeoIP(*)
- JSON(內置)
- Judy
- Lua
- LuaSandbox
- Misc(核心)
- Parsekit
- SeasLog(-)
- SPL(核心)
- SPL Types(實驗性)
- Streams(核心)
- stream_wrapper_register
- stream_register_wrapper(同上別名)
- stream_context_create
- stream_socket_client
- stream_socket_server
- stream_socket_accept
- stream_socket_recvfrom
- stream_socket_sendto
- Swoole(*)
- Tidy擴展
- Tokenizer
- URLs(核心)
- V8js(*)
- Yaml
- Yaf
- Yaconf(核心)
- Taint(檢測xss字符串等)
- Data Structures
- Igbinary(7.0+)
- 其它服務
- 網絡(核心)
- Sockets
- socket_create
- socket_bind(服務端即用于監聽的套接字)
- socket_listen(服務端)
- socket_accept(服務端)
- socket_connect(客戶端)
- socket_read
- socket_recv(類似socket_read)
- socket_write
- socket_send
- socket_close
- socket_select
- socket_getpeername
- socket_getsockname
- socket_get_option
- socket_getopt(socket_get_option的別名)
- socket_set_option
- socket_setopt( socket_set_option的別名)
- socket_recvfrom
- socket_sendto
- socket_addrinfo_bind
- socket_addrinfo_connect
- socket_addrinfo_explain
- socket_addrinfo_lookup
- socket_clear_error
- socket_last_error
- socket_strerror
- socket_cmsg_space
- socket_create_listen
- socket_create_pair
- socket_export_stream
- socket_import_stream
- socket_recvmsg
- socket_sendmsg
- socket_set_block
- socket_set_nonblock
- socket_shutdown
- socket_wsaprotocol_info_export
- socket_wsaprotocol_info_import
- socket_wsaprotocol_info_release
- cURL(*)
- curl_setopt
- Event(*)
- chdb
- FAM
- FTP
- Gearman
- Gopher
- Gupnp
- Hyperwave API(過時)
- LDAP(+)
- Memcache
- Memcached(+)
- mqseries
- RRD
- SAM
- ScoutAPM
- SNMP
- SSH2
- Stomp
- SVM
- SVN(試驗性的)
- TCP擴展
- Varnish
- YAZ
- YP/NIS
- 0MQ(ZeroMQ、ZMQ)消息系統
- 0mq例子
- ZooKeeper
- 搜索引擎擴展
- mnoGoSearch
- Solr
- Sphinx
- Swish(實驗性)
- 針對服務器的擴展
- Apache
- FastCGI 進程管理器
- IIS
- NSAPI
- Session 擴展
- Msession
- Sessions
- Session PgSQL
- 文本處理
- BBCode
- CommonMark(markdown解析)
- cmark函數
- cmark類
- Parser
- CQL
- IVisitor接口
- Node基類與接口
- Document
- Heading(#)
- Paragraph
- BlockQuote
- BulletList
- OrderedList
- Item
- Text
- Strong
- Emphasis
- ThematicBreak
- SoftBreak
- LineBreak
- Code
- CodeBlock
- HTMLBlock
- HTMLInline
- Image
- Link
- CustomBlock
- CustomInline
- Parle
- 類函數
- PCRE( 核心)
- POSIX Regex
- ssdeep
- 字符串(核心)
- 變量與類型相關擴展
- 數組(核心)
- 類/對象(核心)
- Classkit(未維護)
- Ctype
- Filter擴展
- 過濾器函數
- 函數處理(核心)
- quickhash擴展
- 反射擴展(核心)
- Variable handling(核心)
- Web 服務
- OAuth
- api
- 例子:
- SCA(實驗性)
- SOAP
- Yar
- XML-RPC(實驗性)
- Windows 專用擴展
- COM
- 額外補充:Wscript
- win32service
- win32ps(停止更新且被移除)
- XML 操作(也可以是html)
- libxml(內置 默認開啟)
- DOM(內置,默認開啟)
- xml介紹
- 擴展類與函數
- DOMNode
- DOMDocument(最重要)
- DOMAttr
- DOMCharacterData
- DOMText(文本節點)
- DOMCdataSection
- DOMComment(節點注釋)
- DOMDocumentFragment
- DOMDocumentType
- DOMElement
- DOMEntity
- DOMEntityReference
- DOMNotation
- DOMProcessingInstruction
- DOMXPath
- DOMException
- DOMImplementation
- DOMNamedNodeMap
- DOMNodeList
- SimpleXML(內置,5.12+默認開啟)
- XMLReader(5.1+內置默認開啟 用于處理大型XML文檔)
- XMLWriter(5.1+內置默認開啟 處理大型XML文檔)
- SDO(停止維護)
- SDO-DAS-Relational(試驗性的)
- SDO DAS XML
- WDDX
- XMLDiff
- XML 解析器(Expat 解析器 默認開啟)
- XSL(內置)
- 圖形用戶界面(GUI) 擴展
- UI
- PHP SPL(PHP 標準庫)
- 數據結構
- SplDoublyLinkedList(雙向鏈表)
- SplStack(棧 先進后出)
- SplQueue(隊列)
- SplHeap(堆)
- SplMaxHeap(最大堆)
- SplMinHeap(最小堆)
- SplPriorityQueue(堆之優先隊列)
- SplFixedArray(陣列【數組】)
- SplObjectStorage(映射【對象存儲】)
- 迭代器
- ArrayIterator
- RecursiveArrayIterator(支持遞歸)
- DirectoryIterator類
- FilesystemIterator
- GlobIterator
- RecursiveDirectoryIterator
- EmptyIterator
- IteratorIterator
- AppendIterator
- CachingIterator
- RecursiveCachingIterator
- FilterIterator(遍歷并過濾出不想要的值)
- CallbackFilterIterator
- RecursiveCallbackFilterIterator
- RecursiveFilterIterator
- ParentIterator
- RegexIterator
- RecursiveRegexIterator
- InfiniteIterator
- LimitIterator
- NoRewindIterator
- MultipleIterator
- RecursiveIteratorIterator
- RecursiveTreeIterator
- 文件處理
- SplFileInfo
- SplFileObject
- SplTempFileObject
- 接口 interface
- Countable
- OuterIterator
- RecursiveIterator
- SeekableIterator
- 異常
- 各種類及接口
- SplSubject
- SplObserver
- ArrayObject(將數組作為對象操作)
- SPL 函數
- 預定義接口
- Traversable(遍歷)接口
- Iterator(迭代器)接口
- IteratorAggregate(聚合式迭代器)接口
- ArrayAccess(數組式訪問)接口
- Serializable 序列化接口
- JsonSerializable
- Closure 匿名函數(閉包)類
- Generator生成器類
- 生成器(php5.5+)
- yield
- 反射
- 一、反射(reflection)類
- 二、Reflector 接口
- ReflectionClass 類報告了一個類的有關信息。
- ReflectionObject 類報告了一個對象(object)的相關信息。
- ReflectionFunctionAbstract
- ReflectionMethod 類報告了一個方法的有關信息
- ReflectionFunction 類報告了一個函數的有關信息。
- ReflectionParameter 獲取函數或方法參數的相關信息
- ReflectionProperty 類報告了類的屬性的相關信息。
- ReflectionClassConstant類報告有關類常量的信息。
- ReflectionZendExtension 類返回Zend擴展相關信息
- ReflectionExtension 報告了一個擴展(extension)的有關信息。
- 三、ReflectionGenerator類用于獲取生成器的信息
- 四、ReflectionType 類用于獲取函數、類方法的參數或者返回值的類型。
- 五、反射的應用場景
- phpRedis
- API
- API詳細
- redis DB 概念:
- 通用命令:rawCommand
- Connection
- Server
- List
- Set
- Zset
- Hash
- string
- Keys
- 事物
- 發布訂閱
- 流streams
- Geocoding 地理位置
- lua腳本
- Introspection 自我檢測
- biMap
- 原生
- php-redis 操作類 封裝
- redis 隊列解決秒殺解決超賣:
- swoole+框架筆記
- 安裝及常用Cli操作
- TCP
- 4種回調函數的寫法
- easyswoole
- 目錄結構
- 配置文件
- Linux+Nginx
- 前置
- linux
- 開源網站鏡像及修改yum源
- 下載linux
- Liunx中安裝PHP7.4 的三種方法(Centos8)
- yum安裝
- 源碼編譯安裝
- LNMP一鍵安裝
- 查看linux版本號
- 設置全局環境變量
- 查看php.ini必須存放的位置
- 防火墻與端口開放
- nohup 后臺運行命令
- linux 查看nginx,php-fpm運行用戶及用戶組
- 網絡配置
- CentOS中執行yum update時報錯
- 關閉防火墻
- 查看端口是否被占用
- 查看文件夾大小
- nginx相關
- 一個典型的nginx配置
- nginx關于多個項目的配置(易于管理)
- nginx.config配置文件的結構
- 1、events
- 2、http
- nginx的location配置詳解
- Nginx相關命令
- Nginx安裝
- 配置偽靜態
- 為靜態配置例子
- apache
- nginx
- pathinfo模式
- Shell腳本
- bash
- shell 語言中 0 代表 true,0 以外的值代表 false。
- 變量
- shell字符串
- shell數組
- shell注釋
- 向Shell腳內傳遞參數
- 運算符
- 顯示命令執行結果
- printf
- test 命令
- 流程控制與循環
- if
- case
- for
- while
- until
- break和continue
- select 結構
- shell函數
- shell函數的全局變量和局部變量
- 將shell輸出寫入文件中(輸出重定向)
- Shell腳本中調用另一個Shell腳本的三種方式
- 定時任務
- PHP實現定時任務的五種方法
- 優化
- ab壓力測試
- 緩存
- opcache
- memcache
- php操作
- 數據庫
- 配置
- 數據庫鎖機制
- 主從分布
- 數據庫設計
- 邏輯設計
- 物理設計
- 字段類型的選擇
- 筆記
- SET FOREIGN_KEY_CHECKS
- 字符集與亂碼
- SQL插入 去除重復記錄的實現
- 分區表
- nginx 主從配置
- nginx 負載均衡的配置
- 手動搭建Redis集群和MySQL主從同步(非Docker)
- Redis Cluster集群
- mysql主從同步
- 用安卓手機搭建 web 服務器
- 軟件選擇
- url重寫
- 大流量高并發解決方案
- 權限設計
- ACL
- RBAC
- RBAC0
- RBAC1(角色上下級分層)
- RBAC2(用戶角色限約束)
- RBAC3
- 例子
- Rbac.class.php
- Rbac2
- Auth.class.php
- fastadmin Auth
- tree1
- ABAC 基于屬性的訪問控制
- 總結:SAAS后臺權限設計案例分析
- casbin-權限管理框架
- 開始使用
- casbinAPI
- casbin管理API
- RBAC API
- Think-Casbin
- 單點登錄(SSO)
- OAuth授權
- OAuth 2.0 的四種方式
- 授權碼
- 隱藏式
- 密碼式
- 憑證式
- 更新令牌
- 例子:第三方登錄
- 微服務架構下的統一身份認證和授權
- 代碼審計
- 漏洞挖掘的思路
- 命令注入
- 代碼注入
- XSS 反射型漏洞
- XSS 存儲型漏洞
- xss過濾
- HTML Purifier文檔
- 開始
- id規則
- class規則
- 過濾分類
- Attr
- AutoFormat
- CSS
- Cache
- Core
- Filter
- html
- Output
- Test
- URI
- 其他
- 嵌入YouTube視頻
- 加快HTML凈化器的速度
- 字符集
- 定制
- Tidy
- URI過濾器
- 在線測試
- xss例子
- 本地包含與遠程包含
- sql注入
- 函數
- 注釋
- 步驟
- information_schema
- sql注入的分類
- 實戰
- 防御
- CSRF 跨站請求偽造
- 計動態函數執行與匿名函數執行
- unserialize反序列化漏洞
- 覆蓋變量漏洞
- 文件管理漏洞
- 文件上傳漏洞
- 跳過登錄
- URL編碼對照表
- XXE
- 前端、移動端
- html5
- meta標簽
- flex布局
- javascript
- jquery
- 選擇器
- 精細分類
- 事件
- on事件無效:
- jquery自定義事件
- 表單操作
- 通用
- select
- checkbox
- radio
- js正則相關
- js中判斷某字符串含有某字符出現的次數
- js匹配指定字符
- $.getjson方法配合在url上傳遞callback=?參數,實現跨域
- pajax入門
- jquery的extend插件制作
- jquery的兼容
- jquery的連續調用:
- $ 和 jQuery 及 $() 的區別
- 頁面響應順序及$(function(){})等使用
- 匿名函數:
- ajax
- 獲取js對象所有方法
- dom加載
- ES6函數寫法
- ES6中如何導入和導出模塊
- 數組的 交集 差集 補集 并集
- phantomjs
- js數組的map()方法操作json數組
- 實用函數
- js精確計算CalcEval 【價格計算】 浮點計算
- js精確計算2
- js數組與對象的遍歷
- bootstrap
- class速查
- 常見data屬性
- data-toggle與data-target的作用
- 組件
- bootstrapTable
- 表選項
- 表選項2
- 示例
- 數據格式(json)
- 用法(row:行,column:列)
- Bootstrap-table使用footerFormatter做統計列功能
- 示例2
- JQuery-Jquery的TreeGrid插件
- 服務器端分頁
- 合并單元格1
- 合并單元格2
- 合并單元格3
- 合并單元格4
- 合并單元格5(插件)
- 列求和
- 添加行,修改行、擴展行數據
- 擴展
- 開源項目
- PhpSpreadsheet
- 實例
- 會員 數據庫表設計
- 程序執行
- 開發總結
- API接口
- API接口設計
- json轉化
- app接口
- 雜項
- 三方插件庫
- 檢測移動設備(包括平板電腦)
- curl封裝
- Websocket
- 與谷歌瀏覽器交互
- Crontab管理器
- 實用小函數
- PHP操作Excel
- SSL證書
- sublime Emmet的快捷語法
- 免費翻譯接口
- 接口封裝
- 免費空間
- 架構師必須知道的26項PHP安全實踐
- 大佬博客
- 個人支付平臺
- RPC(遠程調用)及框架