Hằng số (constant) là tên cho một giá trị không bao giờ thay đổi trong khi script chạy. Khai báo bằng const MAX_USERS = 100; hoặc define('MAX_USERS', 100);, rồi dùng tên trần, không có $.
Theo quy ước, tên hằng số được viết dạng UPPER_SNAKE_CASE. Hằng số có phạm vi toàn cục: một hằng số khai báo ở đầu tệp sẽ thấy được bên trong mọi hàm mà không cần global.
define() và const
Cả hai đều tạo hằng số, nhưng chúng hoạt động vào những thời điểm khác nhau. const được xử lý khi PHP biên dịch tệp, còn define() chạy như mọi lời gọi hàm khác.
const | define() | |
|---|---|---|
Bên trong if, vòng lặp, hàm | Không | Có |
| Tên ghép từ một biến | Không | Có |
| Hằng số lớp | Có | Không |
| Giá trị là một biểu thức | Có, gồm hằng số và giá trị literal | Có, giá trị bất kỳ |
| Tự động thuộc namespace | Có | Không (phải ghi tên đầy đủ) |
Mặc định hãy dùng const, vì nó ngắn hơn và được kiểm tra lúc biên dịch. Dùng define() khi hằng số phụ thuộc vào một điều kiện hoặc một tên được tính ra.
Hằng số không thể thay đổi
Gán giá trị cho một hằng số là lỗi cú pháp (parse error):
<?php
const LIMIT = 10;
LIMIT = 20;
PHP Parse error: syntax error, unexpected token "=" in /home/index.php on line 3
Định nghĩa cùng một hằng số hai lần thì không phải lỗi, nhưng PHP in ra cảnh báo và giữ giá trị đầu tiên:
<?php
define("LIMIT", 10);
define("LIMIT", 20);
echo LIMIT; // 10
Warning: Constant LIMIT already defined in /home/index.php on line 3
Khi một giá trị có thể đã được đặt từ trước (ví dụ trong một tệp cấu hình được nạp nhiều lần), hãy kiểm tra bằng defined() trước:
Hằng số mảng
Hằng số có thể chứa một mảng. Bạn đọc được nó bằng NAME[key], duyệt qua nó và truyền nó đi khắp nơi, nhưng không sửa được.
Hằng số lớp
Bên trong một lớp, const khai báo một hằng số thuộc về lớp đó. Đọc nó bằng ClassName::NAME từ bên ngoài và bằng self::NAME hoặc static::NAME từ bên trong. Hằng số lớp có thể có phạm vi truy cập, có thể là final, và từ PHP 8.3 có thể khai báo kiểu.
Một nhóm hằng số lớp liên quan như STATUS_NEW và STATUS_PAID thường nên viết thành một enum, cách này còn ngăn các giá trị không hợp lệ bị truyền đi khắp nơi.
Magic constant: LINE, FILE, DIR và các hằng số khác
Magic constant đổi giá trị tùy theo nơi chúng xuất hiện. Giá trị của chúng được điền vào lúc biên dịch.
Hằng số được dùng nhiều nhất là __DIR__, thư mục của tệp hiện tại. Tạo đường dẫn include từ nó giúp đường dẫn luôn đúng, bất kể script được chạy từ thư mục nào: require __DIR__ . '/config.php';. Xem cách làm đầy đủ ở trang include và require.
Những hằng số có sẵn nên biết
PHP định nghĩa sẵn rất nhiều hằng số. Đây là những hằng số bạn sẽ gặp thường xuyên:
PHP_EOL là ký tự xuống dòng của hệ thống mà PHP đang chạy ("\n" trên Linux và macOS, "\r\n" trên Windows). Nó dành cho văn bản ghi ra tệp và terminal; trong đầu ra HTML, ký tự xuống dòng không hiển thị, nên ở đó hãy dùng <br>.
Câu hỏi thường gặp
define() và const trong PHP khác nhau thế nào?
const là một cấu trúc ngôn ngữ được xử lý khi tệp được biên dịch: dùng được ở cấp cao nhất và bên trong lớp, nhưng không dùng được trong if, vòng lặp hay hàm. define() là một hàm được gọi lúc chạy, nên dùng được ở mọi nơi và tên có thể ghép từ một biến, nhưng không khai báo được hằng số lớp.
Hằng số trong PHP có thể là mảng không?
Có. Cả const COLORS = ['red', 'green']; lẫn define('COLORS', ['red', 'green']); đều dùng được, và bạn đọc một phần tử bằng COLORS[0]. Sau đó mảng không thể bị sửa.
Làm sao kiểm tra một hằng số đã được định nghĩa trong PHP?
Dùng defined('NAME'), hàm này nhận tên dưới dạng chuỗi và trả về true hoặc false. Một mẫu thường gặp là if (!defined('APP_ENV')) { define('APP_ENV', 'production'); }. Với hằng số lớp, truyền 'ClassName::NAME'.
Magic constant trong PHP là gì?
Là những hằng số có giá trị tùy vào nơi chúng được viết: __LINE__ (dòng hiện tại), __FILE__ (đường dẫn đầy đủ của tệp), __DIR__ (thư mục chứa tệp), __FUNCTION__, __CLASS__, __METHOD__ và __NAMESPACE__. Chúng được viết với hai dấu gạch dưới ở mỗi bên và không phân biệt hoa thường.