【问题标题】:Best practice for writing sql statements in phpphp写sql语句的最佳实践
【发布时间】:2010-06-15 20:56:58
【问题描述】:

谁能给我指点资源或者给我看一个用php编写sql语句的好方法的例子。

大多数语句看起来都如此丑陋和难以理解。

【问题讨论】:

标签: php mysql


【解决方案1】:
  1. 使用prepared statements
  2. 随意格式化您的代码

代码示例:

$stmt = $pdo->prepare('
    SELECT ...
    FROM   ...
    JOIN   ...
    JOIN   ...
    WHERE  ... AND abc = :abc AND def = :def
');

$stmt->execute(array(
    'abc' => 'abc value',
    'def' => 'def value'
));

【讨论】:

    【解决方案2】:

    避免SELECT *

    VARCHAR 上使用ENUM

    准备好的语句(PHP 的 PDO http://www.php.net/manual/en/intro.pdo.php

    【讨论】:

      【解决方案3】:

      http://en.wikibooks.org/wiki/Programming:PHP:SQL_Injection

      请参阅底部关于参数化语句的部分。

      【讨论】:

      • 我看到我的一些网页设计师朋友涉足网页开发并最终使用不安全的代码。
      【解决方案4】:

      考虑prepared statements

      $stmt = $db->prepare("SELECT col1, col2, col3 FROM tbl WHERE col1 = ? AND col2 = ?");
      $stmt->bindParam(1, $col1);
      $stmt->bindParam(2, $col2);
      

      或者使用sprintf()

      $sql = sprintf("SELECT col1, col2, col3 FROM tbl WHERE col1='%s' AND col2='%s'",
          mysql_real_escape_string($col1),
          mysql_real_escape_string($col2)
      );
      

      无论哪种方式,您最终都会得到一个更大的未连接的 SQL 字符串,该字符串更具可读性。

      【讨论】:

        【解决方案5】:

        我使用 MySQL 客户端处理我的查询 (SQLWave)。非常方便的工具,可让您进行查询并将其保存为 SQL,它会输出如下文件:

        /*
        get-all-tags.sql
        
        get all tags from t.tags, combine info with t.taglink to 
        2012-12-18: updated blabla
        
        */
        select tags.*,group_concat(subid) as subs from t.tags
        
            join t.taglink on taglink.id=tags.id
        
        group by id
        order by category,tag,subid
        

        这是我喜欢的布局,但您当然可以使用自己的喜好。然后可以将查询插入到您的代码中,如下所示:

        mysql_query(file_get_contents("sql/get-all-tags.sql"));
        

        等等。您还可以通过将字符串替换为您可能需要的值来动态更改文件“get-all-tags”的内容。

        注意!!我并不是说这很快。这是很多不必要的开销。但是,如果您只想保持 PHP 代码干净和清晰,这是一个非常好的选择。

        为了获得更好的性能,您可以在上传内容之前将“file_get_contents("sql/get-all-tags.sql") 替换为该文件的实际内容,从而将您的 PHP 代码“编译”成您发布的代码。

        再说一遍,这不是快速代码,但非常易读!

        当然,您可以将相同的格式直接放入您的 PHP 代码中,而无需从客户端程序中复制:

        <?
            $result=mysql_query("
               select tags.*,group_concat(subid) as subs from t.tags
                  join t.taglink on taglink.id=tags.id
               group by id
               order by category,tag,subid
            ");
        ?>
        

        没有开销,没有访问文件,所以它(相对)快

        【讨论】:

          【解决方案6】:

          这里的这篇博文是一个很好的方法。

          http://www.communitymx.com/content/article.cfm?page=1&cid=A5B54EAAE1BC138F

          就我个人而言,我不包括空换行符。

          【讨论】:

          • 这是为了 SQL 的可读性;语法是 SQL Server 而不是 MySQL 并且没有提到 PHP...
          【解决方案7】:

          我个人喜欢这样分离我的 SQL:

          SELECT * FROM `table` a
          INNER JOIN `table2` b
          ON a.`id`=b.`id`
          WHERE b.`colour` = "frink"
          

          所以我喜欢将单独的命令放在新行上,这样便于阅读。

          【讨论】:

            【解决方案8】:

            PHP Security Guide: SQL Injection。这本书Essential PHP Security 也是一本快速、易于消化的读物。

            【讨论】:

              【解决方案9】:

              由于与其他代码层的紧密耦合,IMO 的 SQL 通常看起来很丑陋且难以阅读。复杂的 SQL 查询通常需要有条件地构建,当您开始在 SQL 查询之间添加 HTML 时,除了业务逻辑等之外,结果是不可读的代码。

              考虑使用 DAL(数据访问层)或更正式的表数据网关或仅使用 SQL 网关。它将提供令人难以置信的优势:

              1. 抽象的 SQL 代码使切换/移植到另一个 RDBMS 变得更加容易
              2. 将 SQL 代码与您的业务逻辑和模板等隔离开来,使代码更具可读性。

              干杯, 亚历克斯

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2014-06-05
                • 1970-01-01
                • 2018-12-10
                • 2012-10-18
                • 1970-01-01
                • 1970-01-01
                • 2013-09-06
                • 1970-01-01
                相关资源
                最近更新 更多