【问题标题】:Nice way to pass parameters to PDO将参数传递给 PDO 的好方法
【发布时间】:2009-12-06 22:48:22
【问题描述】:

当处理超过 3 或 4 个参数时,位置参数会成为一场噩梦。命名参数是冗长的。我正在考虑这样做:

query("SELECT * FROM users WHERE username = ", $username, " AND password = ", $password)

使用动态参数(使用func_get_args()),每一秒都会转换为位置参数。

我以前从未见过这种情况,想知道以前是否有人这样做过,为什么/为什么不这样做?

【问题讨论】:

    标签: php sql parameters variadic-functions


    【解决方案1】:

    命名参数不必很冗长,至少与位置参数相比是这样。您可以使用仍然很明显的缩短版本:

    $st = $dbh->prepare('SELECT * FROM users WHERE username = :u AND password = :p');
    $st->bindValue(':u', $username);
    $st->bindValue(':p', $password);
    $st->execute();
    

    【讨论】:

      【解决方案2】:

      这是一个聪明的主意。我看到的唯一问题是如何区分 SQL 和传入的变量。除非您假设每一秒 arg 都是一个变量。我只是认为这种假设是脆弱的,并且使事情变得模糊而不是使事情变得清晰。

      更好的方法可能是使用插值:

      query("SELECT foo FROM bar WHERE id = #{id}",  array("id" => "23"));
      

      然后编写逻辑来插入这些。

      【讨论】:

      • 插值返回到命名属性。您已经可以通过将第二个参数传递给 execute() 函数来实现它。
      • 我看到做原始的唯一方法是让类 SQLParameter 包装任何必须转义的东西。 query("SELECT * FROM users WHERE username = ", new SQLParameter($username), " AND ..."); # etc 但这并没有让它变得不那么冗长。 PHP 没有很好的语法来使这更简单。
      • 好吧,也许我的例子有点误导,我说的是大 SQL 语句,想象一下如果你必须用 10 个参数来做这件事:使用上面的命名参数/插值你最终会写一个大数组字面量和位置参数会非常混乱。
      • 无论你使用什么方法,在 10 个参数之后事情开始看起来有点乱,即使是直接使用 SQL。
      【解决方案3】:

      我不认为位置参数那么糟糕......这是我最喜欢的方法:

      function mysql_safe_string($value) {
          if(is_numeric($value))      return $value;
          elseif(empty($value))       return 'NULL';
          elseif(is_string($value))   return "'".mysql_real_escape_string($value)."'";
          elseif(is_array($value))    return implode(',',array_map('mysql_safe_string',$value));
      }
      
      function mysql_safe_query($format) {
          $args = array_slice(func_get_args(),1);
          $args = array_map('mysql_safe_string',$args);
          $query = vsprintf($format,$args);
          $result = mysql_query($query);
          if($result === false) echo '<div class="mysql-error"><strong>Error: </strong>',mysql_error(),'<br/><strong>Query: </strong>',$query,'</div>';
          return $result;
      }
      
      // example
      $result = mysql_safe_query('SELECT * FROM users WHERE username=%s', $username);
      

      【讨论】:

      • 那些不是准备好的查询中的位置参数。当您没有准备好查询时,这就是您伪造它的方式。
      • 哦。我认为“位置”意味着第一个 %s 指的是第一个参数,依此类推......
      • 您可以证明您正在使用位置参数。我评论的要点是您没有使用准备好的查询,因此没有解决 OP 的问题。
      猜你喜欢
      • 2019-03-25
      • 2010-11-12
      • 1970-01-01
      • 1970-01-01
      • 2020-09-13
      • 1970-01-01
      • 2011-07-23
      • 2017-01-05
      • 2013-10-04
      相关资源
      最近更新 更多