2016-05-28 6 views
2

現在はPDOを使用してクエリを実行するために、私は次のコード行を使用します。速記PDOクエリ

$stmt_test = $conn->prepare("SELECT * FROM status WHERE status_id = ?"); 
$stmt_test->execute([$id])->fetchAll(PDO::FETCH_ASSOC); 
$result = $stmt_test->fetchAll(PDO::FETCH_ASSOC); 
$sql = "SELECT * FROM myTable WHERE id = :id"; 
$stmt = $conn->prepare($sql); 
$stmt->bindParam(':id', $id); 
$stmt->execute(); 
$result = $stmt->fetchAll(PDO::FETCH_ASSOC); 

そして、いくつかの研究の後、私は同じコマンドを実行するための簡単な方法を発見した

そこから

私はおそらく次のコードでそれをさらに短くすることができると思った:

$stmt_test = $conn->prepare("SELECT * FROM status WHERE status_id = ?"); 
$result = $stmt_test->execute([$id])->fetchAll(PDO::FETCH_ASSOC); 

しかし、私は、次のERを取得ROR:

Fatal error: Call to a member function fetchAll() on a non-object in /home/.../index.php on line 20

QUESTION:は、なぜ私はこのエラーを取得していますか?私の理解から、$stmt_test->execute([$id])が最初に実行され、その結果、->fetchAll(PDO::FETCH_ASSOC)が実行され、そこから配列が$resultに返されますが、エラーが発生しているので、ロジックに何か不備があります。私は間違って何をしていますか?また、誰も以前のクエリを実行するためのより簡略な方法を知っていますか?

+0

の可能性のある重複[PDO - 非オブジェクト上()フェッチメンバ関数の呼び出し(http://stackoverflow.com/questions/ 12126193/pdo-call-to-a-member-function-non-objectを呼び出す) – johannes

+0

@johannesエラーが同じ名前であっても、エラーが発生する状況は異なります。 – Webeng

+0

ああ、十分に慎重に読んでいない、以下に答えます。 – johannes

答えて

6

「なぜこのエラーが発生するのですか」という質問に対する回答がありますが、「簡略PDOクエリ」の質問はありません。

これについては、「プログラミング」と呼ばれるものが少し必要です。

プログラミングに関する興味深い点の1つは、他の職業のような既存のツールに限定されないことです。プログラミングによって、私たちはいつも私たち自身のツールを作り、それを古いものの代わりに使うことができます。

オブジェクト指向プログラミングは、既存のオブジェクトを使用して機能を追加して残りの部分をそのまま残すことができるため、特に優れています。

たとえば、PDOで準備済みのクエリを実行するための簡略な方法を考えてみましょう。私たちが必要とするのは、PDOオブジェクトを新しい簡略メソッドで拡張することだけです。最も難しいのは、新しいメソッドに名前を付けることです。

残りは単純です:you need only few lines of code

class MyPDO extends PDO 
{ 
    public function run($sql, $bind = NULL) 
    { 
     $stmt = $this->prepare($sql); 
     $stmt->execute($bind); 
     return $stmt; 
    } 
} 

これはあなたが必要とするすべてのコードです。データベース資格情報を保存するのと同じファイルに格納することができます。この追加は、既存のコードには何ら影響しません。これはまったく同じです。既存のすべてのPDOメソッドを通常どおり使用することができます。

今、あなたは

$conn = new MyPDO(...the rest is exactly the same...); 

として、それを呼び出して、PDOのコンストラクタで唯一の2文字を変更する必要があるとすぐに、あなたはあなたのピカピカの新しいツールの使用を開始可能性があります。それを少し与え、

$sql = "SELECT * FROM myTable WHERE id = :id"; 
$result = $conn->run($sql, ['id' => $id])->fetchAll(PDO::FETCH_ASSOC); 

しますか、

$result = $conn->run("SELECT * FROM myTable WHERE id = ?", [$id])->fetchAll(); 

いつでも既定のフェッチモードをすべて1回だけ設定できますle変数名前付きプレースホルダには使用できません。後者ではないことをどの受け入れ答え、

$stmt_test = $conn->prepare("SELECT * FROM status WHERE status_id = ?"); 
$stmt_test->execute([$id]); 
$result = $stmt_test->fetchAll(PDO::FETCH_ASSOC); 

とも、あなたがこれまで持って最善の答えにに比べて、このコードに本当の速記を行い、

$result = $conn->prepare("SELECT * FROM status WHERE status_id = ?"); 
$result->execute([$id]); 

ないに言及配列を取得するのに適しているので、常に使用可能です。 速記で任意結果フォーマットが可能であるが:

$result = $conn->run($sql, [$id])->fetchAll(); // array 
$result = $conn->run($sql, [$id])->fetch(); // single row 
$result = $conn->run($sql, [$id])->fetchColumn(); // single value 
$result = $conn->run($sql, [$id])->fetchAll(PDO::FETCH_*); // dozens of different formats 
+0

とよく訂正されました。それは非常に完全な答えであり、栄誉ある緑のチェックマークを裏切ることは間違いありません – Webeng

+0

ありがとうございました。このマークは実際に私のためではなく、省略形のPDO関数を探している他の開発者のためのものです。私の解決策は、問題を認めているだけでなく、本当に問題に答える唯一の解決策だと思います。 –

+0

PDO用のラッパークラスを作成することは、2つのメソッドを1つに単純に結合する1つのメソッドを作成するために、過剰なもののようです。答えは、PDOを使用して準備された文を実行する方法がより早くないことです。それは大きな答えです。あなたはそれに同意する必要があります。 – JasonK

4

$stmt_test->execute([$id])は、booleanの値を返します。つまり、

$result = $stmt_test->execute([$id])->fetchAll(PDO::FETCH_ASSOC); 

は無効です。代わりにあなたが

$stmt_test->execute([$id]); 
$result = $stmt_test->fetchAll(PDO::FETCH_ASSOC); 
+0

完璧な答えです。時間制限が切れると、私はこの回答を受け入れます。 '$ stmt_test'がブール値を返すことを認識していないので、' $ stmt_test'自体ではなく 'fetchAll'がその戻り値に適用されていました。 – Webeng

+1

@Webeng私はこの答えを完璧とは呼んでいませんが、あなたのコードを短くすることはありません。 –

0

を行う必要があり、私はPDOの​​メソッドがtrueまたはfalseを返すと考えています。エラーが既にあなたに伝えているように:fetchAll()はオブジェクトを期待しています。 3行のコードを使うのが最短です。

もう1つの選択肢は、propelのようなORMを使用することです。これは本当にスムーズに動作し、多くの時間を節約します。

+0

ツールを推奨する回答には、OPのニーズに適用される実際の例が常に役立ちます。それ以外の場合、彼らは注意を受けません。 –

1

エラーは、PDOの設計時に発生します。 PDOStatement::execute()は文を返さず、成功を示すブール値を返します。したがって、あなたが望むショートカットは不可能です。

http://php.net/manual/en/pdostatement.execute.php

参照関数の定義は、さらに私は、多くの場合、それはforEach()は(常にではない)コードのにおいであり、それはPHP値としてすべての行を格納するために持っているように、比較的多くのメモリをとる追加してみましょう。

+0

ああ、私は 'foreach($ result as ...)をしないように' while($ row = $ stmt_test-> fetch(PDO :: FETCH_ASSOC)){...} 'に変更することをお勧めします) '私の上記のコードで? – Webeng

+0

PDOStatementはトラバーサルを実装しているので、 'foreach($ stmt_test as ...)'を実行することができます(これはどのモードが使用されているかわかりませんが、PDO :: FETCH_BOTHかもしれません)。現在の要素をメモリに入れて、それを1回だけ繰り返すか、それとも2回実行するのがどちらのアプローチですか? – johannes

+0

?xD私がそれを2回しているコードであるかどうか分かりません。hahahを知ることに本当に関心があります。 – Webeng

-1

これはおそらく最短の例です。

$fetchAll = function ($id) use (&$pdo) { 
    $stmt = $pdo->prepare("SELECT * FROM `status` WHERE `status_id` = ?"); 
    $stmt->execute([$id]); 
    return $stmt->fetchAll(PDO::FETCH_ASSOC); 
}; 
print_r($fetchAll($id)); 
+0

@Webengはい彼はそれが私がちょうど短縮バージョンを書いた理由です。 '$ stmt_test-> execute([$ id])はブール値を返します.'はエラーとこの質問の答えです。 –

+0

この例は、OPの条件と矛盾しています。なぜ誰かがそれをアップレボリューションするだろうかと不思議。 –

+0

正確にOPがこの回答を設定した条件は矛盾していますか? @YourCommonSense次回は、答えのクイッククラスを提示するかもしれません。 ORは、タイトルの '略語PDOクエリ'の主な条件ではありません。私はそれが本当にその部分だと思った。私は彼の主な目的が彼のコードを短縮することだと本当に思った。そして、この答えでは、OPの条件と矛盾する私の例ですか?私はあなたが面白いよ、あなたはコメディアンですか?落札してくれてありがとうございますが、私は返信しません。あなたの答えは正しいので、私はそれをしません。しかし、それは間違いなく、OPの「短期化」の期待外れです。 –