質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Heroku

HerokuはHeroku社が開発と運営を行っているPaaSの名称です。RubyやNode.js、Python、そしてJVMベース(Java、Scala、Clojureなど)の複数のプログラミング言語をサポートしている。

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

PDO

PDO(PHP Data Objects)はPHPのデータベース抽象化レイヤーです。

MacOS(OSX)

MacOSとは、Appleの開発していたGUI(グラフィカルユーザーインターフェース)を採用したオペレーションシステム(OS)です。Macintoshと共に、市場に出てGUIの普及に大きく貢献しました。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

2回答

373閲覧

PHPの$stmt->execute()ができない。

suika11

総合スコア166

Heroku

HerokuはHeroku社が開発と運営を行っているPaaSの名称です。RubyやNode.js、Python、そしてJVMベース(Java、Scala、Clojureなど)の複数のプログラミング言語をサポートしている。

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

PDO

PDO(PHP Data Objects)はPHPのデータベース抽象化レイヤーです。

MacOS(OSX)

MacOSとは、Appleの開発していたGUI(グラフィカルユーザーインターフェース)を採用したオペレーションシステム(OS)です。Macintoshと共に、市場に出てGUIの普及に大きく貢献しました。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

0クリップ

投稿2020/09/15 16:15

編集2020/09/15 17:59

前提・実現したいこと

下記のモデルに検索ワード($_GET['search'])を送ると検索結果を表示する処理を作りたいのですが、
$articles->execute()の部分でtrueにならず次の処理へ進めません。
ここをtrueにしたいです。

※$_GET['search']が''の状態だと記事を取得することができます。

発生している問題・エラーメッセージ

$articles->execute()がfalseになってしまう。

該当のソースコード

PHP

1 { 2 if (isset($_GET['search']) && !empty($_GET['search'])) { 3 $word = preg_replace('/(\s| )+/', ',', $_GET['search']); 4 if (strpos($word, ',') === 0) { 5 $word = substr($word, 1, strlen($word) - 1); 6 } 7 $searchWord = explode(',', $word); 8 $keywordCondition = []; 9 for ($i = 0; $i < count($searchWord); $i++) { 10 $keywordCondition[] = "title LIKE :title{$i}"; 11 } 12 $title = implode(' AND ', $keywordCondition); 13 } else { 14 $title = ''; 15 } 16 17 if ($_GET['category'] !== '') { 18 $category = 'category = :category '; 19 } else { 20 $category = ''; 21 } 22 23 $top = filter_input(INPUT_GET, 'top'); 24 switch ($top) { 25 case 'all': 26 $top = ''; 27 break; 28 case '0': 29 $top = "top = 0"; 30 break; 31 case '1': 32 case '2': 33 $top = '(top = :top OR top = 3)'; 34 break; 35 case '3': 36 $top = "top = 3"; 37 break; 38 } 39 if ($title === '' && $top === '' && $category === '') { 40 $where = ''; 41 } else { 42 $where = 'WHERE '; 43 } 44 $and1 = ''; 45 $and2 = ''; 46 $and3 = ''; 47 if ($title !== '' && $category !== '' && $top !== '') { 48 $and1 = ' AND '; 49 $and2 = ' AND '; 50 } else if ($title !== '' && $category !== '' && $top === '') { 51 $and1 = ' AND '; 52 } else if ($title === '' && $category !== '' && $top !== '') { 53 $and2 = ' AND '; 54 } else if ($title !== '' && $category === '' && $top !== '') { 55 $and3 = ' AND '; 56 } 57 58 $sql = "SELECT * FROM articles {$where} {$title} {$and1} {$and3} {$category} {$and2} {$top} ORDER BY created DESC"; 59 $articles = $this->db->prepare($sql); 60 $i = 0; 61 if (isset($searchWord)) { 62 foreach ($searchWord as $search) { 63 $articles->bindValue(":title{$i}", '"%' . $search . '%"'); 64 $i++; 65 } 66 } 67 if ($_GET['category'] !== '') { 68 $articles->bindValue(':category', $_GET['category']); 69 } 70 if ($_GET['top'] !== '') { 71 $articles->bindValue(':top', $_GET['top']); 72 } 73 74 if ($articles) { 75 if ($articles->execute()) { 76 while ($row = $articles->fetch()) { 77 $rows[] = $row; 78 } 79 if (!isset($rows)) { 80 $errors = '0件でした'; 81 return $errors; 82 } 83 } 84 $this->db = null; 85 return $rows; 86 } 87 } 88

試したこと

下記のbindValue部分で値がバインドされているか確認すると、trueとなった。
追記、trueではなく1が返ってきてました。

php

1if (isset($searchWord)) { 2 foreach ($searchWord as $search) { 3 $articles->bindValue(":title{$i}", '"%' . $search . '%"'); 4 $i++; 5 } 6 }

補足情報(FW/ツールのバージョンなど)

heroku/7.42.13
PHP 7.1.33
macOS Mojave 10.14.6

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

この状態で他人がデバッグするのはかなり難しいので、
まずは

を仕込んでSQLプリペアドコマンドを確認、

  • 各所の変数をvar_dump()するなりxdebugでブレークポイントを仕掛けて想定通りになっているか確認。

  • 怪しそうな変数を固定値に置き換えてテストしてみる

あたりでデバッグをしていって、その結果を整理して質問に追記されるとより適切な回答がえらるかと思います。(整理している間に解決することも多いです)


自分がデバッグするとしたら(例外は吐かせるようにしておくのは前提として)

PHP

1 2$sql = "SELECT * FROM articles {$where} {$title} {$and1} {$and3} {$category} {$and2} {$top} ORDER BY created DESC";

が想定通りになっているかを

PHP

1$sql = "SELECT * FROM articles {$where} {$title} {$and1} {$and3} {$category} {$and2} {$top} ORDER BY created DESC"; 2var_dump($sql); 3die();

等で想定通りになっているか確認するところからスタートすると思います。
これが想定通りなら、
その出力された文字列を使って簡単なテスト用スクリプトを書いて、想定が正しいかをチェックします。

投稿2020/09/15 19:55

編集2020/09/15 19:58
tanat

総合スコア18713

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

suika11

2020/09/15 20:02

ありがとうございます。アドバイスを参考に再度デバックを行ってみます。
tanat

2020/09/15 20:14

まずは PHPでデータベースに接続するときのまとめ の 接続後にオプションを指定 の $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); が最も重要なところです。 質問のソース中に書くなら$pdoの部分を$this->dbに差し替えればとりあえずは動くと思います。(出来ればDB接続している部分に追加する方が良いですが)
suika11

2020/09/15 22:57

ありがとうございます。オプションの設定も勉強になりました。 無事解決することができました。 SQLに検索ワードをバインドするときに、下記のようにダブルクォーテーションをバインドさせていたのですが、それを外したらうまく動作しました。 ×$articles->bindValue(":title{$i}", '"%' . $search . '%"'); ○$articles->bindValue(":title{$i}", '%' . $search . '%'); どこかでLIKE検索のさい値をバインドするときはダブルクォーテーションを含める、みたいな話を聞いたことがあったのですがそれが違ったようでした。 ありがとうございました。
guest

0

$sqlで名前付きプレースホルダの書き方が間違ってます。
あと$whereが常に設定されないため、SQLのSyntaxエラーが発生していると思われます。
PDOStatement::bindValue

投稿2020/09/15 19:47

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

suika11

2020/09/15 20:04

コメントありがとうございます。 名前付きプレースホルダを書き方は間違っているでしょうか? 検索ワードが複数あった場合に備えて、$keywordCondition[] = "title LIKE :title{$i}";としたのですが、 どう記述したらよいですか?
退会済みユーザー

退会済みユーザー

2020/09/15 20:24

LIKE '%' . :title{$i} . '%' かな?
suika11

2020/09/15 20:27

プレスホルダ作成の段階で%とつけたほうがいいということですか? bindValueのバインド時につけてしまいましたが。
退会済みユーザー

退会済みユーザー

2020/09/15 20:47

おお、見落としてました。 どちらが正解か検証してみてください。
suika11

2020/09/15 22:58

どうも調べたらバインドするときに%をつけるほうが良いとのことでした。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問