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

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

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

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

phpMyAdmin

phpMyAdminはオープンソースで、PHPで書かれたウェブベースのMySQL管理ツールのことです。

SQL

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

WordPress

WordPressは、PHPで開発されているオープンソースのブログソフトウェアです。データベース管理システムにはMySQLを用いています。フリーのブログソフトウェアの中では最も人気が高く、PHPとHTMLを使って簡単にテンプレートをカスタマイズすることができます。

PHP

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

Q&A

解決済

1回答

813閲覧

WordPressのプリペアドステートメントで不定数の値を扱う方法

marusankakun

総合スコア16

MySQL

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

phpMyAdmin

phpMyAdminはオープンソースで、PHPで書かれたウェブベースのMySQL管理ツールのことです。

SQL

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

WordPress

WordPressは、PHPで開発されているオープンソースのブログソフトウェアです。データベース管理システムにはMySQLを用いています。フリーのブログソフトウェアの中では最も人気が高く、PHPとHTMLを使って簡単にテンプレートをカスタマイズすることができます。

PHP

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

0グッド

0クリップ

投稿2020/01/23 23:17

編集2020/01/23 23:23

###知りたいこと
SQL文の発行にあたって以下プリペアドステートメントを用いますが、この際に各値が不定数であるときの方法を知りたいです。

PHP

1$sql = $wpdb->prepare(‘query’,$vaule1,$vaule2)

つまり下記該当のソースコートの$dataのような不定数な配列から、正常な$sqlを作りたいということになります。

###該当のソースコード
不定数の値とは下記$dataでして、これがなんであろうと正常な$sqlを作りたいのですが、以下でvar_dump($sql)string(0) ""となる事態に遭遇しました。

php

1<?php 2global $wpdb; 3 4// 不定数の値 5$data = ['data_int'=>1,'data_str'=>'a']; 6 7// $sqlに用いる値 8$format = my_get_format($data); // var_dump($format); => string(5) "%d,%s" 9$data_keys = rtrim(implode(",",array_keys($data))); 10$data_vals = rtrim(implode(",",$data)); 11 12// SQL文発行 13$sql = $wpdb->prepare("INSERT INTO wp_yasai_table ( $data_keys ) values ( $formats )", $data_vals ); 14var_dump($sql); // => string(0) "" 15 16// $dataから、$sqlに渡すデータ型を取得 17function my_get_format( $arr ){ 18 $format = []; 19 foreach ( $arr as $v ) { 20 $type = gettype( $v ); 21 if ( $type == 'string' ) { 22 $format[] = '%s'; 23 } elseif ( $type == 'integer' ) { 24 $format[] = '%d'; 25 } 26 } 27 return rtrim(implode(",",$format)); 28} 29

###試したこと
まず上のコードの確認ですが、var_dump($sql)string(0) ""となります。

PHP

1$sql = $wpdb->prepare("INSERT INTO wp_yasai_table ( $data_keys ) values ( $formats )", $data_vals ); 2var_dump($sql); // => string(0) ""

そしてprepare()の第二引数$data_valsを、$data[0]$data[1]のように与えるとこうなりました。最後のvaluesがおかしいです。

php

1$sql = $wpdb->prepare("INSERT INTO wp_yasai_table ( $data_keys ) values ( $formats )", $data[0], $data[1] ); 2var_dump($sql); // => string(64) "INSERT INTO wp_yasai_table ( data_int,data_str ) values ( 0,'' )"

さらに$data_valsを、変数$val1$val2のように与えるとこうなりまして、無事正常な$sqlとなりました。

php

1$val1 = 1; 2$val2 = 'a'; 3$sql = $wpdb->prepare("INSERT INTO wp_yasai_table ( $data_keys ) values ( $formats )", $val1, $val2 ); 4var_dump($sql); // => string(65) "INSERT INTO wp_yasai_table ( data_int,data_str ) values ( 1,'a' )"

###わかったこと
以上のことから、WordPressのprepare()の第二引数は、変数を与えれば問題ないが、配列を与えると機能しないということがわかりました。

なので変数を与えれば済む話ですが、今回知りたいことは、$dataのような不定数な配列から$sqlを作ることにあります。変数がいくつになるか不定なので、$val1, $val2のように変数を与えることができないのです。

どうすればprepare()の第二引数に、不定数の値を与えることができるか…、宜しくお願い致します。

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2020/01/23 23:23

メソッドは利用してるが「プリペアードステートメント」じゃないきがする
guest

回答1

0

ベストアンサー

prepareの第二引数には値をまとめた配列を渡せるんやで

php

1$sql = $wpdb->prepare("INSERT INTO wp_yasai_table ( $data_keys ) values ( $formats )", $data_vals ); 23$sql = $wpdb->prepare("INSERT INTO wp_yasai_table ( $data_keys ) values ( $formats )", $data );

投稿2020/01/24 10:18

KazuhiroHatano

総合スコア7802

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

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

marusankakun

2020/01/24 13:15

お兄さんまじですごいですね。こんな書き方ドキュメントのどこにもないのによくご存じで。どうもありがとうございます。いつも助かります。 ところでこの書き方ができるのでしたら、$data_keysっていらないですよね。$dataのキーが$data_keysなのですし。 つまり $sql = $wpdb->prepare("INSERT INTO wp_yasai_table ( $data_keys ) values ( $formats )", $data ); でなく $sql = $wpdb->prepare("INSERT INTO wp_yasai_table values ( $formats )", $data ); だけでできてくれよ、と思いませんか?
KazuhiroHatano

2020/01/24 13:29

keysは要ります prepareは第二引数が配列で 第三引数以降がなければ 第二引数の中の値を使う様になってるだけです キー値は無視されます 連想配列で簡単に処理したいなら それこそ$wpdb->insertメソッド使えば良いのです そのためのメソッドですから
marusankakun

2020/01/24 13:38

>keysは要ります なるほど。ありがとうございます。
marusankakun

2020/01/24 13:39

>連想配列で簡単に処理したいなら でも$wpdb->insertですとユーザーから受け取った値を使うときに不安ですよね? つまり下記$dataが受け取った値である場合、SQLインジェクションされてしまう可能性があるということらしいので、だから、受け取った値を使うときにはprepareが必須だ、と理解しているのですが…。 $data = ['data_int'=>1,'data_str'=>'a']; // ユーザーから受け取った値を使う $format = [ '%s', '%d' ]; $wpdb->insert( $table, $data, $format ); // ここでSQLインジェクションされてしまう可能性がある
KazuhiroHatano

2020/01/24 13:45

$wpdb->insertは内部的にprepareをしていて おおよそSQL文の生成も質問のコードと同様のことをしてます
marusankakun

2020/01/24 13:55

え”っ… $wpdb->insertや$wpdb->updateではダメで、安全にやるためにはprepareが必須なのだと思い込んでおりましたので、ここ2、3日大変な苦労をしていたのですが…笑 それでも今知ることができたおかげで今後の時間が大きく短縮できます。本当にありがとうございました。
marusankakun

2020/01/27 00:25

こんにちは。リファレンスを見ていて疑問に思ったのですが、 $wpdb->insert $wpdb->update $wpdb->replace など「保存、更新、置換」は、引数に『値を型』を渡せば、サニタイズもprepareも勝手にやってくれますよね。 しかし $wpdb->get_results $wpdb->get_col $wpdb->get_row など「取得」に関するものたちは、引数が『$query』となっており、自分でサニタイズもprepareもしなければならないわけですよね。 「取得」も『値と型』で安全にできてくれたっていいだろう、と思うのですけど…
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問