2015-05-11 27 views
0

http://php.net/manual/en/pdo.prepared-statements.php在函数或方法中使用

查询只需要被解析(或制备的)一次时,但也可以是 执行多次使用相同的或不同的参数从PDO准备声明受益。当 准备好查询时,数据库将分析,编译并优化其执行查询的计划。对于复杂的查询,如果需要用不同的 参数多次重复相同的查询,则该过程可能会花费足够的时间,以致明显地减慢应用程序的速度 。通过使用准备好的语句,该应用程序避免了重复分析/编译/优化循环的 。这意味着准备好的 语句使用更少的资源,从而运行得更快。

因此,下面将与更好的性能使用预处理语句时,受益:

<?php 
... 
$stmt=$conn->prepare('SELECT a FROM mytable WHERE x=?'); //I often use globals or similar for $conn 
foreach($array as $id){ 
    $stmt->execute(array($id)); 
    $data=$stmt->fetchAll(PDO::FETCH_COLUMN); 
    ... 
} 
... 
?> 

为了消除重复的代码,我希望在一个函数来执行查询。

在这种情况下,我如何从预先准备好的陈述的改进表现中受益?

请注意以下代码没有提供效率优势,实际上比首先使用预准备语句慢。

<?php 
function getStuff($x) 
{ 
    ... 
    $stmt=$conn->prepare('SELECT a FROM mytable WHERE x=?'); 
    $stmt->execute(array($x)); 
    $data=$stmt->fetchAll(PDO::FETCH_COLUMN); 
    ... 
    return $data;  
}; 

... 
foreach($array as $x){ 
    $data=getStuff($x); 
    ... 
} 
... 
?> 
+0

让两个功能,一是准备,一个用于执行。在你的情况下,你每次都准备相同的查询,这不会提高性能。 – Bv202

+0

在您的方案中,您根本没有任何收益。您准备/执行您的查询,然后THROW AWAY让您可以重新使用查询的语句句柄。 –

+0

Bv202和Marc。同意我的第二个方案没有任何好处,只有我的第一个。我如何在第二种情况下受益? – user1032531

回答

2

我已经在过去使用这样的:

function getStuff($x) 
{ 
    global $conn; 
    static $stmt; 

    if (null === $stmt) { 
     $stmt = $conn->prepare('SELECT a FROM mytable WHERE x=?'); 
    } 

这工作如果函数是无状态的。 例如,它没有意义,使$conn变量参数:

function getStuff($conn, $x) 
{ 
    static $stmt; 

    if (null === $stmt) { 
     $stmt = $conn->prepare('SELECT a FROM mytable WHERE x=?'); 
    } 

因为,静态的语句不一定属于附带的连接。

但是你这样做,你需要使语句在函数中保持不变,否则使用该函数作为工厂并在别处缓存语句。

编辑,测试非接力场景:

echo '<pre>'; 

function do_something() 
{ 
    static $i = 0; 

    echo $i . PHP_EOL; 

    $i++; 
} 

do_something(); 
do_something(); 
do_something(); 
do_something(); 
do_something(); 

输出:

0 
1 
2 
3 
4 
+0

你可以在函数中声明静态变量(而不是类成员)?我永远不会想到试试:) – CD001

+0

谢谢Flosculus。为什么你的第二个版本没有工作,只要它总是通过相同的$ conn?我不是说我通常使用全局的$ conn,但实际上我使用了一个静态单例类(可能效果相同)。 – user1032531

+0

@ CD001是的,它工作正常。 – user1032531