2012-04-01 73 views
-1

在PHP中你经常包含其他PHP串那样的SQL查询:美化在PHP代码SQL字符串

$sql = "SELECT * 
FROM `mytable` 
". (isset($a) ? $a : "") . " 
LIMIT " . ($page - 1) * 10 . ",10"; 

如果查询是更大然后是与PHP的毛绒,它有时会难以阅读。

是否有任何可以格式化PHP包含(我的)SQL的美化工?

+0

我见过很多,比这更糟糕。无论如何,你想如何让它变得光明?你是什​​么意思,解析SQL字符串为它的关键字着色? – 2012-04-01 11:02:25

+0

这就是为什么发明变量的原因。那么,不完全是,但他们也在这里帮助。 – JJJ 2012-04-01 11:03:29

+7

请看,看在上帝的份上......不要通过字符串concat来建立你的SQL!至少逃避参数。更好:使用PDO和准备好的语句。 – Malax 2012-04-01 11:08:21

回答

3

让我采取不同的方法,以你的问题:

如果你有一个看起来像SQL查询,你这样做是错误的。

Prepared statements是你的朋友。 SQL注入不是你的朋友。引述the PDO documentation

预处理语句是非常有用,所以他们是唯一的功能, PDO将模拟对于不支持它们的驱动程序。

也许你觉得你很好,你使用mysql_real_escape_string()无处不在,你需要(而不是偶然使用mysql_escape_string()代替)。也许你认为magic_quotesstripslashes会救你。也许你会很幸运并且做对了。但是,为了解释Ms. Schmich:如果我只能提供给您未来的一个建议,那就是“使用准备好的陈述”。

Here is a nice StackOverflow answer illustrating them in more detail,以下是我的(不含不管它是你与$a做)你的例子来使用预处理语句部分转换:

$statement = $dbh->prepare("SELECT * FROM `mytable` LIMIT :offset , 10"); 
$statement->bindValue(":offset", ($page - 1) * 10)); 
$statement->execute(); 

当然,也许你已经继承了一些遗留代码和这就是为什么你问,所以我的立场变得有点没有意义。我仍然认为,您最好是重构准备好的语句,无论是为了安全/功能优势,还是因为如果可能更详细,它们可能会更容易阅读。

+0

我对此有一个小问题。绑定值/ param比将它们放入数组慢一点? (我认为它是相同的,但通过yiis框架文档,它说执行时引用速度更快) – itachi 2012-04-01 11:39:08

+0

我似乎记得可能是这种情况,但我会非常惊讶地听到这是你的瓶颈剖析... – 2012-04-01 11:40:11

+0

Lol no。已经完成基准。微不足道。几乎没有。 – itachi 2012-04-01 11:43:00

1

也许尝试确定您的查询字符串以外的值。一旦他们通过了任何想要应用的过滤/验证检查,就添加它们。

$param = (isset($a) ? $a : ""); 
$param2 = ($page - 1) * 10; 

$sql = "SELECT * FROM mytable " . $param . " LIMIT " . $param2 . ",10"; 
+0

另外,要小心你放入该字符串的内容,确保它不是来自客户端的任何内容(get/post/server等)。 – 2012-04-01 11:08:50

+0

更合适,在放入查询之前,变量应该进行清理/转义/过滤(不同的人使用不同的单词)。如果我们禁止来自客户的变量来源,那么主流网站的用途是什么? – itachi 2012-04-01 11:33:27

+0

我会重新修改,确保它不是直接从客户端获得。适用的卫生条件已经适用。 – 2012-04-01 12:14:15

0

您可以计算查询

$a = isset($a) ? $a : ""; 
$page = ($page - 1) * 10; 

$sql = "SELECT * FROM `mytable` $a LIMIT $page,10"; 
3

之外有没有美化,将调整你的代码,以便它更易于阅读。这是你的作为程序员的工作;有人认为这是程序员的主要工作。所以,不要编写难看的代码,并试图让计算机为您清理它,而是首先要养成编写可读代码的习惯。在这种情况下,比可读性更好(例如转义和验证变量)。

$conditions = (isset($a) ? $a : ""); 
$lowerLimit = ($page - 1) * 10; 

$sql = "SELECT * 
    FROM `mytable` 
    $conditions 
    LIMIT $lowerLimit, 10"; 
0

你可以尝试找一些数据库代理,但在我的经验,我可以告诉你,或者他们缺乏能力,或者他们很难去适应它。

尽管如此,你可以尝试自己做一个更清晰的查询,声明瓦尔分开。 你甚至可以做出简单的帮手功能。

0

如果可能,请使用准备好的语句。

PDO例如:

$PDO = new PDO('host=localhost;dbname=test', 'foo', 'bar'); 

$query = $PDO->prepare(' 
    SELECT 
     * 
    FROM 
     foobar 
    WHERE 
     id = :user_id 
    LIMIT 
     :limit 
'); 

$query->execute(array(
    ':user_id' => $user_id, 
    ':limit' => $limit 
)); 
$query->fetchAll(); 
/*...*/ 

预处理语句是易于维护,你可以避免手工串逃跑。

0

你可以改变你写你的SQL代码的方式,以使其更易于粘贴复制/到一个基于Web的美化,像这样

$param = (isset($a) ? $a : ""); 
$param2 = ($page - 1) * 10; 

$sql = " 
SELECT * FROM mytable $param LIMIT $param2,10 
"; 

然后你复制的中间线,并粘贴到一个基于Web的美化(see here)和它吐出

SELECT * 
FROM mytable $param 
LIMIT $param2, 10 

如果您正在使用vim/emacs的,那么这整个事情可以通过传递到一个基于SQL壳美化简化,但对我的生活我不能找到一个。