PHP7新特性的介绍

截止到目前为止,PHP官方已经发布了php7的RC7版本,距离发布第一个正式版本不会很远了!现在来说php7的重大特性肯定已经是定型了,不会再有什么变动了。后续一些版本的迭代主要也就是修修bug,优化之类的。下面就来说话我们一直期待的php7会有那些主要的变化了。。。

关于PHP

  • 20年的发展历史;

  • 迄今为止最流行的WEB开发语言;

  • 超过82%的网站都会使用PHP作为他们的服务端开发语言;

新特性介绍

  • PHP NG – Zend Engine 3

  • 抽象语法树

  • 64位的 INT 支持

  • 统一的变量语法

  • 新增Closure::call()

  • 一致性foreach循环

  • 匿名类的支持

  • 新增 <=>**??\u{xxxx}操作符

  • 增加了返回类型的声明

  • 增加了标量类型的声明

  • 核心错误可以通过异常捕获

  • 增加了上下文敏感的词法分析

PHP NG

  • ZVAL

大小从24字节减少到16字节

  • Zend Array(HashTable)

HashTable大小从72字节减少到56字节
HashTable bucket大小从72字节减少到32字节

  • 函数调用的优化

  • 使用了新的内存分配,管理方式,减少了内存的浪费

  • Immutable array optimization

    $arr = [];
    
    for($i=0; $i<100000; $i++) {
        $arr[] = ['php'];
    }
    
    p(memory_get_usage(true));

PHP5: 45M
PHP7: 10M

  • 一些非常常用,开销不大的的函数直接变成了引擎支持的opcode

call_user_function(_array) => ZEND_INIT_USER_CALL
is_intis_stringis_array、... => ZEND_TYPE_CHECK
strlen => ZEND_STRLEN
defined => ZEND+DEFINED

  • 核心排序的优化

PHP5(zend_qsort
快速排序(非稳定排序)

array(1 => 0, 0 => 0)

PHP7(zend_sort
快速排序+选择排序(稳定排序)

array(0 => 0, 1 => 0)

小于16个元素的使用选择排序,大于16个按照16个为单位去分割,分别使用选择排序,然后再全部合起来使用快速排序。排序较之前相比,内部元素由非稳定排序变成稳定排序,减少元素的交换次数,减少对内存的操作次数,性能提升40%

抽象语法树

clipboard.png

假如现在我们有这样的需求,要对php源文件就行语法检测,实现编码规范。php5之前的话,没有AST,直接从parser就生成了opcodes!就需要借助一些外部的php语法解析器来实现;而php7增加了AST,我们可以自己去实现这样一个扩展,利用扩展提供的函数可以直接获取文件对应的的AST结构,而这样的结构正是我们可以识别的,所以就可以在这个基础上去做一些优化和判断了。

64位的INT支持

  • 支持存储大于2GB的字符串

  • 支持上传大小大于2GB的文件

  • 保证字符串在所有平台上【64位】都是64bit

统一的语法变量

$$foo['bar']['baz'] 

PHP5: ${$foo[‘bar’]['baz']}
PHP7: ($$foo)[‘bar’][‘baz']【从左至右法则】

(function() {})();
$foo()();
[$obj, 'method']();

class A {
    public static function a1() {}
}

[new A, 'a1']();

新增Closure::call()

$f = function() {
    p($this->name);
};

class F {
    private $name = 'F';
}

$f->call(new F);

匿名类的支持

function getAnonymousClass($config) {
    return new class(config) {};
 }

p(getAnonymousClass(array()));

一致性的foreach循环

//PHP5
$a =  array(1, 2, 3);foreach ($a as $v){var_dump(current($a));}
int(2)
int(2)
int(2)

$a =  array(1, 2, 3);$b=&$a;foreach ($a as $v){var_dump(current($a));}
int(2)
int(3)
bool(false)

$a =  array(1, 2, 3);$b=$a;foreach ($a as $v){var_dump(current($a));}
int(1)
int(1)
int(1)

//PHP7:不再操作数据的内部指针了
$a =  array(1, 2, 3);foreach ($a as $v){var_dump(current($a))}
int(1)
int(1)
int(1)

$a =  array(1, 2, 3);$b=&$a;foreach ($a as $v){var_dump(current($a))
int(1)
int(1)
int(1)

$a =  array(1, 2, 3);$b=$a;foreach ($a as $v){var_dump(current($a))}
int(1)
int(1)
int(1)

新增的几个操作符

<=>

//PHP5
function compare($a, $b) {
    return ($a < $b) ? -1 : (($a >$b) ? 1 : 0);
}
//PHP7
function compare($a, $b) {
    return $a <=> $b;
}

**

2 ** 2; // 2 * 2 = 4
2 ** -1; // 1 / 2 = 0.5
3 ** -2; // 1 / 9 = 0.111111111

??

$a = null;
$b = 1;
$c = 2;
echo $a ?? $b , ‘,’ , $c ?? $b; // 1,2
echo $a ?? $b ?? $c  , ‘,’ , $a ?? $d ?? $c; // 1,2

\u{xxxx}

echo "\u{4f60}";//你
echo "\u{65b0}";//新
// 从右至左强制
echo"\u{202E}iabgnay\u{1F602}";;
? yangbai

返回类型的声明

function getInt() : int {
    return 'test';
}; 

getInt();

//返回值为DateTime的函数
function getDateTime() : DateTime {
    return new DateTime();
}; 

标量类型的声明

function getAmount(int $num) : int {
    return $num;
}; 

getAmount('test');

//PHP5
#PHP Catchable fatal error:  Argument 1 passed to getInt() must be an instance of int, string given…

//PHP7
#Fatal error: Uncaught TypeError: Argument 1 passed to getInt() must be of the type integer, string given…

getAmount('123');
#PHP7新增的严格模式选项开启下也会报错【declare(strict_types=1),注意要放到代码的第一行】

核心错误可以通过异常捕获了

try {
    non_exists_func();
} catch(EngineException $e) {
    echo "Exception: {$e->getMessage();}\n";
} finally {
    echo "undefined function…";
}

//这里用php7试了一下没有捕获成功【但是确实抛出了异常】。。。
#Exception: Call to undefined function non_exists_func()

上下问敏感的词法分析

//PHP5
class Collection {public function foreach($arr) {}}
#Parse error:  parse error, expecting `"identifier (T_STRING)”’...

//PHP7
class Collection {
    public function foreach($arr) {
        return $this;
    }
    public function in($arr){
        return $this;
    }
    public function sort($condition){
        return $this;
    }
    public function echo($condition){
        return 'ok';
    }
}
$collection = new Collection();
$collection->in()->foreach()->sort()->echo();

打破的一些东西

  • mysql、ereg

mysql 移到了 ext/pecl 中去了,ereg 移到了 ext/pcre

  • isapi、tux etc SAPIs

  •  <?和<? language=“php”这样的标签被移除了

  • HTTP_RAW_POST_DATA移除了(可以使用php://input替代)

  • $o = & new className(),不再支持这样的写法

  • mktime()gmmktime() 函数的$is_dst 参数被移除了

  • setlocale()函数的$category参数不支持字符串了,必须是LC开头的常量

  • php.ini文件移除了#作为注释,统一用;去注释

  • 函数定义同名参数不支持了

  • 类的同名构造函数不推荐(目前没有移除,后续会去掉)

  • Stringintfloat等这些关键字不能被作为类、接口、trait的名称使用了

  • func_get_arg/func_get_args获取的是当前变量的值

  • 无效的八进制数字会产生编译错误

  • preg_replace()不再支持匹配模式/e

  • 16进制的字符串数字转换被移除了

  • 不再支持静态调用一个不兼容的$this上下文的非静态调用

  • Unsafe curl file uploads (use CurlFile instead)

    //PHP5
    curl_setopt(ch, CURLOPT_POSTFIELDS, array(
        'file' => '@'.realpath('image.png'), 
    )); 
    
    //PHP7
    curl_setopt(ch, CURLOPT_POSTFIELDS, [
        'file' => new CURLFile(realpath('image.png')), 
    ]); 
    
  • 一些移除的函数和选项

    set_magic_quotes_runtime();
    magic_quotes_runtime();
    
    //(use stream_set_blocking() instead)
    set_socket_blocking();
    
    //(use mcrypt_generic_deinit() instead)
    mcrypt_generic_end();
    
    //(use mcrypt_encrypt() and mcrypt_decrypt() instead)
    mcrypt_ecb();
    mcrypt_cbc();
    mcrypt_cfb();
    mcrypt_ofb();
    
    //(use datefmt_set_timezone() or IntlDateFormatter::setTimeZone() instead)
    datefmt_set_timezone_id();
    IntlDateFormatter::setTimeZoneID();
    
    //(use XsltProcessor::setSecurityPrefs() instead)
    xsl.security_prefs;//php.ini 
    
    //(use php.input_encoding、php.internal_encoding and php.output_encoding instead)
    iconv.input_encoding;
    iconv.output_encoding;
    iconv.internal_encoding;
    mbstring.http_input;
    mbstring.http_output;
    mbstring.internal_encoding;
    
    (use PDO::ATTR_EMULATE_PREPARES instead)
    PDO::PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT;//driver option 
     
    //(use peer_name instead)
    CN_match;//SSL context options 
    SNI_server_name;//SSL context options 
    

差不多了,夜已深、人已困!
更多、更详细的介绍请猛戳 这里


yangbai
如果非要用一种东西来记录我得生命历程,我会用朋友!

良好的心里,出众的发挥!

2.8k 声望
43 粉丝
0 条评论
推荐阅读
利用Charles做代理测试电脑上写的H5页面
做H5页面的同学可能经常会遇到一个场景,就是电脑上调试好的页面怎么在手机上访问测试呢? 下面就介绍一种自己经常使用的方式,利用Charles代理软件来实现! 安装Charles 直接去官网下载对应的系统版本安装即可。...

杨佰2阅读 5.8k

怎样用 PHP 来实现枚举?
在数学和计算机科学理论中,一个集的枚举是列出某些有穷序列集的所有成员的程序,或者是一种特定类型对象的计数。这两种类型经常(但不总是)重叠。枚举是一个被命名的整型常数的集合,枚举在日常生活中很常见,...

唯一丶25阅读 6.7k评论 4

PHP转Go实践:xjson解析神器「开源工具集」
我和劲仔都是PHP转Go,身边越来越多做PHP的朋友也逐渐在用Go进行重构,重构过程中,会发现php的json解析操作(系列化与反序列化)是真的香,弱类型语言的各种隐式类型转换,很大程度的减低了程序的复杂度。

王中阳Go11阅读 2.7k评论 4

封面图
Git操作不规范,战友提刀来相见!
年终奖都没了,还要扣我绩效,门都没有,哈哈。这波骚Git操作我也是第一次用,担心闪了腰,所以不仅做了备份,也做了笔记,分享给大家。问题描述小A和我在同时开发一个功能模块,他在优化之前的代码逻辑,我在开...

王中阳Go6阅读 2.9k评论 4

封面图
图片防盗链破解 解决图片防盗链问题 反向代理
当客户端(浏览器)向服务器请求内容的时候,会提交一个header,这个header中包含了如:浏览器信息、cookie等内容,那么有一个叫referer的东东,也包含在这里面。

TANKING7阅读 11.7k评论 5

Hyperf 3.0 发布,PHP 新时代
在过去的一年半时间里,Hyperf 2.2 共发布了 35 个小版本,使 Hyperf 达到了一个前所未有的高度,这里也获得了一些不错的数据反馈。

huangzhhui4阅读 1.5k评论 1

封面图
微信公众号开发:自动回复文本/图片/图文消息/关键词回复/上传素材/自定义菜单
对接流程1、申请微信公众号测试账号URL:[链接]2、登录,配置开发者服务器URL和Token开发者服务器配置代码:config.php {代码...} URL是config.php在你服务器的URLToken是上面代码自己设置的Token搞定之后,就能完...

TANKING2阅读 10.6k

良好的心里,出众的发挥!

2.8k 声望
43 粉丝
宣传栏