Xử lý Ngoại lệ trong PHP

Trong bài hướng dẫn tự học lập trình PHP này, bạn sẽ học xử lý ngoại lệ bằng cách ném (throw) và bắt (catch) trong PHP.

Trong bài hướng dẫn tự học lập trình PHP này, bạn sẽ học xử lý ngoại lệ bằng cách ném (throw) và bắt (catch) trong PHP.

Ngoại lệ là gì?

Một Ngoại lệ (Exception) là một tín hiệu chỉ ra một số loại sự kiện hoặc lỗi đặc biệt đã xảy ra. Các ngoại lệ có thể được gây ra do nhiều lý do,.

Ví dụ: Kết nối cơ sở dữ liệu hoặc truy vấn không thành công, tệp mà bạn đang cố truy cập không tồn tại, v.v.

PHP cung cấp một cơ chế xử lý ngoại lệ mạnh mẽ cho phép bạn xử lý các ngoại lệ một cách đơn giản.

Trái ngược với hệ thống xử lý lỗi trong PHP, xử lý ngoại lệ là phương pháp hướng đối tượng để xử lý lỗi, cung cấp hình thức báo cáo lỗi linh hoạt và có kiểm soát hơn.

Mô hình ngoại lệ được giới thiệu lần đầu tiên trong PHP 5.

Sử dụng Throw và cấu trúc Try…Catch để xử lý ngoại lệ trong PHP

Xử lý ngoại lệ trong PHP
Xử lý ngoại lệ trong PHP

Theo cách tiếp cận này, code chương trình được viết trong một khối try, một ngoại lệ có thể được ném ra bằng cách sử dụng câu lệnh throw.

Khi một sự kiện đặc biệt xảy ra trong quá trình thực thi code trong khối try. Nó sẽ được bắt và giải quyết bằng một hoặc nhiều khối bắt.

Ví dụ sau đây cho thấy cách xử lý ngoại lệ hoạt động trong PHP:

<?php
function division($dividend, $divisor){
    // Ném ra ngoại lệ chia cho số 0
    if($divisor == 0){
        throw new Exception('Chia cho số 0.');
    } else{
        $quotient = $dividend / $divisor;
        echo "<p>$dividend / $divisor = $quotient</p>";
    }
}
 
try{
    division(10, 2);
    division(30, -4);
    division(15, 0);
    
    // Nếu ngoại lệ được ném ra thì dòng sau không được thực thi
    echo '<p>Tất cả các phép chia thực hiện thành công.</p>';
} catch(Exception $e){
    // Xử lý ngoại lệ
    echo "<p>Ngoại lệ: " . $e->getMessage() . "</p>";
}
 
// Tiếp tục thực thi
echo "<p>Hello World!</p>";
?>

Nếu bạn chưa hiểu đoạn code trên thực hiện như thế nào. Vậy thì, chúng ta hãy đi qua từng phần của đoạn code này để hiểu rõ hơn.

Giải thích về cách xử lý ngoại lệ trong ví dụ trên

Hệ thống xử lý ngoại lệ của PHP về cơ bản có bốn phần: try, throw, catcht và Exception class.

Danh sách sau đây sẽ mô tả chính xác cách mỗi phần hoạt động:

  • Hàm division() trong ví dụ trên kiểm tra xem một ước số có bằng 0 hay không. Nếu đúng như vậy, một ngoại lệ được ném ra thông qua câu lệnh throw của PHP. Nếu không, hàm này thực hiện phép chia bằng các số đã cho và hiển thị kết quả.
  • Sau đó, hàm division() được gọi trong một khối try với các đối số khác nhau. Nếu một ngoại lệ được tạo trong khi thực thi code trong khối try, PHP sẽ dừng thực thi tại điểm đó và cố gắng tìm khối catch tương ứng. Nếu nó được tìm thấy, code trong khối catch đó được thực thi, nếu không, một lỗi nghiêm trọng (fatal error) sẽ được tạo ra.
  • Khối catch thường bắt ngoại lệ được ném trong khối try và tạo một object($e) có chứa thông tin ngoại lệ. Thông báo lỗi từ đối tượng này có thể được truy xuất bằng phương thức getMessage() của Exception class.

Exception class của PHP cũng cung cấp các phương thức khác như getCode(), getFile(), getLine() và getTraceAsString() có thể được sử dụng để truy xuất ra các thông tin cần thiết cho việc gỡ lỗi chi tiết.

<?php
// Tắt báo cáo lỗi mặc định
error_reporting(0);
 
try{
    $file = "somefile.txt";
    
    // Có gắng mở file
    $handle = fopen($file, "r");
    if(!$handle){
        throw new Exception("Không thể mở file!", 5);
    }
    
    // Cố gắng đọc nội dung file
    $content = fread($handle, filesize($file));
    if(!$content){
        throw new Exception("Không thể đọc file!", 10);
    }
    
    // Đóng file
    fclose($handle);
    
    // Hiển thị nội dung
    echo $content;
} catch(Exception $e){
    echo "<h3>Ngoại lệ xảy ra!</h3>";
    echo "<p>Error message: " . $e->getMessage() . "</p>";    
    echo "<p>File: " . $e->getFile() . "</p>";
    echo "<p>Line: " . $e->getLine() . "</p>";
    echo "<p>Error code: " . $e->getCode() . "</p>";
    echo "<p>Trace: " . $e->getTraceAsString() . "</p>";
}
?>

Hàm constructor của Exception nhận một thông báo ngoại lệ và code ngoại lệ. Mặc dù thông báo ngoại lệ thường được sử dụng để hiển thị thông tin chung về những gì đã sai, code ngoại lệ có thể được sử dụng để phân loại lỗi.

Code ngoại lệ được cung cấp có thể được truy xuất sau thông qua phương thức getCode() của Exception class.

Lưu ý: Ngoại lệ chỉ nên được sử dụng để biểu thị các điều kiện đặc biệt. Chúng không nên được sử dụng để kiểm soát luồng ứng dụng thông thường, ví dụ: Nhảy đến một vị trí khác trong tập lệnh tại một điểm cụ thể. Làm như vậy sẽ ảnh hưởng không tốt đến hiệu suất của ứng dụng.

Cách xác định ngoại lệ tùy chỉnh

Bạn thậm chí có thể định nghĩa các trình xử lý ngoại lệ tùy chỉnh của riêng bạn để xử lý các loại ngoại lệ khác nhau theo một cách khác. Nó cho phép bạn sử dụng một khối catch riêng cho từng loại ngoại lệ.

Bạn có thể định nghĩa một ngoại lệ tùy chỉnh bằng cách mở rộng lớp Exception, vì Exception là lớp cơ sở cho tất cả các ngoại lệ.

Lớp ngoại lệ tùy chỉnh kế thừa tất cả các thuộc tính và phương thức từ lớp Exception của PHP.

Bạn cũng có thể thêm các phương thức tùy chỉnh của mình vào lớp ngoại lệ tùy chỉnh., hãy xem ví dụ sau:

<?php
// Mở rộng lớp Exception
class EmptyEmailException extends Exception {}
class InvalidEmailException extends Exception {}
 
$email = "hello@niithanoi.edu.vn";
 
try{
    // Ném ra ngoại lệ nếu Email trống
    if($email == ""){
        throw new EmptyEmailException("<p>Bạn phải điền Email</p>");
    }
    
    // Ném ra ngoại lệ nếu Email không hợp lệ
    if(filter_var($email, FILTER_VALIDATE_EMAIL) === FALSE) {           
        throw new InvalidEmailException("<p><b>$email</b> không hợp lệ!</p>");
    }
    
    // Thông báo thành công nếu email hợp lệ
   echo "<p>CHÚC MỪNG: Xác thực Email thành công.</p>";
} catch(EmptyEmailException $e){
    echo $e->getMessage();
} catch(InvalidEmailException $e){
    echo $e->getMessage();
}
?>

Trong ví dụ trên, chúng ta đã nhận được hai lớp ngoại lệ mới: EmptyEmailExceptionUnlimitedEmailException từ lớp cơ sở là Exception.

Nhiều khối catch được sử dụng để hiển thị các thông báo lỗi khác nhau, tùy thuộc vào loại ngoại lệ nào được ném ra.

Do các lớp ngoại lệ tùy chỉnh này kế thừa các thuộc tính và phương thức từ lớp Exception, nên chúng ta hoàn toàn có thể sử dụng các phương thức của lớp Exception như getMessage(), getLine(), getFile(), v.v. để lấy thông tin lỗi từ đối tượng ngoại lệ.

Thiết lập Xử lý ngoại lệ toàn cục trong PHP

Như chúng ta đã thảo luận trước đó trong chương này nếu một ngoại lệ không bị bắt, PHP tạo ra Lỗi nghiêm trọng với thông báo ‘Uncaught Exception …’.

Thông báo lỗi này có thể chứa thông tin nhạy cảm như tên file và số dòng nơi xảy ra sự cố. Nếu bạn không muốn để lộ thông tin đó cho người dùng, bạn có thể tạo một hàm tùy chỉnh và đăng ký nó với hàm set_exception_handler() để xử lý tất cả các ngoại lệ chưa được phát hiện.

<?php
function handleUncaughtException($e){
    // Hiển thị thông báo lỗi chung cho người dùng
    echo "Opps! Có lỗi xảy ra. Hãy thử lại hoặc liên hệ với chúng tôi nếu còn lỗi.";
    
    // Lấy thông tin lỗi
    $error = "Uncaught Exception: " . $message = date("Y-m-d H:i:s - ");
    $error .= $e->getMessage() . " trong file " . $e->getFile() . " ở dòng " . $e->getLine() . "\n";
    
    // Ghi nhật ký chi tiết lỗi
    error_log($error, 3, "var/log/exceptionLog.log");
}
 
// Đăng ký xử lý ngoại lệ tùy chỉnh
set_exception_handler("handleUncaughtException");
 
// Ném ra một ngoại lệ
throw new Exception("Kiểm tra ngoại lệ!");
?>

Lưu ý: Một ngoại lệ chưa được lưu sẽ luôn dẫn đến việc chấm dứt tập lệnh. Vì thế, nếu bạn muốn tập lệnh tiếp tục thực thi ngoài điểm xảy ra ngoại lệ, bạn phải có ít nhất một khối catch tương ứng cho mỗi khối try.

Bạn đã hiểu về các xử lý ngoại lệ chưa?

Như vậy là trong bài này mình đã hướng dẫn bạn biết cách xử lý ngoại lệ trong PHP với việc sử dụng throw try… catch.

  • Tham khảo Khóa học PHP hoàn thiện từ Front end đến Back end nếu như bạn là người mới bắt đầu.

Nếu có bất cứ thắc mắc nào về vấn đề ngoại lệ trong PHP thì vui lòng để lại câu hỏi trong phần bình luận. Mình sẽ giải thích cho bạn.

Chúc bạn thành công!

JSON Parsing: Phân giải dữ liệu JSON với PHP

Trong bài hướng dẫn tự học Lập trình PHP này, bạn sẽ dược học cách mã hóa (endcode) và giải mã (decode) dữ liệu JSON trong PHP.

Trong bài hướng dẫn tự học Lập trình PHP này, bạn sẽ dược học cách mã hóa (endcode)giải mã (decode) dữ liệu JSON với PHP.

Vậy,

JSON là gì?

JSON là từ viết tắt của Javascript Object Notation. JSON là một định dạng tiêu chuẩn trong trao đổi dữ liệu nhẹ, nhanh chóng và dễ dàng tạo (generate) và phân tích (parse).

JSON, giống như XML, là một định dạng dựa trên văn bản, dễ viết và dễ hiểu cho cả con người và máy tính.

Nhưng không giống như XML, các cấu trúc dữ liệu JSON chiếm ít băng thông hơn các phiên bản XML của chúng.

Dữ liệu kiểu JSON dựa trên hai cấu trúc cơ bản:

  • Object: Được định nghĩa là một tập hợp các cặp key / value (nghĩa là key: value). Mỗi đối tượng bắt đầu bằng dấu ngoặc nhọn trái { và kết thúc bằng dấu ngoặc nhọn phải }. Có nhiều cặp key / value được phân tách bằng dấu phẩy , .
  • Array: Được định nghĩa là một danh sách các giá trị được sắp xếp. Một mảng bắt đầu bằng dấu ngoặc vuông trái [ và kết thúc bằng dấu ngoặc vuông phải ]. Các giá trị được phân tách bằng dấu phẩy , .

Trong JSON, các key luôn là các string, trong khi giá trị có thể là một string, number, true hoặc false, null, thậm chí là một Object hoặc một Array.

Các string phải được đặt trong dấu ngoặc kép “” và có thể chứa các ký tự thoát như \n, \t và \.

Một đối tượng JSON có thể trông như thế này:

Ví dụ về JSON Object theo cấu trúc Object

{
    "book": {
        "Tên": "Lập trình viên PHP",
        "Chữ ký": "PHP Dev",
        "Năm": 2019,
        "Loại": "Công nghệ",
        "Nổi tiếng": true
    }
}

Ví dụ về JSON Object theo cấu trúc Array

{
    "Danh mục": [
        "PHP Cơ Bản",
        "PHP Nâng Cao",
        "PHP & MySQL",
        "Ví dụ thực tế"
    ]
}

Ghi chú:

Định dạng data-interchange là định dạng văn bản được sử dụng để trao đổi hoặc hoán đổi dữ liệu giữa các nền tảng và hệ điều hành khác nhau. JSON là định dạng trao đổi dữ liệu nhẹ và phổ biến nhất cho các ứng dụng web.

Hướng dẫn phân giải dữ liệu JSON với PHP
Hướng dẫn phân giải dữ liệu JSON với PHP

Phân giải JSON với PHP (JSON Parsing)

Cấu trúc dữ liệu JSON rất giống với mảng của PHP. PHP có các hàm dựng sẵn để encode và decode dữ liệu JSON.

Các hàm này lần lượt là json_encode()json_decode(). Cả hai chức năng chỉ hoạt động với dữ liệu chuỗi được mã hóa theo chuẩn UTF-8.

Endcoding dữ liệu JSON bằng PHP

Trong PHP, chúng ta sử dụng hàm json_encode() được sử dụng để mã hóa một giá trị thành định dạng JSON.

Giá trị được mã hóa có thể là bất kỳ loại dữ liệu PHP nào ngoại trừ tài nguyên như cơ sở dữ liệu hoặc liên quan đến xử lý tệp.

Ví dụ dưới đây trình bày cách mã hóa một mảng kết hợp PHP thành một đối tượng JSON:

<?php
// Một mảng kết hợp
$tuoiNhanVien = array("Khánh"=>27, "Đức"=>32, "Huyền"=>35, "Thúy"=>30);
 
echo json_encode($tuoiNhanVien);
?>

Kết quả nhận được như sau:

{"Khánh":27,"Đức":32,"Huyền":35,"Thúy":30}

Tương tự…

Bạn có thể mã hóa mảng chỉ số trong PHP thành một mảng JSON, như thế này:

<?php
// Mảng chỉ số
$mauSac= array("Đỏ", "Xanh", "Vàng", "Lục", "Lam");
 
echo json_encode($colors);
?>

Kết quả nhận được là:

["Đỏ","Xanh","Vàng","Lục","Lam"]

Bạn cũng có thể buộc hàm json_encode() trả về một mảng chỉ số trong PHP dưới dạng đối tượng JSON bằng cách sử dụng tùy chọn JSON_FORCE_OBJECT, như trong ví dụ dưới đây:

<?php
// Mảng chỉ số
// Mảng chỉ số
$mauSac= array("Đỏ", "Xanh", "Vàng", "Lục", "Lam");
 
echo json_encode($colors, JSON_FORCE_OBJECT);
?>

Kết quả nhận được là:

{"Đỏ","Xanh","Vàng","Lục","Lam"}

Như bạn có thể thấy trong các ví dụ trên, một mảng không kết hợp có thể được mã hóa thành mảng hoặc đối tượng. Tuy nhiên, một mảng kết hợp luôn được mã hóa dưới dạng đối tượng.

Decoding dữ liệu JSON bằng PHP

Decoding dữ liệu JSON đơn giản như Endcoding nó. Bạn có thể sử dụng hàm json_decode() của PHP để chuyển đổi chuỗi được mã hóa JSON thành kiểu dữ liệu PHP phù hợp.

Ví dụ sau minh họa cách decoding hoặc chuyển đổi một đối tượng JSON thành đối tượng trong PHP.

<?php
// Lưu dữ liệu JSON trong biến
$json = '{"Khánh":27,"Đức":32,"Huyền":35,"Thúy":30}';
 
var_dump(json_decode($json));
?>

Kết quả của ví dụ trên sẽ trông giống như thế này:

object(stdClass)#1 (4) { ["Khánh"]=> int(27) ["Đức"]=> int(32) ["Huyền"]=> int(35) ["Thúy"]=> int(30) }

Theo mặc định, hàm json_decode() trả về một đối tượng. Tuy nhiên, bạn có thể tùy ý chỉ định tham số thứ hai $assoc chấp nhận giá trị boolean mà khi:

  • Được thiết lập là true => các đối tượng JSON thực được decoding thành các mảng kết hợp.
  • Còn mặc định là false

Đây là ví dụ:

<?php
// Lưu dữ liệu JSON trong biến
$json = '{"Khánh":27,"Đức":32,"Huyền":35,"Thúy":30}';
 
var_dump(json_decode($json, true));
?>

Kết quả nhận được:

array(4) { ["Khánh"]=> int(27) ["Đức"]=> int(32) ["Huyền"]=> int(35) ["Thúy"]=> int(30) }

Tiếp theo, hãy xem một ví dụ sẽ chỉ cho bạn cách decoding JSON data và cách truy cập các phần tử riêng lẻ của đối tượng JSON hoặc mảng trong PHP.

<?php
// Gán chuỗi được mã hóa JSON cho một biến PHP
$json = '{"Khánh":27,"Đức":32,"Huyền":35,"Thúy":30}';
 
// Decode JSON data thành mảng kết hợp trong PHP
$arr = json_decode($json, true);
// Truy cập giá trị của mảng kết hợp
echo $arr["Khánh"];  // Output: 27
echo $arr["Đức"];  // Output: 32
echo $arr["Huyền"];   // Output: 35
echo $arr["Thúy"];  // Output: 30
 
// Decode JSON data thành đối tượng trong PHP
$obj = json_decode($json);
// Truy cập dữ liệu từ đối tượng được trả về
echo $obj->Khánh;   // Output: 65
echo $obj->Đức;   // Output: 80
echo $obj->Huyền;    // Output: 78
echo $obj->Thúy;   // Output: 90
?>

Bạn cũng có thể lặp qua dữ liệu được decoding bằng vòng lặp foreach(), như thế này:

<?php
// Gán chuỗi được mã hóa JSON cho một biến PHP
$json = '{"Khánh":27,"Đức":32,"Huyền":35,"Thúy":30}';
 
// Decode JSON data thành mảng kết hợp trong PHP
$arr = json_decode($json, true);
 
// Lặp qua mảng Kết hợp
foreach($arr as $key=>$value){
    echo $key . "=>" . $value . "<br>";
}
echo "<hr>";
// Decode JSON data thành đối tượng trong PHP
$obj = json_decode($json);
 
// Lặp qua đối tượng
foreach($obj as $key=>$value){
    echo $key . "=>" . $value . "<br>";
}
?>

Hướng dẫn trích xuất các giá trị từ dữ liệu JSON lồng nhau trong PHP

Trong khi làm việc với JSON, các đối tượng và mảng JSON cũng có thể được lồng nhau. Một đối tượng JSON có thể tùy ý chứa các đối tượng JSON, mảng, mảng lồng nhau, mảng đối tượng JSON, v.v.

Ví dụ sau sẽ chỉ cho bạn cách giải mã một đối tượng JSON lồng nhau và in tất cả các giá trị của nó trong PHP .

<?php
// Khai báo hàm đệ quy để trích xuất các giá trị lồng nhau
function printValues($arr) {
    global $count;
    global $values;
    
    // Kiểm tra đầu vào của một mảng
    if(!is_array($arr)){
        die("ERROR: Đầu vào không phải một mảng");
    }
    
    /*
    *Lặp qua một mảng
    *Nếu giá trị tự nó là một mảng thì gọi hàm đệ quy
    *Nếu không thì thêm giá trị tìm thấy vào mảng đầu ra
    *Tăng bộ đếm lên 1 đơn vị
    */
    foreach($arr as $key=>$value){
        if(is_array($value)){
            printValues($value);
        } else{
            $values[] = $value;
            $count++;
        }
    }
    
    // Trả về tổng số giá trị được tìm thấy trong Mảng
    return array('total' => $count, 'values' => $values);
}
 
// Gán chuỗi JSON được mã hóa cho một biến PHP
$json = '{
    "book": {
        "name": "Harry Potter and the Goblet of Fire",
        "author": "J. K. Rowling",
        "year": 2000,
        "characters": ["Harry Potter", "Hermione Granger", "Ron Weasley"],
        "genre": "Fantasy Fiction",
        "price": {
            "paperback": "$10.40", "hardcover": "$20.32", "kindle": "4.11"
        }
    }
}';
// Decode Dữ liệu JSON thành định dạng mảng kết hợp
$arr = json_decode($json, true);
 
// Gọi hàm và in tất cả các giá trị
$result = printValues($arr);
echo "<h3>" . $result["total"] . " value(s) found: </h3>";
echo implode("<br>", $result["values"]);
 
echo "<hr>";
 
// In giá trị riêng lẻ
echo $arr["book"]["author"] . "<br>";  // Output: J. K. Rowling
echo $arr["book"]["characters"][0] . "<br>";  // Output: Harry Potter
echo $arr["book"]["price"]["hardcover"];  // Output: $20.32
?>

Tổng kết

Như vậy là qua bài này bạn đã được học về cách endcode decode dữ liệu JSON trong PHP.

Đây là một dạng dữ liệu trao đổi giữa các nền tảng rất phổ biến. Hãy thực hành lại các ví dụ để chắc chắn bạn đã hiểu và nắm được các thao tác với dữ liệu JSON bằng PHP.

PHPDev

Bài 31: Tìm hiểu Class và Object trong PHP

Trong bài hướng dẫn này, bạn sẽ được học cách lập trình theo kiểu hướng đối tượng (OOP) trong PHP. Tìm hiểu về cách khai báo Class, Object và truy cập thuộc tính, phương thức của chúng…

Trong bài hướng dẫn này, bạn sẽ được học cách lập trình theo kiểu hướng đối tượng (OOP) trong PHP. Tìm hiểu về cách khai báo Class, Object và truy cập thuộc tính, phương thức của chúng…

Tìm hiểu về Class và Object trong PHP
Tìm hiểu về Class và Object trong PHP

Lập trình hướng đối tượng là gì

Lập trình hướng đối tượng (OOP) là một mô hình lập trình dựa trên khái niệm về các lớp và các đối tượng.

Trái ngược với lập trình thủ tục trong đó trọng tâm là viết các thủ tục hoặc hàm thực hiện các thao tác trên dữ liệu. Trong lập trình hướng đối tượng, trọng tâm là tạo các đối tượng chứa cả dữ liệu và hàm cùng nhau.

Lập trình hướng đối tượng có một số lợi thế so với phong cách lập trình thông thường hoặc theo thủ tục. Những cái quan trọng nhất được liệt kê dưới đây:

  • Hướng đối tượng cung cấp một cấu trúc mô-đun rõ ràng cho chương trình
  • Nó giúp bạn tuân thủ nguyên tắc ‘không lặp lại chính mình’ (DRY) và do đó làm cho mã của bạn dễ dàng hơn nhiều để duy trì, sửa đổi và gỡ lỗi
  • Nó có thể tạo ra hành vi phức tạp hơn với ít mã hơn và thời gian phát triển ngắn hơn và mức độ tái sử dụng cao

Các phần sau đây sẽ mô tả cách các lớp và các đối tượng hoạt động trong PHP.

Mẹo nhanh: Ý tưởng đằng sau nguyên tắc Đừng lặp lại chính mình (DRY) là giảm việc lặp lại code bằng cách trừu tượng hóa các đoạn code tương tự, phổ biến cho ứng dụng và đặt chúng tại một nơi duy nhất và sử dụng lại chúng thay vì viết đi viết lại nhiều lần.

Hiểu về Lớp và Đối tượng trong PHP

Các Lớp (Class) và các Đối tượng (Object) là hai khía cạnh chính của Lập trình hướng đối tượng.

Một lớp là một container tập hợp các biến và hàm độc lập, hoạt động cùng nhau để thực hiện một hoặc nhiều tác vụ cụ thể, trong khi các đối tượng là các thể hiện riêng lẻ của một lớp.

Một lớp hoạt động như một khuôn mẫu hoặc bản thiết kế mà từ đó có thể tạo ra rất nhiều đối tượng riêng lẻ.

Khi các đối tượng riêng lẻ được tạo, chúng kế thừa các thuộc tínhhành vi chung giống nhau, mặc dù mỗi đối tượng có thể có các giá trị khác nhau cho các thuộc tính nhất định.

Ví dụ, hãy nghĩ về một lớp học như một bản thiết kế cho một ngôi nhà. Bản thân bản thiết kế chi tiết không phải là một ngôi nhà, mà là một kế hoạch chi tiết để xây dựng ngôi nhà.

Chúng ta có thể xây dựng một số ngôi nhà giống hệt nhau từ cùng một bản thiết kế, nhưng mỗi ngôi nhà có thể có màu sơn khác nhau, nội thất và gia đình khác nhau bên trong, như trong hình minh họa dưới đây.

Minh họa Class và Object
Minh họa Class và Object

Một lớp có thể được khai báo bằng từ khóa class, theo sau là tên của lớp và một cặp dấu ngoặc nhọn ({}), như trong ví dụ sau.

Chúng ta hãy tạo một tệp PHP có tên là Rectangle.php và đặt code ví dụ sau vào bên trong. Chúng ta tách chúng khỏi phần còn lại của chương trình. Sau đó, chúng ta có thể sử dụng nó bất cứ nơi nào cần thiết bằng cách bao include tệp Rectangle.php

<?php
class Rectangle
{
    // Khai báo thuộc tính
    public $length = 0;
    public $width = 0;
    
    // Phương thức tính chu vi
    public function getPerimeter(){
        return (2 * ($this->length + $this->width));
    }
    
    // Phương thức tính diện tích
    public function getArea(){
        return ($this->length * $this->width);
    }
}
?>

Từ khóa public trước các thuộc tính và phương thức trong ví dụ trên, là một cách để điều chỉnh cấp độ truy cập, nó cho biết thuộc tính hoặc phương thức này có thể truy cập được từ mọi nơi.

Chúng ta sẽ tìm hiểu thêm về các cấp độ truy cập trong các bài học sau này.

Lưu ý: Về mặt cú pháp, các biến trong một lớp được gọi là các thuộc tính, trong khi các hàm được gọi là các phương thức. Ngoài ra, các tên lớp theo quy ước được viết bằng PascalCase, tức là mỗi từ được ghép bắt đầu bằng một chữ cái viết hoa (ví dụ: MyClass).

Khi một lớp đã được xác định, các đối tượng có thể được tạo từ lớp với từ khóa new. Các phương thức và thuộc tính lớp có thể được truy cập trực tiếp thông qua thể hiện đối tượng này.

Tạo một tệp PHP tên là test.php khác và đặt đoạn mã sau vào bên trong nó.

<?php
// Include Lớp Rectangle
require "Rectangle.php";
 
// Tạo một đối tượng mới từ class Rectangle
$obj = new Rectangle;
 
// Lấy các giá trị thuộc tính của đối tượng
echo $obj->length; // 0utput: 0
echo $obj->width; // 0utput: 0
 
// Thiết lập giá trị thuộc tính
$obj->length = 30;
$obj->width = 20;
 
/* Đọc các giá trị thuộc tính đối tượng một lần nữa để hiển thị sự thay đổi*/
echo $obj->length; // 0utput: 30
echo $obj->width; // 0utput: 20
 
 
// Gọi phương thức của đối tượng
echo $obj->getPerimeter(); // 0utput: 100
echo $obj->getArea(); // Output: 600
?>

Ký hiệu mũi tên (->) là cấu trúc OOP được sử dụng để truy cập các thuộc tính và phương thức chứa của một đối tượng nhất định. Trong khi đó, biến giả $this cung cấp một tham chiếu đến đối tượng gọi tức là đối tượng mà phương thức thuộc về.

Sức mạnh thực sự của lập trình hướng đối tượng trở nên rõ ràng khi sử dụng nhiều phiên bản của cùng một lớp, như trong ví dụ sau:

<?php
// Include lớp Rectangle
require "Rectangle.php";
 
// Tạo nhiều đối tượng mới từ Lớp Rectangle
$obj1 = new Rectangle;
$obj2 = new Rectangle;
 
// Tính diện tích của cả 2 đối tượng
echo $obj1->getArea(); // Output: 0
echo $obj2->getArea(); // Output: 0
 
// Thiết lập thuộc tính cho đối tượng $obj1
$obj1->length = 30;
$obj1->width = 20;
 
// Thiết lập thuộc tính cho đối tượng $obj2
$obj2->length = 35;
$obj2->width = 50;
 
// Gọi phương thức tính diện tích của cả 2 đối tượng 1 lần nữa
echo $obj1->getArea(); // Output: 600
echo $obj2->getArea(); // Output: 1750
?>

Như bạn có thể thấy trong ví dụ trên, việc gọi phương thức getArea() trên các đối tượng khác nhau khiến phương thức đó hoạt động trên một tập hợp dữ liệu khác nhau.

Mỗi đối tượng là hoàn toàn độc lập, với các thuộc tính và phương thức riêng của nó và do đó có thể được thao tác độc lập, ngay cả khi chúng cùng loại.

Sử dụng Constructors và Destructors

Để làm cho việc lập trình hướng đối tượng trở nên dễ dàng hơn, PHP cung cấp một số phương thức được thực thi tự động khi một số hành động nhất định xảy ra trong một đối tượng.

Ví dụ, phương thức __construct() (được gọi là hàm tạo / hàm khởi tạo) được thực thi tự động bất cứ khi nào một đối tượng mới được tạo.

Tương tự, phương thức __destruct() (được gọi là hàm hủy) được thực thi tự động khi đối tượng bị hủy. Hàm hủy diệt sẽ dọn sạch mọi tài nguyên được phân bổ cho một đối tượng sau khi đối tượng bị hủy.

<?php
class MyClass
{
    // Constructor
    public function __construct(){
        echo 'Lớp "' . __CLASS__ . '" đã được khởi tạo!<br>';
    }
    
    // Destructor
    public function __destruct(){
        echo 'Lớp "' . __CLASS__ . '" đã được phá hủy.<br>';
    }
}
 
// Tạo một đối tượng mới
$obj = new MyClass;
 
// Xuất một in nhắn ở cuối file
echo "Kết thúc tập tin.";
?>

Chạy đoạn code PHP trên chúng ta sẽ nhận được kết quả sau:

Lớp MyClass đã được khởi tạo!
Kết thúc tập tin.
Lớp MyClass đã được phá hủy.

Hàm hủy được gọi tự động khi tập lệnh kết thúc. Tuy nhiên, để kích hoạt rõ ràng hàm hủy, bạn có thể hủy đối tượng bằng hàm unset() của PHP, như sau:

<?php
class MyClass
{
    // Constructor
    public function __construct(){
        echo 'Lớp "' . __CLASS__ . '" đã được khởi tạo!<br>';
    }
    
    // Destructor
    public function __destruct(){
        echo 'Lớp "' . __CLASS__ . '" đã được phá hủy.<br>';
    }
}
 
// Tạo một đối tượng mới
$obj = new MyClass;

// Phá hủy đối tượng
unset($obj);
 
// Xuất một in nhắn ở cuối file
echo "Kết thúc tập tin.";
?>

Bây giờ, chạy tập tin trên và nhận được kết quả:

Lớp MyClass đã được khởi tạo!
Lớp MyClass đã được phá hủy.
Kết thúc tập tin.

Mẹo nhanh: PHP tự động dọn sạch tất cả các tài nguyên được phân bổ trong khi thực thi khi tập lệnh kết thúc, ví dụ: Đóng kết nối cơ sở dữ liệu, phá hủy các đối tượng, vv

Lưu ý: __CLASS__ là hằng số chứa tên của lớp mà nó xảy ra. Nó trống rỗng, nếu nó xảy ra bên ngoài lớp học.

Mở rộng (Extend) Lớp thông qua Kế thừa (Inheritance)

Các lớp có thể kế thừa các thuộc tínhphương thức của một lớp khác bằng cách sử dụng từ khóa extends. Quá trình mở rộng này được gọi là thừa kế.

Đây có lẽ là lý do việc sử dụng mô hình lập trình hướng đối tượng phổ biến như thế.

<?php
// Include lớp Rectangle
require "Rectangle.php";
 
// Xác định một lớp mới dựa trên một lớp hiện có
class Square extends Rectangle
{   
    /* Phương pháp kiểm tra xem hình chữ nhật có phải là hình vuông không */
    public function isSquare(){
        if($this->length == $this->width){
            return true; // Hình Vuông
        } else{
            return false; // Hình Chữ Nhật
        }
    }
}
 
// Tạo một đối tượng mới từ Lớp Square
$obj = new Square;
 
// Thiết lập giá trị thuộc tính đối tượng
$obj->length = 20;
$obj->width = 20;
 
// Gọi phương thức
if($obj->isSquare()){
    echo "Diện tích hình Vuông là ";
} else{
    echo "Diện tích hình Chữ Nhật là ";
};
echo $obj->getArea();
?>

Đoạn mã PHP trong ví dụ trên sẽ cho ra kết quả như sau:

Diện tích hình Vuông là 400

Như bạn có thể thấy trong ví dụ trên, mặc dù định nghĩa lớp của Square không rõ ràng chứa phương thức getArea() cũng như thuộc tính $length và $width, các thể hiện của lớp Square vẫn có thể sử dụng chúng, vì chúng được kế thừa từ Lớp cha của nó là Rectangle.

Mẹo nhanh: Vì một lớp con có nguồn gốc từ một lớp cha, nên nó cũng được gọi là lớp dẫn xuất và lớp cha của nó được gọi là lớp cơ sở.

Kiểm soát mức độ hiển thị của các thuộc tính và phương thức

Khi làm việc với các lớp, bạn có thể hạn chế quyền truy cập vào các thuộc tính và phương thức của nó bằng cách sử dụng các từ khóa hiển thị để kiểm soát tốt hơn.

Có ba từ khóa hiển thị (từ dễ thấy nhất đến ít nhìn thấy nhất): public, protected, private.

Từ đó các thuộc tính và phương thức có thể được kiểm soát mức độ truy cập và sửa đổi.

  • public: Một thuộc tính hoặc phương thức công khai có thể được truy cập ở bất cứ đâu, từ trong lớp đến bên ngoài lớp. Đây là khả năng hiển thị mặc định cho tất cả các thành viên lớp trong PHP.
  • protected: Một thuộc tính hoặc phương thức được bảo vệ chỉ có thể được truy cập từ bên trong chính lớp đó hoặc trong các lớp con hoặc các lớp được kế thừa, tức là các lớp mở rộng lớp đó.
  • private: Một thuộc tính hoặc phương thức riêng tư chỉ có thể truy cập được từ bên trong lớp định nghĩa nó. Ngay cả các lớp con hoặc lớp thừa kế cũng không thể truy cập các thuộc tính hoặc phương thức private.

Ví dụ sau đây sẽ cho bạn thấy khả năng hiển thị / mức độ truy cập này thực sự hoạt động như thế nào.

<?php
// Định nghĩa class
class Automobile
{
    // Khai báo thuộc tính
    public $fuel;
    protected $engine;
    private $transmission;
}
class Car extends Automobile
{
    // Constructor
    public function __construct(){
        echo 'Lớp "' . __CLASS__ . '" đã được khởi tạo!<br>';
    }
}
 
// Tạo một đối tượng từ lớp Automobile
$automobile = new Automobile;
 
// Thiết lập thuộc tính cho đối tượng $automobile
$automobile->fuel = 'Petrol'; // ok
$automobile->engine = '1500 cc'; // fatal error
$automobile->transmission = 'Manual'; // fatal error
 
// Tạo một đối tượng từ Lớp Car
$car = new Car;
 
// Thiết lập thuộc tính cho đối tượng $car
$car->fuel = 'Diesel'; // ok
$car->engine = '2200 cc'; // fatal error
$car->transmission = 'Automatic'; // undefined
?>

Phương thức static và thuộc tính stactic

Ngoài khả năng hiển thị trên, các thuộc tính và phương thức cũng có thể được khai báo là static, điều này làm cho chúng có thể truy cập được mà không cần phải khởi tạo lớp.

Các thuộc tính và phương thức tĩnh có thể được truy cập bằng toán tử phân giải phạm vi (: :), như thế này: ClassName::$property và ClassName::method().

Một thuộc tính được khai báo là static không thể được truy cập thông qua đối tượng của lớp đó mặc dù có thể là một phương thức tĩnh, như được minh họa trong ví dụ sau:

<?php
// Định nghĩa Lớp
class HelloClass
{
    // Khai báo thuộc tính static
    public static $greeting = "Hello World!";
    
    // Khai báo phương thức static
    public static function sayHello(){
        echo self::$greeting;
    }
}
// Cố gắng truy cập vào thuộc tính và phương thức static
echo HelloClass::$greeting; // Output: Hello World!
HelloClass::sayHello(); // Output: Hello World!
 
// Cố gắng truy cập thuộc tính và phương thức tĩnh thông qua đối tượng
$hello = new HelloClass;
echo $hello->greeting; // Strict Warning
$hello->sayHello(); // Output: Hello World!
?>

Từ khóa self trong ví dụ trên có nghĩa là ‘lớp hiện tại’. Nó không bao giờ đi trước ký hiệu đô la ($) và luôn được theo sau bởi toán tử :: (ví dụ: self::$name).

Từ khóa self khác với từ khóa this có nghĩa là ‘đối tượng hiện tại’ hoặc ‘thể hiện hiện tại của một lớp’. Từ khóa this luôn đi trước ký hiệu đô la ($) và theo sau là toán tử -> (ví dụ: $this -> name).

Lưu ý: Vì các phương thức static có thể được gọi mà không có phiên bản của một lớp (tức là đối tượng), biến giả $this không có sẵn bên trong phương thức được khai báo là static.

Lời kết

Chúng tôi hy vọng bạn đã hiểu các khái niệm cơ bản về lập trình hướng đối tượng. Bạn sẽ tìm thấy nhiều ví dụ về OOP trong phần cơ sở dữ liệu PHP và MySQL.

Bài 30: Xử lý lỗi trong PHP (PHP Error Handling)

Trong bài hướng dẫn tự học PHP này, bạn sẽ học cách sử dụng các hàm xử lý lỗi trong PHP để xử lý khi xảy ra lỗi, cấc cấp độ lỗi, ví dụ hướng dẫn cụ thể

Trong bài hướng dẫn tự học PHP này, bạn sẽ học cách sử dụng các hàm xử lý lỗi trong PHP để xử lý khi xảy ra lỗi.

Lỗi là gì? Tại sao phải xử lý lỗi

Thỉnh thoảng ứng dụng hoặc trang web của bạn không chạy như mong muốn đó chính là lỗi. Có một số lý do gây ra lỗi ví dụ như sau:

  • Máy chủ có thể bị hết dung lượng / băng thông
  • Người dùng có thể đã nhập một giá trị không hợp lệ trong biểu mẫu
  • Bản ghi tệp hoặc cơ sở dữ liệu mà bạn đang cố truy cập có thể không còn tồn tại
  • Ứng dụng có thể không có quyền ghi vào một tệp trên đĩa
  • Một dịch vụ mà ứng dụng cần truy cập có thể tạm thời không khả dụng

Các loại lỗi này được gọi là runtime error (lỗi khi chạy), bởi vì chúng xảy ra tại thời điểm tập lệnh chạy. Chúng khác với các lỗi cú pháp cần được sửa trước khi chạy tập lệnh.

Lỗi là điều không mong muốn và gây khó chịu cho người dùng, thậm chí có thể gây hại cho ứng dụng.

Vì vậy, một trang web hay một ứng dụng chuyên nghiệp phải có khả năng xử lý lỗi thời gian chạy như vậy. Thông thường điều này có nghĩa là thông báo cho người dùng về vấn đề rõ ràng và chính xác hơn.

Hiểu rõ hơn về các cấp độ lỗi trong PHP

Thông thường, khi có sự cố ngăn tập lệnh chạy đúng, công cụ PHP sẽ gây ra lỗi. Mỗi lỗi được biểu thị bằng một giá trị nguyên và hằng số liên quan. Bảng sau liệt kê một số cấp độ lỗi phổ biến:

Cấp độ lỗiGiá trịMô tả
E_ERROR1Một lỗi Runtime nghiêm trọng, không thể được phục hồi. Việc thực thi kịch bản được dừng lại ngay lập tức
E_WARNING2Một cảnh báo runtime. Nó không trí mạng và hầu hết các lỗi có xu hướng rơi vào loại này. Việc thực thi kịch bản sẽ không dừng lại.
E_NOTICE8Một thông báo runtime. Cho biết rằng tập lệnh gặp phải lỗi có thể xảy ra, mặc dù tình huống cũng có thể xảy ra khi chạy tập lệnh bình thường
E_USER_ERROR256Một thông báo lỗi do người dùng tạo ra. Điều này giống như một E_ERROR, ngoại trừ nó được tạo bởi tập lệnh PHP bằng cách sử dụng hàm trigger_error () chứ không phải là PHP engine
E_USER_WARNING512Một thông điệp cảnh báo không trí mạng do người dùng tạo ra. Điều này giống như một E_WARNING, ngoại trừ nó được tạo bởi tập lệnh PHP bằng cách sử dụng hàm trigger_error () chứ không phải PHP engine
E_USER_NOTICE1024Một thông báo thông báo do người dùng tạo. Điều này giống như một E_NOTICE, ngoại trừ nó được tạo bởi tập lệnh PHP bằng cách sử dụng hàm trigger_error () chứ không phải PHP engine
E_STRIC2048Không hoàn toàn là một lỗi, nhưng được kích hoạt bất cứ khi nào PHP gặp mã có thể dẫn đến sự cố hoặc chuyển tiếp không tương thích
E_ALL8189Tất cả các lỗi và cảnh báo, ngoại trừ E_STRICT trước PHP 5.4.0.

Để tìm hiểu thêm, bạn có thể xem tại trang chủ của PHP tại đây

PHP Engine gây ra lỗi bất cứ khi nào nó gặp sự cố với tập lệnh của bạn, nhưng bạn cũng có thể tự kích hoạt lỗi để tạo ra nhiều thông báo lỗi thân thiện với người dùng hơn.

Bằng cách này bạn có thể làm cho ứng dụng của bạn trở nên thông minh hơn. Phần sau đây mô tả một số phương thức phổ biến được sử dụng để xử lý lỗi trong PHP

Xử lý lỗi trong PHP (PHP Error Handling)
Xử lý lỗi trong PHP (PHP Error Handling)

Xử lý lỗi cơ bản trong PHP với hàm die()

Hãy xem xét ví dụ sau, chúng ta chỉ đơn giản là cố gắng mở một tệp văn bản để chỉ đọc:

<?php
  // Cố gắng mở một tệp không tồn tại
  $file = fopen("sample.txt", "r");
?>

Nếu bạn cố gắng mở một tệp không tồn tại như ví dụ trên, bạn có thể gặp lỗi như thế này:

Warning: fopen(sample.txt) [function.fopen]: failed to open stream: No such file or directory in C:\wamp\www\project\test.php on line 2

Nếu chúng ta làm theo một số bước đơn giản, chúng ta có thể ngăn người dùng nhận được thông báo lỗi như vậy. Vì họ nhận thông báo như thế này cũng không hiểu, thậm chí gây khó chịu.

<?php
  if(file_exists("sample.txt")){
      $file = fopen("sample.txt", "r");
  } else{
      die("Error: File không tồn tại.");
  }
?>

Bây giờ nếu bạn chạy đoạn mã trên, bạn sẽ nhận được thông báo lỗi như thế này:

Error: File không tồn tại

Như bạn có thể thấy bằng cách thực hiện kiểm tra đơn giản xem tệp có tồn tại hay không trước khi thử truy cập nó, chúng ta có thể tạo thông báo lỗi có ý nghĩa hơn đối với người dùng.

Hàm die() được sử dụng ở trên chỉ đơn giản hiển thị thông báo lỗi tùy chỉnh và chấm dứt tập lệnh hiện tại nếu không tìm thấy tệp ‘sample.txt’

Hướng dẫn tạo trình xử lý lỗi tùy chỉnh trong PHP

Bạn có thể tạo chức năng xử lý lỗi của riêng mình để xử lý lỗi runtime do PHP Engine tạo ra.

Trình xử lý lỗi tùy chỉnh cung cấp cho bạn tính linh hoạt cao hơn và kiểm soát lỗi tốt hơn, nó có thể kiểm tra lỗi và quyết định phải làm gì với lỗi, nó có thể hiển thị thông báo cho người dùng, ghi lại lỗi trong tệp hoặc cơ sở dữ liệu hoặc gửi bởi e -mail, cố gắng khắc phục sự cố và tiếp tục, thoát khỏi việc thực thi tập lệnh hoặc bỏ qua lỗi hoàn toàn.

Hàm xử lý lỗi tùy chỉnh phải có khả năng xử lý ít nhất hai tham số (errno errstr), tuy nhiên, nó có thể tùy ý chấp nhận thêm ba tham số (errfile, errline errcontext), như được mô tả dưới đây:

Các tham số bắt buộc trong trình xử lý lỗi tùy chỉnh :

  • errno: Chỉ định mức độ lỗi, dưới dạng một số nguyên. Điều này tương ứng với hằng số cấp độ lỗi phù hợp (E_ERROR, E_WARNING, v.v.)
  • errstr: Chỉ định thông báo lỗi dưới dạng chuỗi

Các tham số tùy chọn trong trình xử lý lỗi tùy chỉnh:

  • errfile: Chỉ định tên file của tập lệnh trong đó xảy ra lỗi, dưới dạng chuỗi
  • errline: Chỉ định số dòng mà lỗi xảy ra, dưới dạng một chuỗi
  • errcontext: Chỉ định một mảng chứa tất cả các biến và giá trị của chúng tồn tại tại thời điểm xảy ra lỗi. Tham số này rất hữu ích cho việc gỡ lỗi

Đây là một ví dụ về chức năng xử lý lỗi tùy chỉnh đơn giản. Trình xử lý này, customError() được kích hoạt mỗi khi xảy ra lỗi, bất kể lỗi tầm thường như thế nào. Sau đó, nó đưa ra các chi tiết lỗi cho trình duyệt và dừng việc thực thi tập lệnh.

<?php
  // Hàm xử lý lỗi
  function customError($errno, $errstr){
      echo "<b>Error:</b> [$errno] $errstr";
  }
?>

Bạn cũng cần báo cho PHP sử dụng hàm xử lý lỗi tùy chỉnh của bạn – chỉ cần gọi hàm set_error_handler() tích hợp, chuyển vào tên của hàm.

<?php
  // Hàm xử lý lỗi
  function customError($errno, $errstr){
      echo "<b>Error:</b> [$errno] $errstr";
  }
 
  // Thiết lập xử lý lỗi
  set_error_handler("customError");
 
  // Thông báo lỗi
  echo($test);
?>

Ghi nhật ký lỗi

Ghi lỗi ra một file text

Bạn cũng có thể ghi nhật ký chi tiết lỗi vào file text, như sau:

<?php
function calcDivision($dividend, $divisor){
    if($divisor == 0){
        trigger_error("calcDivision(): The divisor cannot be zero", E_USER_WARNING);
        return false;
    } else{
        return($dividend / $divisor);
    }
}
function customError($errno, $errstr, $errfile, $errline, $errcontext){
    $message = date("Y-m-d H:i:s - ");
    $message .= "Error: [" . $errno ."], " . "$errstr in $errfile on line $errline, ";
    $message .= "Variables:" . print_r($errcontext, true) . "\r\n";
    
    error_log($message, 3, "logs/app_errors.log");
    die("There was a problem, please try again.");
}
set_error_handler("customError");
echo calcDivision(10, 0);
echo "This will never be printed.";
?>

Gửi lỗi qua Email

Bạn cũng có thể gửi e-mail với các chi tiết lỗi bằng cách sử dụng cùng hàm error_log().

<?php
function calcDivision($dividend, $divisor){
    if ($divisor == 0){
        trigger_error("calcDivision(): The divisor cannot be zero", E_USER_WARNING);
        return false;
    } else{
        return($dividend / $divisor);
    }
}
function customError($errno, $errstr, $errfile, $errline, $errcontext){
    $message = date("Y-m-d H:i:s - ");
    $message .= "Error: [" . $errno ."], " . "$errstr in $errfile on line $errline, ";
    $message .= "Variables:" . print_r($errcontext, true) . "\r\n";
    
    error_log($message, 1, "webmaster@example.com");
    die("There was a problem, please try again. Error report submitted to webmaster.");
}
set_error_handler("customError");
echo calcDivision(10, 0);
echo "This will never be printed.";
?>

Thông báo lỗi

Mặc dù PHP Engine gây ra lỗi bất cứ khi nào nó gặp sự cố với tập lệnh của bạn, tuy nhiên bạn cũng có thể tự kích hoạt lỗi.

Điều này có thể giúp làm cho ứng dụng của bạn mạnh mẽ hơn, bởi vì nó có thể đánh dấu các vấn đề tiềm ẩn trước khi chúng biến thành các lỗi nghiêm trọng.

Để kích hoạt lỗi từ trong tập lệnh của bạn, hãy gọi hàm trigger_error(), gửi thông báo lỗi mà bạn muốn tạo:

trigger_error("There was a problem.");

Xét hàm sau về việc tính toán chia cho hai số.

<?php
function calcDivision($dividend, $divisor){
    return($dividend / $divisor);
}
 
// Gọi hàm
echo calcDivision(10, 0);
?>

Nếu giá trị 0 (số 0) được truyền cho tham số $divisor, lỗi chia cho số 0 được tạo bởi PHP Engine sẽ trông giống như sau:

Warning: Division by zero in C:\wamp\www\project\test.php on line 3

Thông báo này có vẻ không dễ đọc nếu là người dùng. Hãy xem xét ví dụ sau sử dụng hàm trigger_error() tạo thông báo lỗi.

<?php
function calcDivision($dividend, $divisor){
    if($divisor == 0){
        trigger_error("Số bị chia không thể là số 0", E_USER_WARNING);
        return false;
    } else{
        return($dividend / $divisor);
    }
}
 
// Gọi hàm
echo calcDivision(10, 0);
?>

Khi chạy lại tập lệnh đã truyền số 0 vào số bị chia, chúng ta sẽ nhận được lỗi như thế này:

Warning: Số bị chia không thể là số 0 in C:\wamp\www\project\error.php on line 4

Như bạn có thể thấy thông báo lỗi được tạo bởi ví dụ thứ hai giải thích vấn đề rõ ràng hơn, thân thiện hơn so với ví dụ trước.

Lời kết

Như vậy bạn đã được học về cách xử lý lỗi trong PHP và các cấp độ lỗi. Xử lý lỗi mềm dẻo để có được một ứng dụng, trang web thân thiện hơn.

Đây cũng là kỹ năng quan trọng để giúp bạn có thể kiểm soát tốt hơn ứng dụng của mình.

Bài 29: Hướng dẫn các Làm sạch và Xác thực dữ liệu phổ biến với PHP Filters

Trong bài hướng dẫn tự học lập trình PHP này, bạn sẽ được hướng dẫn về cách làm sạch và xác thực dữ liệu đầu vào của người dùng với PHP Filters

Trong bài hướng dẫn tự học lập trình PHP này, bạn sẽ được hướng dẫn về cách làm sạchxác thực dữ liệu đầu vào của người dùng.

Chúng ta sẽ sử dụng các bộ lọc có sẵn trong PHP – PHP Filters

Làm sạch và xác thực dữ liệu đầu vào của người dùng là một trong những nhiệm vụ phổ biến nhất trong khi lập trình web. Để làm cho nhiệm vụ này dễ dàng hơn, PHP cung cấp tiện ích mở rộng filters mà bạn có thể sử dụng để làm sạch hoặc xác thực dữ liệu như địa chỉ email, URL, địa chỉ IP, v.v.

Để xác thực dữ liệu bằng cách sử dụng Filter, bạn cần sử dụng hàm filter_var() của PHP. Cú pháp cơ bản của hàm này như sau:

filter_var(variable, filter, options)

Hàm này có ba tham số trong đó hai tham số filter options là tùy chọn.

Tham số variable là giá trị được lọc, tham số thứ hai là ID của bộ lọc sẽ áp dụng và tham số thứ ba là mảng các tùy chọn liên quan đến bộ lọc.

Hướng dẫn làm sạch và xác thực dữ liệu với bộ lọc PHP (PHP Filters)
Hướng dẫn làm sạch và xác thực dữ liệu với bộ lọc PHP (PHP Filters)

Hãy cùng xem chức năng filter hoạt động như thế nào qua các ví dụ bên dưới đây.

1. Làm sạch một chuỗi với bộ lọc Filter

Ví dụ sau sẽ làm sạch một chuỗi bằng cách xóa tất cả các thẻ HTML khỏi nó:

<?php
  // Comment của người dùng có chứa thẻ HTML
  $comment = "<h1>Chào bạn, hôm nay có gì vui không?</h1>";
 
  // Làm sạch và in ra chuỗi comment đã làm sạch
  $sanitizedComment = filter_var($comment, FILTER_SANITIZE_STRING);
  echo $sanitizedComment;
?>

Sau khi làm sạch với bộ lọc với ID bộ lọc là FILTER_SANITIZE_STRING chúng ta có kết quả đầu ra như sau:

Chào bạn, hôm nay có gì vui không?

2. Xác thực giá trị kiểu số nguyên

Ví dụ sau sẽ xác nhận xem giá trị có phải là số nguyên hợp lệ hay không:

<?php
  // Cho một giá trị số
  $int = 20;
 
  // Xác thực xem biến $int có phải là số nguyên
  if(filter_var($int, FILTER_VALIDATE_INT)){
      echo "<b>$int</b> là số nguyên";
  } else{
      echo "<b>$int</b> không là số nguyên";
  }
?>

Trong ví dụ trên, nếu biến $int gán giá trị 0, đoạn mã sẽ hiển thị thông báo “… không là số nguyên”. Để khắc phục sự cố này, bạn cần kiểm tra rõ ràng giá trị 0, như sau:

<?php
  // Cho một giá trị số
  $int = 0;
 
  // Xác thực xem giá trị có phải số nguyên
  if(filter_var($int, FILTER_VALIDATE_INT) === 0 || filter_var($int, 
  FILTER_VALIDATE_INT)){
      echo "<b>$int</b> là số nguyên";
  } else{
      echo "<b>$int</b> không là số nguyên";
  }
?>

3. Xác thực địa chỉ IP

Ví dụ sau sẽ xác thực xem giá trị có phải là địa chỉ IP hợp lệ hay không:

<?php
  // Cho một địa chỉ IP
  $ip = "172.16.254.1";
 
  // Xác thực địa chỉ IP
  if(filter_var($ip, FILTER_VALIDATE_IP)){
      echo "<b>$ip</b> là địa chỉ IP hợp lệ";
  } else {
      echo "<b>$ip</b> không là địa chỉ IP hợp lệ";
  }
?>

Bạn có thể tiếp tục áp dụng xác thực cho các địa chỉ IP IPV4 hoặc IPV6 bằng cách sử dụng các bộ lọc FILTER_FLAG_IPV4 hoặc FILTER_FLAG_IPV6 tương ứng. Dưới đây là một ví dụ:

<?php
  // Cho một địa chỉ IP
  $ip = "172.16.254.1";
 
  // Xác thực địa chỉ IP
  if(filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)){
      echo "<b>$ip</b> là địa chỉ IPV6 hợp lệ";
  } else {
      echo "The <b>$ip</b> không là địa chỉ IPV6 hợp lệ";
  }
?>

>> Tham khảo ngay: Khóa học Lập trình PHP Fullstack chỉ trong 3 tháng.

4. Làm sạch và Xác thực URL

Ví dụ sau đây sẽ cho bạn thấy cách làm sạch và xác thực một url thông qua bộ lọc Fillter của PHP.

<?php
  // Cho một URL
  $url = "https:://laptrinhvienphp.com/";
 
  // Xóa ký tự không hợp lệ khỏi URL
  $urls = filter_var($url, FILTER_SANITIZE_URL);
  
  // Xác thực URL
  if(filter_var($urls, FILTER_VALIDATE_URL)){
      echo "<b>$urls</b> là URL hợp lệ";
  } else{
      echo "<b>$urls</b> không là URL hợp lệ";
  }
?>

Bạn cũng có thể kiểm tra xem URL có chứa chuỗi truy vấn hay không bằng cách sử dụng FILTER_FLAG_QUERY_REQUIRED, như trong ví dụ sau:

<?php
  // Cho một URL
  $url = "http://www.example.com?topic=filters";
 
  // Xác thực URL có chứa chuỗi truy vấn hay không
  if(filter_var($url, FILTER_VALIDATE_URL, FILTER_FLAG_QUERY_REQUIRED)) 
  {
      echo "<b>$url</b> chứa chuỗi truy vấn";
  } else{
      echo "<b>$url</b> không chứa chuỗi truy vấn";
  }
?>

5. Cách Xác thực số nguyên trong một khoảng cho phép

Ví dụ sau sẽ xác thực giá trị được cung cấp có phải là số nguyên hay không, cũng như liệu nó có nằm trong phạm vi từ 0 đến 100 hay không.

<?php
  // Cho một số nguyên
  $int = 75;
 
  // Xác thực giá trị trong khoảng từ 0 - 100
  if(filter_var($int, FILTER_VALIDATE_INT, array("options" => 
  array("min_range" => 0,"max_range" => 100)))){
      echo "<b>$int</b> là số nguyên nằm trong khoảng 0 - 100";
  } else{
      echo "<b>$int</b> không là số nguyên nằm trong khoảng 0- 100";
  }
?>

6. Cách xác thực địa chỉ Email hợp lệ sử dụng bộ lọc Filters

Ví dụ sau sử dụng hàm filter_var() với ID bộ lọc là FILTER_SANITIZE_EMAIL để loại bỏ tất cả các ký tự bất hợp pháp từ biến $email, sau đó xác thực xem có đúng là địa chỉ Email hợp lệ hay không với FILTER_VALIDATE_EMAIL:

<?php
  $email = "hello@niithanoi.edu.vn";

  // Loại bỏ ký tự không hợp lệ trong email
  $email = filter_var($email, FILTER_SANITIZE_EMAIL);

  // Xác thực địa chỉ email
  if (!filter_var($email, FILTER_VALIDATE_EMAIL) === false) {
      echo("$email là email hợp lệ");
  } else {
      echo("$email không phải email hợp lệ");
  }
?>

Tổng kết

Như vậy là bạn đã được hướng dẫn 6 cách làm sạchxác thực dữ liệu đầu vào của người dùng với bộ lọc Filters do PHP cung cấp sẵn.

Để tìm hiểu kỹ hơn về các bộ lọc trong PHP. Bạn vui lòng tìm hiểu thêm tại đây.

Bài 28: Hướng dẫn Validate Form trong PHP

Trong Lập trình chúng ta phải xác thực và làm sạch dữ liệu hay thường được gọi là validate form. Trong hướng dẫn này, bạn sẽ tìm hiểu cách validate form trong PHP.

Ở bài trước chúng ta đã tạo form để nhận dữ liệu của người dùng. Nhưng như mình đã nói. Dữ liệu của người dùng có thể “Không sạch”.

Vì thế, trong Lập trình web hay bất cứ lập trình ứng dụng nào khác. Chúng ta phải xác thực và làm sạch dữ liệu hay thường được gọi là validate form.

Trong hướng dẫn này, bạn sẽ tìm hiểu cách validate form trong PHP.

Hướng dẫn Validate Form trong PHP
Hướng dẫn Validate Form trong PHP

Hướng dẫn Làm sạch và Xác thực dữ liệu (Validate) trong PHP

Bạn đã thấy trong các bài hướng dẫn trước, quá trình bắt và hiển thị dữ liệu của form đã gửi khá đơn giản.

Trong hướng dẫn này, bạn sẽ tìm hiểu cách triển khai một form liên hệ đơn giản trên trang web của mình cho phép người dùng gửi nhận xét và phản hồi của họ qua email.

Chúng ta sẽ sử dụng cùng hàm PHP mail() để gửi email.

Chúng ta cũng sẽ triển khai một số tính năng bảo mật cơ bản như Làm sạchXác thực dữ liệu đầu vào của người dùng để chắc chắn rằng người dùng không thể chèn dữ liệu độc hại (ví dụ như tiêm injection) có thể làm tổn hại đến bảo mật trang web hoặc có thể phá vỡ trang web.

Sau đây là tập lệnh tất cả trong một của chúng ta, nó thực hiện những việc sau:

  • Nó sẽ yêu cầu người dùng nhập nhận xét ​​của mình về trang web.
  • Kịch bản tương tự hiển thị form liên hệ và xử lý dữ liệu form liên hệ đã gửi.
  • Kịch bản làm sạchxác thực dữ liệu đầu vào của người dùng. Nếu bất kỳ trường bắt buộc nào (được đánh dấu *) bị thiếu hoặc xác thực không thành công do nhập sai, tập lệnh sẽ hiển thị lại form với thông báo lỗi cho trường tương ứng.
  • Kịch bản ghi nhớ các trường mà người dùng đã điền và điền trước các trường đó khi biểu mẫu được hiển thị lại do lỗi xác thực.
  • Nếu dữ liệu được gửi bởi người dùng có thể chấp nhận được và mọi thứ đều ổn, nó sẽ gửi email đến quản trị viên trang web và hiển thị thông báo thành công cho người dùng.

Tạo file có tên là contact.php và lưu trong thư mục gốc dự án của bạn:

<?php
// Functions to filter user inputs
function filterName($field){
    // Làm sạch tên người dùng
    $field = filter_var(trim($field), FILTER_SANITIZE_STRING);
    
    // Xác thực tên người dùng
    if(filter_var($field, FILTER_VALIDATE_REGEXP, array("options"=>array("regexp"=>"/^[a-zA-Z\s]+$/")))){
        return $field;
    } else{
        return FALSE;
    }
}    
function filterEmail($field){
    // Làm sạch Email
    $field = filter_var(trim($field), FILTER_SANITIZE_EMAIL);
    
    // Xác thực Email
    if(filter_var($field, FILTER_VALIDATE_EMAIL)){
        return $field;
    } else{
        return FALSE;
    }
}
function filterString($field){
    // Làm sạch nội dung
    $field = filter_var(trim($field), FILTER_SANITIZE_STRING);
    if(!empty($field)){
        return $field;
    } else{
        return FALSE;
    }
}
 
// Khai báo biến và khởi tạo các giá trị trống
$nameErr = $emailErr = $messageErr = "";
$name = $email = $subject = $message = "";
 
// Xử lý dữ liệu biểu mẫu khi biểu mẫu được gửi
if($_SERVER["REQUEST_METHOD"] == "POST"){
 
    // Xác thực tên người dùng
    if(empty($_POST["name"])){
        $nameErr = "Nhập tên của bạn.";
    } else{
        $name = filterName($_POST["name"]);
        if($name == FALSE){
            $nameErr = "Nhập tên hợp lệ.";
        }
    }
    
    // Xác thực Email
    if(empty($_POST["email"])){
        $emailErr = "Nhập địa chỉ Email.";     
    } else{
        $email = filterEmail($_POST["email"]);
        if($email == FALSE){
            $emailErr = "Nhập email hợp lệ.";
        }
    }
    
    // Xác thực tiêu đề
    if(empty($_POST["subject"])){
        $subject = "";
    } else{
        $subject = filterString($_POST["subject"]);
    }
    
    // Xác thực nội dung
    if(empty($_POST["message"])){
        $messageErr = "Điền nhận xét.";     
    } else{
        $message = filterString($_POST["message"]);
        if($message == FALSE){
            $messageErr = "Điền nhận xét hợp lệ.";
        }
    }
    
    // Check input errors before sending email
    if(empty($nameErr) && empty($emailErr) && empty($messageErr)){
        // Địa chỉ Email người nhận
        $to = 'webmaster@example.com';
        
        // Tạo tiêu đề Email
        $headers = 'From: '. $email . "\r\n" .
        'Reply-To: '. $email . "\r\n" .
        'X-Mailer: PHP/' . phpversion();
        
        // Gửi Email
        if(mail($to, $subject, $message, $headers)){
            echo '<p class="success">Nhận xét của bạn gửi thành công!</p>';
        } else{
            echo '<p class="error">Không thể gửi. Vui lòng thử lại sau!</p>';
        }
    }
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Contact Form</title>
    <style type="text/css">
        .error{ color: red; }
        .success{ color: green; }
    </style>
</head>
<body>
    <h2>Contact Us</h2>
    <p>Please fill in this form and send us.</p>
    <form action="contact.php" method="post">
        <p>
            <label for="inputName">Name:<sup>*</sup></label>
            <input type="text" name="name" id="inputName" value="<?php echo $name; ?>">
            <span class="error"><?php echo $nameErr; ?></span>
        </p>
        <p>
            <label for="inputEmail">Email:<sup>*</sup></label>
            <input type="text" name="email" id="inputEmail" value="<?php echo $email; ?>">
            <span class="error"><?php echo $emailErr; ?></span>
        </p>
        <p>
            <label for="inputSubject">Subject:</label>
            <input type="text" name="subject" id="inputSubject" value="<?php echo $subject; ?>">
        </p>
        <p>
            <label for="inputComment">Message:<sup>*</sup></label>
            <textarea name="message" id="inputComment" rows="5" cols="30"><?php echo $message; ?></textarea>
            <span class="error"><?php echo $messageErr; ?></span>
        </p>
        <input type="submit" value="Send">
        <input type="reset" value="Reset">
    </form>
</body>
</html>

Giải thích code Validate Form trong PHP

Bạn có thấy, đây là đoạn mã Validate form đơn giản nhất. Chúng ta sẽ đi vào giải thích cụ thể:

  • filterName() function (line no-03) xác nhận giá trị đầu vào là tên người dùng. Tên hợp lệ chỉ có thể chứa các ký tự chữ cái (a-z, A-Z).
  • filterEmail() function (line no-14) xác nhận giá trị đầu vào như địa chỉ email.
  • filterString() function (line no-25) chỉ làm sạch giá trị đầu vào bằng cách loại bỏ thẻ HTML và các ký tự đặc biệt.
  • Thuộc tính action="contact.php" (line no-111) bên trong thẻ <form> chỉ định rằng tệp contact.php sẽ được thực thi khi người dùng nhấn nút gửi.
  • Mã PHP bên trong giá trị thuộc tính của thẻ <input> và textarea, ví dụ:
    <?php echo $name; ?> Hiển thị giá trị được điền sẵn khi biểu mẫu được hiển thị lại xảy ra lỗi xác thực.
  • Mã PHP bên trong class .error, ví dụ <span class=”error”><?php echo $nameErr; ?></span> Hiển thị lỗi theo trường tương ứng.

Phần còn trong mã Validate form trong PHP chúng ta đã tìm hiểu trong các chương trước. Để tìm hiểu thêm về vệ sinh và xác thực các bộ lọc, vui lòng xem tham khảo thêm PHP Fillter tại trang chủ của PHP tại đây

Tham khảo: Code hướng dẫn Validate form bằng PHP

Bài 27: Thu thập dữ liệu Người dùng bằng Biểu mẫu trong PHP

Trong bài hướng dẫn tự học Lập trình PHP này, mình sẽ giúp bạn tìm hiểu cách lấy, thu thập dữ liệu đầu vào của người dùng được gửi qua một biểu mẫu (form) bằng cách sử dụng các biến superglobal trong PHP như: $_GET, $_POST và $_REQUEST.

Trong bài hướng dẫn tự học Lập trình PHP này, mình sẽ giúp bạn tìm hiểu cách lấy, thu thập dữ liệu đầu vào của người dùng được gửi qua một biểu mẫu (form) bằng cách sử dụng các biến superglobal trong PHP như: $_GET, $_POST$_REQUEST.

Nhận lấy dữ liệu người dùng bằng biểu mẫu trong PHP
Nhận lấy dữ liệu người dùng bằng biểu mẫu trong PHP

Bước 1: Tạo biểu mẫu đơn giản với HTML

Trong bài hướng dẫn này, chúng tôi sẽ tạo một biểu mẫu liên hệ bằng HMTL đơn giản.

Biểu mẫu này cho phép người dùng nhập nhận xét và phản hồi của họ sau đó hiển thị nó cho trình duyệt bằng PHP.

Mở phần mềm soạn lập trình php yêu thích của bạn và tạo một tệp PHP mới. Bây giờ hãy nhập đoạn mã sau và lưu tệp này dưới dạng ‘contact-form.php‘ trong thư mục gốc của dự án.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Biểu mẫu trong PHP</title>
</head>
<body>
    <h2>Contact Us</h2>
    <p>Điền vào biểu mẫu và nhấn Gửi.</p>
    <form action="process-form.php" method="post">
        <p>
            <label for="inputName">Tên:<sup>*</sup></label>
            <input type="text" name="name" id="inputName">
        </p>
        <p>
            <label for="inputEmail">Email:<sup>*</sup></label>
            <input type="text" name="email" id="inputEmail">
        </p>
        <p>
            <label for="inputSubject">Tiêu đề:</label>
            <input type="text" name="subject" id="inputSubject">
        </p>
        <p>
            <label for="inputComment">Nội dung:<sup>*</sup></label>
            <textarea name="message" id="inputComment" rows="5" cols="30"></textarea>
        </p>
        <input type="submit" value="Gửi">
        <input type="reset" value="Làm lại">
    </form>
</body>
</html>

Giải thích đoạn code biểu mẫu HTML trên

Lưu ý rằng có hai thuộc tính trong thẻ mở <form>:

  • Thuộc tính action: Tham chiếu tệp PHP ‘process-form.php‘ nhận dữ liệu được nhập vào biểu mẫu khi người dùng gửi nó. Nôm na là thuộc tính action chỉ định giai đoạn sau khi thực hiện Gửi dữ liệu thành công.
  • Thuộc tính method: Yêu cầu trình duyệt gửi dữ liệu biểu mẫu thông qua phương thức POST.

Phần còn lại của các thành phần bên trong biểu mẫu là các thành phần cơ bản để nhận thông tin người dùng nhập vào.

Bước 2: Lấy dữ liệu người dùng nhập vào biểu mẫu bằng PHP

Để truy cập giá trị của một trường cụ thể trong biểu mẫu, bạn có thể sử dụng các biến superglobal sau đây. Các biến này có sẵn trong tất cả các phạm vi trong tập lệnh.

  • $_GET: Chứa danh sách tất cả các tên và giá trị trường được gửi bởi một biểu mẫu bằng phương thức get (dữ liệu sẽ hiển thị trong URL).
  • $_POST: Chứa danh sách tất cả các tên và giá trị trường được gửi bởi một biểu mẫu bằng phương thức đăng (dữ liệu sẽ không hiển thị trong URL).
  • $_REQUEST: Chứa các giá trị của cả hai biến $_GET$_POST cũng như các giá trị của biến superglobal $_COOKIE.

Khi người dùng gửi biểu mẫu liên hệ ở trên thông qua việc nhấp vào nút submit, dữ liệu biểu mẫu được gửi đến tệp ‘process-form.php‘ trên máy chủ để xử lý.

Nó chỉ đơn giản là nắm bắt thông tin được gửi bởi người dùng và hiển thị nó cho trình duyệt.

Code PHP của tệp ‘process-form.php’ sẽ được viết như sau:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Contact Form</title>
</head>
<body>
    <h1>Cám ơn bạn!</h1>
    <p>Đây là thông tin bạn đã gửi:</p>
    <ol>
        <li><em>Tên:</em> <?php echo $_POST["name"]?></li>
        <li><em>Email:</em> <?php echo $_POST["email"]?></li>
        <li><em>Tiêu đề:</em> <?php echo $_POST["subject"]?></li>
        <li><em>Nội dung:</em> <?php echo $_POST["message"]?></li>
    </ol>
</body>
</html>

Đoạn code PHP ở trên khá đơn giản. Vì dữ liệu biểu mẫu được gửi qua phương thức POST, bạn có thể truy xuất giá trị của trường biểu mẫu cụ thể bằng cách chuyển tên của nó đến mảng superglobal $_POST và hiển thị từng giá trị trường bằng câu lệnh echo().

Cú pháp truy cập dữ liệu trong mảng superglobal:

$_POST["name"]

Trong thực tế, khi lấy, thu thập dữ liệu người dùng bằng biểu mẫu thì nội dung người dùng gửi cần phải được xử lý trước khi chuyển lên server. (Tránh trường hợp lợi dụng gửi mã độc lên server)

Luc này bạn phải thực hiện một số bước xác thực dữ liệu để đảm bảo dữ liệu người dùng sạch và đúng chuẩn cho phép.

Trong bài học tiếp theo, mình sẽ hướng dẫn bạn cách làm sạch và xác thực dữ liệu biểu mẫu liên hệ và gửi qua email bằng PHP.

Bài 26: Hướng dẫn gửi Email trong PHP

Trong bài hướng dẫn học lập trình PHP này, mình sẽ hướng dẫn bạn cách cách gửi email văn bản thông thường hoặc HTML đơn giản trong PHP bằng hàm mail().

Trong bài hướng dẫn học lập trình PHP này, mình sẽ hướng dẫn bạn cách cách gửi email văn bản thông thường hoặc HTML đơn giản trong PHP bằng hàm mail().

Hướng dẫn gửi Email trong PHP
Hướng dẫn gửi Email trong PHP

Giới thiệu về hàm mail() trong PHP

Gửi tin email là rất phổ biến trong khi lập trình website, ví dụ, gửi email chào mừng khi người dùng tạo tài khoản trên trang web của bạn, gửi bản tin cho người dùng đã đăng ký của bạn hoặc nhận phản hồi hoặc nhận xét của người dùng thông qua biểu mẫu liên hệ của trang web, v.v.

Bạn có thể sử dụng hàm mail() tích hợp sẵn trong PHP để tạo và gửi thư email đến một hoặc nhiều người nhận từ trang web PHP của bạn ở dạng văn bản thuần hoặc văn bản dạng HTML được định dạng.

Cú pháp cơ bản của chức năng này như sau:

mail(to, subject, message, headers, parameters) 

Giải thích về các tham số trong hàm mail()

Các tham số bắt buộc:

  • to: Địa chỉ email người nhận
  • subject: Tiêu đề, chủ đề của email sẽ được gửi. Tham số này không thể chứa bất kỳ ký tự tạo dòng mới nào (\n).
  • message: Đây là tin nhắn sẽ được gửi. Mỗi dòng nên được phân tách ra bằng (\n). Các dòng không được vượt quá 70 ký tự.

Các tham số tùy chọn (có thể có hoặc không):

  • headers: Tham số này thường được sử dụng để thêm các tiêu đề bổ sung, chẳng hạn như ‘From’, ‘Cc’, ‘Bcc’. Các tiêu đề bổ sung phải được phân tách bằng return và xuống dòng (\r\n).
  • parameters: Đây là các tham số bổ sung

Hướng dẫn gửi email văn bản đơn giản trong PHP

Cách đơn giản nhất để gửi email bằng PHP là gửi email văn bản thông thường (chỉ bao gồm text).

Trong ví dụ dưới đây, trước tiên chúng ta khai báo các biến – địa chỉ email, dòng tiêu đề và nội dung thư – sau đó chúng ta truyền các biến này đến hàm mail() để gửi email.

<?php

// Khai báo các biến
$to = 'hello@niithanoi.edu.vn';
$subject = 'Xin chào NIIT';
$message = 'Xin chào, Chúng ta làm bạn nhé'; 
$from = 'ironman@email.com';
 
// Gửi Email
if(mail($to, $subject, $message)){
    echo 'Chúc mừng. Email của bạn được gửi thành công.';
} else{
    echo 'Không thể gửi Email. Vui lòng thử lại.';
}
?>

Ok, bên trên đây bạn đã biết cách gửi email bằng văn bản thông thường. Rất đơn giản phải không?

Tiếp tục nhé…

Hướng dẫn gửi email văn bản định dạng HTML trong PHP

Vì khi bạn gửi email văn bản thông thường (chỉ có text) bằng PHP, tất cả nội dung sẽ rất đơn điệu, không thu hút người dùng.

Chúng ta sẽ cải thiện đầu ra đó và biến email thành email có định dạng HTML.

Để gửi email HTML, về quy trình gửi email sẽ giống nhau. Tuy nhiên, lần này chúng ta cần cung cấp thêm các headers cũng như một thông báo được định dạng HTML.

<?php

// Khai báo biến
$to = 'hello@niithanoi.edu.vn';
$subject = 'Xin chào NIIT';
$from = 'ironman@email.com';
 
// Để gửi thư HTML, Content-type header phải được thiết lập
$headers  = 'MIME-Version: 1.0' . "\r\n";
$headers .= 'Content-type: text/html; charset=utf-8' . "\r\n";
 
// Tạo Email headers
$headers .= 'From: '.$from."\r\n".
    'Reply-To: '.$from."\r\n" .
    'X-Mailer: PHP/' . phpversion();
 
// Soạn tin nhắn email HTML đơn giản
$message = '<html><body>';
$message .= '<h1 style="color:#f40;">Xin chào!</h1>';
$message .= '<p style="color:#080;font-size:18px;">Chúng ta làm bạn nhé!</p>';
$message .= '</body></html>';
 
// Gửi email bằng hamgf mail()
if(mail($to, $subject, $message, $headers)){
    echo 'Chúc mừng. Email của bạn được gửi thành công.';
} else{
    echo 'Không thể gửi Email. Vui lòng thử lại.';
}
?>

Note 1: .= là toán tử nối và gán. Có nghĩa là từng dòng sẽ được nối vào với nhau và gán vào biến $message

Note 2: Hàm PHP mail() là một phần của PHP core nhưng bạn cần thiết lập mail server trên máy của mình để làm cho nó thực sự hoạt động.

Việc gửi email trong PHP cũng đơn giản phải không nào? :D. Dù là email văn bản thông thường hay Email HTML cũng đơn giản thôi.

Trong hai chương tiếp theo chúng ta sẽ học về (Xử lý biểu mẫu PHP và Xác thực mẫu PHP), bạn sẽ tìm hiểu cách triển khai biểu mẫu liên hệ tương tác trên trang web của mình để nhận nhận xét và phản hồi của người dùng thông qua email bằng tính năng gửi email PHP này.

Bài 25: Section trong PHP

Trong hướng dẫn này, bạn sẽ tìm hiểu cách lưu trữ dữ liệu nhất định trên máy chủ tạm thời bằng cách sử dụng Section trong PHP.

Trong hướng dẫn này, bạn sẽ tìm hiểu cách lưu trữ dữ liệu nhất định tạm thời trên máy chủ bằng cách sử dụng Section trong PHP.

Section trong PHP
Section trong PHP

Section trong PHP là gì?

Section có nghĩa là Phiên.

Mặc dù bạn có thể lưu trữ dữ liệu bằng cookie nhưng nó có một số vấn đề bảo mật. Vì cookie được lưu trữ trên máy tính của người dùng, kẻ tấn công có thể dễ dàng sửa đổi nội dung cookie để chèn dữ liệu có hại trong website của bạn.

Ngoài ra, mỗi khi trình duyệt gửi một request URL đến máy chủ, tất cả dữ liệu cookie cho trang web sẽ tự động được gửi đến máy chủ trong request đó.

Điều này có nghĩa là nếu bạn đã lưu trữ 5 cookie trên hệ thống của người dùng, mỗi cookie có kích thước 4KB, trình duyệt cần tải thêm 20KB dữ liệu mỗi khi người dùng xem một trang, điều này có thể ảnh hưởng đến hiệu suất trang web của bạn.

Bạn có thể giải quyết cả hai vấn đề này bằng cách sử dụng Section trong PHP. Một phiên lưu trữ dữ liệu trên máy chủ thay vì máy tính của người dùng.

Trong mỗi phiên, mọi người dùng được xác định thông qua một số duy nhất được gọi là định danh phiên hoặc SID. Section ID duy nhất này được sử dụng để liên kết mỗi người dùng với thông tin của riêng họ trên máy chủ như email, bài đăng, v.v.

Note: ID phiên được tạo ngẫu nhiên bởi công cụ PHP gần như không thể đoán được. Hơn nữa, vì dữ liệu phiên được lưu trữ trên máy chủ, nên nó không cần phải gửi với request của user.

Các khởi tạo một phiên trong PHP

Trước khi bạn có thể lưu trữ bất kỳ thông tin nào trong các biến của phiên, trước tiên bạn phải bắt đầu khởi tạo một phiên.

Để bắt đầu một phiên mới, chỉ cần gọi hàm PHP session_start(). Nó sẽ tạo một phiên mới và tạo ID phiên duy nhất cho người dùng.

Đoạn mã PHP trong ví dụ dưới đây chỉ đơn giản là bắt đầu một phiên mới.:

<?php
  // Bắt đầu một phiên
  session_start();
?>

Hàm session_start() trước tiên kiểm tra xem liệu một phiên đã tồn tại chưa bằng cách tìm kiếm sự hiện diện của ID.

  • Nếu nó tìm thấy, tức là phiên đã bắt đầu, nó sẽ thiết lập các biến phiên
  • Nếu không, nó sẽ bắt đầu một phiên mới bằng cách tạo ID phiên mới.

Lưu ý: Bạn phải gọi hàm session_start() ở ngay đầu trang tức là trước bất kỳ đoạn mã nào, nó cũng giống như bạn làm trong khi thiết lập cookie với hàm setcookie().

Hướng dẫn lưu trữ và truy cập dữ liệu của Phiên

Bạn có thể lưu trữ tất cả dữ liệu phiên của mình dưới dạng các cặp key – value trong mảng supperglobal $ _SESSION[].

Dữ liệu được lưu trữ có thể được truy cập trong suốt thời gian tồn tại của phiên. Hãy xem xét đoạn mã sau, cách tạo ra một phiên mới và đăng ký hai biến phiên.

<?php
  // Starting session
  session_start();
 
  // Storing session data
  $_SESSION["firstname"] = "Php";
  $_SESSION["lastname"] = "DEV";
?>

Để truy cập dữ liệu phiên, chúng ta đã đặt trên ví dụ trước từ bất kỳ trang nào khác trên cùng một tên miền web – chỉ cần tạo lại phiên bằng cách gọi session_start() và sau đó chuyển key tương ứng vào mảng kết hợp $ _SESSION

<?php
  // Starting session
  session_start();
 
  // Accessing session data
  echo 'Hi, ' . $_SESSION["firstname"] . ' ' . $_SESSION["lastname"];
?>

Đoạn mã PHP trong ví dụ trên tạo ra kết quả như sau:

Hi, Php DEV

Note: Để truy cập dữ liệu phiên trong cùng một trang, không cần phải tạo lại phiên vì nó đã được bắt đầu trên đầu trang.

Hướng dẫn các Phá hủy Phiên

Nếu bạn muốn xóa dữ liệu nhất định của phiên, chỉ cần unset key tương ứng của mảng kết hợp $_SESSION, như trong ví dụ sau:

<?php
  // Bắt đầu phiên
  session_start();
 
  // Xóa dữ liệu của phiên
  if(isset($_SESSION["lastname"])){
      unset($_SESSION["lastname"]);
  }
?>

Tuy nhiên, việc unset không phá hủy hoàn toàn phiên.

Muốn hủy hoàn toàn một phiên, chỉ cần gọi hàm session_destroy(). Hàm này không cần bất kỳ đối số nào và một lệnh gọi sẽ hủy tất cả dữ liệu phiên.

<?php
  // Bắt đầu phiên
  session_start();
 
  // Phá hủy phiên
  session_destroy();
?>

Lưu ý: Trước khi hủy phiên với hàm session_destroy(), trước tiên bạn cần tạo lại môi trường phiên nếu nó chưa có ở đó bằng cách sử dụng hàm session_start(). Phải có thứ gì đó thì mới hủy được chứ, đúng không nào?

Mỗi phiên PHP có một giá trị thời gian chờ – thời lượng, được tính bằng giây – xác định thời gian một phiên sẽ tồn tại trong trường hợp không có bất kỳ hoạt động nào của người dùng. Bạn có thể điều chỉnh thời lượng hết thời gian này bằng cách thay đổi giá trị của biến session.gc_maxlifetime trong tệp cấu hình PHP (php.ini).

Lời kết

Như vậy qua bài này bạn đã biết Section (phiên) là gì, cách tạo một phiên, các truy cập phiênxóa / phá hủy dữ liệu của phiên.

Chúng ta sẽ còn sử dụng phiên để cá nhân hóa trải nghiệm cho người dùng rất nhiều. Bạn sẽ quen dần qua các bài tập sau này.

Bài 24: PHP Cookies

Trong bài học này, mình sẽ hướng dẫn bạn sẽ tìm hiểu làm thế nào để sử dụng cookies trong PHP. Cách thiết lập cookie, truy cập cookie, xóa cookie trong PHP.

Trong bài học này, mình sẽ hướng dẫn bạn sẽ tìm hiểu làm thế nào để sử dụng cookies trong PHP lưu trữ một số thông tin trong trình duyệt của người dùng.

PHP Cookie, Hướng dẫn thiết lập Cookie trong PHP
PHP Cookie, Hướng dẫn thiết lập Cookie trong PHP

1. Cookie là gì?

Một cookie là một tập tin văn bản cho phép bạn lưu trữ một ít dữ liệu (gần 4KB) trên máy tính của người dùng.

Các lập trình viên thường dùng cookies để theo dõi các thông tin như tên người dùng … để có thể cá nhân hóa lượt truy cập của họ trong các lần tiếp theo.

Note: Mỗi lần trình duyệt gửi request đến máy chủ, tất cả dữ liệu trong cookie cũng sẽ tự động được gửi đến máy chủ.

2. Hướng dẫn thiết lập Cookie trong PHP

Hàm setcookie() được sử dụng để thiết lập cookie trong PHP.

Cần phải đảm bảo bạn đã gọi hàm setcookie() trước khi bất kỳ output nào được tạo nếu không cookie sẽ không được thiết lập.

Cú pháp để thiết lập Cookie như sau:

setcookie(namevalueexpirepathdomainsecure);

Các tham số của hàm setcookie() có các ý nghĩa sau:

  • name: Tên của cookie
  • value: Giá trị của cookie. Lưu ý, không lưu trữ thông tin nhạy cảm vì giá trị này được lưu trữ trên máy tính của người dùng.
  • expires: Ngày hết hạn ở định dạng dấu thời gian UNIX. Sau thời gian này cookie sẽ không thể truy cập được. Giá trị mặc định là 0.
  • path: Chỉ định đường dẫn trên máy chủ mà cookie sẽ có hiệu lực. Nếu được đặt thành /, cookie sẽ có sẵn trong toàn bộ domain.
  • domain: Chỉ định tên miền mà cookie có hiệu lực, ví dụ: www.laptrinhvienphp.com
  • sercure: Trường này, nếu có, chỉ ra rằng cookie chỉ được gửi nếu có kết nối HTTPS

Note: Nếu thời gian hết hạn của cookie được đặt thành 0 hoặc bị bỏ qua, cookie sẽ hết hạn vào cuối phiên (section), tức là cho đến khi trình duyệt đóng lại.

Dưới đây là một ví dụ sử dụng hàm setcookie() để tạo cookie có username và gán giá trị giá trị Em Vi cho nó. Và xác định rằng cookie sẽ hết hạn sau 30 ngày (30 ngày * 24 giờ * 60 phút * 60 giây).

<?php
// Setting a cookie
setcookie("username", "Em Vi", time()+30*24*60*60);
?>

Note: Tất cả những tham số ngoại trừ username đều là tùy chọn. Bạn cũng có thể thay thế một tham số với một chuỗi rỗng (”) để bỏ qua nó, tuy nhiên để bỏ qua expires thì nên sử dụng số 0, vì kiểu của nó là một số nguyên.

Cảnh báo: Không lưu trữ dữ liệu nhạy cảm trong cookie vì nó có khả năng bị người dùng “không trong sáng” thao túng. Hãy lưu trữ dữ liệu nhạy cảm một cách an toàn sử dụng section để thay thế.

3. Hướng dẫn truy cập giá trị của Cookie.

Biến superglobal PHP $ _COOKIE được sử dụng để truy xuất giá trị của cookie. Nó thường là một mảng kết hợp có chứa một danh sách tất cả các giá trị cookie được trình duyệt gửi, nó được khóa bằng tên cookie.

Giá trị cookie riêng lẻ có thể được truy cập bằng cách sử dụng ký hiệu mảng tiêu chuẩn.

Ví dụ: Để hiển thị cookie tên người dùng được đặt trong ví dụ trước, bạn có thể sử dụng đoạn mã sau đây.

<?php
// Truy cập một giá trị Cookie riêng lẻ
echo $_COOKIE["username"];
?>

Chúng ta nhận được kết của của ví dụ trên như sau:

Em Vi

Đấy là một cách làm tốt để kiểm tra xem cookie có được thiết lập hay không trước khi truy cập giá trị của nó. Để làm điều này, bạn có thể sử dụng hàm PHP isset(), như thế này:

<?php
// Các xác minh xem Cookie có được thiết lập hay không
  if(isset($_COOKIE["username"])){
      echo "Hi " . $_COOKIE["username"];
  } else{
      echo "Welcome Guest!";
  }
?>

Bạn có thể sử dụng hàm print_r() như print_r($ _ COOKIE); Để xem cấu trúc của mảng kết hợp $ _COOKIE này, nó giống như cách bạn với các mảng khác thôi.

4. Hướng dẫn Xóa Cookie trong PHP

Bạn có thể xóa cookie bằng cách gọi cùng hàm setcookie() với tên cookie và bất kỳ giá trị nào (chẳng hạn như chuỗi rỗng), tuy nhiên lần này bạn cần đặt ngày hết hạn trong quá khứ, như trong ví dụ dưới đây:

<?php
// Xóa Cookie
  setcookie("username", "", time()-3600);
?>

Note: Bạn nên truyền chính xác cùng một đường dẫn, tên miền và các đối số khác mà bạn đã sử dụng khi lần đầu tiên tạo cookie để đảm bảo rằng cookie bị xóa chính xác.

Tổng kết

Như vậy là qua bài này bạn đã được giới thiệu về Cookie trong PHP, cách thiết lập Cookie, Cách truy cập giá trị của Cookie và cả cách xóa Cookie.

Chúng ta sẽ thường xuyên sử dụng cookie để cá nhân hóa trình duyệt ví dụ theo tài khoản của người dùng, theo email họ đăng nhập…