PHP7和PHP5区别

本文详细对比了PHP7与PHP5在底层优化、语法变化和性能提升等方面的差异,包括引入抽象语法树(AST)、NativeTLS、类型声明、zval结构优化、异常处理的改变、HashTable和执行器的改进等。PHP7显著提升了运行速度,降低了资源消耗,并通过异常处理增强了错误处理的可控性。此外,还介绍了PHP7的新语法特性,如null合并运算符、太空船操作符和常量数组定义。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

PHP7比PHP5.0 ~ 5.6快了近5倍,同时还降低了对系统资源的占用。主要是PHP7对Zend引擎进行了深度优化。

之前在书上看到过两者比较全面的区别,回头去翻了翻书【眼过千遍,不如手过一遍啊】,特记录如下。

分三个方面来比较:

  • 底层优化
  • 语法变化
  • 性能变化

0、增加抽象语法树(AST)
PHP5:PHP代码在语法解析阶段直接生成opline指令,执行器直接执行opline指令。
PHP7: PHP代码解析生成抽象语法树,然后将抽象语法树编译成opline指令。解耦编译器和执行器。

1、Native TLS(线程局部存储)
PHP5: 通过参数传递的方式传递本线程资源池。容易遗漏、并且及其不优雅。
PHP7: 使用Native TLS来保存线程的资源池。

2、指定函数参数、返回值类型
PHP7: 指定了函数参数和返回值类型。

注意⚠️:如果类型不一致会报error错误。尝试了不太好用,比如int和string不好分,input过来的id=1是string, 代码中是int, 需要手动转换。

3、zval结构的变化。
PHP5: refcount__gc在zval中;zval结构大小24byte。
PHP7: refcount__gc在zval的value中;zval结构大小16byte。

3.1、PHP5 zval结构
定义文件{PHPSRC}/Zend/zend.h

typedef struct _zval_struct {
    zvalue_value value;
    zend_uint refcount__gc;
    zend_uchar type;
    zend_uchar is_ref__gc;
} zval;
 
typedef union _zvalue_value {
    long lval;
    double dval;
    struct {
        char *val;
        int len;
    } str;
    HashTable *ht;
    zend_object_value obj;
} zvalue_value;

3.2、PHP7 zval结构
定义文件{PHPSRC}/Zend/zend_types.h

typedef struct _zval_struct     zval;
struct _zval_struct {
    zend_value        value;            /* value */
    union {
        struct {
            ZEND_ENDIAN_LOHI_3(
                zend_uchar    type,         /* active type */
                zend_uchar    type_flags,
                union {
                    uint16_t  extra;        /* not further specified */
                } u)
        } v;
        uint32_t type_info;
    } u1;
    union {
        uint32_t     next;                 /* hash collision chain */
        uint32_t     cache_slot;           /* cache slot (for RECV_INIT) */
        uint32_t     opline_num;           /* opline number (for FAST_CALL) */
        uint32_t     lineno;               /* line number (for ast nodes) */
        uint32_t     num_args;             /* arguments number for EX(This) */
        uint32_t     fe_pos;               /* foreach position */
        uint32_t     fe_iter_idx;          /* foreach iterator index */
        uint32_t     access_flags;         /* class constant access flags */
        uint32_t     property_guard;       /* single property guard */
        uint32_t     constant_flags;       /* constant flags */
        uint32_t     extra;                /* not further specified */
    } u2;
};
 
typedef union _zend_value {
    zend_long         lval;             /* long value */
    double            dval;             /* double value */
    zend_refcounted  *counted;
    zend_string      *str;
    zend_array       *arr;
    zend_object      *obj;
    zend_resource    *res;
    zend_reference   *ref;
    zend_ast_ref     *ast;
    zval             *zv;
    void             *ptr;
    zend_class_entry *ce;
    zend_function    *func;
    struct {
        uint32_t w1;
        uint32_t w2;
    } ww;
} zend_value;

4、异常处理
PHP7将多数错误改为异常抛出。
PHP5: 调用的方法不存在报error。
PHP7: 可通过try catch捕获,使得错误处理更加可控。

try {
    salmonl();
} catch (Throwable $e) {
    var_dump($e->getMessage);
}
 
// PHP5下运行结果
// <b>Fatal error</b>:  Call to undefined function salmonl() in <b>[...][...]</b> on line <b>3</b><br />
 
// PHP7下运行结果
// <b>Notice</b>:  Undefined property: Error::$getMessage in <b>[...][...]</b> on line <b>5</b><br />

说明:PHP7下是通过Throwable异常类来捕获的,Throwable是父类,Exception类和Error类是子类。

5、HashTable的变化。
PHP5: HashTable结构大小72tye; 数组元素Bucket结构72byte。
PHP7: HashTable结构大小56tye; 数组元素Bucket结构32byte。

6、执行器。
PHP5: 通过执行器的调度函数execute_ex()传递execute_data和opline两个变量。
PHP7: execute_data和opline通过寄存器变量存储。

7、新的参数解析方式。
PHP7: 定义2个宏包裹待解析参数。

8、语法新特性
8.0、null合并运算符

// PHP5
$id = isset($_GET['id']) ? $_GET['id'] : 0;
 
// PHP7
$id = $_GET['id'] ?? 0;

8.1、太空船操作符

// PHP5
usort($datas, function ($a, $b) {
    if ($a['score'] == $b['score']) {
            return 0;
    }
    return ($a['score'] < $b['score']) ? 1 : -1;
});
 
// PHP7
usort($datas, function ($a, $b) {
    return $b['score'] <=> $a['score'];
});

8.2、define定义常量数组

// version >= 5.6
const IT = ['sina', 'baidu', 'tencent'];
echo IT[0];
 
// version >= 7.0
define('IT', ['sina', 'baidu', 'tencent']);
echo IT[0];

多版本在线测试环境:http://sandbox.onlinephpfunctions.com/

参考:
《PHP7内核剖析》
手册:PHP7新特性

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值