PHP7新特性小結

說明

PHP 7使用新的Zend Engine 3.0將應用程序性能提升近兩倍,內存消耗比PHP 5.6高出50%。它容許服務更多的併發用戶,而不須要任何額外的硬件。PHP 7是考慮到今天的工做負載而設計和重構的。php

PHP新功能總結

  • 改進的性能 - 將PHPNG代碼合併到PHP7中,速度是PHP 5的兩倍。
  • 下降內存消耗 - 優化的PHP 7使用較少的資源。
  • 標量類型聲明 - 如今能夠強制執行參數和返回類型。
  • 一致的64位支持 - 對64位體系結構機器的一致支持。
  • 改進了異常層次 - 異常層次獲得了改進
  • 許多致命的錯誤轉換爲例外 - 例外範圍增長,涵蓋許多致命的錯誤轉換爲例外。
  • 安全隨機數發生器 - 增長新的安全隨機數發生器API。
  • 已棄用的SAPI和擴展已刪除 - 各類舊的和不受支持的SAPI和擴展從最新版本中刪除。
  • 空合併運算符(?) - 添加了新的空合併運算符。
  • 返回和標量類型聲明 - 支持所添加的返回類型和參數類型。
  • 匿名類 - 支持匿名添加。
  • 零成本斷言 - 支持零成本斷言增長。

標量類型聲明

在PHP 7中,引入了一個新的特性,即標量類型聲明。標量類型聲明有兩個選項數組

  • 強制 - 強制是默認模式,不須要指定。
  • 嚴格 - 嚴格的模式已經明確暗示。

功能參數的如下類型可使用上述模式強制執行安全

  • float
  • int
  • bool
  • string
  • interfaces
  • array
  • callable
強制模式
<?php
   // Coercive mode
   function sum(int ...$ints) {
      return array_sum($ints);
   }
   print(sum(2, '3', 4.1)); //9
?>
嚴格模式
<?php
   // Strict mode
   declare(strict_types=1);
   function sum(int ...$ints) {
      return array_sum($ints);
   }
   print(sum(2, '3', 4.1)); //Fatal error: Uncaught TypeError: Argument 2 passed to sum() must be of the type integer, string given, ...
?>

返回類型聲明

有效的返回類型
<?php
   declare(strict_types = 1);
   function returnIntValue(int $value): int {
      return $value;
   }
   print(returnIntValue(5));
?>
無效返回類型
<?php
   declare(strict_types = 1);
   function returnIntValue(int $value): int {
      return $value + 1.0;
   }
   print(returnIntValue(5));//Fatal error: Uncaught TypeError: Return value of returnIntValue() must be of the type integer, float returned.
?>

空合併運算符

在PHP 7中,引入了一個新的特性,即空合併運算符(??)。它用來替代與isset()函數結合的三元操做。該空若是它存在,而不是空合併運算符返回第一個操做數; 不然返回第二個操做數。session

<?php
   // fetch the value of $_GET['user'] and returns 'not passed'
   // if username is not passed
   $username = $_GET['username'] ?? 'not passed';
   print($username);
   print("<br/>");

   // Equivalent code using ternary operator
   $username = isset($_GET['username']) ? $_GET['username'] : 'not passed';
   print($username);
   print("<br/>");
   // Chaining ?? operation
   $username = $_GET['username'] ?? $_POST['username'] ?? 'not passed';
   print($username);

   // output
   //not passed
?>

飛船運算符

它用來比較兩個表達式。當第一個表達式分別小於,等於或大於第二個表達式時,它返回-1,0或1。字符串比較ASCII閉包

//integer comparison
   print( 1 <=> 1);print("<br/>");
   print( 1 <=> 2);print("<br/>");
   print( 2 <=> 1);print("<br/>");

// output
    0
    -1
    1

常量數組

使用define()函數定義數組常量。在PHP 5.6中,只能使用const關鍵字來定義它們。併發

<?php
//define a array using define function
   define('animals', [
      'dog',
      'cat',
      'bird'
   ]);
   print(animals[1]);
// output
    cat  
?>

匿名類

如今可使用新類來定義匿名類。匿名類能夠用來代替完整的類定義。app

<?php
   interface Logger {
      public function log(string $msg);
   }

   class Application {
      private $logger;

      public function getLogger(): Logger {
         return $this->logger;
      }

      public function setLogger(Logger $logger) {
         $this->logger = $logger;
      }  
   }

   $app = new Application;
   $app->setLogger(new class implements Logger {
      public function log(string $msg) {
         print($msg);
      }
   });

   $app->getLogger()->log("My first Log Message");
?>

//output

My first Log Message

Closure類

Closure :: call()方法被添加爲一個簡短的方式來臨時綁定一個對象做用域到一個閉包並調用它。與PHP5的bindTo相比,它的性能要快得多。dom

在PHP 7以前
<?php
   class A {
      private $x = 1;
   }

   // Define a closure Pre PHP 7 code
   $getValue = function() {
      return $this->x;
   };

   // Bind a clousure
   $value = $getValue->bindTo(new A, 'A');

   print($value());
   //output
   1
?>
PHP 7+
<?php
   class A {
      private $x = 1;
   }

   // PHP 7+ code, Define
   $value = function() {
      return $this->x;
   };

   print($value->call(new A));
   //output
   1
?>

過濾unserialize

PHP 7引入了過濾的unserialize()函數,以便在對不可信數據上的對象進行反序列化時提供更好的安全性。它能夠防止可能的代碼注入,並使開發人員可以對能夠反序列化的類進行白名單。函數

<?php
   class MyClass1 {
      public $obj1prop;   
   }
   class MyClass2 {
      public $obj2prop;
   }

   $obj1 = new MyClass1();
   $obj1->obj1prop = 1;
   $obj2 = new MyClass2();
   $obj2->obj2prop = 2;

   $serializedObj1 = serialize($obj1);
   $serializedObj2 = serialize($obj2);

   // default behaviour that accepts all classes
   // second argument can be ommited.
   // if allowed_classes is passed as false, unserialize converts all objects into __PHP_Incomplete_Class object
   $data = unserialize($serializedObj1 , ["allowed_classes" => true]);

   // converts all objects into __PHP_Incomplete_Class object except those of MyClass1 and MyClass2
   $data2 = unserialize($serializedObj2 , ["allowed_classes" => ["MyClass1", "MyClass2"]]);

   print($data->obj1prop);
   print("<br/>");
   print($data2->obj2prop);

   //output
   1
   2
?>

IntlChar

在PHP7中,增長了一個新的IntlChar類,它試圖揭示額外的ICU功能。這個類定義了一些靜態方法和常量,能夠用來處理Unicode字符。在使用這個課程以前,你須要安裝Intl擴展。性能

<?php
   printf('%x', IntlChar::CODEPOINT_MAX);
   print (IntlChar::charName('@'));
   print(IntlChar::ispunct('!'));

   //output
   10ffff
   COMMERCIAL AT
   true
?>

CSPRNG

在PHP 7中,引入了兩個新的函數來以跨平臺的方式生成密碼安全的整數和字符串。

  • random_bytes() - 生成密碼安全的僞隨機字節。
  • random_int() - 生成密碼安全的僞隨機整數。
<?php
   $bytes = random_bytes(5);
   print(bin2hex($bytes));

   //output
   54cc305593

  print(random_int(100, 999));
  print("");
  print(random_int(-1000, 0));

  //output
  614
  -882
?>

使用聲明

從PHP7開始,可使用單個use語句從相同的命名空間導入類,函數和常量,而不是使用多個use語句。

<?php
   // Before PHP 7
   use com\tutorialspoint\ClassA;
   use com\tutorialspoint\ClassB;
   use com\tutorialspoint\ClassC as C;

   use function com\tutorialspoint\fn_a;
   use function com\tutorialspoint\fn_b;
   use function com\tutorialspoint\fn_c;

   use const com\tutorialspoint\ConstA;
   use const com\tutorialspoint\ConstB;
   use const com\tutorialspoint\ConstC;

   // PHP 7+ code
   use com\tutorialspoint\{ClassA, ClassB, ClassC as C};
   use function com\tutorialspoint\{fn_a, fn_b, fn_c};
   use const com\tutorialspoint\{ConstA, ConstB, ConstC};

?>

整數部分

PHP 7引入了一個新的函數intdiv(),它對它的操做數進行整數除法,並將除法運算返回爲int。

<?php
   $value = intdiv(10,3);
   var_dump($value);
   print(" ");
   print($value);

   //output
   int(3)
   3
?>

會話選項

session_start()函數接受來自PHP7 + 的一系列選項來覆蓋php.ini中設置的會話配置指令。這些選項支持session.lazy_write,默認狀況下,它會致使PHP在會話數據發生更改時覆蓋任何會話文件。

添加的另外一個選項是read_and_close,它表示應該讀取會話數據,而後應該當即關閉會話。例如,將session.cache_limiter設置爲private,並使用如下代碼片斷將標誌設置爲在讀取完畢後當即關閉會話。

<?php
   session_start([
      'cache_limiter' => 'private',
      'read_and_close' => true,
   ]);
?>

棄用

PHP 4樣式構造函數是與它們定義的類具備相同名稱的方法,如今已被棄用,而且未來將被刪除。若是PHP 4的構造函數是類中定義的惟一構造函數,則PHP 7將發出E_DEPRECATED。實現__construct()方法的類不受影響。
<?php
   class A {
      function A() {
         print('Style Constructor');
      }
   }
?>
對非靜態方法的靜態調用已被棄用,並可能在未來被刪除
<?php
   class A {
      function b() {
         print('Non-static call');
      }
   }
   A::b();
   // Deprecated: Non-static method A::b() should not be called statically in...Non-static call
?>
password_hash()函數的salt選項已被棄用,因此開發人員不會生成本身的(一般是不安全的)鹽。當開發人員不提供鹽時,函數自己會生成密碼安全的鹽,所以再也不須要定製鹽的生成。
該capture_session_meta SSL上下文選項已被棄用。SSL元數據如今經過stream_get_meta_data()函數使用。

錯誤處理

從PHP 7開始,錯誤處理和報告已經改變。而不是經過PHP 5使用的傳統錯誤報告機制來報告錯誤,如今大多數錯誤都是經過拋出錯誤異常來處理的。與異常相似,這些錯誤異常會一直冒泡,直到它們到達第一個匹配的catch塊。若是沒有匹配的塊,則使用set_exception_handler()安裝的默認異常處理程序將被調用。若是沒有默認的異常處理程序,那麼異常將被轉換爲致命錯誤,並將像傳統的錯誤同樣處理。

因爲錯誤層次結構不是從Exception擴展的,因此使用catch(Exception $ e){...}塊來處理PHP 5中未捕獲的異常的代碼將不會處理這樣的錯誤。catch(Error $ e){...}塊或set_exception_handler()處理程序是處理致命錯誤所必需的。

<?php
   class MathOperations {
      protected $n = 10;

      // Try to get the Division by Zero error object and display as Exception
      public function doOperation(): string {
         try {
            $value = $this->n % 0;
            return $value;
         } catch (DivisionByZeroError $e) {
            return $e->getMessage();
         }
      }
   }

   $mathOperationsObj = new MathOperations();
   print($mathOperationsObj->doOperation());

   // output
   Modulo by zero
?>

結尾說明

2017已經接近尾聲,嶄新的2018即未來臨,在這個知識突飛猛進的時代,溫故而知新。script maker!
相關文章
相關標籤/搜索