zoukankan      html  css  js  c++  java
  • 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%

      抽象语法树

      假如现在我们有这样的需求,要对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}iabgnayu{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();}
      ";
      } 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 
        
  • 相关阅读:
    JVM学习笔记之认识JDK(一)
    C#发送邮件异常:根据验证过程,远程证书无效
    windows下使用mysql双机热备功能
    批处理实现mysql的备份
    WebApi FormData+文件长传 异步+同步实现
    Oracle中已知字段名查询所在的表名
    mstsc遇到CredSSP加密Oracle修正
    使用subgit进行svn迁移至git(branch,tags)
    使用guava进行对字符串的加锁
    使用spring-data-solr做solr客户端
  • 原文地址:https://www.cnblogs.com/chunguang/p/5538522.html
Copyright © 2011-2022 走看看