如果我的网站出现问题,用户可以在空闲时发布空消息。
if (isset($_POST['submit'])) {
// check for empty fields
if (empty($_POST['headline']) || empty($_POST['text']) ||
empty($_POST['forum_id'])) {
header("Refresh: 2; url=/add-thread");
die('You must fill out every field.');
}
// No errors? Save.
else {
$headline = mysql_real_escape_string($_POST['headline']);
$text = mysql_real_escape_string($_POST['text']);
mysql_query("INSERT INTO threads (headline, text, date, forum_id, user_id)
VALUES ('$headline', '$text', NOW(), '$_POST[forum_id]', '$user[id]')");
header("Location: /thread/".mysql_insert_id()."");
}
}
我该如何解决这个问题?
答案 0 :(得分:9)
trim()
文字输入。你可以这样轻松地做到这一点:
// get input vars and trim space
$callback = array('filter' => FILTER_CALLBACK, 'options' => 'trim');
$fields = filter_input_array(INPUT_POST, array(
'headline' => $callback,
'text' => $callback,
'forum_id' => $callback,
));
// check for empty fields by counting how many are set
if ( count($fields) != count(array_filter($fields)) ) {
// something was unset
}
答案 1 :(得分:3)
空函数检查符合设定条件的变量,来自the manual
如果var具有非空和非零值,则返回FALSE。
以下内容被认为是空的:
“”(空字符串)
0(0为整数)
“0”(0为字符串)
NULL
FALSE
array()(空数组)
var $ var; (声明的变量,但在类中没有值)
您的$ _POST字段实际上包含类似
的内容" ";
这不是空字符串,而是一个用空格字符填充的字符串。
在使用empty()之前,修剪()POSTed值中的空格
$trimmed_post = array();
foreach($_POST as $key=>$value){
$trimmed_post[$key] = $value;
}
if(!empty($trimmed_post['headline'])){
//...
}
您不需要将新值放入新数组中,但我不喜欢更改自动生成的超全局中的内容。
最后一点,你不能做这样的事情
if(!empty(trim($_POST['headline']))){
//...
}
因为空函数希望传递一个实际变量。你可以做这样的事情
if('' != trim($_POST['headline'])){
//...
}
这可能是最好的方法。您减少了需要调用的函数数量,用户可以发布值为0的条目,并且代码更明确地说明它的作用。您将看到的另一种形式是
if(trim($_POST['headline'])){
}
这是有效的,因为PHP将空字符串('')计算为false,将非空字符串计算为true。我倾向于避免使用这种形式,因为我发现很多PHP漏洞都是关于等式运算符如何从某些类型中获取布尔值的误解。明确有助于减少这些类型的错误的发生。
答案 2 :(得分:1)
快速说明:您将$_POST['forum_id']
的值注入SQL;这不是一个好主意,因为用户可以根据需要操纵该值,即使它来自隐藏字段。转义该值是至关重要的,或者至少将其传递给intval()
并确保它是一个整数(假设整数后标识符)。
答案 3 :(得分:1)
我同意修剪是要走的路。这是一个更简单的方法:
$_POST = array_map('trim', $_POST);
答案 4 :(得分:0)
尝试
if (!empty($_POST['headline']) && !empty($_POST['text']) &&
!empty($_POST['forum_id']))
逻辑。
你必须切换它。
更新澄清:
if (isset($_POST['submit']) && !empty($_POST['headline']) &&
!empty($_POST['text']) && !empty($_POST['forum_id'])) {
$headline = mysql_real_escape_string($_POST['headline']);
$text = mysql_real_escape_string($_POST['text']);
mysql_query("INSERT INTO threads (headline, text, date, forum_id, user_id)
VALUES ('$headline', '$text', NOW(), '$_POST[forum_id]', '$user[id]')");
header("Location: /thread/".mysql_insert_id()."");
}
else
{
header("Refresh: 2; url=/add-thread");
die('You must fill out every field.');
}
}
答案 5 :(得分:-1)
检查提交后立即:
foreach ( $_POST as $key => &$value ) $value = trim($value);
根据提问者的评论进行编辑:
奇怪的是它没有像上面那样工作。这是我的练习,以确认它会。
tbramble@wayfarer:~$ php -a
Interactive shell
php > $arr = array('one',' two', ' three ');
php > print_r($arr);
Array
(
[0] => one
[1] => two
[2] => three
)
php > foreach ( $arr as $key => &$value ) $value = trim($value);
php > print_r($arr);
Array
(
[0] => one
[1] => two
[2] => three
)
必须与处理超全局而不是普通数组有关。
答案 6 :(得分:-1)
我修剪每$_GET
&应用程序启动后立即显示$_POST
个变量。尝试这样的事情:
function trimArray(&$array) {
if (empty($array)) {
return;
}
foreach ($array as $k => $v) {
if (! is_array($v)) {
$array[$k] = trim($v);
} else {
trimArray($v);
}
}
}
if (! empty($_GET)) {
trimArray($_GET);
}
if (! empty($_POST)) {
trimArray($_POST);
}