Học PHP với ví dụ chạy trực tiếp
Hướng dẫn và tài liệu tham khảo PHP 8 miễn phí: mảng, foreach, hàm xử lý chuỗi, ngày tháng, biểu mẫu, lớp và lỗi. Mọi ví dụ đều chạy ngay trên trang, ví dụ in ra HTML sẽ hiện thành trang web, kèm biểu mẫu bạn gửi được.
Bắt đầu khóa họcBắt đầu
- PHP là gì?PHP là ngôn ngữ kịch bản phía máy chủ (server-side): tệp PHP chạy trên máy chủ web và gửi HTML mà nó tạo ra về trình duyệt. PHP đứng sau WordPress, Laravel và một phần lớn các trang web, đồng thời cũng chạy được script từ dòng lệnh.
- Cài đặt PHPCài đặt PHP chỉ với một lệnh: winget trên Windows, Homebrew trên macOS, apt hoặc dnf trên Linux. Sau đó chạy php -v trong terminal để kiểm tra PHP đã chạy được chưa và bạn đang có phiên bản nào.
- Chạy PHPChạy một tệp PHP từ terminal bằng php index.php, hoặc mở cả thư mục trong trình duyệt bằng máy chủ có sẵn của PHP: php -S localhost:8000. Cả hai cách đều không cần Apache hay XAMPP.
- echo và printecho in ra một hoặc nhiều chuỗi: echo "Hello, $name"; hoặc echo $a, $b;. Đây là cách thông dụng để gửi chữ hoặc HTML ra trang web. print làm điều tương tự với một giá trị và trả về 1; <?= $x ?> là dạng rút gọn bên trong HTML.
- Báo lỗiĐể hiện mọi lỗi PHP, hãy đặt ini_set('display_errors', '1'); và error_reporting(E_ALL); ở đầu script, hoặc đặt display_errors = On và error_reporting = E_ALL trong php.ini. Trên môi trường production, hãy ghi lỗi vào log thay vì hiển thị chúng.
- PHP vs PythonPHP sinh ra cho web: mỗi request chạy một tệp và in ra một trang, và nó là nền tảng của WordPress và Laravel. Python là ngôn ngữ đa năng, cũng làm web (Django, Flask) và dẫn đầu trong khoa học dữ liệu, tự động hóa và machine learning.
- PHP vs JavaScriptPHP chạy trên máy chủ và gửi HTML hoàn chỉnh về trình duyệt. JavaScript chạy trong trình duyệt, nơi nó thay đổi trang sau khi tải xong, và chạy cả trên máy chủ với Node.js. Phần lớn website dùng cả hai: PHP để dựng trang và API, JavaScript cho phần tương tác.
Kiến thức cơ bản
- BiếnBiến trong PHP bắt đầu bằng $ và được tạo ra khi bạn gán giá trị cho nó: $name = "Ada";. Không có từ khóa khai báo và không có kiểu cố định. Hàm không thấy biến bên ngoài trừ khi bạn truyền vào, dùng global hoặc capture nó; static giữ giá trị giữa các lần gọi.
- Kiểu dữ liệuPHP có mười kiểu dữ liệu: bốn kiểu vô hướng (int, float, string, bool), bốn kiểu phức hợp (array, object, callable, iterable) và hai kiểu đặc biệt (null, resource). var_dump($x) cho thấy kiểu và giá trị, gettype($x) trả về tên kiểu.
- ChuỗiNối chuỗi PHP bằng toán tử dấu chấm ("Hello, " . $name) hoặc đặt biến thẳng vào trong dấu nháy kép ("Hello, $name"). Dấu nháy đơn in văn bản đúng như khi viết. Tìm hiểu cách nối chuỗi, toán tử .=, nội suy mảng và đối tượng, cùng cách đổi chữ hoa, chữ thường với strtoupper, strtolower, ucfirst và ucwords.
- Heredoc và nowdocHeredoc trong PHP là một chuỗi nhiều dòng bắt đầu bằng <<<EOT và kết thúc bằng EOT; nó thay thế biến giống chuỗi trong ngoặc kép. Nowdoc, <<<'EOT', giữ nguyên văn bản như khi viết. Tìm hiểu cú pháp, quy tắc thụt lề, chèn mảng và đối tượng, cùng template HTML.
- Toán tửToán tử trong PHP làm việc với các giá trị: +, -, *, /, %, ** cho số học, =, +=, .=, ??= cho phép gán, &&, ||, ! và xor cho logic, . để nối chuỗi, ==, ===, <=> để so sánh và ++, -- để tăng giảm. Học từng nhóm qua ví dụ chạy được, cùng cái bẫy độ ưu tiên của and so với &&.
- Toán tử so sánhPHP so sánh giá trị bằng == (bằng nhau sau khi chuyển kiểu), === (cùng giá trị và cùng kiểu), != và !==, < > <= >= và toán tử spaceship <=>. Tìm hiểu khi nào == chuyển kiểu, PHP 8 đã thay đổi gì, và xem mọi phép so sánh lỏng và chặt trong một bảng.
- Toán tử ba ngôiToán tử ba ngôi (ternary) trong PHP là một câu if/else trên một dòng: $result = $condition ? 'yes' : 'no';. Tìm hiểu dạng rút gọn ?: (toán tử Elvis), điểm khác với ??, vì sao toán tử ba ngôi lồng nhau cần dấu ngoặc từ PHP 8, và khi nào match là lựa chọn gọn hơn.
- Null coalescing ??Toán tử null coalescing trong PHP trả về vế trái trừ khi vế đó là null hoặc chưa được đặt: $name = $_GET['name'] ?? 'Guest';. Nó không bao giờ cảnh báo khi thiếu biến hay khóa mảng. Tìm hiểu chuỗi ??, phép gán ??=, ?? so với ?: và toán tử nullsafe ?->.
- Ép kiểuChuyển chuỗi PHP thành số nguyên bằng (int) $str hoặc intval($str); (int) "42" là 42 và (int) "12abc" là 12. Tìm hiểu cách ép kiểu sang int, float, bool, string và array, chuỗi số, intval với hệ cơ số, settype, và cách kiểm tra dữ liệu nhập thay vì lặng lẽ nhận về 0.
- Hằng sốHằng số trong PHP là tên cho một giá trị không thể thay đổi: const MAX_USERS = 100; hoặc define('MAX_USERS', 100);. Tìm hiểu define và const, hằng số mảng, hằng số lớp với self::, kiểm tra bằng defined(), và các magic constant __LINE__, __FILE__, __DIR__, __CLASS__.
- isset()isset($var) trả về true khi biến tồn tại và khác null, ngược lại trả về false, không kèm cảnh báo nào. Hàm này còn kiểm tra được khóa mảng và thuộc tính đối tượng: isset($user['email']). Tìm hiểu isset với nhiều biến, khóa lồng nhau, isset và empty, isset và array_key_exists, cùng cách kiểm tra form đã được gửi.
- empty()empty($var) trả về true khi một biến không tồn tại hoặc có giá trị falsy: null, false, 0, 0.0, "", "0" hoặc []. Hàm này không bao giờ cảnh báo về biến hay khóa chưa định nghĩa. Tìm hiểu vì sao "0" bị coi là rỗng, cách kiểm tra chính xác chuỗi rỗng hay mảng rỗng, empty và isset, và kiểm tra dữ liệu form.
- Toán học và làm trònround($x, 2) làm tròn đến hai chữ số thập phân, floor() luôn làm tròn xuống và ceil() luôn làm tròn lên. Thêm intdiv(), toán tử %, ** để tính lũy thừa, abs(), max(), min() và random_int() để lấy số ngẫu nhiên.
Luồng điều khiển
- if, elseif, elseif (condition) { ... } chỉ chạy khối lệnh khi điều kiện là true, elseif kiểm tra điều kiện tiếp theo, còn else chạy khi không có điều kiện nào khớp. Bài viết so sánh elseif với else if, nói về && và ||, giá trị truthy và cú pháp if: endif; cho template HTML.
- Câu lệnh switchswitch ($value) so sánh một giá trị với danh sách các nhãn case và chạy code từ case khớp đầu tiên cho đến khi gặp break. Gồm nhiều case cho một khối, fallthrough, default, switch(true) và lý do switch dùng phép so sánh lỏng ==.
- Biểu thức matchmatch ($x) { 1, 2 => 'low', default => 'other' } so sánh một giá trị bằng === nghiêm ngặt, trả về kết quả của nhánh khớp đầu tiên và ném ra UnhandledMatchError khi không nhánh nào khớp. Gồm match so với switch, match(true) và match với enum.
- Vòng lặp forfor ($i = 0; $i < 10; $i++) { ... } chạy một khối lệnh với số lần định trước: giá trị bắt đầu, điều kiện được kiểm tra trước mỗi lượt và bước nhảy. Bài viết gồm duyệt mảng theo chỉ số, đếm ngược, vòng lặp lồng nhau, break và continue.
- Vòng lặp whilewhile (condition) { ... } lặp lại một khối lệnh chừng nào điều kiện còn đúng, và kiểm tra điều kiện trước mỗi lần lặp. do { ... } while (condition); kiểm tra sau, nên luôn chạy ít nhất một lần. Bài này gồm while (true) với break, đọc tệp từng dòng và cách tránh vòng lặp vô hạn.
- Vòng lặp foreachforeach ($array as $value) đi qua mọi phần tử của mảng, còn foreach ($array as $key => $value) cho bạn cả khóa. Bài viết gồm lấy chỉ số, đổi giá trị qua tham chiếu và cái bẫy unset(), break và continue, mảng lồng nhau, list() trong foreach và dựng HTML.
Mảng
- MảngMảng trong PHP là một danh sách có thứ tự, mỗi giá trị nằm dưới một khóa: $fruits = ['apple', 'banana']; đọc phần tử bằng $fruits[0]. Tìm hiểu cách tạo mảng, đọc và sửa phần tử, duyệt mảng, in mảng và nên chọn hàm mảng nào.
- Mảng kết hợpMảng kết hợp trong PHP lưu giá trị dưới các khóa do bạn đặt tên: $user = ['name' => 'Ada', 'age' => 36]; đọc bằng $user['name']. Tìm hiểu cách thêm, sửa, xóa cặp, duyệt khóa và giá trị, lấy mọi khóa hoặc giá trị, kiểm tra khóa và sắp xếp theo khóa hoặc giá trị.
- Mảng đa chiềuMảng đa chiều trong PHP là mảng có các phần tử là mảng, đọc bằng một cặp ngoặc vuông cho mỗi cấp: $grid[1][2] hoặc $users[0]['name']. Học cách tạo mảng lồng nhau, đọc và sửa giá trị ở sâu bên trong, lặp bằng foreach lồng nhau, tạo bảng HTML, lấy ra một cột và sắp xếp các hàng.
- array_push()array_push($arr, $value) thêm một hoặc nhiều giá trị vào cuối mảng; $arr[] = $value làm điều tương tự cho một giá trị và nhanh hơn. Tìm hiểu cách thêm vào cuối, đầu hoặc giữa mảng, thêm khóa và giá trị, và tránh bug kinh điển với giá trị trả về.
- count()count($arr) trả về số phần tử của một mảng PHP, nên count(['a', 'b', 'c']) là 3. Tìm hiểu cách đếm mảng lồng nhau với COUNT_RECURSIVE, quan hệ giữa sizeof() và count(), cách đếm các giá trị thỏa điều kiện, và vì sao count(null) ném TypeError từ PHP 8.
- in_array()in_array($needle, $haystack) trả về true khi giá trị có trong mảng. Truyền true làm đối số thứ ba để kiểm tra nghiêm ngặt, in_array('1', $ids, true), khi đó kiểu dữ liệu cũng phải khớp. Tìm hiểu cờ strict, tìm kiếm không phân biệt hoa thường, kiểm tra nhiều giá trị, mảng lồng nhau và cách tra cứu nhanh bằng isset.
- array_search()array_search($value, $array) trả về khóa của phần tử đầu tiên bằng $value, hoặc false khi không có phần tử nào. Vì khóa có thể là 0, hãy luôn kiểm tra kết quả bằng !== false. Tìm hiểu tìm kiếm strict, tìm mọi kết quả khớp, tìm trong mảng đa chiều với array_column và tìm kiếm không phân biệt hoa thường.
- array_key_exists()array_key_exists('key', $array) trả về true khi mảng có khóa đó, kể cả khi giá trị là null. isset($array['key']) nhanh hơn nhưng trả về false với giá trị null. Tìm hiểu sự khác biệt, key_exists(), khóa lồng nhau, kiểm tra nhiều khóa và vì sao đối tượng cần property_exists().
- array_merge()array_merge($a, $b) gộp các mảng thành một: giá trị có khóa số được nối vào cuối và đánh số lại, còn với khóa chuỗi thì mảng đứng sau thắng. Tìm hiểu array_merge khác toán tử + và cú pháp spread [...$a, ...$b] ra sao, cách gộp một danh sách các mảng, và khi nào array_merge_recursive hay array_replace phù hợp hơn.
- array_map()array_map($callback, $array) gọi callback trên mọi phần tử và trả về một mảng mới chứa kết quả. Tìm hiểu arrow function, khóa, xử lý nhiều mảng cùng lúc và khi nào array_walk hay foreach phù hợp hơn.
- array_filter()array_filter($array, $callback) giữ lại các phần tử mà callback trả về true. Tìm hiểu cách xóa giá trị rỗng, lọc theo khóa với ARRAY_FILTER_USE_KEY, đánh số lại kết quả bằng array_values và cộng dồn bằng array_reduce.
- Sắp xếp mảngsort($array) sắp xếp một danh sách ngay tại chỗ, asort và ksort sắp xếp mảng kết hợp theo giá trị hoặc theo khóa, còn usort sắp xếp theo hàm so sánh của riêng bạn. Tìm hiểu tất cả các hàm này, sắp xếp mảng nhiều chiều theo một cột, và tránh lỗi kinh điển $sorted = sort($arr).
- Xóa phần tử khỏi mảngunset($array[$key]) xóa một phần tử theo khóa, array_splice xóa theo vị trí và đánh số lại, còn array_diff xóa theo giá trị. Tìm hiểu từng cách, cách đánh lại chỉ số sau khi xóa, và cái bẫy của array_search khiến bạn xóa nhầm phần tử.
- array_slice()array_slice($array, $offset, $length) trả về bản sao một phần của mảng mà không thay đổi mảng gốc. Tìm hiểu offset âm để lấy các phần tử cuối, preserve_keys, phân trang một danh sách và khác biệt với array_splice.
- array_unique()array_unique($array) xóa các giá trị trùng lặp và giữ lần xuất hiện đầu tiên của mỗi giá trị cùng khóa gốc. Tìm hiểu cách đánh số lại kết quả, xóa trùng lặp không phân biệt hoa thường, lọc trùng mảng nhiều chiều, đếm và tìm giá trị trùng.
- array_column()array_column($rows, 'email') trả về trường email của mọi hàng dưới dạng một mảng phẳng. Tìm hiểu đối số index key, đánh chỉ mục lại các hàng theo id, dùng hàm này với đối tượng và tìm một hàng bằng array_search.
- Destructuring và list()[$a, $b] = $array gán hai phần tử đầu tiên cho $a và $b chỉ trong một dòng, còn ['name' => $name] = $user làm điều tương tự theo khóa. list() là cách viết cũ hơn. Trang này gồm bỏ qua phần tử, hoán đổi biến, trả về nhiều giá trị, destructuring trong foreach và toán tử spread ...
Chuỗi
- explode()explode(',', $string) tách một chuỗi tại mọi dấu phẩy và trả về các phần dưới dạng mảng. Tìm hiểu tham số limit, tách theo dòng, trim từng phần, và khi nào str_split hay preg_split là lựa chọn tốt hơn.
- implode()implode(', ', $array) nối các giá trị của mảng thành một chuỗi, đặt dấu phân cách giữa chúng. Tìm hiểu implode với khóa, mảng kết hợp, cách tạo danh sách HTML và khác biệt giữa implode và join.
- str_replace()str_replace($search, $replace, $subject) thay mọi lần xuất hiện của $search bằng $replace. Tìm hiểu cách dùng mảng cho giá trị tìm và thay, đếm số lần thay, str_ireplace không phân biệt hoa thường, và cách chỉ thay lần xuất hiện đầu tiên.
- substr()substr($string, $offset, $length) trả về một phần của chuỗi. Tìm hiểu offset âm, cách lấy các ký tự đầu hoặc cuối, mb_substr cho tiếng Việt, tiếng Nhật và văn bản UTF-8 khác, substr_count, và cách rút gọn văn bản kèm dấu ba chấm.
- strpos()strpos($haystack, $needle) trả về vị trí xuất hiện đầu tiên của $needle, hoặc false nếu không tìm thấy. Tìm hiểu phép kiểm tra !== false, hàm stripos không phân biệt hoa thường, lần xuất hiện cuối cùng với strrpos và cách tìm mọi lần xuất hiện.
- str_contains()str_contains($haystack, $needle) trả về true nếu $needle xuất hiện ở bất kỳ đâu trong $haystack. Tìm hiểu cách kiểm tra không phân biệt hoa thường, str_starts_with và str_ends_with, kiểm tra nhiều từ cùng lúc, và cách dùng strpos cho PHP 7.
- trim()trim($string) xóa khoảng trắng, tab và ký tự xuống dòng ở cả hai đầu chuỗi; ltrim() và rtrim() làm sạch một phía. Tìm hiểu cách xóa các ký tự cụ thể, khoảng trắng toàn khổ của tiếng Nhật và trim mọi giá trị trong mảng.
- strlen()strlen($string) trả về độ dài chuỗi tính theo byte; mb_strlen($string) trả về độ dài tính theo ký tự. Tìm hiểu vì sao chữ có dấu, tiếng Nhật và emoji cho kết quả khác nhau, cách kiểm tra chuỗi rỗng và cách kiểm tra độ dài dữ liệu nhập vào.
- sprintf()sprintf() tạo một chuỗi từ một định dạng và các giá trị: sprintf('%05.2f', 3.14159) trả về "03.14". Tìm hiểu %s, %d và %f, thêm số 0 ở đầu, cố định số chữ số thập phân, căn lề, đánh số đối số, printf và vsprintf.
- number_format()number_format(1234567.891, 2) trả về "1,234,567.89": hàm làm tròn đến số chữ số thập phân đã chọn và thêm dấu phân cách hàng nghìn. Tìm hiểu bốn tham số, định dạng kiểu châu Âu và kiểu Việt Nam, cách hàm làm tròn và vì sao kết quả là một chuỗi.
- Xuống dòngĐể in xuống dòng trong PHP, viết "\n" trong dấu nháy kép hoặc dùng PHP_EOL. Trên trang web, ký tự xuống dòng không hiện ra, nên hãy dùng <br> hoặc nl2br(). Tìm hiểu sự khác nhau, vì sao '\n' trong dấu nháy đơn không chạy, và cách tách hoặc bỏ ký tự xuống dòng.
- preg_match()preg_match($pattern, $subject, $matches) kiểm tra một chuỗi với biểu thức chính quy, trả về 1 nếu khớp và 0 nếu không. Tìm hiểu nhóm bắt, nhóm có tên, preg_match_all, neo, mẫu kiểm tra dữ liệu và modifier u cho văn bản UTF-8 như tiếng Việt hay tiếng Nhật.
- preg_replace()preg_replace($pattern, $replacement, $subject) thay thế mọi phần khớp với một biểu thức chính quy: preg_replace('/\s+/', ' ', $text) gộp các khoảng trắng liền nhau. Tìm hiểu tham chiếu ngược như $1, preg_replace_callback, cách xóa ký tự không phải chữ và số, giới hạn và đếm số lần thay.
Hàm
- HàmĐịnh nghĩa một hàm PHP bằng function name($param) { return $value; }. Tìm hiểu giá trị trả về, tham số mặc định, đối số có tên, truyền tham chiếu, khai báo kiểu với strict_types, kiểu nullable và union, cùng tham số biến đổi ...$args.
- Arrow functionArrow function là hàm ẩn danh chỉ gồm một biểu thức, viết dạng fn($x) => $x * 2. Hàm tự dùng các biến bên ngoài theo giá trị mà không cần use. Tìm hiểu cú pháp, cách bắt biến, kiểu dữ liệu, callback cho array_map và usort, và khi nào nên dùng closure đầy đủ.
- Hàm ẩn danhHàm ẩn danh (closure) là một hàm không có tên được lưu trong biến: $greet = function ($name) { return "Hi $name"; };. Tìm hiểu từ khóa use, bắt biến theo tham chiếu, callable, cú pháp first-class callable strlen(...) và closure bên trong lớp.
- GeneratorGenerator là một hàm dùng yield để trả từng giá trị một, nhờ đó foreach có thể lặp qua một triệu phần tử mà không cần tạo mảng. Tìm hiểu yield, khóa, tiết kiệm bộ nhớ, dãy vô hạn, yield from, send() và getReturn().
Lớp và đối tượng
- Lớp và đối tượngLớp trong PHP là một bản thiết kế khai báo bằng `class Name { }`, còn `new Name()` tạo ra một đối tượng từ lớp đó. Tìm hiểu thuộc tính, phương thức, `$this`, public/private/protected, thuộc tính có kiểu và readonly, `__toString`, và vì sao gán đối tượng không tạo bản sao.
- Hàm khởi tạoHàm khởi tạo (constructor) trong PHP là phương thức `__construct()`, tự động chạy khi bạn viết `new ClassName(...)`. Tìm hiểu constructor property promotion, đối số mặc định và đối số có tên, kiểm tra dữ liệu, `parent::__construct()`, và cách giả lập nhiều hàm khởi tạo bằng phương thức factory static.
- Kế thừaTrong PHP, một lớp kế thừa lớp khác bằng `class Dog extends Animal`: nó nhận các thuộc tính và phương thức public, protected của lớp cha, có thể ghi đè chúng và vẫn gọi được bản gốc bằng `parent::method()`. Tìm hiểu ghi đè, protected, final, instanceof và cái bẫy phương thức private.
- InterfaceInterface trong PHP liệt kê các phương thức mà một lớp cam kết phải có: `interface Shape { public function area(): float; }`, khi đó `class Circle implements Shape` bắt buộc định nghĩa `area()`. Tìm hiểu type hint với interface, implement nhiều interface, hằng số trong interface, interface kế thừa interface, các interface có sẵn như Countable, và so sánh interface với lớp trừu tượng.
- Abstract classAbstract class trong PHP được khai báo bằng `abstract class Name` và không thể tạo instance: nó tồn tại để được kế thừa. Nó có thể chứa thuộc tính, hàm khởi tạo và các phương thức hoàn chỉnh, cùng các phương thức `abstract` không có thân mà mọi lớp con phải cài đặt.
- TraitTrait trong PHP là một khối phương thức và thuộc tính dùng lại được, mà bạn chép vào một lớp bằng `use TraitName;`. Tìm hiểu cách dùng nhiều trait, giải quyết xung đột tên bằng `insteadof` và `as`, thành viên abstract và static trong trait, phương thức nào được ưu tiên, và so sánh trait, interface với lớp trừu tượng.
- EnumEnum trong PHP (8.1+) là một kiểu có danh sách giá trị cố định: `enum Status: string { case Active = 'active'; }`. Tìm hiểu pure enum và backed enum, `->value` và `->name`, chuyển đổi bằng `from()` và `tryFrom()`, liệt kê case bằng `cases()`, phương thức, hằng số, interface và enum trong `match`.
- Phương thức tĩnhMột phương thức hay thuộc tính `static` thuộc về lớp chứ không thuộc về đối tượng: bạn gọi nó bằng `ClassName::method()` và đọc bằng `ClassName::$count`, không cần `new`. Tìm hiểu `self::` và `static::` (late static binding), `new static`, biến static bên trong hàm, và khi nào static là lựa chọn sai.
- NamespaceNamespace trong PHP gom các lớp, hàm và hằng số dưới một tiền tố: `namespace App\Models;` ở đầu tệp, rồi `use App\Models\User;` ở nơi khác để gọi lớp bằng tên ngắn. Tìm hiểu tên đầy đủ, alias với `use ... as`, `use function`, dấu gạch chéo ngược ở đầu cho lớp toàn cục và autoload theo PSR-4.
Lỗi và ngoại lệ
- try catchTrong PHP, code có thể lỗi được đặt trong khối `try { }`, và `catch (Exception $e) { }` chạy khi code đó ném ra ngoại lệ, với lý do nằm trong `$e->getMessage()`. Tìm hiểu cách bắt nhiều loại ngoại lệ, `finally`, vì sao `catch (Exception)` bỏ sót `TypeError` và `DivisionByZeroError` (hãy bắt `Throwable`), ném lại ngoại lệ và trình xử lý toàn cục.
- Ngoại lệBạn ném một ngoại lệ trong PHP bằng `throw new Exception('message');`, và nơi gọi đọc nó bằng `$e->getMessage()` trong một khối `catch`. Tìm hiểu các lớp exception có sẵn, cách viết exception tùy chỉnh, `getCode()`, `getLine()` và `getPrevious()`, `throw` dưới dạng biểu thức, và các lỗi do chính PHP ném ra như `ValueError` và `TypeError`.
Dữ liệu, tệp và web
- json_encode()json_encode($value) chuyển một mảng, đối tượng hoặc giá trị vô hướng của PHP thành chuỗi JSON. Mảng kết hợp thành object JSON, danh sách thành mảng JSON, còn các flag như JSON_PRETTY_PRINT và JSON_UNESCAPED_UNICODE điều chỉnh đầu ra.
- json_decode()json_decode($json, true) chuyển một chuỗi JSON thành mảng kết hợp trong PHP; không có true thì bạn nhận được đối tượng stdClass. Tìm hiểu giá trị lồng nhau, xử lý lỗi với JSON_THROW_ON_ERROR, json_validate() và lý do json_decode trả về null.
- date()date('Y-m-d') trả về ngày hôm nay dưới dạng chuỗi, còn date('Y-m-d', $timestamp) định dạng bất kỳ Unix timestamp nào. Tìm hiểu time(), mktime(), strtotime(), DateTimeImmutable, cách cộng ngày, tính khoảng cách giữa hai ngày và xử lý múi giờ, với ví dụ bạn chạy được.
- Định dạng ngàyĐịnh dạng ngày trong PHP là một chuỗi gồm các chữ cái như 'Y-m-d H:i:s', trong đó Y là năm 4 chữ số, m là tháng, d là ngày, H là giờ, i là phút và s là giây. Trang này liệt kê mọi ký tự định dạng kèm ví dụ, cùng cách escape, ISO 8601, ngày kiểu Nhật và cách chuyển từ định dạng này sang định dạng khác.
- file_get_contents()file_get_contents('notes.txt') đọc toàn bộ một tệp và trả về nó dưới dạng một chuỗi, hoặc false nếu không đọc được. Hàm đi cặp với nó, file_put_contents(), ghi một chuỗi vào tệp, còn file() trả về các dòng dưới dạng mảng.
- fopen()fopen('data.txt', 'r') mở một tệp và trả về một handle, hoặc false khi thất bại. Đọc từ handle bằng fgets() hoặc fread(), ghi bằng fwrite(), đóng bằng fclose(). Mode ('r', 'w', 'a', 'x', 'c' và các dạng có dấu +) quyết định bạn được làm gì với tệp.
- include và requireinclude 'header.php'; chạy một file PHP khác ngay tại vị trí đó, như thể code của nó được dán vào. require làm điều tương tự nhưng dừng script với lỗi nghiêm trọng (fatal error) khi không tìm thấy file, còn include chỉ cảnh báo rồi chạy tiếp. include_once và require_once chỉ nạp file ở lần đầu tiên.
- FormMột form PHP gửi về chính nó bằng <form method="post">, và script đọc các trường từ $_POST['name'] khi $_SERVER['REQUEST_METHOD'] là 'POST'. Tìm hiểu cách kiểm tra dữ liệu, hiện lỗi cạnh từng trường, giữ lại giá trị đã nhập, checkbox và select, cùng cách escape đầu ra.
- $_GET và $_POST$_GET chứa query string của URL (?page=2 cho bạn $_GET['page']) còn $_POST chứa các trường của form gửi bằng method="post". Tìm hiểu cách đọc cả hai an toàn, tạo liên kết bằng http_build_query, kiểm tra $_SERVER['REQUEST_METHOD'] và chọn giữa GET với POST.
- htmlspecialchars()htmlspecialchars($text) biến năm ký tự có ý nghĩa trong HTML (& < > " ') thành entity, nhờ đó dữ liệu người dùng nhập được hiển thị như văn bản thay vì chạy như mã HTML. Tìm hiểu ENT_QUOTES, escape thuộc tính, mã hóa hai lần, htmlentities và strip_tags.
- Session và cookieGọi session_start() ở đầu mỗi trang, rồi lưu giá trị vào $_SESSION['key']; PHP giữ chúng trên máy chủ và nhận ra người xem qua một cookie. setcookie('name', 'value', $options) lưu một giá trị nhỏ trong trình duyệt, đọc lại từ $_COOKIE. Tìm hiểu đăng nhập, đăng xuất, flash message, các tùy chọn cookie và thiết lập bảo mật.
- password_hash()Băm mật khẩu bằng password_hash($password, PASSWORD_DEFAULT), lưu kết quả dài 60 ký tự và kiểm tra khi đăng nhập bằng password_verify($password, $hash). Tìm hiểu vì sao mỗi lần băm cho kết quả khác nhau, cost, password_needs_rehash, Argon2id và vì sao không dùng md5, sha1 cho mật khẩu.
- filter_var()filter_var($value, FILTER_VALIDATE_EMAIL) trả về giá trị nếu hợp lệ và false nếu không; FILTER_VALIDATE_INT, FILTER_VALIDATE_URL, FILTER_VALIDATE_BOOL và FILTER_VALIDATE_IP hoạt động theo cùng cách. Tìm hiểu các tùy chọn (min_range, default), flag, bộ lọc sanitize và cái bẫy false so với 0.
- PDOPDO là lớp truy cập cơ sở dữ liệu của PHP: kết nối bằng new PDO('mysql:host=localhost;dbname=shop;charset=utf8mb4', $user, $pass), rồi chạy mọi truy vấn có giá trị qua prepare() và execute([$value]). Tìm hiểu cách kết nối, prepared statement, lấy hàng, thêm dữ liệu, transaction và WHERE IN.
- ComposerComposer là trình quản lý package của PHP: composer require vendor/package tải thư viện vào vendor/, ghi nó vào composer.json, và require 'vendor/autoload.php' nạp nó. Tìm hiểu cách cài Composer, composer.json, ràng buộc phiên bản, install và update, autoload PSR-4 cho class của bạn.
Gỡ lỗi và luyện tập
- var_dump() và print_r()print_r($array) in một mảng ở dạng dễ đọc, var_dump($value) hiển thị thêm kiểu và độ dài của mọi giá trị, còn var_export in ra code PHP hợp lệ. Tìm hiểu khi nào dùng hàm nào, cách lấy kết quả print_r dưới dạng chuỗi, và cách in đẹp trong HTML với <pre>.
- Câu hỏi phỏng vấn24 câu hỏi phỏng vấn PHP với câu trả lời ngắn gọn, chính xác cho PHP 8, từ == và ===, isset và empty đến tham chiếu trong foreach, self và static, generator, SQL injection và băm mật khẩu. Phần lớn câu trả lời kèm code bạn có thể chạy và sửa.