关于使用PDO组成查询的几个问题

时间:2013-12-15 06:26:25

标签: php sql pdo placeholder

我有两个关于在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..
}

如果我错了,请纠正我,但只要我在slctFunctionupdtFunction等单独绑定用户输入数据的值,而不是将它们注入查询直接然后我不会让它容易受到sql注入,对吧?

先谢谢

2 个答案:

答案 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。它会使您的代码确实很短但仍然可读。但是为了所有善良的缘故 - 放弃这样一个建设者的想法。