PHP7新特性介绍

作者:南丞 时间:2017-12-15 02:28

PHP7新特性介绍

新特性介绍:

  • 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

<?php
$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%

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)

新增的几个操作符

  • <=>
<?php
//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}";;
  • 返回类型的声明
    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 

评论:

回到顶部
回到顶部