Web back-end (8) - Biến và Phương thức POST

Video bài học [https://youtu.be/_aiZWV_zVnA]

1.1       Biến và Phương thức POST

1.1.1       Biến

Trong lập trình, biến (variable) là một vị trí lưu trữ trừu tượng được gắn với một cái tên, nó có thể chứa giá trị hoặc chưa có giá trị. Có thể hiểu đơn giản hơn, biến là một thùng chứa (vùng nhớ) được đặt tên, dùng để chứa các bit thông tin hoặc các loại dữ liệu khác nhau (như số nguyên, số thực, chuỗi,…v.v.). Ngôn ngữ lập trình sẽ sử dụng tên biến để tham chiếu và thao tác với giá trị đang được lưu trữ trong biến. Giá trị trong biến có thể thay đổi trong quá trình thực thi chương trình. Biến chỉ là nơi lưu trữ dữ liệu tạm thời khi chương trình đang thực thi. Xem hình minh họa,


Khai báo biến trong PHP

PHP là ngôn ngữ định kiểu yếu hay định kiểu động, nghĩa là bạn không phải xác định kiểu của biến lúc khai báo. Kiểu dữ liệu của biến sẽ được xác định dựa vào giá trị thực tế mà chúng ta gán cho biến. Một biến không nhất thiết luôn luôn chứa một kiểu dữ liệu cố định mà nó có thể chứa nhiều loại dữ liệu khác nhau, ví dụ bạn có thể gán một số nguyên vào biến, ngay sau đó lại có thể gán một chuỗi vào chính biến đó. Sử dụng dấu bằng (=) để gán giá trị cho biến.

Để thực hành các đoạn mã, nhằm hiểu rõ hơn cách hoạt động của PHP mà không ảnh hưởng tới phần xử lý “form đặt mua sách”, bạn nên tạo thêm tập tin khác để viết mã. Ví dụ trong thư mục sach, sẽ tạo thêm tập tin test.php để kiểm tra, khi đó bạn chỉ việc nhập đoạn mã PHP vào tập tin mã nguồn, lưu lại, sau đó vào trình duyệt nhập đường dẫn http://sach.vn/test.php để xem kết quả.

Ví dụ sau minh họa việc khai báo biến, gán giá trị cho biến và biến có thể nhận nhiều kiểu giá trị khác nhau:

<?php

    $HTMLsoLuong = 5;

    echo $HTMLsoLuong . "<br>";

    $HTMLsoLuong = "năm";

    echo $HTMLsoLuong;

// kết quả là:

// 5

// năm

?>

Quy ước đặt tên biến

– Một biến luôn bắt đầu bằng kí hiệu $, sau đó là tên biến

– Tên biến phải bắt đầu bằng một chữ cái hoặc kí tự gạch dưới (_) (underscore), sau đó có thể là kí tự, kí số hoặc kí tự gạch dưới

– Tên biến có phân biệt chữ hoa và chữ thường, ví dụ biến $soLuong khác với $SoLuong

­– Tên biến không chứa khoảng trắng

Bạn phải đặt tên biến theo các quy ước và lựa chọn một phong cách đặt tên biến cho bản thân. Một số kiểu đặt tên biến mà bạn có thể tham khảo và học theo: camelCase, underscore, PascalCase. Chi tiết kiểu đặt tên biến theo camelCase: nếu biến gồm một chữ thì viết thường toàn bộ; nếu biến gồm nhiều chữ thì viết thường toàn bộ chữ đầu tiên, các chữ tiếp theo sẽ viết hoa chữ cái đầu tiên, ví dụ $so, $soLuong, $tienThanhToan.

Kiểm tra biến có tồn tại hay không?

Trong PHP, khi nào cần sử dụng đến một biến thì sẽ vừa khai báo và vừa gán giá trị cho nó trong một câu lệnh. Việc này sẽ tạo cho chúng ta cảm giác là không có thao tác khai báo biến mà chỉ có thao tác gán giá trị cho biến hoặc thay đổi giá trị của biến. Một câu hỏi hay được đặt ra là “không biết biến này đã có ở đâu đó trong chương trình hay chưa?”. Xem ví dụ:

    // khai báo biến

    $HTMLsoLuong = 5;

    echo $HTMLsoLuong;

    // thay đổi giá trị của biến

    $HTMLsoLuong = 7;

    echo "<br>" . $HTMLsoLuong;

    // kết quả là:

    // 5

    // 7

Khi chỉ khai báo biến mà không gán giá trị, thì PHP sẽ cảnh báo là biến chưa được định nghĩa (undefined variable). PHP không bắt buộc phải khởi tạo giá trị cho biến, tuy nhiên chúng ta nên thực hiện điều này, vì nếu không, giá trị mặc định trong biến sẽ được xác định tùy theo ngữ cảnh sử dụng, và nó sẽ nằm ngoài tầm kiểm soát của chúng ta. Kinh nghiệm là: luôn luôn gán giá trị cho biến khi sử dụng (tạm quên và không quan tâm tới động tác khai báo). Ví dụ:

// không nên chỉ khai báo biến mà không khởi tạo giá trị 

$HTMLsoLuong;

    echo $HTMLsoLuong;

    // kết quả là:

    // Warning: Undefined variable $HTMLsoLuong in C:\Apache24\htdocs\sach\test.php on line 3

 

// nên khởi tạo giá trị cho biến khi sử dụng

    $tongTien = 100;

    echo $tongTien;

 

Hàm isset()

Chúng ta có thể sử dụng hàm isset() để kiểm tra xem một biến đã sẵn sàng để sử dụng hay chưa, nghĩa là nó đã được khai báo và được gán giá trị (khác null) hay chưa.

Hàm isset() là hàm có sẵn của PHP, nó trả về giá trị true nếu biến đã sẵn sàng để sử dụng, trả về null nếu biến chưa sẵn sàng để sử dụng (xem như không tồn tại). Ví dụ:

    if(isset($HTMLsoLuong) == null)

        echo "biến chưa tồn tại";

    $tongTien = 100;

    echo "<br>" . $tongTien;

    // kết quả:

    // biến chưa tồn tại

    // 100

Chúng ta có thể xóa một biến bằng cách dùng hàm unset() hoặc gán giá trị cho nó là null.

Ngoài hàm isset(), chúng ta có thể sử dụng hàm is_null() để kiểm tra một biến đã tồn tại hay chưa. Hàm is_null() trả về giá trị true nếu biến không tồn tại và trả về false nếu tồn tại.

if(is_null($HTMLsoLuong))

        echo "biến HTMLsoLuong chưa tồn tại";

    $tongTien = 100;

    if(!is_null($tongTien))

        echo "<br>" . "biến tongTien đã có";

    // kết quả:

    // Warning: Undefined variable $HTMLsoLuong in C:\Apache24\htdocs\sach\test.php on line 2

    // biến HTMLsoLuong chưa tồn tại

    // biến tongTien đã có

Để chương trình chạy an toàn, trước khi thao tác với một biến, bằng cách nào đó chúng ta cần đảm bảo biến đó đã tồn tại.

Phạm vi của biến

Phạm vi (scope) trong ngôn ngữ lập trình là một khái niệm dùng để xác định một vùng của chương trình máy tính, mà trong đó, biến có tồn tại và có thể tham chiếu tới nó để thực hiện các thao tác.

Trong PHP có 6 loại phạm vi sau:

– Biến siêu toàn cục của hệ thống (built-in superglobal): có phạm vi trong toàn bộ tập tin mã nguồn

– Hằng (constant): khi đã được khai báo sẽ có phạm vi toàn cục (global), có thể sử dụng ở trong và ngoài các hàm

– Toàn cục (global): là biến được khai báo trong một tập tin mã nguồn, có thể sử dụng trong toàn bộ tập tin, trừ trong các hàm.

– Biến được tạo ở trong hàm và được khai báo là toàn cục thì có thể tham chiếu tới các biến toàn cục cùng tên.

– Biến được tạo ở trong hàm, được khai báo là static thì không cho bên ngoài truy cập, nhưng giữ được giá trị giữa lần chạy đầu tiên (của hàm) và lần kế tiếp

– Biến được tạo ở trong hàm: có phạm vi cục bộ đối với hàm đó và bị hủy sau khi hàm thực thi xong

Chúng ta sẽ tìm hiểu kĩ hơn về các loại phạm vi của hàm ở các phần sau.

1.1.2       Làm quen với phương thức POST

Quay trở lại ứng dụng website bán sách, sau khi người dùng nhập số cuốn sách họ muốn mua, bấm nút “Đặt mua”, dữ liệu từ form sẽ được trình duyệt gửi về web server bằng phương thức POST của giao thức HTTP.

Phương thức POST sẽ tạo một gói tin, gọi là gói POST request, trong đó có chứa các cặp name:value là giá trị của các input tương ứng. Ví dụ: HTMLsoLuong: 1; CSSsoLuong: 2; JSsoLuong: 3

Chúng ta có thể kiểm tra thông tin các cặp name:value này để đảm bảo dữ liệu của form gửi về web server là chính xác. Cách thực hiện:

– Mở trang http://sach.vn/orderform.html

– Nhập vào số lượng các cuốn sách cần mua, ví dụ: 1 cuốn HTML, 2 cuốn CSS, 3 cuốn JavaScript ; bấm nút "Đặt mua"

– Đường dẫn trên trình duyệt lúc này sẽ là http://sach.vn/processorder.php. Nghĩa là dữ liệu của form đã được gửi về web server, đã được web server xử lý và trả về trang kết quả.

– Để xem các dữ liệu của form gửi về web server, bạn mở Developer tools/ chọn tab Network/ trong khung cửa sổ của Developer tools, chọn tập tin processorder.php/ chọn tab Payload, tại khung Form Data, bạn sẽ thấy các cặp name:value gửi về web server. Bạn cũng có thể bấm vào mục "view source" ngay bên cạnh, để xem các cặp name:value ở định dạng khác, ví dụ:  "HTMLsoLuong=1&CSSsoLuong=2&JSsoLuong=3". Xem hình minh họa,


Payload (khối hàng)

Payload là phần dữ liệu của một gói tin. Khi truyền trên mạng, một gói tin gồm 2 phần: header và payload, phần header chứa các thông tin điều khiển giúp truyền gói tin đến được đích, phần payload chứa dữ liệu mà một gói tin chuyên chở từ máy nguồn tới máy đích.

Xử lý form tại web server

Như chỉ định tại trường action trong form (action="processorder.php" ), dữ liệu của form sẽ được gửi tới trang processorder.php của website. Tại trang processorder.php, chúng ta sẽ viết mã để xử lý dữ liệu nhận được.

PHP có nhiều cách để nhận dữ liệu từ form gửi về. Ví dụ, form của chúng ta đang lập trình có khai báo là “method=POST”, nghĩa là bên server sử dụng phương thức POST để nhận dữ liệu. Trong trường hợp này, PHP sẽ sử dụng một biến “siêu toàn cục” (superglobal), kiểu mảng, có tên là $_POST. Mảng $_POST lấy name làm chỉ mục và giá trị là value từ các cặp name:value. Ví dụ: 

$_POST[‘HTMLsoLuong’] = 1

$_POST[‘CSSsoLuong’] = 2

$_POST[‘JSsoLuong’] = 3

Ngoài mảng $_POST, PHP còn dùng 2 mảng khác để nhận dữ liệu từ form là $_GET và $_REQUEST.

Chúng ta sẽ viết đoạn mã kiểm tra xem phần tử mảng tại vị trí “name” đã có giá trị chưa, nếu có rồi thì lấy ra, lưu vào một biến khác để thực hiện các xử lý tiếp theo.

Với đoạn mã PHP đơn thuần là tính toán, hoặc xuất ra thông tin đơn giản thì bạn để nó ở trước, hay ở sau thẻ <html>, hoặc ở các vị trí khác đều không ảnh hưởng gì đến kết quả thực thi. Do vậy, bạn nên để nó ở trên đầu tập tin, giúp dễ tìm kiếm và thao tác.

Bạn sẽ tạo ra 3 biến $HTMLsoLuong, $CSSsoLuong$JSsoLuong để chứa các thông tin do form gửi lên từ web client. Hãy thêm đoạn mã sau vào đầu tập tin processorder.php.

<?php

    $HTMLsoLuong = $_POST['HTMLsoLuong'];

    $CSSsoLuong = $_POST['CSSsoLuong'];

    $JSsoLuong = $_POST['JSsoLuong'];

?>

Tới đây, chúng ta đã có thể xuất các thông ra giao diện trang web, bằng cách thêm đoạn mã sau vào phía dưới dòng mã [echo "<p>Đơn hàng đã được xử lý</p>";],

...

        echo "<p>Chi tiết đơn hàng của bạn:</p>";

        echo $HTMLsoLuong . " cuốn HTML";

        echo "<br>" . $CSSsoLuong . " cuốn CSS";

        echo "<br>" . $JSsoLuong . " cuốn JavaScript";

      ...

Lưu lại các trang mã nguồn, chạy lại trang web, chúng ta sẽ thấy kết quả xuất hiện trên trình duyệt như dưới đây:

[Kết quả trang http://sach.vn/processorder.php]

Cửa hàng sách

Các đơn hàng

Đơn hàng đã được xử lý vào lúc 01:49, 1st December 2021

 

Chi tiết đơn hàng của bạn:

 

1 cuốn HTML

2 cuốn CSS

3 cuốn JavaScript

Ở phần xử lý trên, phía web server đã nhận trực tiếp dữ liệu từ các input của form, rồi xuất ngay về trình duyệt. Cách làm này tiềm ẩn nhiều rủi ro liên quan đến bảo mật. Thực tế, chúng ta cần sử dụng PHP để kiểm tra (validation) và lọc (filter) dữ liệu đầu vào, nhằm đảm bảo dữ liệu hợp lệ, an toàn. Với một chương trình PHP, dữ liệu đầu vào có thể là dữ liệu được gửi từ form, từ cookie, từ dịch vụ web, hoặc từ cơ sở dữ liệu.

Tạm thời, do chưa tìm hiểu về kiểm tra và lọc dữ liệu đầu vào, nên trước khi xuất dữ liệu, chúng ta sẽ sử dụng hàm htmlspecialchars() của PHP để chuyển đổi các kí tự đặc biệt trong dữ liệu đầu vào thành thực thể HTML (HTML entity). Mục đích của việc này là ngăn chặn việc gửi các thẻ (nằm ngoài kiểm soát của lập trình viên) có khả năng thực thi các đoạn mã độc về trình duyệt, gây ảnh hưởng đến việc thực thi, sự an toàn của ứng dụng và người dùng.

Khi đó, đoạn mã xuất dữ liệu nên được sửa lại là:

        ...

        echo "<p>Chi tiết đơn hàng của bạn:</p>";

        echo htmlspecialchars($HTMLsoLuong) . " cuốn HTML";

        echo "<br>" . htmlspecialchars($CSSsoLuong) . " cuốn CSS";

        echo "<br>" . htmlspecialchars($JSsoLuong) . " cuốn JavaScript";

        ...

1.1.3       Xem và đọc thêm

– [1] Dùng các từ khóa sau, tìm kiếm trên mạng để đọc thêm: payload, POST request, PHP variable

– [2] Đọc thêm về biến: https://www.php.net/manual/en/language.variables.basics.php

– [3] Ebook: Luke Welling & Laura Thomson, PHP and MySQL web development, fifth edition, 2017, page 20 – 26

– [4] htmlspecialchars(): https://www.php.net/manual/en/function.htmlspecialchars.php

– [5] Bài tập: https://www.w3resource.com/php-exercises/php-basic-exercise-3.php

– [6] Syntax and variables: https://www.youtube.com/watch?v=t0syDUSbdfE&t=1077s

1.1.4       Bài tập và thực hành

Bài tập 1. Cài đặt chức năng nhận dữ liệu từ form gửi tới web server và xuất dữ liệu ngược về trình duyệt (đã trình bày ở phần lý thuyết).

Bài tập 2. $var = 'PHP Tutorial'. Put this variable into the title section, h3 tag and as an anchor text within an HTML document.

[Sample Output] :

PHP Tutorial

PHP, an acronym for Hypertext Preprocessor, is a widely-used open source general-purpose scripting language. It is a cross-platform, HTML embedded server-side scripting language and is especially suited for web development.

Go to the PHP Tutorial.

Bài tập 3. Create a simple HTML form and accept the user name and display the name through PHP echo statement.

[Sample output of the HTML form]


Hướng dẫn làm bài tập và thực hành

[Bài tập 2]

<?php

$var = 'PHP Tutorial';

?>

<!DOCTYPE html>

<html>

<head>

  <meta http-equiv="content-type" content="text/html; charset=utf-8">

  <title><?php echo $var; ?> - W3resource!</title>

  </head>

  <body>

  <h3><?php echo $var; ?></h3>

  <p>PHP, an acronym for Hypertext Preprocessor, is a widely-used open source general-purpose scripting language. It is a cross-platform, HTML embedded server-side scripting language and is especially suited for web development.</p>

  <p><a href="https://www.w3resource.com/php/php-home.php">Go to the <?php echo $var; ?></a>.</p>

</body>

</html>

[Bài tập 3]

<!DOCTYPE html>

<html>

<head>

   <title></title>

   <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

   </head>

   <body>

   <form method='POST'>

   <h2>Please input your name:</h2>

 <input type="text" name="name">

 <input type="submit" value="Submit Name">

 </form>

<?php

//Retrieve name from query string and store to a local variable

$name = $_POST['name'];

echo "<h3> Hello $name </h3>";

?>

</body>

</html>

1.1.5       Câu hỏi ôn tập

Câu 1. Khai báo nào sau đây là hợp lệ?

A. $5soLuong =5;

B. $_5soLuong = 6;

C. soLuong = 7;

D. $so Luong = 8;

Câu 2. Phát biểu nào sau đây không đúng khi nói về biến trong PHP?

A. Không cần xác định kiểu khi khai báo biến

B. Là một vùng nhớ được đặt tên, dùng để lưu trữ tạm thời các giá trị

C. Một biến chỉ được chứa một loại dữ liệu duy nhất

D. Một biến luôn bắt đầu bằng kí hiệu $

Câu 3. Variable names follow the same rules as other labels in PHP. A valid variable name starts with a letter or ______, followed by any number of letters, numbers, or underscores.

A. hyphen

B. number

C. dollar sign

D. underscore

Câu 4. Trong PHP, bạn có thể sử dụng các mảng sau để nhận giá trị gửi từ form tới. Chọn đáp án đúng nhất.

A. POST, GET, REQUEST

B. $_POST, $_GET, $_REQUEST

C. $_POST, $_GET

D. $_POST, $_REQUEST

Câu 5. Trong quá trình gửi dữ liệu giữa client-server, khái niệm “payload” được hiểu là?

A. Phần chứa dữ liệu mà một gói tin chuyên chở từ máy nguồn tới máy đích

B. Thời gian để tải một trang web

C. Kích thước của một đơn vị dữ liệu gửi đi

D. Thời gian cần thiết để gửi một gói tin từ nguồn tới đích

-----

Video bài học [https://youtu.be/_aiZWV_zVnA]

-----

Cập nhật: 13/9/2023

-----

Bạn muốn tự học HTML bài bản? Xem thêm