我正在进行相当广泛的数据库插入前过滤器列表,我对代码的冗长和丑陋感到非常沮丧:
/*******************************************************************
* START OF sanitising input
********************************************************************/
// main user inputs
$title = filter_var($place_ad['title'], FILTER_SANITIZE_STRING);
$desc = filter_var($place_ad['desc'], FILTER_SANITIZE_SPECIAL_CHARS);
$cat_1 = filter_var($place_ad['cat_1'], FILTER_SANITIZE_NUMBER_INT);
$cat_2 = filter_var($place_ad['cat_2'], FILTER_SANITIZE_NUMBER_INT);
$cat_3 = filter_var($place_ad['cat_3'], FILTER_SANITIZE_NUMBER_INT);
$price = filter_var($place_ad['price'], FILTER_SANITIZE_NUMBER_FLOAT,FILTER_FLAG_ALLOW_FRACTION);
$suffix = filter_var($place_ad['suffix'], FILTER_SANITIZE_STRING);
// check input
if(empty($title) || strlen($title) < 3 || strlen($title) > 100) { $error[] = 'Title field empty, too long or too short.'; }
if(empty($desc) || strlen($desc) < 3 || strlen($place_ad['desc']) > 5000) { $error[] = 'Description field empty, too long or too short.'; }
if(empty($cat_1) || empty($cat_2)) { $error[] = 'You did not select a category for your listing.'; }
if(empty($price) || $price < 0 || $price > 1000000) { $error[] = 'Price field empty, too low or too high.'; }
// google location stuff
$lat = filter_var($place_ad['lat'], FILTER_SANITIZE_NUMBER_FLOAT,FILTER_FLAG_ALLOW_FRACTION);
$lng = filter_var($place_ad['lng'], FILTER_SANITIZE_NUMBER_FLOAT,FILTER_FLAG_ALLOW_FRACTION);
$formatted_address = filter_var($place_ad['formatted_address'], FILTER_SANITIZE_STRING);
// check input
if(empty($lat) || empty($lng)) { $error[] = 'Location error. No co-ordinates for your location.'; }
// account type
$registered = filter_var($place_ad['registered'], FILTER_SANITIZE_NUMBER_INT);
// money making extras
$extras = filter_var($place_ad['extras'], FILTER_SANITIZE_NUMBER_INT); //url encoded string
$icons = filter_var($place_ad['icons'], FILTER_SANITIZE_STRING); //url encoded string
$premium= filter_var($place_ad['premium'], FILTER_SANITIZE_NUMBER_INT); //numeric float;
$bump = filter_var($place_ad['bump'], FILTER_SANITIZE_NUMBER_INT); //numeric float;
// user details field
if ($registered == '1') // Registering as new user
{
$type = filter_var($place_ad['n_type'], FILTER_SANITIZE_NUMBER_INT);
$name = filter_var($place_ad['n_name'], FILTER_SANITIZE_STRING);
$phone = filter_var($place_ad['n_phone'], FILTER_SANITIZE_STRING);
$email = filter_var($place_ad['n_email'], FILTER_SANITIZE_EMAIL);
$pass = filter_var($place_ad['n_password'], FILTER_UNSAFE_RAW);
if(empty($type)) { $error[] = 'Type field error.'; }
if(empty($name) || strlen($name) > 100) { $error[] = 'You did not enter your name or name too long.'; }
if(empty($email) || strlen($email) < 5 || strlen($email) > 100) { $error[] = 'You did not enter a valid email.'; }
if(!filter_var($email, FILTER_VALIDATE_EMAIL)) { $error[] = 'You did not enter a valid email.'; }
if(empty($pass) || strlen($pass) < 6 || strlen($pass) > 100) { $error[] = 'Your password must be at least 6 characters.'; }
}
elseif ($registered =='2') // registered user
{
$email = filter_input($place_ad['n_email'], FILTER_SANITIZE_EMAIL);
$pass = filter_input($place_ad['n_password'], FILTER_UNSAFE_RAW);
if(empty($email) || strlen($email) < 5 || strlen($email) > 100) { $error[] = 'You did not enter a valid email.'; }
if(empty($pass) || strlen($pass) < 6 || strlen($pass) > 100) { $error[] = 'Your password must be at least 6 characters.'; }
}
elseif ($registered == '3') // dont wanna register details
{
$name = filter_input($place_ad['n_name'], FILTER_SANITIZE_STRING);
$phone = filter_input($place_ad['n_phone'], FILTER_SANITIZE_STRING);
$email = filter_input($place_ad['n_email'], FILTER_SANITIZE_EMAIL);
if(empty($name) || strlen($name) > 100) { $error[] = 'You did not enter your name or name too long.'; }
if(empty($email) || strlen($email) < 5 || strlen($email) > 100) { $error[] = 'You did not enter a valid email.'; }
}
/*******************************************************************
* END OF Sanitising input
********************************************************************/
我认为我的很多代码都是“不必要的”,但我认为如果我删除它可能是不好的编码实践。
例如,我可以放弃所有FILTER_SANITIZE_NUMBER
*过滤器,因为数据库已使用INT/FLOAT
字段正确设置。
我还可以放弃很多'大于&gt;'检查,因为大多数只是为了防止用户输入大量数据(再次,这将受到数据库字段长度的限制)。
其他人都有这个丑陋的用户输入验证码吗?
------------------ EDIT ----------------------
非常感谢您的信息。由于我正在使用PDO,我想我可能会尝试将其压缩一点,但我可以问下列内容:
答案 0 :(得分:2)
IMO,即使看起来不实用,但在应用层如果您想要通知用户并且让他们更正输入的数据时,所有验证的明显过度是必要的。否则,您可以让数据访问层(例如PDO)通过在绑定查询值时分配PDO constants来清理数据。
您可以根据需要使消毒过程变得复杂或简单,您只需要找出最适合您需求的配置。
----更新-----
一些建议使代码不那么压倒性。这假设您无法加载Zend或Symfony Validator Component之类的供应商库。
class Validator
{
public function validateString($string, array $options)
{
$min = ((isset($options['min'])) && (strlen($options['min'] > 1))) ? $options['min'] : null;
$max = ((isset($options['max'])) && (strlen($options['max'] > 1))) ? $options['max'] : null;
$string = filter_var($string, FILTER_SANITIZE_STRING);
if (empty($string)) {
throw new Exception(sprintf('Empty value: %s', $string));
}
if ((false === is_null($min) && (strlen($string) < $min)) {
throw new Exception(sprintf('Value too short: %s', $string));
}
if ((false === is_null($max) && (strlen($string) > $max)) {
throw new Exception(sprintf('Value too long: %s', $string));
}
}
return $string;
}
// Calling code
try {
$title = Validator::validateString($place_ad['title'], array('min' => 3, 'max' => 100));
} catch (Exception $e) {
$errors[] = 'Title field empty, too long or too short.';
// OR
$errors[] = $e->getMessage();
}
try {
$title = Validator::validateString($place_ad['desc'], array('min' => 3, 'max' => 5000));
} catch (Exception $e) {
$errors[] = 'Description field empty, too long or too short.';
// OR
$errors[] = $e->getMessage();
}
希望你能得到这张照片。通过使方法对数据类型通用,并且灵活地使用一组选项,您可以重复使用代码来减少占用空间,但仍然保持您希望实现的数据清理级别。
答案 1 :(得分:-2)
假设信息将显示在网站上(作为HTML的一部分),您需要做两件事:
第一个很容易,如果你经常使用mysqli或PDO,你应该已经知道如何这样做了。以下是关于此主题的问题: PHP PDO prepared statements 。
在你的情况下,第二个更棘手。您需要遍历每个变量,并将其传递给清理功能。无论是htmlspecialchars
还是更具侵略性的HTML过滤器,例如HTML Purifier。以下是关于此主题的问题: How to strip specific tags and specific attributes from a string? 。
如果您拥有数组中的值,则可以使用array_walk
或array_map
来清理几行中的整个数组。