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

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

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

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

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

PHP

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

Q&A

解決済

1回答

1935閲覧

PHP SQL UPDATEでエラーが出ています。

heypo

総合スコア3

PDO

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

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

PHP

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

0グッド

0クリップ

投稿2020/06/30 13:54

前提・実現したいこと

DBに登録済みのデータをUPDATEしたいのですが、エラーが出ています。
実現したいこと : if文で分岐して、foreachで回して、sql文を作成して、バインドができるようになりたいです。

初心者です。
要領を得ない質問かもしれませんが、よろしくお願いします。

PHPで会員登録ができるシステムを作っています。
会員登録変更機能を実装中に以下のエラーメッセージが発生しました。

変更予定箇所のDBデータ型は全て varchar
owner_email のみ unique 設定

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

エラーメッセージ PDOException: SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'WHERE owner_id = ?' at line 1 in /Applications/MAMP/htdocs/hoge_hoge/owner/owner_edit_info_done.php:270 Stack trace: #0 /Applications/MAMP/htdocs/hoge_hoge/owner/owner_edit_info_done.php(270): PDO->prepare('UPDATE owner_in...') #1 {main}SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'WHERE owner_id = ?' at line 1 **** owner_edit_info_done.php:375 $prepare->execute(); **** ### 該当のソースコード PHP 7.4.1 //sql文作成のためのターゲット 変更内容がPOSTされているときだけ配列に格納する if (isset($post['owner_name_rubi'])) { $target[] = 'owner_name_rubi'; } if (isset($post['owner_name'])) { $target[] = 'owner_name'; } if (isset($post['zip1'])) { $target[] = 'zip1'; } if (isset($post['zip2'])) { $target[] = 'zip2'; } if (isset($post['pref'])) { $target[] = 'pref'; } if (isset($post['address1'])) { $target[] = 'address1'; } if (isset($post['address2'])) { $target[] = 'address2'; } if (isset($post['owner_phone_home'])) { $target[] = 'owner_phone_home'; } if (isset($post['owner_phone_mobile'])) { $target[] = 'owner_phone_mobile'; } if (isset($post['owner_fax'])) { $target[] = 'owner_fax'; } if (isset($post['owner_email'])) { $target[] = 'owner_email'; }  //foreachでsql文を作成 $s = []; foreach ($target as $key => $values) { $s[] = $target[$key] . " = :" . $target[$key]; } $s = implode(",", $s); $sql = "UPDATE owner_info SET " . $s . " WHERE owner_id = :owner_id"; //名前付きプレースホルダー $prepare = $dbh->prepare($sql); // sql文のバインド処理。変更入力されたもののみ postデータを変数に代入済み if (isset($post['owner_name_rubi'])) { $prepare->bindValue(':owner_name_rubi', (string) $owner_name_rubi, PDO::PARAM_STR); } if (isset($post['owner_name'])) { $prepare->bindValue(':owner_name', (string) $owner_name, PDO::PARAM_STR); } if (isset($post['zip1'])) { $prepare->bindValue(':zip1', (string) $zip1, PDO::PARAM_STR); } if (isset($post['zip2'])) { $prepare->bindValue(':zip2', (string) $zip2, PDO::PARAM_STR); } if (isset($post['pref'])) { $prepare->bindValue(':pref', (string) $pref, PDO::PARAM_STR); } if (isset($post['address1'])) { $prepare->bindValue(':address1', (string) $address1, PDO::PARAM_STR); } if (isset($post['address2'])) { $prepare->bindValue(':address2', (string) $address2, PDO::PARAM_STR); } if (isset($post['owner_phone_home'])) { $prepare->bindValue(':owner_phone_home', (string) $owner_phone_home, PDO::PARAM_STR); } if (isset($post['owner_phone_mobile'])) { $prepare->bindValue(':owner_phone_mobile', (string) $owner_phone_mobile, PDO::PARAM_STR); } if (isset($post['owner_fax'])) { $prepare->bindValue(':owner_fax', (string) $owner_fax, PDO::PARAM_STR); } if (isset($post['owner_email'])) { $prepare->bindValue(':owner_email', (string) $owner_email, PDO::PARAM_STR); }  // WHERE 変更箇所を指定する owner_id をバインド sessionデータを変数に代入済み $prepare->bindValue(':owner_id', (string) $owner_id, PDO::PARAM_STR); // sql文実行 $prepare->execute(); ソースコード

試したこと

パスワードは単体で変更するようにしたのですが、そちらはこの流れで変更ができました。(バインド箇所はIDとパスワードの2カ所、IDは非公表でログイン時にsessionに渡したデータから取得)
今は前ページからPOSTがある箇所をifで分岐する仕様にしていますが、全ての項目をバインドしていた時もエラーが出ていました。
仕様上、nullの項目も必要なので、ifでの分岐を考えました。
HTMLのformからは、現在登録情報をinputのvalueに入れて渡しています。

$count = 0;
$columns = '';
$values = '';

foreach (array_keys($params) as $key) {
if ($count++ > 0) {
$columns .= ',';
$values .= ',';
}
$columns .= $key;
$values .= ':' . $key;
}

$sql = 'update owner_info (' . $columns . ')values(' . $values .
') WHERE owner_email = :owner_email'; //名前付きプレースホルダー

このような形のsql文の作成も試しましたが、上手くいきませんでした。

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

PHP 7.4.1
Apache/2.2.34
mysqlnd 7.4.1

ここにより詳細な情報を記載してください。

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

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

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

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

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

javahack

2020/06/30 17:16

$sqlの内容を出力して自分が考えているSQLになっているか確認してはいかがでしょうか。
guest

回答1

0

ベストアンサー

全体的に$postをつかってますが、$_POSTではないかと

$_POST

(issetでチェックしてるから変数存在に関してエラーも出ない)


記載されているエラーになるのは多分

php

1 // ソース略 2 // $postでやってるためisset全てに当てはまらず$targetには何も入ってない 3 4 //foreachでsql文を作成 5 $s = []; 6 foreach ($target as $key => $values) { 7 $s[] = $target[$key] . " = :" . $target[$key]; 8 } 9 10 // $target何も入ってないので$sはから配列 11 12 $s = implode(",", $s); 13 14 // $sは空文字が入る 15 16 $sql = "UPDATE owner_info SET " . $s . " WHERE owner_id = :owner_id"; //名前付きプレースホルダー 17 // $sが空文字なのでSQL文法エラーになる(UPDATE owner_info SET WHERE owner_id = :owner_idってなるため) 18 19 $prepare = $dbh->prepare($sql);

投稿2020/06/30 14:27

編集2020/06/30 14:30
rururu3

総合スコア5545

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

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

heypo

2020/06/30 23:16

早速のお返事、ありがとうございました。 解決いたしました。 初歩的なミスを見逃してました。 すごく助かりました。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問