2017-01-18 7 views
0


私は長い間解決できなかった問題があります。私はDBにデータを書き込むための方法と、この1PHP PDO例外

class DB { 

    private static $dbserver = "mysql:dbname=db;host=localhost"; 
    private static $dbuser = "root"; 
    private static $dbpass = ""; 

    public static function connectDB() { 

     @$dbh = new PDO(self::$dbserver, self::$dbuser, self::$dbpass); 
     $dbh->setAttribute(\PDO::ATTR_EMULATE_PREPARES, false); 
     $dbh->setAttribute(PDO::MYSQL_ATTR_INIT_COMMAND, 'SET NAMES utf8'); 

     return $dbh; 
    } 

とサービスクラスのような単純なDBクラスを持っています。テーブルのタイプはInnoDBです。私は、関数insert_data IN PDO :: PDOへATTR_ERRMODE :: ERRMODE_EXCEPTIONを設定している場合、この

function insert_data($data) { 
    $error = NULL; 
    try { 
     $dbh = DB::connectDB(); 
     $dbh->beginTransaction(); 

     $query_insert_1 = 'INSERT INTO table (f1, f2, f3) VALUES (?,?,?)'; 
     $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 
     $stmt = $dbh->prepare($query_insert_1); 
     $stmt->execute(array($d1, $d2, $d3)); 

     $last_insert_id = $dbh->lastInsertId(); 

     $query_insert_2 = 'INSERT INTO table2 (f4, f5, f6) VALUES (?,?,?)'; 
     $stmt = $dbh->prepare($query_insert_2); 
     $stmt->execute(array($last_insert_id, $d4, $d5)); 

     $dbh->commit();    
    } 
    catch(Exception $e) {      
     $dbh->rollback(); 
     $error = $e->getMessage(); 
    } 
    $return = new Result($error ? 1 : 0, $error ? 0 : 1, $error ? $error : '', NULL); 
    error_log(print_r($error,1)); 
    return $return; 
} 

PDOが唯一の例外がスローされますようにサービスクラスが見えます。 DBクラスに設定した場合、例外はスローされません。この行動の理由は何ですか?

私はマイケル

EDITこの質問から助け

用(PDO exception is not being thrown

感謝を機能で定数を設定すると、例外をスローするためのソリューションを持っている: 私の元々のコードです次

class CarService { 

private $dbh; 

function __construct($dbh) { 
    $this->dbh = $dbh; 
} 

function insert_car($customer_id, $brand, $model) { 
    $error = NULL; 

    try { 
     $this->dbh->beginTransaction(); 

     $query_insert_car = 'INSERT INTO fahrzeug (kunde_id, fabrikat, modell) VALUES (?,?,?)'; 

     $stmt = $this->dbh->prepare($query_insert_car); 
     $stmt->execute(array($customer_id, $brand, $model)); 
     // Get the ID of the last inserted car 
     $last_insert_id = $this->dbh->lastInsertId(); 
     // Create the entry of the corresponding car version 
     $query_insert_car_version = 'INSERT INTO fahrzeugversion (fahrzeug_id, version, fabrikat, modell) VALUES (?,?,?,?)'; 
     $stmt = $this->dbh->prepare($query_insert_car_version); 
     $stmt->execute(array($last_insert_id, 1, $brand, $model)); 

     $this->dbh->commit();    
    } 
    catch(Exception $e) {      
     $this->dbh->rollback(); 
     $error = $e->getMessage(); 
    } 

    $return = new Result(1, 0, NULL, NULL); 
error_log(print_r($error,1)); 
    return $return; 
} 

new_car.php

<?php 

require_once('DB.php'); 
require_once('CarService.php'); 
require_once('Result.php'); 

$dbh = DB::connectDB(); 
$car_service = new CarService($dbh); 

$result = new Result(1, 0, NULL, NULL); 

if (isset($_POST['fabrikat']) && isset($_POST['modell'])) { 
    $brand = trim($_POST['fabrikat']); 
    $model = trim($_POST['modell']); 

    $result = $car_service->insert_car(1, $brand, $model);   
} 
print_r(json_encode($result)); 
?> 

をdb.php

<?php 

class DB { 

    private static $dbserver = "mysql:dbname=db;host=localhost"; 
    private static $dbuser = "root"; 
    private static $dbpass = ""; 

    public static function connectDB() { 

     $dbh = new PDO(self::$dbserver, self::$dbuser, self::$dbpass); 
     $dbh->setAttribute(\PDO::ATTR_EMULATE_PREPARES, false); 
     $dbh->setAttribute(PDO::MYSQL_ATTR_INIT_COMMAND, 'SET NAMES utf8'); 
     $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 
     return $dbh; 
    } 

} 
?> 
+0

ちょうど推測ですが、$ dbhの割り当てをオフにしてみてください。エラーメッセージを表示しません。 – aynber

+0

こんにちは、私はそれが問題ではないと思います。間違ったフィールド名などのMySQL構文でエラーが発生した場合、DBクラスにERR_MODEを設定すると例外はスローされません –

答えて

1

PDO接続プロセスに

public static function connectDB() { 

    $dbh = new PDO(self::$dbserver, self::$dbuser, self::$dbpass); 
    $dbh->setAttribute(\PDO::ATTR_EMULATE_PREPARES, false); 
    $dbh->setAttribute(\PDO::MYSQL_ATTR_INIT_COMMAND, 'SET NAMES utf8'); 
    $dbh->setAttribute(\PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 
    return $dbh; 
} 

PDO::ERRMODE_EXCEPTION属性を追加し、それはあなたがそれを閉じるまで、この接続を使用してすべてのために設定されます。

今、あなたはそれを

を設定したことを他の場所から削除することができます注:

多分これは、例外がスローされます時期についてちょうど誤解です。

PDO :: ATTR_ERRMODEをPDO :: ERRMODE_EXCEPTIONに設定すると、例外がスローされます。

しかし:

->prepare()文がコンパイルのためにデータベースにクエリを発行 PDO::ATTR_EMULATE_PREPARES = fale場合

、したがって、あなたは、クエリがコンパイルされない場合->prepare()によってスローされた例外を取得します。

PDO::ATTR_EMULATE_PREPARES = trueの場合、prepare文はほとんど機能しません。この時点でコンパイルのためにクエリがデータベースに発行されることはありません。クエリは->execute()処理の一部としてコンパイルのためデータベースに発行され、コンパイルに失敗した場合は ` - > execute()文がスローされます。

+0

Hello RiggsFolly、これを実行すると例外はスローされません。これは私のデフォルト設定でした。 PDO :: ERRMODE_EXCEPTION属性をtryブロックに追加するので、例外がスローされます。 –

+0

他の何かが間違っています。私はもっ​​と近く見てみましょう – RiggsFolly

+0

実際これは良いプロセスではありません。あなたのコードでは、すべての方法で接続する必要があり、スクリプトごとに一度だけ接続したい場合は、 – RiggsFolly

0

他のコードのいくつかは、PDO :: ERRMODE_EXCEPTIONを別の値に設定しているようです。

あなたはここに掲載のみコードを含む分離実施例を記述するためにわざわざ場合は、その例外がすべての権利スローされます表示されます。