PHP7 版本特性

PHP7 极大地提升了性能,在一些 WordPress 基准测试中,性能可以达到 PHP5.6 的3倍,原因如下:

  • 1、变量存储字节减小,减少内存占用,提升变量操作速度
  • 2、改善数组结构,数组元素和hash映射表被分配在同一块内存里,降低了内存占用、提升了 CPU 缓存命中率
  • 3、改进了函数的调用机制,通过优化参数传递的环节,减少了一些指令,提高执行效率

1、标量类型声明

默认情况下,所有的PHP文件都处于弱类型校验模式
PHP7 增加了标量类型声明的特性,标量类型声明有两种模式:
    强制模式 (默认)
    严格模式
标量类型声明语法格式:
    declare(strict_types=1);
    // 1 表示严格类型校验模式,作用于函数调用和返回语句
    // 0 表示弱类型校验模式
强制模式实例:
    //... 操作符: 表示这是一个可变参数. php5.6及以上的版本可使用: 函数定义的时候变量前使用. 
    function sumup(int ...$ints) {
       return array_sum($ints);
    }
    print(sumup(1, '2', 3.4)); // 6(将参数转换为整数后再相加)
严格模式实例:
    declare(strict_types=1);
    function sumup(int ...$ints) {
       return array_sum($ints);
    }
    print(sumup(1, '2', 3.4)); // PHP Fatal error:  Uncaught TypeError: Argument 2 passed to sum() must be of the type integer, string given, called in……

 2、函数返回值类型声明

可以声明的返回类型有:
    int
    float
    bool
    string
    interfaces
    array
    callable
// 有效的返回类型
    declare(strict_types = 1);
    function getInt(int $value): int {
        return $value;
    }
    print(getInt(1)); // 1
// 无效返回类型
    declare(strict_types = 1);
    function getInt(int $value): int {
        return $value + '2.3';
    }
    print(getInt(1)); // Fatal error: Uncaught TypeError: Return value of returnIntValue() must be of the type integer, float returned...
void 函数:
    一个新的返回值类型void被引入。
    void 函数可以省去 return 语句,或者使用一个空的 return 语句。
    对于 void 函数来说,NULL 不是一个合法的返回值。
    返回的类型还有 void,定义返回类型为 void 的函数不能有返回值,即使返回 null 也不行。
    对于标量类型声明:在严格模式下,有一种例外的情况是:
    当函数参数为float时,传入int型变量不会跑出typeerror,而是正常执行,在返回类型声明中,也是同样的.

3、NULL 合并运算符 ??

?? 是用于执行isset()检测的三元运算的快捷方式。
?? 判断变量是否存在且值不为 NULL,如果是,它就会返回自身的值,否则返回它的第二个操作数。
$a = isset($_GET['a']) ? $_GET['a'] : 'a';
// 可简写成
$a = $_GET['a'] ?? 'a';

4、组合比较符<=>

// 字符串比较
print("a" <=> "b");print(PHP_EOL); // -1
print("a" <=> "a");print(PHP_EOL); //  0
print("b" <=> "a");print(PHP_EOL); //  1
// 数字比较
print(1 <=> 2);print(PHP_EOL); // -1
print(1 <=> 1);print(PHP_EOL); //  0
print(2 <=> 1);print(PHP_EOL); //  1

5、常量数组

在 PHP5.6 中仅能通过 const 定义常量数组,PHP7 可以通过 define() 来定义
define('sites', ['Apple','Orange','Tomato']);
print(sites[1]);

6、匿名类

支持通过 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;
// 使用 new class 创建匿名类
$app->setLogger(new class implements Logger {
    public function log(string $msg) {
        print($msg);
    }
});
$app->getLogger()->log("something");

7、增加 Closure::call() 向类绑定匿名函数

PHP7 的 Closure::call() 有着更好的性能,将一个闭包函数动态绑定到一个新的对象实例并调用执行该函数
class A {
    private $x = 1;
}
// PHP7 之前版本定义闭包函数代码
$getXCB = function() {
    return $this->x;
};
// 闭包函数绑定到类 A 上
$getX = $getXCB->bindTo(new A, 'A');
echo $getX(); // 1
// PHP7+ 代码
$getX = function() {
    return $this->x;
};
echo $getX->call(new A); // 1

8、为 unserialize() 提供过滤

class A {
     public $name = 'a';
}
$objA = new A();

$serializedObjA = serialize($objA);

// 默认行为是接收所有类; 第二个参数可以忽略;
$resA = unserialize($serializedObjA , ["allowed_classes" => true]);
var_dump($resA);
// object(A)#2 (1) { ["name"]=> string(1) "a" }

// 如果allowed_classes设置为false,unserialize会将所有对象转换为__PHP_Incomplete_Class对象
$resA = unserialize($serializedObjA , ["allowed_classes" => false]);
var_dump($resA);
// object(__PHP_Incomplete_Class)#3 (2) { ["__PHP_Incomplete_Class_Name"]=> string(1) "A" ["name"]=> string(1) "a" }

// 转换所有对象到 __PHP_Incomplete_Class 对象,除了对象"A"
$resA = unserialize($serializedObjA , ["allowed_classes" => ["A"]]);
var_dump($resA);
// object(A)#2 (1) { ["name"]=> string(1) "a" }

 9、IntlChar()

通过 intl 扩展来支持国际化 (i18n) 和本地化 (l10n) 。
此扩展仅仅是对 ICU 库的基础包装,并提供了和 ICU 库类似的方法和特性。
通过新的 IntlChar 类暴露出 ICU 中的 Unicode 字符特性。
这个类自身定义了许多静态方法用于操作多字符集的 unicode 字符。
IntlChar 提供了一些可用于访问Unicode字符信息的实用方法的访问,须安装 Intl 扩展才能使用
var_dump(IntlChar::CODEPOINT_MAX);     // int(1114111)
var_dump(IntlChar::charName('+'));     // string(9) "PLUS SIGN"
var_dump(IntlChar::ispunct('?'));      // bool(true)
printf('%x', IntlChar::CODEPOINT_MAX); // 10ffff
echo IntlChar::charName('@');          // COMMERCIAL AT
var_dump(IntlChar::ispunct('!'));      // bool(true)

10、CSPRNG

CSPRNG(Cryptographically Secure Pseudo-Random Number Generator,伪随机数产生器)。
通过引入几个 CSPRNG 函数提供一种简单的机制来生成密码学上强壮的随机数。
random_bytes(int $length) - 随机生成字符串。
    length - 随机字符串返回的字节数
$bytes = random_bytes(5);
print(bin2hex($bytes)); // 6f36d48a29
random_int(int $min , int $max) - 随机生成整数。
    min - 必须是大于或等于
    max - 必须是小于或等于
print(random_int(-1000, 999)); // -64

11、异常

PHP7 异常用于向下兼容及增强旧的assert()函数。它能在生产环境中实现零成本的断言,并且提供抛出自定义异常及错误的能力。
老版本的API出于兼容目的将继续被维护,assert()现在是一个语言结构,它允许第一个参数是一个表达式,而不仅仅是一个待计算的 string或一个待测试的boolean
assert() 配置:
zend.assertions  默认1   1 - 生成和执行代码 (开发模式)
                         0 - 生成代码,但在执行时跳过它
                        -1 - 不生成代码 (生产环境)
assert.exception 默认0   1 - 断言失败时抛出,可以抛出异常对象,如果没有提供异常,则抛出 AssertionError 对象实例。
                         0 - 使用或生成 Throwable, 仅仅是基于对象生成的警告而不是抛出对象(与 PHP 5 兼容)
参数:
assertion
断言。在 PHP 5 中,是一个用于执行的字符串或者用于测试的布尔值。在 PHP 7 中,可以是一个返回任何值的表达式, 它将被执行结果用于指明断言是否成功。
description
如果 assertion 失败了,选项 description 将会包括在失败信息里。
exception
在 PHP 7 中,第二个参数可以是一个 Throwable 对象,而不是一个字符串,如果断言失败且启用了 assert.exception 该对象将被抛出。
将 zend.assertions 设置为 0:
实例:
phpini_set('zend.assertions', 0);
assert(true == false);
echo 'Hi!';
以上程序执行输出结果为:Hi!
将 zend.assertions 设置为 1,assert.exception 设置为 1:
实例:
ini_set('zend.assertions', 1);
ini_set('assert.exception', 1);
assert(true == false);
echo 'Hi!';
以上程序执行输出结果为:
Fatal error: Uncaught AssertionError: assert(true == false) in -:2
Stack trace:
#0 -(2): assert(false, 'assert(true == ...')
#1 {main}
  thrown in - on line 2

12、use 语句

PHP7 可以使用一个 use 从同一个 namespace 中导入类、函数和常量
// PHP7 之前版本需要使用多次 use
use namespaceA\namespaceB\ClassA;
use namespaceA\namespaceB\ClassB;
use namespaceA\namespaceB\ClassC as C;
// PHP7+ 之后版本可以使用一个 use 导入同一个 namespace 的类
use namespaceA\namespaceB\{ClassA, ClassB, ClassC as C};

13、错误处理

PHP7 改变了大多数错误的报告方式。不同于 PHP5 的传统错误报告机制,现在大多数错误被作为 Error 异常抛出。
这种 Error 异常可以像普通异常一样被 try/catch 块所捕获。
如果没有匹配的 try/catch 块, 则调用异常处理函数(由 set_exception_handler() 注册)进行处理。 
如果尚未注册异常处理函数,则按照传统方式处理:被报告为一个致命错误(Fatal Error)。
Error 类并不是从 Exception 类 扩展出来的,所以用 catch (Exception $e) { ... } 这样的代码是捕获不 到 Error 的。
你可以用 catch (Error $e) { ... } 这样的代码,或者通过注册异常处理函数( set_exception_handler())来捕获 Error。
Error
    ArithmeticError
    AssertionError
    DivisionByZeroError
    ParseError
    TypeError
     - ...
Exception
- LogicException
- RunTimeException
- ...
// php7 以前 自定义异常处理 
class getException extends Exception { 
    public function errorMsg() { 
        return '错误的信息' . $this->getMessage() . '<br>错误的代码' . $this->getCode(); 
    } 
} 
try {
    $num = 10;
    if ($num > 1) {
        throw new getException($num, 404);
    }
} catch (getException $e) {
    echo $e->errorMsg();
}
// php7 异常处理
try {
    test();
} catch (Error $e) {
    echo $e->getMessage(); // Call to undefined function test()
}

14、 intdiv() 对除法结果取整

接收两个参数,返回值为第一个参数除于第二个参数的值并取整.
echo intdiv(9, 3);  // 3
echo intdiv(10, 3); // 3
echo intdiv(5,10);  // 0

15、Session 选项

session_start() 函数可以接收一个数组作为参数,可以覆盖 php.ini 中 session 的配置项。
这个特性也引入了一个新的 php.ini 设置(session.lazy_write), 默认情况下设置为 true,意味着 session 数据只在发生变化时才写入。
除了常规的会话配置指示项, 还可以在此数组中包含 read_and_close 选项。
如果将此选项的值设置为 TRUE, 那么会话文件会在读取完毕之后马上关闭, 因此,可以在会话数据没有变动的时候,避免不必要的文件锁。
实例:
把 cache_limiter 设置为私有的,同时在阅读完 session 后立即关闭。
session_start([
    'cache_limiter'  => 'private',
    'read_and_close' => true
]);

16、废弃特性

一、PHP4 风格的构造函数:
在 PHP4 中类中的函数可以与类名同名,这一特性在 PHP7 中被废弃,同时会发出一个 E_DEPRECATED 错误。
当方法名与类名相同,且类不在命名空间中,同时PHP5的构造函数(__construct)不存在时,会产生一个 E_DEPRECATED 错误。
实例:
class A {
    function A() {
        print('Style Constructor');
    }
}
// Deprecated: Methods with the same name as their class will not be constructors in a future version of PHP; A has a deprecated constructor in...
二、以静态的方式调用非静态方法
class A {
   function b() {
      print('Non-static call');
   }
}
A::b();
// Deprecated: Non-static method A::b() should not be called statically in...
// Non-static call
三、password_hash() 随机因子选项
函数原 salt 量不再需要由开发者提供了。函数内部默认带有 salt 能力,无需开发者提供 salt 值。
四、capture_session_meta SSL 上下文选项
废弃了 "capture_session_meta" SSL 上下文选项。 在流资源上活动的加密相关的元数据可以通过 stream_get_meta_data() 的返回值访问。

17、移除的扩展

ereg
mssql
mysql
sybase_ct

18、移除的 SAPI

aolserver
apache
apache_hooks
apache2filter
caudium
continuity
isapi
milter
nsapi
phttpd
pi3web
roxen
thttpd
tux
webjames

19、其他

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值