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

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

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

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

PHP

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

Q&A

解決済

2回答

247閲覧

MySQLのクエリ中にPHP変数を伴う場合の質問

salt26

総合スコア15

MySQL

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

PHP

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

0グッド

0クリップ

投稿2018/07/19 06:12

編集2018/07/19 06:34

MySQLとPHP変数について質問させてください。

PHP中に

PHP

1$staff_id = $_POST['staff_id']; 2$menu_id = $_POST['menu_id']; 3$y = $_POST['y']; 4$m = $_POST['m']; 5$d = $_POST['d']; 6$h = $_POST['h']; 7$i = $_POST['i']; 8 9 10$client_id = $mysqli->insert_id; 11// ↑ 別のSQL処理をし、idを取得しています。 12// idの取得は問題なくできております。 13 14$query_register_timetable = "INSERT INTO salt26_timetable(ymd,category,category_id,t" .$h . $i . ") VALUES('" .$y.$m.$d . "','booked','" . $staff_id . "','" . $client_id . "') ON DUPLICATE KEY UPDATE t" . $h.$i . "=" .$client_id;

とし、その後、$mysqli->query($query)が失敗している模様です。

上記のPHPコードは、具体的には、

PHP

1INSERT INTO salt26_timetable(ymd,category,category_id,t1300) VALUES('20180731','booked','40','0') ON DUPLICATE KEY UPDATE t1300=0

というような文字列となります。

この「具体的な文字列」を直接phpmyadminにて実行した場合には、正常動作します。

何がダメなのかをご教示いただける方、よろしくお願いいたします。

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

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

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

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

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

m.ts10806

2018/07/19 06:18

それぞれ変数には何が入ってくるのか設定部分も提示ください。SQLが失敗しているということはエラーが出ているはずです。エラーも確認してください。(接続をどのようにしているかというというところまでのコード提示がないので具体的な指示ができません)
m.ts10806

2018/07/19 06:31

あ、分かりました「table」としているからですね。予約語であるため、`table`など明示的にする必要があります。実際のテーブル名もしくはtestやsampleなどあたり触りない文字列に置き換えてください。
salt26

2018/07/19 06:35

ご回答、ありがとうございます。大変失礼いたしました。実際のコードに変更いたしました。シンタックスエラーを確認したところ、出ておりませんでした。
m.ts10806

2018/07/19 06:53

若干進んだようですが、これ以上はテーブル定義が提示されないと難しいように思います。どのような概要でデータベースが定義されているのか提示してください。
guest

回答2

0

まずいちばんだめなのはカラム名を指定するのに
外部からきたhやiを利用していること

外部からのデータは想定外のものが来る可能性が高く、
当然テーブルのカラム名に合致しないでしょう。
設計思想がまちがっているので、このテーブル構成では
セキュアに処理はできません。

その上でmysqliの処理についてもprepare処理があるので
bind_paramしながらプレースホルダーで対応してください

投稿2018/07/19 06:57

yambejp

総合スコア114829

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

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

salt26

2018/07/19 07:31

ご指摘いただき、ありがとうございます。 設計を根本的に見直すという事ですね。 リファラーを取得し、不正なアクセス元は処理をしない、という方法では甘いでしょうか?
yambejp

2018/07/19 07:47

おそらく想定ではhとiは0000から2359まであるでしょうから 1440カラム必要になります。テーブルの管理を考えるとまず ありえない構成です。 しかもhやiがをユーザーが任意に偽装しておくってくることも 考慮すれば処理が破綻するのは必至です リファラで制限してもさほど効果はないと思います
salt26

2018/07/20 01:44

ご返信いただき、ありがとうございます。 30分間隔のテーブルですので、全部で50カラム程度です。 50カラムという数も、現実的ではないでしょうか? また、prepare処理をすれば、SQLインジェクションは完全に防げるという認識で、よろしいでしょうか? 質問ばかりで申し訳ございません。
yambejp

2018/07/20 01:53

> 50カラムという数も、現実的ではないでしょうか? なるほど、あまり良いやりかたとは思えませんが、 ないこともないくらいの数ですね でもカラム名を外部からきたデータで渡すのは美しくないですね 普通にデータ保存用のテーブルを別途用意し 0000~2330までのデータを横方向(カラムとして)ではなく 縦方向のデータとして保持することが望まれます
salt26

2018/07/20 02:40

ご指摘、ありがとうございます。 現在、テーブル設計を検討しておりますが、縦方向はどうしても別用途で使いたいのです。 カラム名を外部データにて指定する方法の問題点は理解いたしました。 想定外のデータが来た場合には処理を止めるなどして、データベースの保護をしたいと考えております。
yambejp

2018/07/20 02:59

別に時間を別テーブルで持つ分には他の機能と競合はしませんよ 正規化を理解していないと思いますので基本を抑えたほうがよいでしょう
yambejp

2018/07/20 03:03

ちなみに・・・ どのカラムがprimaryもしくはuniqueキーで、 48ある時間カラムには何をいれるのでしょうか?
salt26

2018/07/20 05:11

あるお店のタイムテーブルを作成しています。 primaryはオートインクリメントをするIDです。 年月日情報を保有する「ymd」 部署情報を保有する「category」 担当者情報を保有する「category_id」 この3つを複合ユニークキーとしています。 そして「t0000」から「t2330」までのカラムは、 その時間に行われる業務のIDを保有する仕様です。 何も業務が無い場合にはNULLです。
guest

0

ベストアンサー

php

1$query = "INSERT INTO table(ymd,category,category_id,t" .$h . $i . ") VALUES('" .$y.$m.$d . "','booked','" . $staff_id . "','" . $client_id . "') ON DUPLICATE KEY UPDATE t" . $h.$i . "=" .$client_id; 2 3var_dump($query);

こうしたときに、本当に、

php

1INSERT INTO table(ymd,category,category_id,t1300) VALUES('20180731','booked','40','19') ON DUPLICATE KEY UPDATE t1300=19

と出力されているかどうか確認しましょう。

また、上記のように、変数を文字列で連結するクエリは「書いちゃダメ」な例ですけど。

投稿2018/07/19 06:19

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

salt26

2018/07/19 06:24

ご回答ありがとうございます。 出力は成されております。 書いちゃダメな例だということは、今回の件を調べる過程で気付いたのですが、動的にクエリを作成する他の方法が思い付かず、こうなってしまいました。
退会済みユーザー

退会済みユーザー

2018/07/19 06:29

とりあえず、それは後に回しましょう。 「出力はされている」と言う返事だけでは、(失礼かもですが)回答者は信用できません。 それができなくて困ってるんでしょ笑 だとしたらあなたの眼の前で起きていることを報告してもらわないと、解決のためのお手伝いはできません。 出力された、クエリ文字列をコピペで、追記してください。
m.ts10806

2018/07/19 06:32

動的にカラム名を指定しようとしているところもアウトだと思います。
退会済みユーザー

退会済みユーザー

2018/07/19 06:34 編集

それもまた後で指摘しようと思ってます。 カラム名が動的に変わるなんて、正規化されていない証拠ですからね。
m.ts10806

2018/07/19 06:34

そうですね。よろしくお願いします(私がよろしく言うのはおかしいけど・・)
salt26

2018/07/19 06:37

ありがとうございます。 出力された文字列は INSERT INTO salt26_timetable(ymd,category,category_id,t1300) VALUES('20180731','booked','40','0') ON DUPLICATE KEY UPDATE t1300=0 です。 よろしくお願いいたします。
退会済みユーザー

退会済みユーザー

2018/07/19 06:41

本当にそのクエリが出力されているんなら、コードに問題があるんじゃないですかね? query() の後どんな処理してる?
salt26

2018/07/19 06:51

ご回答、ご指摘ありがとうございます。 まさに仰る通り、まったく関係ない部分でのPHPシンタックスエラーでした。 query()の後は、 if($mysqli->query($query_register_timetable)) { ?> //ココの「?>」の書き忘れ <div class="alert alert-success" role="alert">登録しました</div> <?php } else { ?> <div class="alert alert-danger" role="alert">エラーが発生しました。</div> <?php } というものでした。。。 狙い通りの動きはするようになりました。 動的にカラム名が変わる部分は、どのように対処したらよろしいでしょうか? もしも、ご面倒でなければ、ご教示ください。 よろしくお願いいたします。
退会済みユーザー

退会済みユーザー

2018/07/19 06:58 編集

「動的にカラム名が変わる」こと自体がNGです。 「正規化」するべきこと。また、$_POSTでカラム名を指定するのは全くもってナンセンス。外部からくる変数をカラム名に指定できるのは、悪意を持ってシステムを破壊することができると言うことです。 システムの運用の中でカラムの定義が変わると言う設計から見直しが必要です。
salt26

2018/07/19 07:00

ご指摘、ありがとうございます。 設計の見直しですね、承知いたしました。 仕様を考え直します。 本当にありがとうございました。
退会済みユーザー

退会済みユーザー

2018/07/19 07:04

まず、今回のシンタックスエラーというのは、ちゃんとしたツールを使っていれば、無駄な時間を浪費することはなくなります。 Netbeans とか Eclipse とか PHPStorm とか文法チェックを自動で行ってくれるものがありますので、テキストエディタではなく、IDEと呼ばれるものをお使いください。
salt26

2018/07/19 07:11

ご指摘、ありがとうございます。 このシンタックスエラーで、本日朝から何も進んでおりません。。 仰る通り、IDEというものを取り入れることにいたします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問