编辑:修改代码以包含$ errors变量。请告诉我这是否有效,谢谢。
我是PHP和MySQL的新手。我在我的网络表单中有以下PHP代码,当有任何网站字段为空白或格式不正确时,我在将新记录插入数据库时遇到问题。
我有错误检查发生,按下提交按钮后显示红色的错误信息并且数据为空白或格式不正确。这部分工作正常,问题是它仍然允许记录在有空白/格式不正确的值时发布到数据库。我想添加一些脚本来检查是否有任何必填字段是空白或格式不正确,如果是,请不要继续SQL插入。如果有人可以帮我处理我应该添加的脚本,我将不胜感激。以下是我正在使用的代码,谢谢!
<!DOCTYPE HTML>
<html>
<head>
<style>
.error {color: #FF0000;}
</style>
</head>
<body>
<?php
<?php
$errors = "false";
// define variables and set to empty values
$nameErr = $emailErr = $genderErr = $websiteErr = $subErr = "";
$name = $email = $gender = $comment = $website = $sub = $newrecord = "";
if ($_SERVER["REQUEST_METHOD"] == "POST") {
if (empty($_POST["Name"])) {
$nameErr = "Name is required";
$errors = "true";
} else {
$name = test_input($_POST["Name"]);
// check if name only contains letters and whitespace
if (!preg_match("/^[a-zA-Z ]*$/",$name)) {
$nameErr = "Only letters and white space allowed";
$errors = "true";
}
}
if (empty($_POST["Email"])) {
$emailErr = "Email is required";
$errors = "true";
} else {
$email = test_input($_POST["Email"]);
// check if e-mail address is well-formed
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$emailErr = "Invalid email format";
$errors = "true";
}
}
if (empty($_POST["Website"])) {
$website = "";
} else {
$website = test_input($_POST["Website"]);
// check if URL address syntax is valid (this regular expression also allows dashes in the URL)
if (!preg_match("/\b(?:(?:https?|ftp):\/\/|www\.)[-a-z0-9+&@#\/%?=~_|!:,.;]*[-a-z0-9+&@#\/%=~_|]/i",$website)) {
$websiteErr = "Invalid URL";
$errors = "true";
}
}
if (empty($_POST["Comment"])) {
$comment = "";
} else {
$comment = test_input($_POST["Comment"]);
}
if (empty($_POST["gender"])) {
$genderErr = "Gender is required";
$errors = "true";
} else {
$gender = test_input($_POST["gender"]);
}
if (empty($_POST["Subscription"])) {
$subErr = "Subscription is required";
$errors = "true"; }
else {
$sub = test_input($_POST["Subscription"]);
}
}
function test_input($data) {
$data = trim($data);
$data = stripslashes($data);
$data = htmlspecialchars($data);
return $data;
}
?>
<h2>Southern Tier Daily News</h2>
<form method="post" action="Newspaper3.php">
<input type="hidden" name="submitted" value="true"/>
<img src="https://bloximages.newyork1.vip.townnews.com/dnews.com/content/tncms/custom/image/5eec4204-483e-11e6-93c8-97ef236dc6c5.jpg?_dc=1468334339" alt="HTML5 Icon" style="width:128px;height:128px;">
<p><span class="error">* required field.</span></p>
<form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">
<fieldset>
<legend>Newspaper Subscription Request</legend>
Name: <input type="text" name="Name" value="<?php echo $name;?>">
<span class="error">* <?php echo $nameErr;?></span>
<br><br>
E-mail: <input type="text" name="Email" value="<?php echo $email;?>">
<span class="error">* <?php echo $emailErr;?></span>
<br><br>
Website: <input type="text" name="Website" value="<?php echo $website;?>">
<span class="error"><?php echo $websiteErr;?></span>
<br><br>
Comment: <textarea name="Comment" rows="5" cols="40"><?php echo $comment;?></textarea>
<br><br>
Gender:
<input type="radio" name="gender" <?php if (isset($gender) && $gender=="female") echo "checked";?> value="female">Female
<input type="radio" name="gender" <?php if (isset($gender) && $gender=="male") echo "checked";?> value="male">Male
<span class="error">* <?php echo $genderErr;?></span>
<br><br>
Subscription:
<select name="Subscription">
<option value=""></option>
<option value="Daily">Daily</option>
<option value="Evening">Evening</option>
<option value="Weekly">Weekly</option>
<option value="Monthly">Monthly</option>
</select>
<span class="error">* <?php echo $subErr;?></span>
<br><br>
<input type="submit" name="submit" value="Submit">
<br><br>
<a href="https://www.google.com/">Visit Admin Page</a>
</fieldset>
</form>
<?php
if (isset($_POST['submitted'])) {
and $errors = "False"
include('connect-mysql.php');
$fname = $_POST['Name'];
$femail = $_POST['Email'];
$fcomment = $_POST['Comment'];
$fsubsciption = $_POST['Subscription'];
$sqlinsert = "INSERT INTO subscriptions (Name, Email, Comment, Subscription) VALUES ('$fname',
'$femail', '$fcomment', '$fsubsciption')";
if (!mysqli_query($dbcon, $sqlinsert)) {
die(mysqli_error($dbcon)); // and die('error inserting new record'); ;
} // end of nested if statement
// else
$newrecord = "1 record added to the database";
} // end of main if statement
?>
<?php
echo $newrecord
?>
</body>
</html>
答案 0 :(得分:1)
尝试在SQL语句中使用经过验证的字段值,而不是再次使用$ _POST变量 - 如果该字段不存在,请不要运行查询。
或者,如果在脚本开头发现任何错误,请不要运行SQL语句。要做到这一点,我会这样做:
$errors
设置为false
$errors
变量设置为true if (isset($_POST['submitted']))
,在实际运行插入之前还要检查$errors
是否为false。希望有所帮助。
答案 1 :(得分:0)
在上面的代码中,您不会在插入之前检查无效数据。您只是检查错误并绕过它并存储在db中。所以修改了if条件如下。
if(isset($ _ POST [&#39;提交&#39;])&amp;&amp; empty($ err_array))
在$ err_array中存储错误值而不是单个变量。
答案 2 :(得分:0)
为了清楚起见,我将你的php从你的html中分离出来。首先也是最重要的,如上所述,您很容易受到SQL注入攻击,请使用标记化参数和准备好的语句来帮助保护自己免受此问题的影响(如下所示)。
关于您的问题,我建议您尝试在工作流程中添加一些异常处理。如果您刚刚开始,这可能看起来有点令人生畏,但只要您知道您的错误日志文件在哪里为您的开发服务器,它提供了一种快速简洁的方法来查看哪些错误也将最终为您服务生产环境。
就处理空表单字段而言,您可以在此处采用多渠道方法,HTML5 forms允许您根据需要指定字段并阻止无效表单的执行。 Javascript validation是客户端的另一种选择。尽管如此,在服务器端验证和清理数据总是好的,并且为此php有一些有用的工具(filter_var,filter_input)来帮助完成这项任务,另外所有的请求/服务器superglobals是可迭代的,所以不是设置条件链,而是可以循环它们并避免重复代码。
<?php
$newRecord = false;
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
try {
list($errors, $inputs) = cleanInputs($_POST);
if (!$errors['valid']) {
throw new Exception(json_encode($errors));
}
// using instantiation in the same file for the example.
$mysqli = new mysqli('host', 'user', 'password', 'schema');
if (!$mysqli) {
throw new Exception("({$mysqli->connect_errno}) {$mysqli->connect_error}");
}
// why is your form asking for Gender and URL if you aren't using them?
$insertQuery = "INSERT INTO subscriptions (Name, Email, Comment, Subscription) VALUES (?, ?, ?, ?)";
$stmt = $mysqli->prepare($insertQuery);
if (!$stmt) {
throw new Exception("({$mysqli->errno}) {$mysqli->error}");
}
$stmt->bind_param('ssss', $inputs['Name'], $inputs['Email'], $inputs['Comment'], $inputs['Subscription']);
$stmt->execute();
$newRecord = ($stmt->affected_rows > 0) ? 'Record added to database' : 'Record failed to insert to database';
} catch (Exception $e) {
// Here is where you would set your error variables for the html form.
error_log($e);
}
}
function cleanInputs($inputs)
{
$keys = ['Name', 'Email', 'Website', 'Comment', 'Subscription',];
$clean = [];
$errors = ['valid' => true];
foreach ($keys as $key) {
if (empty($inputs[$key])) {
$errors[$key] = "{$key} is required";
$errors['valid'] = false;
continue;
}
if (in_array($key, ['Name', 'Comment', 'Subscription', 'Gender'])) {
$clean[$key] = trim(filter_var($inputs[$key], FILTER_SANITIZE_STRING));
continue;
} else if ($key === 'Email') {
$filter = filter_var($inputs[$key], FILTER_VALIDATE_EMAIL);
if (!$filter) {
$errors[$key] = 'Invalid email format';
$errors['valid'] = false;
continue;
}
$clean[$key] = trim($filter);
} else if ($key === 'Website') {
$filter = filter_var($inputs[$key], FILTER_VALIDATE_URL);
if (!$filter) {
$errors[$key] = 'Invalid URL Format';
$errors['valid'] = false;
continue;
}
$clean[$key] = trim($filter);
}
}
return [$errors, $clean];
}
?>
扩展以帮助回答以下问题。
cleanInputs()方法将返回干净键和任何错误,因此从catch中你需要填充那些错误变量。我可能建议在处理之前在文件顶部设置默认输入值。然后在错误处理程序中重置它们,如果它们需要存在的话。
<?php
$newRecord = false;
$name = '';
$email = '';
$website = '';
$comment = '';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// ... back to original example
然后使用一些错误处理程序条件更新你的HTML,使用alternative syntax(这里的个人观点,如果你必须将逻辑放入你的模板中,对我来说看起来更干净)
<label for="Name">Name: </label>
<input type="text" name="Name" value="<?= $name ?>">
<?php if (isset($nameErr) && $nameErr !== false) : ?>
<span class="error">* <?= $nameErr ?></span>
<?php endif; ?>
<br><br>
并更新您的catch语句
} catch (Exception $e) {
if (!$errors['valid']) {
// repeat for errors.
$nameErr = (isset($errors['Name'])) ? $errors['Name'] : false;
if (!$nameErr) {
$name .= $inputs['Name'];
}
}
error_log($e);
}