PDO is much better option for calling procedures, views or triggers of mysql 5.x versions from PHP instead of using mysqli extension. Following is a simple demo script which can help anybody on how to call and use mysql procedures through php
try {
$dbh = new PDO('mysql:host=xxx;port=xxx;dbname=xxx', 'xxx', 'xxx', array( PDO::ATTR_PERSISTENT => false));
$stmt = $dbh->prepare("CALL getname()");
// call the stored procedure
$stmt->execute();
echo "<B>outputting...</B><BR>";
while ($rs = $stmt->fetch(PDO::FETCH_OBJ)) {
echo "output: ".$rs->name."<BR>";
}
echo "<BR><B>".date("r")."</B>";
} catch (PDOException $e) {
print "Error!: " . $e->getMessage() . "<br/>";
die();
}
MySQL (PDO_MYSQL) İşlevleri
Giriş
PDO_MYSQL, PHP Veri Nesneleri Arayüzünün (PDO) MySQL 3.x, 4.x ve 5.x veritabanlarına erişimini mümkün kılmak için gerçeklenmiş bir sürücüdür.
PDO_MYSQL eklentisi, MySQL'in 4.1 ve üstü sürümlerinde bulunan yerleşik hazır deyim desteğinden de yararlanır. MySQL'in daha eski istemci kütüphanelerini kullanıyorsanız PDO bu desteği sizin için kendisi sağlayacaktır.
Dikkat: Bazı MySQL tablo türleri (saklama motorları) toplu hareketleri desteklemez. Bir veritabanını kodlarken toplu hareketleri desteklemeyen bir tablo türünü kullanıyorsanız MySQL toplu hareketi başarıyla ilklendirmiş gibi yapar. Ayrıca, DDL sorguları, bekleyen toplu hareketlerin örtük olarak yerine getirilmesine de sebep olur.
Öntanımlı Sabitler
Bu sabitler bu sürücü tarafından
tanımlanmış olup, sadece eklentinin PHP içinde derlenmiş olması veya çalışma
anında devingen olarak yüklenmesi halinde kullanılabilir. Ek olarak, bu
sürücüye özgü sabitler sadece bu sürücüyü kullanıyorsanız kullanılmalıdır.
Sürücüye özgü özniteliklerin postgres sürücüsü ile kullanılması beklenmedik
davranışlara yol açabilir. Eğer kodunuz çok sayıda sürücüye karşı çalışıyorsa
sürücüyü sınayacak PDO_ATTR_DRIVER_NAME özniteliğini
sağlamak için PDO::getAttribute()
kullanılabilir.
-
PDO::MYSQL_ATTR_USE_BUFFERED_QUERY(integer) -
Bu özniteliğe bir PDOStatement nesnesinde
TRUEatanırsa MySQL sürücüsü MySQL arayüzünün tamponlu sürümlerini kullanır. Taşınabilir bir kod yazıyorsanız bunu yapmak yerine PDOStatement::fetchAll() yöntemini kullanın.Örnek 1 - Sorguların tamponlanmasına zorlamak
<?php
if ($db->getAttribute(PDO::ATTR_DRIVER_NAME) == 'mysql') {
$stmt = $db->prepare('select * from foo',
array(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true));
} else {
die("Bu uygulama sadece MySQL ile çalışır; " .
"yerine \$stmt->fetchAll() kullanılmalıydı");
}
?> -
PDO::MYSQL_ATTR_LOCAL_INFILE(integer) -
LOAD LOCAL INFILE etkin olur.
-
PDO::MYSQL_ATTR_INIT_COMMAND(integer) -
MySQL sunucusuna bağlanırken çalıştırılacak komut. Yeniden bağlantı sırasında özdevinimli olarak bu komut çalıştırılır.
-
PDO::MYSQL_ATTR_READ_DEFAULT_FILE(integer) -
Seçenekler my.cnf yerine burada belirtilen dosyadan okunur.
-
PDO::MYSQL_ATTR_READ_DEFAULT_GROUP(integer) -
Seçenekler my.cnf dosyasında belirtilen gruptan veya
MYSQL_READ_DEFAULT_FILEile belirtilen dosyadan okunur. -
PDO::MYSQL_ATTR_MAX_BUFFER_SIZE(integer) -
Azami tampon büyüklüğü; 1 MiB öntanımlıdır.
-
PDO::MYSQL_ATTR_DIRECT_QUERY(integer) -
Hazır deyimler kullanılmaz, sorgular doğrudan çalıştırılır.
İçindekiler
- PDO_MYSQL DSN — MySQL veritabanı bağlantısı
A note for the eager:
There is no way how to get returned row count from an executed prepared statement without fetching the rows.
To use "PDO::MYSQL_ATTR_USE_BUFFERED_QUERY" you should call
PDO::setAttribute("PDO::MYSQL_ATTR_USE_BUFFERED_QUERY", true);
It will not work when passed into PDO::prepare()
- Davey
The SSL options are silently ignored in PHP 5.3.8, see https://bugs.php.net/bug.php?id=55870
Looks like it's addressed upstream, I just want to save others the hour and a half I just wasted :)
Today's PHP snapshot now has SSL support for PDO. Follow the directions here ( http://dev.mysql.com/doc/refman/5.0/en/secure-create-certs.html ) to set up MySQL and then use the following connection options:
<?php
$pdo = new PDO(
'mysql:host=hostname;dbname=ssldb',
'username',
'password',
array(
PDO::MYSQL_ATTR_SSL_KEY =>'/path/to/client-key.pem',
PDO::MYSQL_ATTR_SSL_CERT=>'/path/to/client-cert.pem',
PDO::MYSQL_ATTR_SSL_CA =>'/path/to/ca-cert.pem'
)
);
?>
SQLSTATE[HY000]: General error: 2014 Cannot execute queries while other unbuffered queries are active. ...
After spending hours trying to track down why we were getting this error on a new server, after the same code ran fine on other servers, we found the problem to be an old MySQL _client_ library running on our web server, and a latest-version MySQL _server_ running on the database server's box.
Upgraded the MySQL client on the web server to the current revision and the problem went away.
SQLSTATE[HY000]: General error: 2014 Cannot execute queries while other unbuffered queries are active. ...
This one can be a royal pain to deal with. Never stack statements to be executed in one go. Nobody ever mentions this possibility in all the posts I've seen dealing with this error.
This example is a Zend Framework example but the theory is the same.
As in:
<?php
$sql = <<<____SQL
CREATE TABLE IF NOT EXISTS `ticket_hist` (
`tid` int(11) NOT NULL,
`trqform` varchar(40) NOT NULL,
`trsform` varchar(40) NOT NULL,
`tgen` datetime NOT NULL,
`tterm` datetime,
`tstatus` tinyint(1) NOT NULL
) ENGINE=ARCHIVE COMMENT='ticket archive';
CREATE TABLE IF NOT EXISTS `request_hist` (
`rqid` int(11) NOT NULL,
`rqtid` int(11) NOT NULL,
`rqsid` int(11) NOT NULL,
`rqdate` datetime NOT NULL,
`rqcode` tinyint(1) NOT NULL,
`rssid` int(11) NOT NULL,
`rsdate` datetime,
`rscode` tinyint(1)
) ENGINE=ARCHIVE COMMENT='request archive';
CREATE TABLE IF NOT EXISTS `relay_hist` (
`rqid` int(5) NOT NULL,
`sdesc` varchar(40) NOT NULL,
`rqemail` varchar(40) NOT NULL,
`sid` int(11) NOT NULL,
`rlsid` int(11) NOT NULL,
`dcode` varchar(5) NOT NULL
) ENGINE=ARCHIVE COMMENT='relay archive';
____SQL;
$result = $this->db->getConnection()->exec($sql);
?>
This will run fine but PDO will balk with the 'unbuffered' error if you follow this with another query.
Instead do:
<?php
$sql = <<<____SQL
CREATE TABLE IF NOT EXISTS `ticket_hist` (
`tid` int(11) NOT NULL,
`trqform` varchar(40) NOT NULL,
`trsform` varchar(40) NOT NULL,
`tgen` datetime NOT NULL,
`tterm` datetime,
`tstatus` tinyint(1) NOT NULL
) ENGINE=ARCHIVE COMMENT='ticket archive';
____SQL;
$result = $this->db->getConnection()->exec($sql);
$sql = <<<____SQL
CREATE TABLE IF NOT EXISTS `request_hist` (
`rqid` int(11) NOT NULL,
`rqtid` int(11) NOT NULL,
`rqsid` int(11) NOT NULL,
`rqdate` datetime NOT NULL,
`rqcode` tinyint(1) NOT NULL,
`rssid` int(11) NOT NULL,
`rsdate` datetime,
`rscode` tinyint(1)
) ENGINE=ARCHIVE COMMENT='request archive';
____SQL;
$result = $this->db->getConnection()->exec($sql);
$sql = <<<____SQL
CREATE TABLE IF NOT EXISTS `relay_hist` (
`rqid` int(5) NOT NULL,
`sdesc` varchar(40) NOT NULL,
`rqemail` varchar(40) NOT NULL,
`sid` int(11) NOT NULL,
`rlsid` int(11) NOT NULL,
`dcode` varchar(5) NOT NULL
) ENGINE=ARCHIVE COMMENT='relay archive';
____SQL;
$result = $this->db->getConnection()->exec($sql);
?>
Chopping it into individual queries fixes the problem.
I have been getting the error below when performing multiple queries within a single page.
Setting the attribute below did not seem to work for me.
So building on previous example i am initilizing my stmt variable on every query and a fetch all into an array. Seems to be working for me.
Error:
PDO Error 1.1: Array ( [0] => xxx[1] => yyy[2] => Lost connection to MySQL server during query )
Fix:
(PDO::setAttribute("PDO::MYSQL_ATTR_USE_BUFFERED_QUERY", true);)
<?
try {
$dbh = new PDO('mysql:host=xxx;port=xxx;dbname=xxx', 'xxx', 'xxx', array( PDO::ATTR_PERSISTENT => false));
$stmt = $dbh->prepare("CALL getname()");
// call the stored procedure
$stmt->execute();
// fetch all rows into an array.
$rows = $stmt->fetchAll();
foreach ($rows as $rs)
{
$id = $rs['id'];
}
//initilise the statement
unset($stmt);
$stmt = $dbh->prepare("call secondprocedure(?);");
$stmt->bindValue(1, $id);
if ( ! $stmt->execute() )
{
echo "PDO Error 1.1:\n";
print_r($stmt->errorInfo());
exit;
}
unset($stmt);
} catch (PDOException $e) {
print "Error!: " . $e->getMessage() . "<br/>";
die();
}
?>
Davey wrote:
> To use "PDO::MYSQL_ATTR_USE_BUFFERED_QUERY" you should call
> PDO::setAttribute("PDO::MYSQL_ATTR_USE_BUFFERED_QUERY", true);
>
>It will not work when passed into PDO::prepare()
>
> - Davey
Almost correct. It should be:
PDO::setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true);
so, without the quotes.
otherwise it still won't work :)
On Windows, with Apache, it would not load php_pdo_mysql.dll until I put libmysql.dll in Apache's dll path (e.g. apache/bin)
> konrads dot smelkovs at gmail dot com
> 18-Jul-2007 03:39
> A note for the eager:
>> There is no way how to get returned row count from an executed prepared statement without fetching the rows.
Sure there is, just do something like this:
if ($sth = $pdo->prepare($sql)) {
$sth->execute($values);
$sth->fetch();
// get count of rows in result set
if ($sth_rc = $this->getDataset()->query('SELECT FOUND_ROWS()')) {
$row_count = $sth_rc->fetchColumn(0);
}
}
