介绍
今天发现php5.1.*和php5.2.*在数据库预编译代码执行的时候出现差异。
预编译优点
1.使用占位符,避免逐字输入数据到SQL中。自动处理引号和反斜线等字符的转义——增加安全性。
2.预先“准备”一条语句,然后在每次执行时绑定不同值达到重用的目的。——常用于以后被多次执行的语句。
3.可读性强。
代码
数据库连接代码都一样.
$protol = 'mysql:host=localhost;dbname=test';
$username = 'monty';
$passwd = '0818';
$dbh = new PDO($protol, $username, $passwd);
以下是一些测试。注意里面的SQL和for或者foreach语句!
测试1(用key值进行绑定)
$stmt = $dbh->prepare('select * from t1 where name=:name');
$params = array();
$params['name'] = 'rentao';
foreach($params as $k=>$v){
$stmt->bindParam($k, $v);
}
$stmt->execute();
$item = array();
while($row = $stmt->fetch(PDO::FETCH_ASSOC)){
var_dump($row);
}
$stmt = null;
$dbh = null;
结论:
PHP 5.1.* |
PHP 5.2.* |
执行正常 |
执行正常 |
$params['name'] = 'rentao' 和$params[':name']='rentao'这两个都能执行,说明不受“:”限制。 |
测试2(数字下标去绑定,但是绑定的起始参数是1)——":key"在php5.2.*上不能用数字下标绑定
$stmt = $dbh->prepare('select * from t1 where name=:name limit 2');
$params = array();
$params[] = 'rentao';// 这里加不加":"都能成功执行
for($i=0,$iLen = count($params); $i $k = $i+1;
$stmt->bindParam($k, $params[$i]);
}
echo "HERE1\n";
$stmt->execute();
echo "HERE2\n";
$item = array();
while($row = $stmt->fetch(PDO::FETCH_ASSOC)){
var_dump($row);
}
$stmt = null;
$dbh = null;
结论:
php 5.1.* |
PHP 5.2.* |
执行正常 |
出现错误:“PHP Warning: PDOStatement::execute(): SQLSTATE[HY093]: Invalid parameter number: parameter was not defined” |
如果把":name"改成"?",那么两个版本都可以顺利进行。 |
不能同时使用两种符号。如 select * from t2 where name=? limit :page
|
测试3(limit绑定:page)
$stmt = $dbh->prepare('select * from t2 where name=:name limit :page');
$params = array();
$params['name'] = 'rentao';// 这里加不加":"都能成功执行
$params['page'] = 2;
foreach($params as $k=>$v){
$stmt->bindParam($k, $v);
}
$stmt->execute();
echo "HERE1\n";
$item = array();
while($row = $stmt->fetch(PDO::FETCH_ASSOC)){
var_dump($row);
}
echo "HERE2\n";
$stmt = null;
$dbh = null;
结论:
PHP 5.1.* |
PHP 5.2.* |
执行到$stmt->execute()时,进程一直处于等待状态中 |
执行正常:打印不出结果 |
测试4(在limit下进行预编译操作:page)——使用“?”机制运行
$stmt = $dbh->prepare('select * from t2 where name=? limit ?');
$params = array();
$params[] = 'rentao';
$params[] = 2;
for($i=0,$iLen = count($params); $i $k = $i+1;
$stmt->bindParam($k, $params[$i]);
}
$stmt->execute();
$item = array();
while($row = $stmt->fetch(PDO::FETCH_ASSOC)){
var_dump($row);
}
$stmt = null;
$dbh = null;
PHP 5.1.* |
PHP 5.2.* |
执行正常 |
执行正常:打印不出结果 |
测试5---order by)
PHP 5.1.* |
PHP 5.2.* |
打印出结果,但未按order by进行排序 |
执行正常:打印不出结果 |
总结 PHP在使用PDO做数据库预编译操作的时候,尽量避免使用limit, order by, group by 做预编译处理。绑定变量我们尽量使用统一标准,要不然都使用“?”,要不然使用“:key”。
有用的命令,我在php5.1.*进行测试,测试完了,我通过scp把文件传输到php5.2.*服务器上
scp -P9888 index.php rentao@192.168.10.4:/home/rentao
Stellungnahme:Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn