PHP và các biểu mẫu
Việc tạo và sử dụng các biểu mẫu trong PHP
Các nhà phát triển đã tạo PHP như là một ngôn ngữ lập trình Web. Trong thực tế, trong khi bạn có thể chạy PHP từ dòng lệnh, thì hiếm có ai sử dụng ngôn ngữ này bên ngoài lĩnh vực ứng dụng Web. Kết quả là đối với lập trình viên PHP một trong nhiệm vụ phổ biến sẽ là sử dụng các biểu mẫu Web.
Bạn tạo các biểu mẫu Web bằng HTML và khi người dùng đệ trình biểu mẫu này, trình duyệt sẽ gửi một mảng thông tin đến máy chủ.
Trong phần này, bạn sẽ xem xét các mảng và các cách mà bạn có thể làm với dữ liệu biểu mẫu. Bạn cũng sẽ xem các cách kiểm soát tiến trình của một kịch bản lệnh PHP, chẳng hạn như các vòng lặp và các lệnh if-then.
Bắt đầu bằng cách tạo trang đăng ký cho ứng dụng của bạn. Sau đó người dùng sẽ nhập thông tin của họ và bạn sẽ xác nhận hiệu lực thông tin đó hoặc kiểm tra tính đầy đủ của thông tin đó, trước khi lưu thông tin trong một cơ sở dữ liệu. Bây giờ, chỉ cần tạo biểu mẫu cơ bản. Hãy tạo một tệp mới gọi là tệp registration.php và thêm vào như sau:
<html>
<head>
<title>Workflow System</title> </head>
<body>
<h1>Register for an Account:</h1>
<form action="registration_action.php" method="GET">
Username: <input type="text" name="name" /> <br/>
Email: <input type="text" name="email" /><br />
Password: <input type="password" name="pword" /><br />
<input type="submit" value="GO" />
</form>
</body>
</html>
|
Ở
đây bạn có một biểu mẫu đơn giản (chứa trong phần tử form có hai đầu vào văn bản: đầu vào mật khẩu và một nút đệ trình.
Nếu bạn lưu tệp này trong thư mục tài liệu gốc (với tệp registration_action.php)
và gõ vào từng trường, bạn sẽ thấy vài thứ giống như Hình 3.
Hình 3. Đăng ký cho một biểu mẫu tài khoản
Lưu ý rằng hộp mật khẩu không hiển thị nội dung thực tế mà bạn đang gõ. Nhưng điều gì sẽ xảy ra khi bạn nhấn vào nút GO?
Khi tạo biểu mẫu này, bạn đã tạo
phần tử form thực tế như
sau:
<form action="registration_action.php" method="GET"> |
Phần
tử này có hai mẩu thông tin. Đầu tiên, action, cho
trình duyệt biết nơi gửi thông tin. Trong trường hợp này, nó sẽ gửi đến
trang mà bạn đã tạo trước đó, tệp registration_action.php. Thứ hai, method, cho trình duyệt biết cách gửi dữ
liệu.
Hãy xem cách trình duyệt hoạt động. Điền vào một số dữ liệu và nhấn nút GO. Bạn sẽ thấy vài thứ tương tự như Hình 4.
Hình 4. Xuất dữ liệu
Trong trường hợp này, bạn đã không đệ trình thông tin đó để nói rằng bạn đã làm, nhưng đó là vì bạn vẫn chưa điều chỉnh trang này để xem dữ liệu đang được đệ trình. Nhưng hãy xem URL.
http://localhost/registration_action.php?name=roadnick&email= ibmquestions%40nicholaschase.com&pword=supersecretpassword |
Lưu
ý rằng đối với mỗi phần tử biểu mẫu có một tên, bạn có một cặp giá trị-tên trong
URL, được phân tách bằng các ký hiệu &. URL trông như thế này vì bạn đã sử
dụng phương thức GET. Bạn cũng xem Sử
dụng POST, nhưng trước tiên hãy xem thực tế lấy dữ liệu này từ bên trong
trang PHP.
Bây giờ bạn đã đệ trình biểu mẫu, bạn đã bắt đầu thu được những dữ liệu trong trang đáp ứng thực tế, tệp registration_action.php. Thực hiện các thay đổi sau cho tệp đó:
...
<body>
<p>You entered:</p>
<?php
$username = $_GET['name'];
$password = $_GET['pword'];
echo " <p>Username = " . $username . "</p>";
echo " <p>Password = " . $password . "</p>";
?>
</body>
</html> |
Điều
bạn sắp làm là kéo giá trị có tên ra ngoài mảng $_GET. Sẽ có thêm nhiều hơn về các mảng lúc này, nhưng bây giờ hãy lưu ý
rằng nếu bạn làm mới trình duyệt, các câu trả lời thực sự của bạn xuất hiện như
trong Hình 5.
Hình 5. Thông tin đúng trong trình duyệt
Bạn có thể kéo bất cứ mẩu thông tin đã đệ trình nào theo tên của nó, nhưng vì đây là một mảng, nên bạn còn có các tùy chọn khác.
PHP cho bạn khả năng tạo các mảng hoặc danh sách các giá trị, cho phép bạn di chuyển một nhóm các giá trị tại một thời điểm khá dễ dàng. Ví dụ, bạn có thể tạo một mảng các giá trị và đưa chúng vào trang này:
$formnames = array("name", "email", "pword");
echo "0=".$formnames[0]."<br />";
echo "1=".$formnames[1]."<br />";
echo "2=".$formnames[2]."<br />"; |
Hàm
array() trả về giá trị, trong trường hợp này, là
một mảng. (Các hàm này sẽ được đề cập sau, nhưng bây giờ, hãy hiểu rằng bạn gọi
nó và nó trả về một giá trị mà bạn gán cho một biến).
Kịch bản lệnh này tạo đầu ra sau:
0=name<br /> 1=email<br /> 2=pword<br /> |
Lưu
ý rằng giá trị đầu tiên có chỉ số là 0, thay vì 1. Cũng lưu ý rằng bạn đã
xác định giá trị nào bạn muốn bằng cách thêm chỉ số trong các ngoặc đơn sau tên
của biến mảng. Hành động này cũng tương tự như cách mà bạn truy cập các giá trị
biểu mẫu và không gây tai nạn nào. Biến $_GET là một
loại đặc biệt của một mảng được gọi là mảng kết hợp, có nghĩa là thay vì
một chỉ số bằng số, mỗi giá trị có một khóa.
Khi đệ trình biểu mẫu, chủ yếu bạn tạo một mảng như sau:
$_GET = array("name" => "roadnick",
"email" => "ibmquestions@nicholaschase.com",
"pword" => "supersecretpassword");
|
Đó
là những gì cho phép bạn trích xuất các giá trị cá nhân, chẳng hạn như $_GET["name"]. Tuy nhiên, nó không cần được thực hiện
riêng tư.
Các mảng kết hợp có thể vô cùng tiện dụng trong việc xử lý dữ liệu, nhưng các tình huống thường xuyên phát sinh trong đó bạn thực sự không biết cấu trúc của mảng như thế nào. Ví dụ, bạn có thể đang xây dựng một thường trình cơ sở dữ liệu chung để thu nhận một mảng kết hợp thông qua một truy vấn.
Thật may mắn, PHP cung cấp hai hàm làm cho cuộc sống dễ chịu hơn một chút:
<body>
<p>You entered:</p>
<?php
$form_names = array_keys($_GET);
$form_values = array_values($_GET);
echo "<p>" . $form_names[0] . " = " . $form_values[0] . "</p>";
echo "<p>" . $form_names[1] . " = " . $form_values[1] . "</p>";
echo "<p>" . $form_names[2] . " = " . $form_values[2] . "</p>";
?>
</body>
</html> |
Hàm
array_keys() và hàm array_values() trả về các mảng thông tin số thông thường, do đó bạn
có thể sử dụng các mảng đó để kéo dữ liệu ra bằng cách sử dụng các chỉ số bằng
số, như trong Hình 6.
Hình 6. Các mảng để kéo dữ liệu ra bằng cách sử dụng các chỉ số bằng số
Tuy nhiên, có thể có cách thuận tiện hơn. Ví dụ, điều gì sẽ xảy ra nếu bạn chưa thực sự biết có bao nhiêu các giá trị? PHP cung cấp một số cách để xử lý các mảng kết hợp, cách thuận tiện nhất là xác định xem bạn đã có những thông tin nào rồi. Hãy xem hai cách khác nhau nhằm thực hiện cùng nhiệm vụ tiếp sau đây.
Một nhiệm vụ rất phổ biến trong PHP là lặp theo một số giá trị. Bạn có thể thực hiện dễ dàng nhờ vòng lặp for-next. Một vòng lặp for-next chạy qua một số các giá trị dựa trên định nghĩa của nó. Ví dụ, vòng lặp:
for ($i = 0; $i < 10; $i++) { echo $i . " "; }
|
tạo đầu ra:
0 1 2 3 4 5 6 7 8 9 |
PHP ban đầu gán
một giá trị là 0 cho $i vì
đó là những gì được quy định lúc bắt đầu vòng lặp. Vòng lặp tiếp tục miễn là
$i nhỏ hơn 10 và mỗi lần vòng lặp thực hiện, PHP
sẽ tăng giá trị của $i thêm một.
Điều này có
nghĩa nếu bạn có thể tìm ra bao nhiêu giá trị trong mảng $_GET GET -- mà bạn có thể làm được – thì bạn có thể dễ dàng tạo
vòng lặp qua tất cả các giá trị được biểu mẫu đó cung
cấp:
<body>
<p>You entered:</p>
<?php
$form_names = array_keys($_GET);
$form_values = array_values($_GET);
for ($i = 0; $i < sizeof($_GET); $i++) {
echo "<p>".$form_names[$i]." = " . $form_values[$i] . "</p>";
}
?>
</body>
</html>
|
Hàm
sizeof() cung cấp cho bạn một số các giá trị
trong mảng $_GET.Bạn có thể sử dụng dữ liệu đó để cho
bạn biết khi nào dừng vòng lặp, như trong Hình 7.
Hình 7. Sử dụng hàm sizeof để dừng vòng lặp
Với $_GET là một mảng kết hợp, bạn thực sự có một tùy
chọn khác nữa: vòng lặp foreach.
Các mảng kết hợp phổ biến trong PHP đến mức mà ngôn
ngữ này cũng cung cấp một cách dễ dàng để lấy dữ liệu mà không cần trải qua quá
trình trích xuất các khóa và giá trị. Thay vào đó, bạn có thể sử dụng một vòng
lặp foreach, trực tiếp thao tác mảng. Ví dụ, hãy xem
mã
này:
...
<?php
foreach ($_GET as $value) {
echo "<p>" . $value . "</p>";
}
?> |
Lần
đầu tiên PHP thực hiện vòng lặp này, nó lấy giá trị đầu tiên trong mảng $_GET và gán giá trị đó cho $value, mà nó xuất ra. Rồi PHP trở lại đầu vòng lặp và gán giá trị
tiếp theo cho $value, thực hiện điều này đối với mỗi
giá trị trong $_GET (ở đây là name). Kết quả cuối
cùng là đầu
ra:
<p>roadnick</p> <p>ibmquestions@nicholaschase.com</p> <p>supersecretpassword</p> |
Tuy nhiên, dễ sử dụng hơn là khả năng trích xuất giá trị và khóa:
...
<?php
foreach ($_GET as $key=>$value) {
echo "<p>".$key." = " . $value . "</p>";
}
?>
... |
Điều này làm cho chúng ta trở lại kết quả ban đầu của mình:
Hình 8. Kết quả ban đầu
Các giá trị của nhiều biểu mẫu
Trong chủ đề các giá trị biểu mẫu, bạn cần đối phó với một tình huống đôi khi xảy ra: khi bạn có nhiều giá trị biểu mẫu với một tên duy nhất. Ví dụ, do những người dùng không thể thấy họ đang gõ mật khẩu nào, bạn có thể muốn làm cho họ gõ mật khẩu hai lần để xác nhận rằng họ đã không phạm sai lầm:
... Username: <input type="text" name="name" /><br /> Email: <input type="text" name="email" /><br /> Password: <input type="password" name="pword[]" /><br /> Password (again): <input type="password" name="pword[]" /><br /> <input type="submit" value="GO" /> ... |
Lưu
ý rằng tên của trường pword đã thay đổi một chút. Vì
sắp tìm nhiều giá trị, bạn cần tự xử lý mật khẩu này như là một mảng. Đúng, điều
đó có nghĩa là bạn có một giá trị mảng là một mảng khác. Vì vậy, nếu bạn đệ
trình biểu mẫu đó bây giờ, nó tạo một URL
sau:
http://localhost/registration_action.php?name=roadnick&email=ibmquestions%40nicholas
chase.com&pword[]=supersecretpassword&pword[]=supersecretpassword
|
Đệ trình biểu mẫu giống như việc tạo các mảng, chẳng hạn như:
$passwords = array("supersecretpassword", "supersecretpassword");
$_POST = array("name"=>"roadnick",
"email"=>"ibmquestions@nicholaschase.com",
"pword"=>$passwords);
|
Tất cả điều này có nghĩa là nếu bạn muốn xem các giá trị mật khẩu, bạn sẽ cần truy cập chúng như là một mảng số, như trong:
...
foreach ($_GET as $key=>$value) {
echo "<p>".$key." = " . $value . "</p>";
}
$passwords = $_GET["pword"];
echo "First password = ".$passwords[0];
echo "<br />";
echo "Second password = ".$passwords[1];
... |
Nếu bạn đệ trình biểu mẫu đó (hoặc làm mới trang đó), bạn có thể thấy sự khác biệt, như trong Hình 9.
Hình 9. Đệ trình biểu mẫu
Lưu ý rằng trường mật khẩu bây giờ có kết quả là Array
(mảng), nhưng bạn có thể truy cập trực tiếp các giá trị của nó.
Cho đến nay, bạn đang sử dụng phương thức GET để đệ trình dữ liệu, mà như bạn đã thấy, phương thức đặt đúng dữ
liệu trong URL. Bây giờ, đôi khi điều này thích hợp và đôi khi không. Ví dụ, bạn
có thể sử dụng kỹ thuật này để mô phỏng việc đệ trình một biểu mẫu bằng cách
dùng một liên kết, nhưng nếu bạn có một lượng lớn dữ liệu -- ít nhất là, đến từ
một textarea - vùng văn bản, trong đó những người
dùng có thể nhập các ý kiến -- kỹ thuật này không phải là cách tốt nhất hoàn
thành mục tiêu của bạn. Có một điều là, các máy chủ Web thường hạn chế số ký tự
mà chúng sẽ chấp nhận trong một yêu cầu GET.
Có
một điều khác là, các yêu cầu kỹ thuật và các tiêu chuẩn tốt cho rằng bạn không
bao giờ sử dụng GET cho một hoạt động mà có "các hiệu
ứng phụ" hoặc là thực sự làm cái gì khác. Ví dụ, ngay bây giờ bạn chỉ cần
xem dữ liệu, do đó không có tác dụng phụ nào ảnh hưởng đến hoạt động đó. Nhưng,
về sau bạn sẽ thêm dữ liệu vào cơ sở dữ liệu, theo định nghĩa sẽ có hiệu ứng
phụ.
Nhiều lập trình viên Web không ý thức về sự hạn chế cụ thể này, có
thể sinh ra các vấn đề. Việc sử dụng GET, cụ thể một
URL, có thể dẫn đến các tình huống trong đó các hệ thống thực hiện hoạt động
nhiều lần vì một người sử dụng đã đánh dấu trang đó hoặc vì một máy tìm kiếm
đang đánh chỉ mục URL, không biết nó thực sự đang cập nhật một cơ sở dữ liệu
hoặc thực hiện một số hành động khác.
Vì vậy, trong những trường hợp này,
bạn sẽ phải sử dụng POST để thay thế.
Sử dụng phương thức POST thay cho phương thức GET thực sự khá dễ dàng. Trước tiên, bạn cần thay đổi trang
registration.php:
...
<h1>Register for an Account:</h1>
<form action="registration_action.php" method="POST">
Username: <input type="text" name="name"/><br />
... |
Bây giờ khi bạn đệ trình biểu mẫu đó, URL chỉ vừa đủ:
http://localhost/registration_action.php |
.
Để
lấy ra dữ liệu, bạn cần sử dụng mảng $_POST hơn là
mảng $_GET trong tệp
registration_action.php:
...
<body>
<p>You entered:</p>
<?php
foreach ($_POST as $key=>$value) {
echo "<p>".$key." = " . $value . "</p>";
}
$passwords = $_POST["pword"];
echo "First password = ".$passwords[0];
echo "<br />";
echo "Second password = ".$passwords[1];
?>
</body>
</html> |
Bạn
có thể làm việc với mảng $_POST theo cách chính xác
giống như bạn đã làm với mảng $_GET.
Kiểm tra lỗi: Câu lệnh if-then
Trước khi tiếp tục, thực ra không tạo bất kỳ ý nghĩa nào khi yêu cầu người sử dụng gõ mật khẩu hai lần nếu bạn không chắc chắn rằng cả hai lần đều khớp . Để làm điều đó, bạn sẽ sử dụng một câu lệnh if-then:
...
$passwords = $_POST["pword"];
echo "First password = ".$passwords[0];
echo "<br />";
echo "Second password = ".$passwords[1];
if ($passwords[0] == $passwords[1]) {
echo "<p>Passwords match. Thank you.</p>";
} else { echo "<p>Passwords don't match. Please try again.</p>"; }
...
|
Trong
một câu lệnh if-then, nếu biểu thức trong các ngoặc đơn (trong ví dụ này, $passwords[0] == $passwords[1]) là đúng, PHP thực hiện
các câu lệnh trong tập đầu tiên của các dấu móc. Nếu nó sai, nó sẽ không thực
hiện. Trong trường hợp này, bạn cũng đã có loạt hành động thay thế để dùng nếu
câu lệnh là sai.
Lưu ý rằng $passwords[0] =
$passwords[1] với một ký hiệu dấu bằng đơn, bạn đã đưa $passwords[0] == $passwords[1] với một ký hiệu hai dấu
bằng. Dấu bằng kép là toán tử so sánh. Nó thực sự phát hiện xem cả hai có bằng
nhau không. Ký hiệu dấu bằng đơn là một toán tử gán. Với một ký hiệu dấu bằng
đơn, khi bạn thực hiện câu lệnh đó, PHP sẽ gán giá trị $passwords[1] vào $passwords[0], mà rõ
ràng không phải điều bạn muốn.
Trong trường hợp này, trang này cung cấp cho người dùng một cảnh báo nếu các mật khẩu không phù hợp, như trong Hình 10.
Hình 10. Cảnh báo hiện ra nếu mật khẩu không khớp
Hai toán tử dễ sử dụng hơn là toán tử and - và (&&) và hoặc toán tử or - hoặc (||). Ví dụ, bạn có thể
cho:
if (($today == "Monday") && ($status == "Not a holiday")) {
echo "GO TO WORK!!!";
}
|
Trong trường hợp này, biểu thức trên là đúng chỉ khi hôm nay là Monday (Thứ hai) và nó không phải là một ngày nghỉ. Toán tử or trả về đúng nếu có bất kỳ một trong các thành phần nào là đúng.
