截止到目前为止,PHP官方已经发布了php7的RC7版本,距离发布第一个正式版本不会很远了!现在来说php7的重大特性肯定已经是定型了,不会再有什么变动了。后续一些版本的迭代主要也就是修修bug,优化之类的。下面就来说话我们一直期待的php7会有那些主要的变化了。。。
转自:http://segmentfault.com/a/1190000003893899?utm_source=APP&utm_medium=iOS&utm_campaign=socialShare
关于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_int
、is_string
、is_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%
抽象语法树
假如现在我们有这样的需求,要对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文件移除了#作为注释,统一用;去注释
-
函数定义同名参数不支持了
-
类的同名构造函数不推荐(目前没有移除,后续会去掉)
-
String
,int
,float
等这些关键字不能被作为类、接口、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
差不多了,夜已深、人已困!
更多、更详细的介绍请猛戳 这里