Biến, hằng và kiểu dữ liệu trong PHP

    1

    Biến, hằng và kiểu dữ liệu là những thành phần đầu tiên bạn tiếp xúc khi làm quen với một ngôn ngữ lập trình mới. Trong PHP, việc khai báo biến và hằng có nhiều điểm khác biệt với các ngôn ngữ tương tự C. Điều dễ để ý thấy nhất là ký tự $ có mặt rất thường xuyên. Trong PHP, ký tự $ đứng trước một tên gọi biểu thị rằng đó là một biến. Hằng trong PHP cũng được định nghĩa theo một kiểu tương đối khác với C bằng cách sử dụng hàm define. Hệ thống kiểu dữ liệu của PHP dù có tên gọi tương tự nhưng lại hoạt động hoàn toàn khác với C.

    Chúng ta sẽ cùng tìm hiểu chi tiết tất cả các vấn đề này.

    Biến trong PHP

    Biến trong PHP là những tên gọi liên kết với một giá trị trong bộ nhớ. Bạn sử dụng tên biến thay cho viết trực tiếp giá trị trong các lệnh và biểu thức.

    Tên biến được đặt theo quy tắc đặt định danh chung và thêm ký tự $ vào đầu. Ký tự $ đứng trước một tên gọi báo hiệu đây là một biến trong PHP.

    Tên biến trong PHP bắt buộc phải có ký tự $ ở đầu.

    Khi khai báo một biến bạn đồng thời khởi tạo giá trị của biến sử dụng phép gán.

    Dưới đây là ví dụ về khai báo về sử dụng biến trong PHP (Lưu ý, sử dụng Interactive Shell từ PHP CLI với lệnh php -a).

    php > // Khai báo và khởi tạo một số biến
    php > $name = 'Donald Trump';
    php > $age = 60;
    php > $height = 1.85;
    
    php > // Sau khi khai báo, bạn có thể sử dụng tên biến trong các lệnh và biểu thức
    php > echo $name;
    Donald Trump
    php > echo $age;
    60
    php > echo $height;
    1.85
    
    php > // có thể kết hợp khai báo nhiều biến gán cho cùng một giá trị
    php > $a = $b = $c = 1000;
    

    Khi khai báo biến trong PHP bạn không cần chỉ định kiểu dữ liệu của biến đó. Khi bạn thực hiện phép gán, PHP sẽ tự động xác định kiểu của dữ liệu thông qua giá trị.

    Chú ý, tên biến phân biệt chữ hoa/thường. Ví dụ, $name, $Name, $NAME là ba biến khác nhau.

    Nếu thiếu ký tự $, PHP có thể hiểu rằng đây là một hằng hoặc báo lỗi cú pháp.

    php > age = 60; // quên $ trong tên biến sử dụng cùng phép gán -> lỗi cú pháp
    PHP Parse error:  syntax error, unexpected '=' in php shell code on line 1
    
    Parse error: syntax error, unexpected '=' in php shell code on line 1
    php > echo name; // quên tên biến khi dùng trong lệnh -> hiểu nhầm thành hằng
    PHP Warning:  Use of undefined constant name - assumed 'name' (this will throw an Error in a future version of PHP) in php shell code on line 1
    
    Warning: Use of undefined constant name - assumed 'name' (this will throw an Error in a future version of PHP) in php shell code on line 1
    name
    php >

    Các bạn xuất phát từ C/C++/Java/C# rất thường quên ký tự $ khi khai báo biến.

    Giá trị của một biến sẽ thuộc về một trong các kiểu dữ liệu của PHP.

    Các kiểu dữ liệu chuẩn của PHP

    Giống như các ngôn ngữ khác, PHP định nghĩa sẵn một số kiểu dữ liệu mà bạn có thể sử dụng ngay trong bất kỳ script nào. Chúng được gọi là các kiểu dữ liệu chuẩn của PHP.

    Bảng dưới dây tổng hợp các kiểu dữ liệu chuẩn của PHP.

    KiểuMô tảVí dụ
    bool, booleanGiá trị logic true hoặc falsetrue, false
    int, integerGiá trị số nguyên1, 2, 3, 4, 5
    float, doubleGiá trị số thực dấu phảy động3.14, 2.73
    stringChuỗi ký tự“Hello world”, ‘Hello world’
    objectĐối tượng của một class cụ thể
    arrayDanh sách dữ liệu ở dạng cặp khóa/giá trị
    resourceTham chiếu tới tài nguyên bên ngoài (như cơ sở dữ liệu)
    NULLGiá trị đặc biệt, thể hiện biến chưa được khởi tạo giá trị

    Lưu ý:

    • Số nguyên có thể nhận giá trị âm hoặc dương. Dải giá trị số nguyên phụ thuộc vào số bit của hệ điều hành. Trên máy 32 bit, số nguyên có giá trị từ -2^32 đến 2^32-1.
    • Số thực dấu phảy động có giá trị +-2.23*10^-308 tới +-1.79*10^308.
    • Chuỗi ký tự trong PHP có thể đặt trong cặp nháy đơn hoặc nháy kép đều được.
    • Object sẽ được xem xét riêng trong phần lập trình hướng đối tượng.
    • Resource sẽ được xem xét trong phần lập trình với cơ sở dữ liệu MySQL.
    • NULL (null, Null) là kiểu dữ liệu đặc biệt với 1 giá trị duy nhất – NULL (không phân biệt hoa/thường). Biến không được khởi tạo mặc định sẽ nhận giá trị NULL.

    Một số kiểu có nhiều tên gọi khác nhau tùy thuộc vào trường hợp sử dụng. Ví dụ, bool và boolean đều là cùng một kiểu. Tên gọi bool được sử dụng trong chỉ báo kiểu của hàm, trong khi tên gọi boolean được sử dụng trong kết quả trả về của hàm kiểm tra kiểu gettype().

    Trước PHP 7.4, bạn còn có thể gặp tên gọi real – một tên gọi khác của float và double.

    Trong các bài học tiếp theo chúng ta sẽ lần lượt xem xét chi tiết cách sử dụng các kiểu dữ liệu trên.

    Hằng trong PHP

    Hằng là những giá trị không đổi sau khi được định nghĩa. Ví dụ, nếu bạn cần tính toán số học thì giá trị số PI, số E có thể xem là những hằng số.

    PHP cho phép định nghĩa hằng thông qua hàm define() như sau:

    define('PI', 3.141592653589793);
    define('E', 2.71828);

    Hàm define nhận 3 tham số:

    • tên hằng: kiểu string, cần đặt theo đúng quy tắc đặt định danh.
    • giá trị của hằng: chỉ giới hạn trong các kiểu cơ bản integer, float/double, bool/boolean, string.

    Các hằng định nghĩa như trên cũng được gọi là named constant (hằng hữu danh).

    Giờ bạn có thể sử dụng tên hằng trong các biểu thức và lệnh:

    $radius = 20;
    $area = PI * $radius * $radius;
    $perimeter = 2 * PI * $radius;

    Khi thực hiện bất kỳ script nào PHP sẽ tự động tạo một số hằng.

    Ví dụ, __FILE__ là hằng chứa đường dẫn + tên của chính file script đang được thực thi, __LINE__ là hằng chứa số thứ tự của dòng code nơi sử dụng hằng này. Chú ý có hai dấu gạch chân _ trước và sau tên.

    Các hằng như __FILE__, __LINE__ được gọi là các magic constant.

    Magic constant được tự động tạo ra bởi PHP. Khi bạn chạy script, một loạt hằng sẽ được PHP tự định nghĩa.

    Giá trị của magic constant không thực sự cố định mà thay đổi phụ thuộc vào hoàn cảnh sử dụng. Dễ thấy nhất là __LINE__. Giá trị của hằng này thay đổi phụ thuộc vào nơi bạn sử dụng.

    Đặc điểm của hệ thống kiểu dữ liệu PHP

    Có một số điều khác biệt mà các bạn xuất phát từ C/C++/Java/C# cần lưu ý.

    PHP là ngôn ngữ định kiểu yếu (loosely/weakly typed), nghĩa là kiểu dữ liệu của một biến không cố định. Một biến ban đầu được khai báo để chứa dữ liệu số nguyên nhưng sau đó có thể dùng để chứa giá trị thuộc kiểu chuỗi ký tự.

    Như vậy, các đoạn code sau là hoàn toàn hợp lệ:

    $a = 1000;
    $a = "1000000";
    $b = "GREATE";
    $b = true;

    PHP là ngôn ngữ định kiểu động (dynamic typed). Nghĩa là kiểu dữ liệu của một biến được tự động xác định khi biến đó được gán giá trị lúc thực thi script.

    Xem ví dụ (LỖI) sau:

    <?php
    echo 'Đây là ví dụ về kiểm tra kiểu động của PHP'."\r\n";
    $a = "hello world"; # a là một chuỗi
    echo $a . "\r\n";
    echo $a * 2; # nhân chuỗi với số!

    Kết quả chạy script như sau:

    E:\OneDrive\TuHocICT\LearnPHP\Basic>php types.php
    Đây là ví dụ về kiểm tra kiểu động của PHP
    hello world
    PHP Warning: A non-numeric value encountered in E:\OneDrive\TuHocICT\LearnPHP\Basic\types.php on line 5
    Warning: A non-numeric value encountered in E:\OneDrive\TuHocICT\LearnPHP\Basic\types.php on line 5
    0

    Trong ví dụ này, bạn định nghĩa biến $a với giá trị là chuỗi ký tự “Hello world”. Sau đó bạn thực hiện phép nhân $a * 2.

    PHP sẽ thực hiện script bình thường. Lỗi chỉ phát sinh khi chạy script đến vị trí $a * 2: biến $a có kiểu String, và không thể thực hiện phép nhân với 2. Tuy nhiên, hoàn toàn không có lỗi gì trong quá trình viết code!

    Với đặc điểm này của PHP, bạn phải tự mình kiểm soát kiểu dữ liệu khi viết code. PHP không giúp gì cho bạn!

    Biến trong PHP và giá trị null

    Việc sử dụng biến trong PHP rất linh hoạt. Nó đem lại cho bạn sự tự do khi viết code nhưng đồng thời cũng có thể gây ra nhiều vấn đề.

    Khi bạn truy xuất một biến, nếu biến đó chưa từng được định nghĩa trước đó, PHP sẽ tự động tạo biến mới cho bạn.

    Lấy ví dụ trong script có lệnh sau:

    <?php
    echo $user;

    Bạn chưa từng khai báo biến $user trước đó. Lệnh echo $user sẽ tự động tạo biến $user cho bạn. Code viết như vậy không có lỗi.

    Tuy nhiên khi thực thi script trên, biến $user tạo ra khi này không chứa bất kỳ giá trị nào. Khi gặp tình huống này PHP sẽ đưa ra thông báo PHP Notice: Undefined variable: name in E:\OneDrive\TuHocICT\LearnPHP\Basic\variables.php on line 2.

    Nếu bạn tiếp tục sử dụng biến $name ở những vị trí khác, bạn sẽ vẫn nhận được thông báo như trên.

    Trong trường hợp PHP tự động tạo biến mới như trên, thực tế PHP sẽ gán cho biến giá trị null. null là một hằng giá trị hợp lệ trong PHP với ý nghĩa rằng biến này chưa được gán giá trị nào khác.

    Giá trị null không phân biệt hoa/thường, nghĩa là bạn có thể viết giá trị này là NULL hay Null đều được. Quy ước chung là viết thường toàn bộ null hoặc viết hoa toàn bộ NULL.

    Một biến cũng có thể nhận giá trị null nếu bạn gán trực tiếp giá trị này cho biến: $user = null;

    Trong tình huống gán giá trị null, PHP sẽ không phát thông báo Undefined variable.

    Một số vấn đề khi sử dụng biến trong PHP

    Khi sử dụng biến trong PHP bạn có thể gặp những tình huống đặc biệt không gặp trong những ngôn ngữ khác như C/C++/Java/C#.

    Hủy bỏ biến, hàm unset()

    PHP cho phép chủ động hủy bỏ một biến sử dụng hàm unset().

    <?php
    $name = "Donald Trump";
    $age = 60;
    $height = 1.85;
    
    unset($name, $age, $height); # hủy ba biến $name, $age, $height
    echo $name," ", $age, " ", $height;

    Nếu chạy script trên bạn sẽ gặp 3 thông báo Undefined variable ở vị trí lệnh echo.

    Như đã biết, thông báo Undefined variable sẽ được PHP phát ra nếu bạn truy cập một biến chưa được định nghĩa.

    Kiểm tra sự tồn tại của biến, hàm isset()

    Do một biến có thể được tạo tự động hoặc hủy bỏ, PHP cho phép kiểm tra sự tồn tại của biến trước khi sử dụng.

    Để kiểm tra xem một biến hoặc một danh sách biến đã được định nghĩa hay chưa, bạn sử dụng hàm isset(). Nếu biến/danh sách biến tồn tại, hàm trả về 1 (tương đương với true). Ngược lại sẽ trả về kết quả chuỗi rỗng (tương đương với false).

    Hãy xem ví dụ sau:

    <?php
    $name = "Donald Trump";
    $age = 60;
    $height = 1.85;
    ?>
    Biến $name tồn tại? <?=isset($name)?>
    
    Biến $Name tồn tại? <?=isset($Name)?>
    
    Tổ hợp biến $name và $age tồn tại? <?=isset($name, $age)?>
    <?php
    unset($name, $age, $height);
    ?>
    
    Biến $name tồn tại? <?=isset($name)?>
    E:\OneDrive\TuHocICT\LearnPHP\Basic>php variables.php
    Biến $name tồn tại? 1
    Biến $Name tồn tại?
    Tổ hợp biến $name và $age tồn tại? 1
    Biến $name tồn tại?

    Kiểm tra kiểu của biến, hàm gettype()

    Hãy xem cách sử dụng hàm gettype() qua ví dụ sau (sử dụng Interactive shell):

    E:\OneDrive\TuHocICT\LearnPHP\Basic>php -a
    Interactive shell
    
    php > $name = "Donald Trump";
    php > gettype($name);
    php > echo gettype($name);
    string
    php > $age = 60;
    php > echo gettype($age);
    integer
    php > $isPresident = true;
    php > echo gettype($isPresident);
    boolean
    php > $height = 1.85;
    php > echo gettype($height);
    double
    php > $null = null;
    php > echo gettype($null);
    NULL
    php >

    Cách hàm gettype() gọi tên kiểu có thể khiến bạn hơi bối rối. Hãy để ý tên kiểu mà hàm gettype() trả về: boolean (chứ không phải bool), integer (không phải int), double (không phải float).

    Biến và quản lý bộ nhớ trong PHP

    Khi làm việc với biến trong PHP bạn cần hình dung cách PHP quản lý biến và bộ nhớ tương ứng.

    Trong PHP, mỗi biến bao gồm hai thành phần riêng biệt: tên biến và giá trị trong bộ nhớ. Lấy ví dụ, tên biến $name và giá trị ‘Donald Trump’ là hai phần độc lập.

    PHP sử dụng một cơ chế gọi là symbol table để ánh xạ tên biến với giá trị trong bộ nhớ. Có thể hình dung symbol table như một cuốn từ điển để tra cứu xem tên biến (từ) tương ứng với giá trị (nghĩa) nào.

    Khi bạn tạo một biến mới và gán giá trị cho nó, PHP tạo giá trị trong bộ nhớ, tạo một tên biến và tạo một mục mới trong symbol table để ánh xạ tên sang giá trị.

    Để quản lý bộ nhớ trong quá trình tạo biến, PHP sử dụng hai cơ chế: copy-on-write và reference counting.

    Copy-on-write đảm bảo không tạo giá trị thừa khi sao chép giá trị của biến. Hãy xem ví dụ sau:

    php > $a = 'Hello world';
    php > $b = $a;
    php > echo $b, "\t", $a;
    Hello world     Hello world
    php > $b = 'Hello world, Trump';
    php > echo $b;
    Hello world, Trump
    php > echo $a;
    Hello world
    php >
    

    Khi gặp dòng lệnh gán $b = $a;, PHP thực tế sẽ không copy giá trị của $a cho $b. Thay vào đó nó để cho $b cùng trỏ vào cùng giá trị với $a.

    Tuy nhiên, khi bạn thực hiện lệnh gán $b = ‘Hello world, Trump’;, PHP sẽ thực sự tạo ra giá trị mới và để $b trỏ vào. Tương tự, nếu bạn thay đổi $a, PHP sẽ tạo ra giá trị mới và để $a trỏ vào.

    Reference counting đảm bảo giải phóng bộ nhớ khi một giá trị không được sử dụng nữa.

    Vẫn trong ví dụ vừa rồi. Giá trị ‘Hello world’ ban đầu chỉ có $a trỏ tới, do vậy counting của nó là 1. Khi tạo thêm $b, couting của nó tăng lên 2. Điều này cũng có nghĩa là đang có hai tên biến cùng trỏ tới giá trị này.

    Nếu vì lý do nào đó số lượng counting bằng 0, nghĩa là giờ không còn biến nào trỏ tới giá trị đó trong bộ nhớ, PHP sẽ tự động giải phóng giá trị tương ứng. Bạn không cần phải giải phóng bộ nhớ thủ công nữa.

    Như vậy, copy-on-write và reference counting giúp tự động quản lý bộ nhớ hiệu quả.

    Trong trường hợp cần chủ động giải phóng biến, bạn có thể sử dụng hàm unset() như đã biết. Nếu cần kiểm tra xem một tên biến có tham chiếu tới giá trị nào hay không trước khi sử dụng, bạn có thể dùng hàm isset().

    Kết luận

    Trong bài học này chúng ta đã làm quen với biến, hằng và kiểu dữ liệu trong PHP. Cụ thể:

    • Tên biến trong PHP phải bắt đầu bằng ký tự $.
    • PHP hỗ trợ các kiểu dữ liệu chuẩn (bool, int, float, string, object, array, resource, null).
    • PHP là ngôn ngữ định kiểu yếu và định kiểu động, dẫn đến cùng một biến có thể gán giá trị thuộc nhiều kiểu khác nhau và không kiểm tra được kiểu khi viết code.
    • Hằng trong PHP được định nghĩa qua hàm define().
    • Bạn có thể chủ động hủy bỏ biến sử dụng hàm unset().
    • Có thể kiểm tra sự tồn tại của biến với hàm isset().
    • Kiểm tra kiểu của biến với hàm gettype().
    • PHP hỗ trợ tự động quản lý bộ nhớ thông qua cơ chế copy-on-write và reference counting.

    + Nếu bạn thấy site hữu ích, trước khi rời đi hãy giúp đỡ site bằng một hành động nhỏ để site có thể phát triển và phục vụ bạn tốt hơn.
    + Nếu bạn thấy bài viết hữu ích, hãy giúp chia sẻ tới mọi người.
    + Nếu có thắc mắc hoặc cần trao đổi thêm, mời bạn viết trong phần thảo luận cuối trang.
    Cảm ơn bạn!

    Subscribe
    Notify of
    guest
    1 Thảo luận
    Oldest
    Newest
    Inline Feedbacks
    View all comments
    Trịnh đức thắng

    Hay quá admin ơi