像专业人士一样处理表单:选对 HTTP 方法、严格验证输入,并安全地重新显示。
在 Kodokon 中打开本课表单是你的用户与你的 PHP 代码之间的第一个接触点。get 方法把数据放在 URL 中(?q=pizza):非常适合搜索或筛选,因为页面可以被收藏和分享。post 方法把数据放在请求体中:只要请求会改变某些东西(创建账户、下单、删除)或携带敏感数据,它就是必须使用的方法。PHP 会把接收到的值存放在 $_GET 和 $_POST 超全局变量中。
<form action="search.php" method="get">
<label for="q">Search</label>
<input id="q" name="q" type="text">
<button type="submit">Search</button>
</form>
<?php
$query = trim($_GET['q'] ?? '');
if ($query !== '') {
echo "<p>You are searching for: " .
htmlspecialchars($query, ENT_QUOTES) . "</p>";
}
?>职业铁律第一条:永远不要信任传入的数据。用户可以发送任何东西,包括在你的表单之外精心伪造的值。filter_input() 函数一步完成读取和验证:它返回验证通过的值,无效时返回 false,字段缺失时返回 null - 这是你在错误提示中需要区分的三种情况。
<?php
declare(strict_types=1);
$errors = [];
$email = filter_input(
INPUT_POST,
'email',
FILTER_VALIDATE_EMAIL
);
$age = filter_input(
INPUT_POST,
'age',
FILTER_VALIDATE_INT,
['options' => ['min_range' => 18, 'max_range' => 120]]
);
$name = trim((string) ($_POST['name'] ?? ''));
if ($name === '' || mb_strlen($name) > 50) {
$errors[] = "Name required (50 characters max).";
}
if (!is_string($email)) {
$errors[] = "Invalid email address.";
}
if (!is_int($age)) {
$errors[] = "Invalid age (between 18 and 120).";
}
if ($errors === []) {
echo "Registration valid.";
}当验证失败时,不要返回一个空表单:重新显示用户输入过的值(一个 "粘性" 表单),并在相关字段旁边显示错误提示。任何重新显示的值都必须经过 htmlspecialchars():正是它中和了标签并阻止了脚本注入。
<?php
$name = trim($_POST['name'] ?? '');
$hasError = isset($_POST['name']) && $name === '';
$safeName = htmlspecialchars($name, ENT_QUOTES);
?>
<form method="post" action="">
<label for="name">Your name</label>
<input id="name" name="name"
value="<?= $safeName ?>">
<?php if ($hasError): ?>
<p>Name is required.</p>
<?php endif; ?>
<button type="submit">Submit</button>
</form>