Hướng dẫn dùng parseerror trong PHP

Trong bài này, chúng ta sẽ tìm hiểu về các loại lỗi [error] trong PHP. Để học tốt bài này, các bạn cần đọc lại bài Cài đặt môi trường lập trình Web PHP với XAMPP để biết cách chạy ứng dụng web PHP với XAMPP.

Lỗi [error] là các vấn đề hoặc tình trạng bất thường, ảnh hưởng nghiêm trọng đến chương trình. Khi xảy ra lỗi, chương trình thường sẽ ngừng thực thi. Có 4 loại lỗi cơ bản trong PHP là:

    • Parse error hoặc Syntax error
    • Fatal error
    • Warning error
    • Notice error

1. Syntax error trong PHP

Syntax error hoặc Parse error còn gọi là lỗi cú pháp. Lỗi này xảy ra là do chúng ta không tuân thủ cú pháp của PHP khi soạn thảo chương trình. Các syntax error thường mắc phải như lỗi thiếu hoặc thừa dấu ngoặc, thiếu dấu chấm phẩy,… Lỗi cú pháp được phát hiện bởi trình thông dịch PHP [PHP interpreter].

Ví dụ lỗi cú pháp trong PHP


Trong ví dụ trên, câu lệnh gán giá trị cho biến $x thiếu dấu chấm phẩy ; nên gây ra lỗi cú pháp. Bên dưới là một số ví dụ syntax error khác.


2. Fatal error trong PHP

Fatal error xảy ra khi chúng ta gọi một hàm chưa được định nghĩa. Ví dụ:


Kết quả
sum = 20
Fatal error: Uncaught Error: Call to undefined function diff[]

3. Warning error trong PHP

Warning error là một cảnh báo và không dừng thực thi chương trình. Warning error thường xảy ra khi include hoặc require một file không tồn tại. Ví dụ:


Kết quả
Warning: include[gochocit.php]: Failed to open stream: No such file or directory in C:\xampp\htdocs\gochocit\index.php on line 3
Hello all!

4. Notice error trong PHP

Notice error tương tự như Warning error. Notice error thông báo chương trình có một vấn đề nào đó nhưng vẫn cho phép thực thi script PHP.


5. Error constants trong PHP

Bên dưới là những error constant được định nghĩa sẵn trong PHP.

Giá trịHằngÝ nghĩa1E_ERRORMột fatal error sẽ làm dừng chương trình2E_WARNINGNhững warning sẽ không làm dừng chương trình4E_PARSELỗi khi phân tích cú pháp8E_NOTICENotice error và chương trình có thể chạy bình thường16E_CORE_ERRORFatal error xảy ra khi PHP mới khởi chạy. Lỗi này liên quan đến core PHP32E_CORE_WARNINGGiống E_WARNING nhưng liên quan đến core PHP64E_COMPILE_ERRORGiống E_ERROR nhưng được tạo ra bởi Zend Scripting Engine128E_COMPILE_WARNINGGiống E_WARNING nhưng được tạo ra bởi Zend Scripting Engine32767E_ALLTất cả PHP errors và warnings

Mỗi error trong PHP được đánh một giá trị [value] lỗi. Nó giống như mã lỗi, giúp dễ dàng xác định lỗi đang xảy ra là lỗi gì.

Ngoài những error constant ở trên, PHP còn nhiều error constant khác. Các bạn có thể tham khảo thêm ở Errors and Logging Constants.

PHP hiện tại có khoảng 64 từ dành riêng. Một số trong số chúng được hiểu như là các hàm hay là hằng số. Với những phiên bản PHP trước kia thì bạn không thể nào dùng một trong những bất kì từ nào trong số đó để đặt tên cho hằng số, tên lớp, tên hàm hay tên phương thức. Dùng chúng là tên biến thì nói chung là được tuy nhiên nó dễ gây ra sự nhầm lẫn. Tuy nhiên sang đến phiên bản PHP 7 thì bạn có thể dùng một cách linh hoạt hơn với những hàm có tên như trong danh sách trên. Ví dụ với phiên bản PHP 5x nếu như dùng:

class Collection {
    public function forEach[callable $callback] { /* */ }
    public function list[] { /* */ }
}

PHP sẽ bắn ra lỗi

class Collection extends \ArrayAccess, \Countable, \IteratorAggregate {

    public function forEach[callable $callback] {
        //...
    }

    public function list[] {
        //...
    }

    public static function new[array $itens] {
        return new self[$itens];
    }
}

Collection::new[['foo', 'bar']]->forEach[function[$index, $item]{
  /* callback */
}]->list[];
6

class Collection extends \ArrayAccess, \Countable, \IteratorAggregate {

    public function forEach[callable $callback] {
        //...
    }

    public function list[] {
        //...
    }

    public static function new[array $itens] {
        return new self[$itens];
    }
}

Collection::new[['foo', 'bar']]->forEach[function[$index, $item]{
  /* callback */
}]->list[];
7

Trong PHP 7 chúng ta có thể dùng linh hoạt các hàm bằng cách tự định nghĩa nó trong class như sau:

class Collection extends \ArrayAccess, \Countable, \IteratorAggregate {

    public function forEach[callable $callback] {
        //...
    }

    public function list[] {
        //...
    }

    public static function new[array $itens] {
        return new self[$itens];
    }
}

Collection::new[['foo', 'bar']]->forEach[function[$index, $item]{
  /* callback */
}]->list[];

Thống nhất cú pháp biến

Sự thay đổi này mang đến cái nhìn trực quan về cách sử dụng biến trong PHP 7. Ví dụ về các biểu thức không hợp lệ trước đây, nhưng có hiệu lực với cú pháp biến thống nhất:

// hỗ trợ kết hợp các phép tính
$foo[]['bar'][]
[$obj1, $obj2][0]->prop
getStr[]{0}

// hỗ trợ sự lồng nhau với ::
$foo['bar']::$baz
$foo::$bar::$baz
$foo->bar[]::baz[]

// hỗ trợ sự lồng nhau với []
foo[][]
$foo->bar[][]
Foo::bar[][]
$foo[][]

// hỗ trợ các phép tính bất kì trong [...] của biểu thức
[...]['foo']
[...]->foo
[...]->foo[]
[...]::$foo
[...]::foo[]
[...][]

// hai ví dụ thực tế hay dùng
[function[] { ... }][]
[$obj->closure][]

// hỗ trợ tất cả các phép tính vô hướng [phần này thường không hay dùng]
"string"->toLower[]
[$obj, 'method'][]
'Foo'::$bar

Ví dụ dưới đây chúng ta sẽ thấy rõ sự thay đổi của PHP7 so với phiên bản trước đó:

cách dùng trong PHP 5xCách dùng trong PHP7$$foo['bar']['baz']${$foo['bar']['baz']}[$$foo]['bar']['baz']$foo->$bar['baz']$foo->{$bar['baz']}[$foo->$bar]['baz']$foo->$bar'baz'$foo->{$bar['baz']}[][$foo->$bar]'baz'Foo::$bar'baz'Foo::{$bar['baz']}[][Foo::$bar]'baz'

Sửa lỗi trong foreach[]

PHP vòng lặp foreach khi sử dụng con trỏ thì kết quả của cả quá trình đối với việc xử lý bằng PHP 5x thì không được hợp lý. Kể từ PHP 7 những lỗi phát sinh với foreach được sửa, làm cho các biểu thức sẽ có kết quả dễ nhận thấy và trực quan hơn nhiều so với phiên bản cũ. Ví dụ sau sẽ cho chúng ta hiểu hơn về quá trình này:

$array = [1,2,3];

foreach[$array as &$val] {
    echo "{$val} - ", current[$array], PHP_EOL;
}

// phiên bản trước PHP 7 cho kết quả:
1 - 2
2 - 3
3 -

// phiên bản PHP 7+ cho kết quả:
1 - 1
2 - 1
3 - 1

Loại bỏ cảnh báo date.timezone

Khi bất kì

class Collection extends \ArrayAccess, \Countable, \IteratorAggregate {

    public function forEach[callable $callback] {
        //...
    }

    public function list[] {
        //...
    }

    public static function new[array $itens] {
        return new self[$itens];
    }
}

Collection::new[['foo', 'bar']]->forEach[function[$index, $item]{
  /* callback */
}]->list[];
8 hoặc
class Collection extends \ArrayAccess, \Countable, \IteratorAggregate {

    public function forEach[callable $callback] {
        //...
    }

    public function list[] {
        //...
    }

    public static function new[array $itens] {
        return new self[$itens];
    }
}

Collection::new[['foo', 'bar']]->forEach[function[$index, $item]{
  /* callback */
}]->list[];
9 của một hàm cơ bản nào được gọi và giá trị mặc định của timezone không được set thì một cảnh báo sẽ được hiển thị lên. Đối với các phiên bản trước của PHP 7 thì việc sửa chữa chỉ đơn giản là thêm thiết lập giá trị mặc định cho
// hỗ trợ kết hợp các phép tính
$foo[]['bar'][]
[$obj1, $obj2][0]->prop
getStr[]{0}

// hỗ trợ sự lồng nhau với ::
$foo['bar']::$baz
$foo::$bar::$baz
$foo->bar[]::baz[]

// hỗ trợ sự lồng nhau với []
foo[][]
$foo->bar[][]
Foo::bar[][]
$foo[][]

// hỗ trợ các phép tính bất kì trong [...] của biểu thức
[...]['foo']
[...]->foo
[...]->foo[]
[...]::$foo
[...]::foo[]
[...][]

// hai ví dụ thực tế hay dùng
[function[] { ... }][]
[$obj->closure][]

// hỗ trợ tất cả các phép tính vô hướng [phần này thường không hay dùng]
"string"->toLower[]
[$obj, 'method'][]
'Foo'::$bar
0 hợp lệ trong file cấu hình php.ini. Vấn đề này trong PHP 7 đã được gỡ bỏ và bạn không cần phải cấu hình mặc định cho file cấu hình nữa.

Loại bỏ sự tự định nghĩa lại các tham số trùng lặp

Với các phiên bản PHP 7 trở về trước thì việc đặt tham số trùng lặp và trả về kết quả của tham số thì hàm vẫn sẽ được thực thi, tuy nhiên từ phiên bản PHP 7 thì hàm sẽ không được thực thi và bắn ra lỗi như sau:

function foo[$version, $version]
{
    return $version;
}

echo foo[5, 7];

// Trước PHP 7 kết quả là:
7

// PHP 7+ kết quả là:
Fatal error: Redefinition of parameter $version in /redefinition-of-parameters.php

Loại bỏ sự hỗ trợ mã HEX trong chuỗi số

String của hệ mã HEX không còn được công nhận là kiểu number trong PHP 7+ nữa, lý do được đưa ra là tạo ra tính nhất quán cho các sự truy xuất trong ngôn ngữ.

var_dump[is_numeric['0x123']];
var_dump['0x123' == '291'];
echo '0x123' + '0x123';

// Trước PHP 7 kết quả là:
bool[true]
bool[true]
582

// PHP 7+ kết quả là:
bool[false]
bool[false]
0

Xét ví dụ trên ta thấy sự khá nhập nhằng giữa sự ép kiểu thành số nguyên và kiểm tra thuộc kiểu number. Nếu như:

var_dump[[int] '0x123']; // int[0]
// chuỗi số hex phải mã hóa bằng `filter_var` thì mới cho ra kết quả như mong muốn
var_dump[filter_var['0x123', FILTER_VALIDATE_INT, FILTER_FLAG_ALLOW_HEX]]; // int[291]

Thay đổi giá trị trả về của hàm substr[]

substr[] will now return an empty string instead of false when the start position of the truncation is equal to the string length: trong PHP 7+ thì substr[] trả về giá trị rỗng thay vì fasle như trước kia khi mà cắt chuỗi với giá trị bằng đúng độ dài của chuỗi.

Chủ Đề