Menu

Biến trong PHP: khai báo, phạm vi, global và static

Biế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.

Trang này có trình soạn thảo chạy trực tiếp. Sửa, chạy và xem đầu ra ngay lập tức.

Biến (variable) trong PHP là một tên bắt đầu bằng $, và bạn tạo ra nó bằng cách gán giá trị: $name = "Ada";. Không có từ khóa khai báo và không cần ghi kiểu, vì giá trị quyết định kiểu. Sau này bạn có thể gán một giá trị thuộc kiểu khác.

Quy tắc đặt tên biến

Tên biến bắt đầu bằng $, tiếp theo là một chữ cái hoặc dấu gạch dưới, rồi đến bất kỳ chữ cái, chữ số hoặc dấu gạch dưới nào. Chữ cái ngoài bảng ASCII cũng được tính là chữ cái, nên $名前 là hợp lệ, dù tên ASCII mới là thông lệ. Tên biến phân biệt hoa thường.

TênHợp lệ?
$total, $userName, $user_namecó
$_count, $item2có
$2itemskhông, không được bắt đầu bằng chữ số
$user-namekhông, đó là $user trừ name
$thiskhông, dành riêng cho đối tượng hiện tại; gán cho nó là lỗi nghiêm trọng

Vì vậy $city, $City và $CITY là ba biến khác nhau. Dùng snake_case ($first_name) hoặc camelCase ($firstName), và giữ một kiểu duy nhất trong mỗi dự án. Các chuẩn viết code PSR cố ý không quy định cách đặt tên biến; code Laravel và Symfony phần lớn dùng camelCase.

Dùng biến trong chuỗi

Bên trong dấu nháy kép, PHP thay biến bằng giá trị của nó; bên trong dấu nháy đơn thì không. Bọc biến trong ngoặc nhọn khi có chữ cái đứng ngay sau nó hoặc khi bạn truy cập phần tử mảng bằng khóa dạng chuỗi:

Trang chuỗi trình bày chi tiết về dấu nháy, nối chuỗi và nội suy biến.

Biến chưa định nghĩa và giá trị mặc định

Đọc một biến chưa từng được gán sẽ cho ra null, và PHP của bạn in ra một cảnh báo:

Warning: Undefined variable $discount in /home/index.php on line 3

Hãy kiểm tra trước bằng isset, hoặc dùng toán tử null coalescing ?? để cung cấp giá trị mặc định. Cả hai đều chạy mà không có cảnh báo:

$x ??= 0; là dạng viết tắt của $x = $x ?? 0;. Giá trị từ form và URL là trường hợp thường gặp: $page = $_GET['page'] ?? 1;.

Phạm vi biến trong hàm

Biến định nghĩa bên ngoài hàm không nhìn thấy được bên trong hàm, và biến tạo ra bên trong hàm sẽ biến mất khi hàm trả về. Đây là điều gây bất ngờ nhất cho những ai chuyển từ JavaScript sang:

Không có ?? 0, hàm đầu tiên sẽ cảnh báo $taxRate chưa được định nghĩa. Truyền giá trị vào dưới dạng tham số giúp hàm dễ đoán và dễ kiểm thử, và đó là cách bạn nên nghĩ tới đầu tiên. Trang hàm trình bày về tham số và giá trị trả về.

Từ khóa global và $GLOBALS

Khi một hàm thật sự phải dùng biến toàn cục, hãy khai báo nó bằng global, hoặc đi qua mảng $GLOBALS, nơi chứa mọi biến toàn cục theo tên:

Biến toàn cục làm code khó theo dõi hơn, vì hàm nào cũng có thể thay đổi chúng. Chúng xuất hiện trong code cũ và plugin WordPress (global $wpdb;); trong code mới, hãy truyền giá trị vào hoặc dùng một lớp.

Biến static giữ nguyên giá trị

Biến static bên trong hàm được tạo ra một lần và giữ giá trị giữa các lần gọi. Nó vẫn là biến cục bộ: code bên ngoài hàm không thấy được nó.

Biến của biến ($$name)

$$name dùng giá trị của $name làm tên của một biến khác. Cách này chạy được, nhưng mảng gần như luôn làm cùng việc đó rõ ràng hơn:

<?php
$field = "color";
$$field = "blue";        // creates $color
echo $color, "\n";

// The clearer way to have names chosen at runtime:
$settings = [];
$settings[$field] = "blue";
echo $settings["color"], "\n";

Sao chép hay tham chiếu

Gán một biến cho biến khác sẽ sao chép giá trị, kể cả mảng. Đặt & phía trước để hai tên cùng trỏ tới một giá trị:

Đối tượng thì khác: gán một đối tượng chỉ sao chép một handle trỏ tới cùng đối tượng đó, nên thay đổi qua biến nào cũng thấy được qua biến kia. Dùng clone để có một bản sao thật sự.

Lỗi thường gặp: biến được đặt bên trong if hoặc vòng lặp

PHP không có phạm vi khối lệnh, nên biến tạo ra bên trong if, for hay foreach vẫn tồn tại sau đó. Điều này tiện lợi, nhưng cũng che giấu một bug: khi khối lệnh không chạy, biến chưa bao giờ được tạo.

Không có dòng gán giá trị mặc định, một $orders rỗng sẽ khiến $message chưa được định nghĩa và in ra cảnh báo. Hãy gán giá trị cho mọi biến trước khối lệnh có thể đặt giá trị cho nó.

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

Khai báo biến trong PHP như thế nào?

Gán một giá trị cho một tên bắt đầu bằng $: $count = 10;. PHP không có từ khóa var hay let và không ghi kiểu khi khai báo; biến được tạo ra ở lần gán đầu tiên và mang kiểu của giá trị được gán.

Vì sao hàm của tôi không thấy biến được định nghĩa bên ngoài nó?

Hàm PHP có phạm vi cục bộ riêng và không tự động thấy biến toàn cục. Hãy truyền giá trị vào dưới dạng tham số (cách gọn gàng nhất), khai báo global $name; bên trong hàm, hoặc đọc $GLOBALS['name']. Closure có thể capture biến bằng use ($name), còn arrow function fn() tự động capture.

Biến static trong PHP là gì?

Một biến cục bộ được khai báo bằng static bên trong hàm, như static $calls = 0;. Biến này chỉ được khởi tạo một lần và giữ giá trị giữa các lần gọi hàm, rất hữu ích cho bộ đếm và cache đơn giản.

Tên biến trong PHP có phân biệt hoa thường không?

Có. $name, $Name và $NAME là ba biến khác nhau. Ngược lại, tên hàm và tên lớp trong PHP không phân biệt hoa thường.

Làm sao để xóa một biến trong PHP?

Gọi unset($name);. Sau đó isset($name) là false và đọc biến sẽ gây ra cảnh báo "Undefined variable". Gán null thì giữ lại biến nhưng làm rỗng nó.

Hình minh họa các ngôn ngữ lập trình của Coddy

Học lập trình cùng Coddy

Bắt đầu