php写sql语句的最佳实践

Posted

技术标签:

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

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

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

【问题讨论】:

一些相关问题:***.com/questions/37791/how-do-you-manage-sql-queries***.com/questions/1685362/…***.com/questions/1342556/… 不要在 PHP 中编写 SQL - 使用存储过程:joeyrivera.com/2009/… 刚看到这个问题。对于未来的访客或初学者,这可能会有所帮助:PHP: The Right Way 【参考方案1】:
    使用prepared statements 随意格式化您的代码

代码示例:

$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 网关。它将提供令人难以置信的优势:

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

干杯, 亚历克斯

【讨论】:

以上是关于php写sql语句的最佳实践的主要内容,如果未能解决你的问题,请参考以下文章

MySQL学习之EXPLAIN执行计划详解及最佳实践

MySQL学习之EXPLAIN执行计划详解及最佳实践

最佳实践:使用 PHP 5.x 将 CSV 导入 MYSQL 数据库

ySQL性能优化的21个最佳实践 和 mysql使用索引

MySQL性能优化的21个最佳实践

执行3小时超长SQL的分析优化过程:从索引遇见IS NULL,到最佳实践