PDO başarısız sessizce hazırlamak

3 Cevap php

Ben PHP'nin session_set_save_handler ile deney yaşıyorum ve ben oturum verilerini saklamak için bir PDO bağlantısı kullanmak istiyorum.

Ben yazma eylemler için bir geri olarak bu işlevi vardır:

function _write($id, $data) {
    logger('_WRITE ' . $id . ' ' . $data);
    try {
        $access = time();
        $sql = 'REPLACE INTO sessions SET id=:id, access=:access, data=:data';
        logger('This is the last line in this function that appears in the log.');
        $stmt = $GLOBALS['db']->prepare($sql);
        logger('This never gets logged! :(');
        $stmt->bindParam(':id', $id, PDO::PARAM_STR);
        $stmt->bindParam(':access', $access, PDO::PARAM_INT);
        $stmt->bindParam(':data', $data, PDO::PARAM_STR);
        $stmt->execute();
        $stmt->closeCursor();
        return true;
    } catch (PDOException $e) {
        logger('This is never executed.');
        logger($e->getTraceAsString());
    }
}

İlk iki günlük iletileri her zaman göstermek, ancak üçüncü bir hemen sonra $stmt = $GLOBALS['db']->prepare($sql) günlük dosyasına yapar ve asla bir istisna hiçbir iz de yok.

sessions db tablo boş kalır.

_close geri çağırma gelen günlük mesajı her zaman mevcuttur.

Burada veritabanına bağlanmak nasıl:

$db = new PDO('mysql:host=' . DBHOST . ';dbname=' . DBNAME, DBUSER, DBPASS);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

PHP 5.2.10 var.

Ben sadece bir "elle hazırlanan" $sql içerikli $GLOBALS['db']->exec($sql) çalıştırmayı denedim, ama yine de sessizce başarısız oldu. Sorgu kendisi ben db konsol üzerinden çalıştırmak mümkün oldu tüm hakkıdır.


Edit:

VolkerK Ben bu garip olayların arkasındaki nedeni açıklıyor this article hangi buldum sorunu tespit etti sonra. Belki de diğerleri de bilgilendirici olabilir.


2nd edit:

Az ağrılı, sihirli bir çözüm benim ön denetleyicisi (ana index.php) dosyasının sonuna kadar aşağıdaki işlev çağrısı eklemek zorunda olduğunu:

session_write_close();

3 Cevap

Benim bahisler vardır: $ GLOBALS ['db'] set veya PDO bir örneğini (artık?) Ve bunun bir PHP Fatal error: Call to a member function prepare() on a non-object oluşur ve php kefil değildir.

$sql = 'REPLACE INTO sessions SET id=:id, access=:access, data=:data';
logger('This is the last line in this function that appears in the log.');
if ( !isset($GLOBALS['db']) ) {
  logger('there is no globals[db]');
  return;
}
else if ( !is_object($GLOBALS['db']) ) {
  logger('globals[db] is not an object');
  return;
}
else if ( !($GLOBALS['db'] instanceof PDO) ) {
  logger('globals[db] is not a PDO object');
  return;
}
else {
  logger('globals[db] seems ok');
}

$stmt = $GLOBALS['db']->prepare($sql);
logger('This never gets logged! :(');

Belki PDO sözdizimi REPLACE INTO tanımıyor. Yatan DB erişim kütüphane doğrudan hazırlanmış deyimleri desteklemiyorsa, PDO onları öykünür ve olası deyim türleri kendi listesinde INTO DEĞİŞTİR olmayabilir.

Çağrı hazırlamak sonra $stmt->errorCode() hemen kontrol deneyin?

Bu mysql ise, aşağıdaki gibi hazırlanmış deyimi yeniden deneyebilirsiniz:

INSERT INTO sessions (id, access, data)
VALUES(:id, :access, :data)
ON DUPLICATE KEY UDPATE
    access=VALUES(access), data=VALUES(data);

herhangi bir uzak alır ve eğer görmek.

Kaynak veri türleri $GLOBALS[] erişilebilir değil gibi hissediyorum. Referanslar işlenir veya bu şekilde bir şey hakkında bir şey. Eğer mizah ruh halinde iseniz benim önsezi işlev bildirimi için bu deneyin:

function _write($id, $data) {
    global $db;
    logger('_WRITE ' . $id . ' ' . $data);
    denemek {

Ve bunun yerine:

$stmt = $GLOBALS['db']->prepare($sql);

denemek

$stmt = $db->prepare($sql);

You could also denemek catching plain old Exceptions instead of PDOExceptions; it might be getting caught up on that.

Bu yardımcı olur umarım!