[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 ) )
```
![](https://img.kancloud.cn/3c/2d/3c2d9a4794eb4a29661e8fa507b0c4ab_1384x376.png)
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(远程调用)及框架