cv.cm

Lập trình · Ngôn ngữ lập trình

Hướng dẫn học lập trình PHP cơ bản cho người mới

7 phút đọc

Trả lời nhanh

PHP là ngôn ngữ kịch bản phía máy chủ được tạo ra cho web: tệp PHP chạy trên máy chủ rồi gửi HTML hoặc JSON về trình duyệt. Cài PHP, lưu <?php echo "Hello, world"; thành hello.php và chạy php hello.php, hoặc bật máy chủ cục bộ bằng php -S localhost:8000. Các ý tưởng cốt lõi là biến bắt đầu bằng $, mảng linh hoạt, hàm có khai báo kiểu, lớp, ngoại lệ và cách xử lý dữ liệu người dùng một cách an toàn.

Mở Định dạng JSON

PHP là gì và dùng để làm gì

PHP do Rasmus Lerdorf tạo ra năm 1994; tên gọi hiện nay là viết tắt của "PHP: Hypertext Preprocessor". Nó chạy trên hầu hết các dịch vụ hosting và vận hành một phần lớn các website, trong đó có WordPress, Drupal và MediaWiki của Wikipedia. Lập trình viên dùng PHP cho website nội dung, cửa hàng trực tuyến, REST API và ứng dụng web đầy đủ với các framework như Laravel và Symfony. PHP 8 hiện đại có hệ thống kiểu, trình biên dịch JIT, enum, attribute và hiệu năng tốt hơn nhiều so với các bản cũ.

Cài PHP và chạy Hello, world

Cài PHP từ php.net hoặc bằng trình quản lý gói (brew install php, sudo apt install php-cli, hay gói tổng hợp như XAMPP trên Windows). Kiểm tra bằng php -v. Mã PHP nằm giữa thẻ <?php và thẻ đóng ?> (không bắt buộc).

<?php
echo "Hello, world\n";
php hello.php
# Hello, world
php -S localhost:8000    # serve the current folder at http://localhost:8000

Trong các tệp chỉ chứa mã PHP, hãy bỏ thẻ đóng ?> để tránh vô tình gửi khoảng trắng thừa về trình duyệt.

Biến và các kiểu dữ liệu cơ bản

Tên biến bắt đầu bằng $. Kiểu dữ liệu là động, nhưng bạn có thể khai báo kiểu cho tham số và giá trị trả về, còn declare(strict_types=1); ở đầu tệp sẽ chặn việc tự động chuyển đổi kiểu khi gọi hàm.

KiểuVí dụGhi chú
int$n = 42;64 bit trên hầu hết hệ thống
float$x = 3.14;Độ chính xác kép
string$s = "hi $name";Dấu nháy kép nội suy biến, dấu nháy đơn thì không
bool$ok = true;Từ khóa không phân biệt hoa thường
array$a = [1, 2];Bản đồ có thứ tự: vừa là danh sách vừa là từ điển
null$v = null;Không có giá trị
<?php
$name = "Ada";
$count = 7;
echo "$name has $count items\n";        // Ada has 7 items
echo 'No $interpolation here' . "\n";   // No $interpolation here
echo intdiv($count, 2), " ", $count / 2, "\n";  // 3 3.5
var_dump((int) "12" + 1);                // int(13)

Toán tử . nối chuỗi; + chỉ dùng cho số.

Điều khiển luồng

<?php
$score = 72;
if ($score >= 90) {
    echo "A\n";
} elseif ($score >= 70) {
    echo "B\n";                   // B
} else {
    echo "C\n";
}

for ($i = 0; $i < 3; $i++) {
    echo $i, " ";                 // 0 1 2
}
echo "\n";

foreach (["apple", "pear"] as $fruit) {
    echo $fruit, "\n";
}

$kind = match ($day = "SAT") {   // match is strict and returns a value
    "SAT", "SUN" => "weekend",
    default => "weekday",
};
echo $kind, "\n";                 // weekend

match (từ PHP 8.0) so sánh bằng === và báo lỗi khi không nhánh nào khớp, khác với switch cũ vốn so sánh lỏng và chạy tràn xuống nhánh sau nếu thiếu break.

Hàm

<?php
declare(strict_types=1);

function greet(string $name, string $greeting = "Hello"): string
{
    return "$greeting, $name!";
}

echo greet("Lin"), "\n";                    // Hello, Lin!
echo greet(greeting: "Hi", name: "Lin"), "\n"; // Hi, Lin!  (named arguments)

$square = fn(int $x): int => $x * $x;       // arrow function
echo $square(5), "\n";                      // 25

function total(int ...$nums): int           // variadic
{
    return array_sum($nums);
}
echo total(1, 2, 3), "\n";                  // 6

Tính năng đặc trưng: mảng

Mảng PHP là một kiểu linh hoạt, dùng được như danh sách, từ điển, ngăn xếp hoặc hàng đợi. Khóa là số nguyên hoặc chuỗi, và thứ tự chèn được giữ nguyên. Có rất nhiều hàm dựng sẵn làm việc với mảng.

<?php
$nums = [3, 1, 2];
$nums[] = 5;                       // append
sort($nums);
echo implode(", ", $nums), "\n";   // 1, 2, 3, 5

$ages = ["ann" => 31, "bob" => 25];
$ages["cy"] = 40;
foreach ($ages as $person => $age) {
    echo "$person is $age\n";
}
echo $ages["zed"] ?? 0, "\n";      // 0  (null coalescing)

$evens = array_filter($nums, fn($n) => $n % 2 === 0);
$squares = array_map(fn($n) => $n * $n, $nums);
echo json_encode(array_values($evens)), " ", json_encode($squares), "\n";  // [2] [1,4,9,25]
echo count($ages), " ", array_key_exists("bob", $ages) ? "yes" : "no", "\n"; // 3 yes

Mảng được sao chép khi gán (copy-on-write), khác với đối tượng vốn được truyền theo tay cầm (handle).

Lớp, constructor promotion và enum

<?php
declare(strict_types=1);

enum Role: string
{
    case Admin = "admin";
    case Viewer = "viewer";
}

final class User
{
    public function __construct(
        public readonly string $name,
        public readonly Role $role = Role::Viewer,
    ) {}

    public function label(): string
    {
        return "{$this->name} ({$this->role->value})";
    }
}

$u = new User("Ann", Role::Admin);
echo $u->label(), "\n";               // Ann (admin)
echo Role::from("viewer")->name, "\n"; // Viewer

Constructor promotion (PHP 8.0) khai báo và gán thuộc tính ngay trong chữ ký của hàm khởi tạo. Thuộc tính readonly (8.1) chỉ được gán một lần, còn backed enum (8.1) ánh xạ các case sang chuỗi hoặc số nguyên. Interface, abstract class và trait cũng được hỗ trợ.

Xử lý lỗi

PHP hiện đại ném ngoại lệ cho phần lớn lỗi. Hãy bắt các lớp con của Exception cho những lỗi có thể đoán trước; Throwable còn bao gồm cả lỗi của engine như TypeError.

<?php
function parseAge(string $text): int
{
    if (!ctype_digit($text)) {
        throw new InvalidArgumentException("invalid age: $text");
    }
    return (int) $text;
}

try {
    echo parseAge("41"), "\n";   // 41
    echo parseAge("abc"), "\n";
} catch (InvalidArgumentException $e) {
    echo $e->getMessage(), "\n"; // invalid age: abc
} finally {
    echo "done\n";
}

Một chương trình hoàn chỉnh nhỏ: endpoint API trả JSON

Lưu đoạn này thành api.php, chạy php -S localhost:8000 rồi mở http://localhost:8000/api.php?name=Ann. Chương trình đọc một tham số truy vấn, kiểm tra hợp lệ và trả về JSON.

<?php
declare(strict_types=1);

header("Content-Type: application/json; charset=utf-8");

$name = trim($_GET["name"] ?? "");
if ($name === "" || mb_strlen($name) > 50) {
    http_response_code(400);
    echo json_encode(["error" => "name must be 1 to 50 characters"]);
    exit;
}

$response = [
    "message" => "Hello, $name!",
    "length" => mb_strlen($name),
    "time" => date(DATE_ATOM),
];
echo json_encode($response, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);

$_GET, $_POST và $_COOKIE chứa dữ liệu của yêu cầu. Hãy coi mọi giá trị trong đó là không đáng tin.

Lỗi thường gặp của người mới

  • So sánh bằng ==, vốn tự chuyển đổi kiểu; hãy dùng === và !==.
  • Quên $ trước tên biến, hoặc quên dấu chấm phẩy ở cuối câu lệnh.
  • Lưu mật khẩu bằng md5 hoặc sha1. Hãy dùng password_hash và password_verify.
  • Dùng strlen cho văn bản UTF-8; hàm này đếm byte. Hãy dùng mb_strlen để đếm ký tự.
  • Dùng phiên bản PHP cũ. Hãy dùng bản PHP 8 còn được hỗ trợ để có bản vá bảo mật và tính năng hiện đại.

Học tiếp ở đâu

Tài liệu PHP Manual chính thức trên php.net mô tả mọi hàm, kèm phần tham chiếu ngôn ngữ và ghi chú của người dùng. Hãy học Composer, trình quản lý gói, và các chuẩn viết mã PSR, rồi thử một framework: Laravel hoặc Symfony cho ứng dụng, Slim cho API nhỏ. PHPUnit là công cụ kiểm thử tiêu chuẩn.

Câu hỏi thường gặp

PHP còn đáng học không?

Có. PHP vận hành một phần lớn web, kể cả các site WordPress, và PHP 8 hiện đại cùng Laravel hoặc Symfony là cách làm ứng dụng web hiệu quả. Công việc bảo trì và xây dựng hệ thống PHP vẫn rất phổ biến.

PHP là ngôn ngữ frontend hay backend?

Backend. PHP chạy trên máy chủ và gửi HTML, JSON hay tệp đã hoàn chỉnh về trình duyệt, nơi không bao giờ thấy mã PHP.

Khác nhau giữa echo và print là gì?

Cả hai đều xuất văn bản. echo nhận nhiều đối số cách nhau bằng dấu phẩy và không trả về gì; print nhận một đối số và trả về 1. Trên thực tế phần lớn mã dùng echo.

declare(strict_types=1) làm gì?

Nó làm cho khai báo kiểu vô hướng trở nên nghiêm ngặt với các lời gọi hàm từ tệp đó, nên truyền chuỗi "5" vào tham số int sẽ ném TypeError thay vì được chuyển đổi.

Tất cả hướng dẫn lập trình