2016-07-08 8 views
2

は、私のコードを見てみてください。なぜエラーが発生した場合、execute()はtrueを返しますか?

try { 
    // db connection here 
    $stm = $dbh->prepare("INSERT INTO mytable(id,token) values(NULL,$token)")->execute(); 

} catch(PDOException $e){ 
    if ($stm){ 
     echo 'inserting fails'; 
    } else { 
     echo 'something else is wrong'; 
    } 
} 

-- `token` column is unique 

電流出力:

  • 正常に挿入行。
  • something else is wrong両方のためのエラー{エントリを複製}と{SQL構文}

期待される出力印刷:

  • うまく挿入された行を。次いで
  • それは私が(チェーンなし)を以下のように自分のコードを記述する場合、それは、{SQL構文}

玉ためsomething else is wrongエラーを印刷{エントリを複製}のinserting failsエラー

  • を印刷

    私はこれらのPDOステートメントをいつチェーン化できますか?

  • +2

    これは、あなたは彼らがPHPでどのように機能するかをよりよく理解を得るので、あなたは、グーグル/本を読みたいかもしれない「流れるようなインターフェイス」と呼ばれていますなぜあなたの現在のコードではうまくいかないのでしょうか? – Rizier123

    +0

    本当の質問は、なぜあなたは*になりたいですか? –

    +0

    @JayBlanchard私は今まで私のクエリ(*)のほとんどをチェーン化してきたので、私はこの質問をしました。だから私はそれらのすべてを変更する必要があります知りたいですか?チェーン化されていても問題ありませんか? –

    答えて

    2

    例外は、いずれか一方のみprepareまたはexecute方法でスローすることができます。どちらかが$stm =の前に起こるでしょう。つまり、例外がスローされる場合、$stmへの代入はです。常にはスキップされます。つまり、変数がcatchブロックにまったく存在しないことを意味します。したがって、評価はfalseに過ぎず、実際には未定義に関する通知が生成されます。

    2

    PDOのドキュメントhttp://php.net/manual/en/book.pdo.phpを読んで、戻り値を見てください。ステートメントや結果セットなどのオブジェクトが返されたときだけ連結することができます。

    実行(http://php.net/manual/en/pdostatement.execute.php)は、オブジェクトではなくブール値を返します。したがって、連結できないことがわかります。 Prepare(http://php.net/manual/en/pdo.prepare.php)はステートメントオブジェクトを返すので、returnステートメントを使用して別のメソッド呼び出しを連鎖させることができます。このようなことの

    思う:

    $stmt = $dbh->prepare("..sql.."); 
    $bool = $stmt->execute(); 
    

    これは、に変換することができますから復帰したよう

    $bool = $dbh->prepare("..sql..")->execute(); 
    

    - >(準備)$ stmtはあります。

    +0

    よく若いジェダイが言った。 –

    1

    期待される出力が得られないのは、PDOException$stmのいずれもが真になることはありません。 prepareまたはexecuteのいずれかが失敗する場合、$stmは未定義です。

    私はもともとcatchブロックからexecuteの成功のチェックを外してこの問題を解決できると思っていましたが、間違いました。メソッドを連鎖させながら、期待される出力を得ることはできません。

    try { 
        $success = $dbh->prepare("INSERT INTO mytable(id,token) values(NULL,$token)")->execute(); 
        if (!$success) { 
         // This can never be reached. If your have set PDO::ERRMODE_EXCEPTION, then either 
         // the query is successful and $success === true, or the prepare or the execute 
         // failed, and an exception will be thrown 
         echo 'inserting fails'; 
        } 
    } catch(PDOException $e){ 
        echo 'something else is wrong'; 
    } 
    
    +0

    @deceze答えを読んだ後、これが間違っていることがわかりました。 '$ stm'はfalseにならず、これは動作しません。私は実行も例外を引き起こすことを忘れていました。 –

    0

    ちょうど記録のため。男が質問しようとした質問に答える。

    article on PDOからコード(また、SQLインジェクションを固定):

    try { 
        $dbh->prepare("INSERT INTO mytable(token) values(?)")->execute([$token]); 
    } catch (PDOException $e) { 
        if ($e->getCode() == 1062) { 
         // insert failed due to duplicate key error 
         echo "duplicate token"; 
        } else { 
         // insert failed due to any other error 
         throw $e; 
        } 
    } 
    
    関連する問題