PHP được phát triển lần đầu vào năm 1994 và trải qua nhiều giai đoạn. Đến nay PHP đã được nâng cấp lên version 7.x và mang đến sự cải thiện đáng kể về tốc độ cho các ứng dụng web được lập trình với PHP. 

Những tính năng mới trong PHP 7

1. PHP 7 cải thiện tốc độ, tiêu tốn ít bộ nhớ hơn

PHP sau khi được viết lại phần codebase đã giúp tăng response time lên gấp đôi giảm thiêu bộ nhớ server xuống đáng kể. Chi tiết về benchmark cho từng phiên bản PHP bạn có thể xem tại PHP Benchmark

php benchmark

 

2. Thêm tính năng khai báo kiểu trả về (Type Declaration)

Khai báo kiểu được sử dụng để xác định loại biến. PHP tự động thiết lập kiểu trả về do đó, bạn có thể thoải mái sửa đổi giá trị các biến, như thêm Float vào chuỗi mà không gây ra lỗi. Việc khai báo kiểu trả về sẽ giúp bạn có được kết quả mong đợi và do đó hạn chế phát sinh lỗi và làm cho mã dễ hiểu hơn.

Trong các phiên bản PHP trước, chúng ta có thể sử dụng phương thức gợi ý kiểu. Bạn khai báo kiểu trả về ở tham số trong hàm. Nhưng vấn đề với phương pháp này là bạn chỉ có thể sử dụng nó trong khai báo hàm và giới hạn chỉ có hai kiểu dữ liệu: tên lớp và mảng.

<?php
function sendMail(Sender $sender, array $receiverList) { 
	foreach ($receiverList as $mail) { 
		echo "Send From " . $sender->fromName . " to " . $mail; 
	} 
} 
sendMail("eCode",array("contact@hoclaptrinhweb.org", "robert@hoclaptrinhweb.org"));
//FATAL ERROR Uncaught TypeError: Argument 1 passed to sendMail() must be an instance of Sender, string given

 Để sửa lỗi này bạn cần viết lại thành:

sendMail($sender, array("contact@hoclaptrinhweb.org", "robert@hoclaptrinhweb.org"));

($sender là một object)

Scalar Type Hints

 Với PHP 7 chúng ta có thể khai báo nhiều loại dữ liệu hơn trong tham số của hàm, cụ thể ở đây là int, float, string và bool

Bằng cách thêm scalar type hints và kích hoạt strict mode, mỗi khi tham số nhận vào không đúng kiểu dữ liệu bạn sẽ nhận được 1 exception. Điều này giúp cho developer quản lý code chặt chẽ hơn và làm cho code dễ đọc hơn. Chúng ta cùng xem qua ví dụ sau:

function total(float $a, float $b) {
    return $a + $b;
}
total(2.8, "3.2");
// string "3.2" được chuyển thành float(3.2), không có thông báo lỗi
//returns float(6)

total(2, "1 week"); 
// int(2) changed to float(2.0) và string “1 week” được chuyển thành float(1.0) nhưng bạn sẽ nhận được 1 thông báo “Notice: A non well formed numeric value encountered”
//returns float(3)

 Trong trường hợp kiểu dữ liệu bạn truyền vào không đúng bạn sẽ nhận được 1 "Fatar Error" nếu như strict mode là ON

declare(strict_types=1);
function total(float $a, float $b) {
      return $a + $b;
 }
total(2, "1 week");
// Fatal error: Uncaught TypeError: Argument 2 passed to total() must be of the type float, string given
total(2.5, 1);
// int(1) chuyển thành float(1.0)
//returns float(3.5)

 Khai báo kiểu dữ liệu trả về (Return Type Declarations)

Tương tự như khi khai báo kiểu dữ liệu cho tham số bạn có thể khai báo kiểu dữ liệu trả về cho hàm, PHP 7 cũng hỗ trợ các kiểu dữ liệu tương tự như trên.

function total(float $a, float $b) : float {}

 2. Toán tử mới: spaceship và null coalesce

Spaceship operator:

Toán tử spaceship sẽ kiểm tra nếu 2 giá trị bằng nhau nó sẽ trả về 0, nếu giá trị bên trái nhỏ hơn giá trị bên phải, trả về -1, còn giá trị bên trái lớn hơn bên phải nó sẽ trả về 1

$compare = 2 <=> 1
2 < 1? return -1
2 = 1? return 0
2 > 1? return 1

 Null Coalesce Operator

Null Coalesce được sử dụng khi bạn muốn kiểm tra một giá trị có phải là NULL hay không, toán tử này sẽ trả về giá trị bên trái nếu nó không phải NULL, ngược lại nó sẽ trả về bên phải

$username = $_GET['user'] ?? 'nobody'

 Toán tử này còn thế dùng với nhiều giá trị, trong ví dụ sau nó sẽ kiểm tra từ trái qua phải xem giá trị nào không NULL thì nó sẽ lấy giá trị đó

$name = $firstName ?? $username ?? $lastname ?? “Guest”;

 3. Khai báo mảng hằng số dùng define()

Trong PHP 7 bạn có thể khai báo một hằng số là mảng trong hàm define()

define('NAME', array('Teo', 'Ti', 'Bin'));
echo NAME[1]; // outputs "Ti"

 4. Error Handling

Fatal Error là lỗi rất phổ biến trong PHP5, khi gặp lỗi này biên dịch buộc phải dừng việc biên dịch lại. Đôi khi nó còn xuất hiện màn hình trắng xoá rất dễ gây nhầm lẫn tới người dùng. Trong PHP 7, xử lí ngoại lệ được cải thiện, một exception sẽ sinh ra khi lỗi Fatal xảy ra, trong PHP 5 thì nó chỉ dừng chương trình lại thôi còn PHP 7 ngoài việc dừng chương trình nó còn sản sinh ra exception. Điều này đồng nghĩa với việc giờ đây bạn có thể xử lý Fatar error trong try catch block

<?php
/**
 * Throwable interface
 */


//Error as Throwable
try {
    blablafunction();
} catch (Throwable $t) {
    echo "Throwable: ".$t->getMessage().PHP_EOL;
}

//Exception as Throwable
try {
    throw new Exception("Bla");
} catch (Throwable $t) {
    echo "Throwable: ".$t->getMessage().PHP_EOL;
}

//Error
try {
    sqdf();
} catch (Error $e) {
    echo "Error: ".$e->getMessage().PHP_EOL;
} catch (Exception $e) {
    echo "Exception: ".$e->getMessage().PHP_EOL;
}

//Exception
try {
    throw new Exception("Bla");
} catch (Error $e) {
    echo "Error: ".$e->getMessage().PHP_EOL;
} catch (Exception $e) {
    echo "Exception: ".$e->getMessage().PHP_EOL;
}

//Type error
try {
    function add(int $a, int $b):int {
        return $a + $b;
    }
    echo add(array(), array());
} catch (TypeError $t) {
    echo "Type error: ".$t->getMessage().PHP_EOL;
}

 5. Anonymous class

PHP 7 cho phép bạn sử dụng các class ẩn danh (anonymous), đây là một đặc trưng đã có trong những ngôn ngữ lập trình hướng đối tượng khác như C# và Java. Một class anonymous là một class không có tên. Đối tượng mà nó khởi tạo có cùng chức năng như một đối tượng của một lớp có tên.

Một class ẩn danh có thể được sử dụng với một tên class:

  • Khi class đó không được dùng để ghi dữ liệu
  • Khi class đó chỉ được dùng 1 lần trong suốt quá trình thực thi

Một class ẩn danh là một class mà không có tên với các chức năng không có gì khác biệt so với các class có tên, chúng được sử dụng cú pháp của class nhưng khuyết tên như sau:

(new class[, arguments] [extends] [implements] {
  // include traits
  // methods
});

 Class ẩn danh vẫn có hàm khởi tạo (constructor), nó cũng có thể kế thừa các class và interface như một class thông thường. Dưới đây là 1 ví dụ đơn giản về cách sử dụng class ẩn danh để ghi log khi phát sinh lỗi

// Simple error interface
interface ErrorInterface {
  public abstract function showError($msg);
}

// Class containing users based operations
class User {
  
  protected $error;
  
  public function setErrorInterface(ErrorInterface $error) {
    $this->error = $error;
  }

  public function createUser($user) {
    if ($user) {
      echo 'User Cretaed ' . PHP_EOL;
    } else {
      $this->error->showError('Cannot create user..!!!');
    }
  }
}

$userObj = new User();

$userObj->setErrorInterface(
  // Create and pass the anonymous class.
  new class() implements ErrorInterface {
    public function showError($msg) {
      // Send some headers and set other info's
      echo 'Error: ' . $msg . PHP_EOL;
    }
  }
);

// Error will be showed
$userObj->createUser(null);
// This will display user created.
$userObj->createUser('Foo');

 6. Namespace sử dụng group

Đây là 1 tính năng mới trong php 7 nhằm giúp nhà phát triển tránh việc phải khai báo quá nhiều namespace cùng nhóm bằng từ khóa use

Cú pháp khai báo như sau

use some/namespace/{class1, class2, class3 as C3};

 Ví dụ:

namespace ECodeClasses;

interface Class1 {
}

interface Class2 {
}

interface Class3 {
}

namespace ECodeClass;

use EcodeClass{Class1, Class2, Class3 as C3};

class App implements Class1, Class2, C3 {
  
}

 7. Phương thức Closure::call()

Phương thức call() cho closures được dùng như là một cách viết tắt khi gọi một closure khi lấy phạm vị đối tượng tham chiếu tới nó. Điều này làm cho code nhỏ gọn hơn, loại bỏ sự tạo ra yếu tố trung gian trước khi gọi nó.

class A {private $x = 1;}

// trước PHP 7
$getXCB = function() {return $this->x;};
$getX = $getXCB->bindTo(new A, 'A'); // intermediate closure
echo $getX(); // 1

// PHP 7+ code
$getX = function() {return $this->x;};
echo $getX->call(new A); // 1