• お世話になっており
    ます。 他の方も質問されていますが、私もproduc...
  • まるみまるみ 
    お世話になっております。
    他の方も質問されていますが、私もproductDetail.phpのファイルを読み込もうとすると、index.phpに飛んでしまいます。
    下記を試しましたが手詰まりのため、エラーを探すためのアドバイスいただきたくご連絡しました。

    【試したこと】
    ①差分ツールで誤字確認→問題なし
    ②header("Location:index.php");をコメントアウトし、飛ばないようにしてからphp_err.logでエラー探し
    Function.phpのgetProductOne関数のところ
    【Function.php】===============
    function getProductOne($p_id){
    ~割愛~
    $sql='SELECT p.id,p.name,p.comment,p.price, p.pic1,p.pic2,p.pic3,p.user_id,p.create_date, p.update_date,c.name AS category FROM product AS p LEFT JOIN category AS c ON p.category_id = c.id WHERE p.id = :p_id AND p.delete_flg = 0 AND c.delete_flg = 0';
    $data = array(':p_id' => $p_id);
    $stmt = queryPost($dbh,$sql,$data);
    debug('クエリ結果返却'.print_r($stmt,true));
    if($stmt){
    //クエリ結果のデータを1レコード返却
    return $stmt->fetch(PDO::FETCH_ASSOC);
    ~割愛~
    }
    =======================
    【php_err.log】================
    [08-Aug-2019 10:52:10 Asia/Tokyo] デバッグ:クエリ結果返却PDOStatement Object
    (
    [queryString] => SELECT p.id,p.name,p.comment,p.price, p.pic1,p.pic2,p.pic3,p.user_id,p.create_date, p.update_date,c.name AS category FROM product AS p LEFT JOIN category AS c ON p.category_id = c.id WHERE p.id = :p_id AND p.delete_flg = 0 AND c.delete_flg = 0
    )
    =======================
    になるので多分問題がないと思われますが、そのあと
    【php_err.log】================
    [08-Aug-2019 10:52:10 Asia/Tokyo] エラー発生:指定のページに不正な値が入りました。
    [08-Aug-2019 10:52:10 Asia/Tokyo] デバッグ:取得したDBデータ:
    =======================
    となるので、DBからデータが取得できていないのではと思っております。

    ③phpMyAdminのDBのテーブル名、カラム名もスペルミスないか確認→問題なし

    長文で申し訳ございません。お手数ですがご確認お願いいたします。


    まるみ
    回答 0

    まるみ 

    追記です。
    phpMyAdminに直接SQL文入力して試したところ
    WHERE以降(WHERE p.id = :p_id AND p.delete_flg = 0 AND c.delete_flg = 0)を削除するとエラーが出ないことがわかりました。

    ①p.id = :p_idのみ削除
    エラー「#1054 - 列 'p.delete_flg' は 'where clause(where句という意味でしょうか?)' にはありません。」と出ます。
    ② p.id = :p_id AND p.delete_flg = 0を削除
    エラー「#1054 - 列 'c.delete_flg' は 'where clause' にはありません。」
    ③WHEREのあとにp.id = :p_idのみ入力
    エラー「#1064 - SQL構文エラーです。バージョンに対応するマニュアルを参照して正しい構文を確認してください。 : ':p_id LIMIT 0, 25(0件読み飛ばして25件表示するという意味でしょうか?)' 付近 1 行目」

    エラーメッセージの数字の意味は
    #1054…指定したカラムが見つからない。SQL文が間違えている。
    #1064…SQLの文法に誤りがある。
    というところまでわかりました…。

    何度もご連絡してしまい申し訳ございませんがこの後どのあたりを重点的に確認すべきか、またはどのようにエラーを確認すべきが教えていただきたいです。
    よろしくお願いいたします。

    まるみ

     
    phpmyadminに直接SQLを入力したらエラーになったとのことですが、
    phpで書いているSQLは、そのままphpmyadminで使ってもMySQLが読み込んでくれないケースがあります。今はその状態になっていますね。

    今回であれば、phpの書き方であるプレースホルダ「:p_id」をそのまま使ってしまっているために動作しない状態になっています。
    phpmyadminでSQLを直打ちしてクエリ実行する場合は、phpで使っているSQLそのものではなく、SQL内のプレースホルダ「:p_id」部分に適切な値を入れた状態で実行しましょう。

    下記のSQLを参考に、いま:p_idを入れている部分を、テーブルに入っているデータに合わせて置き換えて実行してみましょう。(p.id = 1となっていますが、1以外の可能性もあるので、テーブルに入ったデータに合わせて数字をいれてあげてください)
    SELECT p.id,p.name,p.comment,p.price, p.pic1,p.pic2,p.pic3,p.user_id,p.create_date, p.update_date,c.name AS category
    FROM product AS p LEFT JOIN category AS c ON p.category_id = c.id WHERE p.id = 1 AND p.delete_flg = 0 AND c.delete_flg = 0

    また今回出ている#1064のエラーについてですが、
    phpMyAdminでSQLを実行する際、「〜WHERE p.id = :p_id〜」 のまま実行すると、DBは命令通りproductテーブルのidカラムから「:p_id(文字列)」に一致するデータを取ってこようとします。
    しかしそれでは「文字列はクォーテーションに囲む」というSQLの文法に違反しているので、③の#1064 - SQL構文エラーが発生しているのです。

    PHPからDBにクエリ実行する時は「$data = array(’:p_id’ => $p_id);」のところで、:p_id部分に、$p_idに入っている値をセットしています。
    例えば変数$p_idに「3」という値が入っていれば、クエリ実行時にはSQLの「:p_id」部分が3という値に置き換えられ、「〜WHERE p.id = 3〜」の状態になっていクエリが実行されます。
    すると数値はクォーテーションに囲む必要が無いので#1064 エラーも発生せず、結果を得られているのです。
    ※プレースホルダの参考:https://webukatu.com/wordpress/blog/1638

    こちらでもSQLを実行してみましたが上記のプレースホルダ部分以外にSQLのミスはなさそうです。
    ①・②の#1054エラーについては、テーブル側にdelete_flgカラムが存在しない可能性が高いです。
    例えばdelete_flagのように、カラム名が1文字でも異なるとこのエラーになってしまいます。product, category両テーブルにdelete_flgが「正しく」存在しているか再確認してみてください。

    これらの部分を訂正したら、もう一度phpMyAdminから直接クエリ実行してみましょう。きちんと結果を得られたのであれば、問題はDBではなく、productDetail.phpの側にあると判断できます。
    その場合は、「$data = array(’:p_id’ => $p_id)」でプレースホルダにセットされる「p_id」にきちんと値が入っているかなどを、var_dump()で変数の中身を出力してチェックしつつ原因部分を探し出していきましょう。

    まるみ 
    お世話になっております。大変詳細まで教えていただきありがとうございます。
    今確認したところ、DB内のスペルミスが原因でした…。
    初歩的なところで躓いておりました…。
    ありがとうございます。