我有两个关于在pdo中查询的问题,第一:哪种类型的占位符最好在pdo中使用,例如比较一下:
$stmt = $db->prepare('SELECT model FROM cars WHERE brand = :brand');
$stmt->bindValue(':brand', $brand, PDO::PARAM_STR);
$stmt->execute();
和此:
$stmt = $db->prepare('SELECT model FROM cars WHERE brand = ?');
$stmt->bindValue(1, $brand, PDO::PARAM_STR);
$stmt->execute();
允许在同一查询中使用这两种类型的占位符。
第二名:如果我愿意使用某些功能来撰写通用查询,例如:
public function genQuery($qType, qFieldsArray, qTablesArray, qWhereArray, qOrderArray, qGroupArray){
switch($type){
case 'select';
//Call to slctFunction
break;
case 'update';
//Call to updtFunction
break;
//**etc..
}
如果我错了,请纠正我,但只要我在slctFunction
,updtFunction
等单独绑定用户输入数据的值,而不是将它们注入查询直接然后我不会让它容易受到sql注入,对吧?
先谢谢
答案 0 :(得分:0)
问题1:您可以使用命名或编号参数,但不能在同一语句中使用它们。来自PDO::prepare
:
您不能在同一SQL语句中同时使用命名和问号参数标记;选择一个或另一个参数样式。
我认为命名参数更好,因为它们是自我记录的,如果您更新查询以添加更多参数,则不会受到影响。
问题2:您是正确的,使用绑定参数而不是在查询中插入值可以保护您免受SQL注入。
答案 1 :(得分:0)
第一个问题毫无意义。没有全部“更好”的方法。每个都有利于它自己的使用。位置占位符是必不可少的,因为它们可以使您的代码不那么臃肿,而不是每次写入每个字段名称十几次。 命名很好,因为几个具有相同名称的占位符可以绑定到单个变量。 顺便说一句,后者已经记住了你可以在执行中传递整个$ _POST数组的情况。在这种情况下,命名占位符可以缩短您的代码。但是通常的情况是数组键是手写的,比如
$sql = "SELECT * FROM table WHERE field1=:foo AND field2=:baz";
$data = DB::getAll($sql, array('foo'=>$foo, 'baz'=>$baz));
他们毫无意义,必须写成
$sql = "SELECT * FROM table WHERE field1=? AND field2=?";
$data = DB::getAll($sql, array($foo, $baz));
使您的代码 DRY
要回答你是否可以混合使用它们 - 老实说,你可以在几秒钟内尝试自己看看。
第二个更好。但是,你的一些场所坏。
只要我绑定用户输入数据的值
你错了。
数据源应该没有分离。这是非常基本的安全原则:不仅仅是臭名昭着和模糊的“用户输入”,而是每个价值。进入查询的Eevery值必须是硬编码或由占位符替换。没有例外。
这也使您的通用功能不安全。更不用说这种功能的想法被设计破坏了。你为什么需要它?为了节省两个人的话?而你得到的回报是什么?一个混淆的喋喋不休出于宝贵的SQL和你自己的束缚。使用这个函数的例子是什么?你试图看到它们在行动吗?您是否尝试将它们与regularrt SQL进行比较?
JOINTS,INSERT DELAYED等查询怎么样?你打算用PHP编写FULL SQL方言吗?
对于真正的简单查询,您应该使用ORM。它会使您的代码确实很短但仍然可读。但是为了所有善良的缘故 - 放弃这样一个建设者的想法。