2017-02-17 81 views
-3

我有一個PHP PDO事務處理比插入一行然後選擇它。當INSERT操作完成時,我調用另一個執行SELECT的函數。問題是SELECT在被調用函數內執行時沒有返回先前插入的行。

這裏有代碼:

INSERT後PHP PDO事務選擇問題

class FinderMyTable { 

    function myfunction(...) { 
    $db = DatabaseManager::getInstance()->getConnection(); 
    $db->beginTransaction(); 
    try { 

     $dbParameters = array(':var1' => $var1, ...); 
     $dbStatement = $db->prepare('INSERT INTO MyTable(...) VALUES(:var1, ...)'); 
     $success = $dbStatement->execute($dbParameters); 
     if (!$success) throw new Exception('internal-database-error'); 

     $insertedRowId = $db->lastInsertId(); 

     $dbParameters = array(':insertedRowId' => $insertedRowId); 
     $dbStatement = $db->prepare('SELECT * FROM MyTable WHERE id = :insertedRowId'); 
     $dbStatement->execute($dbParameters); 
     $row = $dbStatement->fetch(); 

     error_log('ROW: ' . print_r($row, true)); 

     $rowData = $this->obtainRowData($insertedRowId); 

     $db->commit(); 

    } catch (PDOException $e) { 
     $db->rollBack(); 
     error_log($e->getMessage()); 
     throw new Exception('internal-database-error'); 
    } catch (Exception $e) { 
     $db->rollBack(); 
     error_log($e->getMessage()); 
     throw $e; 
    } 
    } 

    function obtainRowData($insertedRowId) { 
    $db = DatabaseManager::getInstance()->getConnection(); 

    $dbParameters = array(':insertedRowId' => $insertedRowId); 
    $dbStatement = $db->prepare('SELECT * FROM MyTable WHERE id = :insertedRowId'); 
    $dbStatement->execute($dbParameters); 
    $row = $dbStatement->fetch(); 

    error_log('ROW INSIDE FUNCTION: ' . print_r($row, true)); 

    $data = $row['field1']; 
    // ... 
    return $data; 
    } 

} 

正如你所看到的,我已經把2個error_log(...);電話。
「行」調用返回已插入正確的數據:

ROW: Array 
(
    [id] => 813 
    [0] => 813 
    [field2] => 289 
    [1] => 289 
    [field3] => value 
    [2] => value 
    [field4] => value2 
    [3] => value2 
) 

的「連續在內線FUNCTION」調用返回不正確的數據:

ROW INSERTED FUNCTION: Array 
(
    [id] => 2345 
    [0] => 2345 
    [comment] => 
    [1] => 
) 

正如你所看到的,沒有的在上次調用中獲得的值與插入的行相對應。此外,我有一個「評論」字段,不出現在這張表中!

下面你有我的DatabaseManager類,這是管理PDO連接一個Singleton類:

final class DatabaseManager { 

    private static $instance = null; 
    private $connection; 

    private function __construct() { 
    try { 
     $connection = new PDO('mysql:host=...;dbname=...;charset=latin1', 'user', 'pass'); 
     $connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 
    } catch (PDOException $e) { 
     error_log($e->getmessage()); 
     die(); 
    } 
    $this->connection = $connection; 
    } 

    public function __clone() {} 

    public static function getInstance() { 
    if (self::$instance === null) self::$instance = new DatabaseManager(); 
    return self::$instance; 
    } 

    public function getConnection() { 
    return $this->connection; 
    } 

} 

可以採取什麼問題嗎? 爲什麼被調用的函數選擇一個完全不同的行?

+0

首先將您的抓取改爲'fetch(PDO :: FETCH_ASSOC);'。它給你沒有重複。並使用'Select SELECT * FROM MyTable WHERE id ON(:insertedRowId)'並使用bindparam和implode來獲得所有ID – MRustamzade

+0

沒有人知道你的代碼有什麼問題。特別是當你張貼故意的人爲代碼時。你必須創建一個*可驗證的*實例來獲得答案。 [如何爲PDO相關問題創建一個MCVE](https://phpdelusions.net/pdo/mcve) –

+1

@MehemmedRustemzade恐怕你根本不理解這個問題。 –

回答

-2

解決!好的,我簡化了代碼...在$row = $dbStatement->fetch();error_log(...);之間有一些代碼行,其中一個代碼覆蓋$row變量。所以兩個SELECT都從頭開始給出相同的結果,error_log(...)是通過覆蓋變量完成的。