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

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

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

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

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

2回答

1505閲覧

PHPでSQLを実行するときに、SQLに変数を使いたい

marusankakun

総合スコア16

MySQL

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

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 03:58

編集2022/01/12 10:55

###実現したいこと
以下my_update_yasai()という関数で、$updatesの値を保存したいです。

###発生している問題
保存が実行されません。

$sqlの変数が原因ではないか?と、
これから書くような根拠から推察していますが、
その解決策がわからない状況です。
宜しくお願い致します。

###該当のソースコード
まず以下$updatesが保存する情報でして、
これをループしてmy_update_yasai()を実行していく流れです。

php

1 2// 保存を実行 3$updates = [ 4 ['yasai_name'=>'野菜A','yasai_count'=>64,'yasai_data'=>'野菜Aはとても甘い'], 5 ['yasai_name'=>'野菜B','yasai_count'=>45,'yasai_data'=>'野菜Bはとても辛い'], 6 ['yasai_name'=>'野菜C','yasai_count'=>78,'yasai_data'=>'野菜Cはとても苦い'], 7]; 8foreach( $updates as $update ) { 9 my_update_yasai( 'insert', $update ); 10}

保存の関数がこちらですが、実現できない状況です。

php

1// 保存の関数 2function my_update_yasai( $type, $update, $targets=null ) { 3 4 global $wpdb; 5 6 // 更新する情報 7 $table = $wpdb->yasai_table; 8 $yasai_time = $update['yasai_time'] ?? 0000; 9 $yasai_name = $update['yasai_name'] ?? 'nothing'; 10 $yasai_count= $update['yasai_count'] ?? 0000; 11 $yasai_data = $update['yasai_data'] ?? 'nothing'; 12 13 // 更新する値 14 $data = []; 15 if ( isset($yasai_time) ) { 16 $data['yasai_time'] = $yasai_time; 17 } 18 if ( isset($yasai_name) ) { 19 $data['yasai_name'] = $yasai_name; 20 } 21 if ( isset($yasai_count) ) { 22 $data['yasai_count'] = $yasai_count; 23 } 24 if ( isset($yasai_data) ) { 25 $data['yasai_data'] = $yasai_data; 26 } 27 28 // $data の値の書式 29 $format = []; 30 if ( isset($yasai_time) ) { 31 $format[] = '%d'; 32 } 33 if ( isset($yasai_name) ) { 34 $format[] = '%s'; 35 } 36 if ( isset($yasai_count) ) { 37 $format[] = '%d'; 38 } 39 if ( isset($yasai_data) ) { 40 $format[] = '%s'; 41 } 42 43 if ( $type == 'insert' ) { 44 45 // $updateで指定した情報を保存する処理 46 $data_keys = rtrim(implode(",",array_keys($data))); 47 $data_vals = rtrim(implode(",",$data)); 48 $formats = rtrim(implode(",",$format)); 49 $sql = $wpdb->prepare("INSERT INTO $wpdb->yasai_table ( $data_keys ) values ( $formats )", $data_vals); 50 var_dump($sql); // 【 ← 追記その1 】 51 $wpdb->query($sql); 52 53 }elseif ( $type == 'update' ) { 54 55 // $targetsで指定した行に対して、$updateで指定した情報を上書きする処理 56 57 } 58} 59

###試したこと
my_update_yasai()で、以下$sql部分の変数が
正しく展開できていないのではないかと考えています。

php

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

そこで$data_keys,$formats,$data_valsの各変数を
var_dumpしたところ以下の結果を得ました。

php

1string(44) "yasai_time,yasai_name,yasai_count,yasai_data" 2string(11) "%d,%s,%d,%s" 3string(49) "1,野菜テスト,111,野菜テストのデータ"

上の値をvar_dumpするコードは次の通りで、
これは該当のソースコードのループをやめたものとなっています。

php

1<?php 2$yasai_time = 1; 3$yasai_name = '野菜テスト'; 4$yasai_count = 111; 5$yasai_data = '野菜テストのデータ'; 6 7// 更新する値 8$data = []; 9if ( isset($yasai_time) ) { 10 $data['yasai_time'] = $yasai_time; 11} 12if ( isset($yasai_name) ) { 13 $data['yasai_name'] = $yasai_name; 14} 15if ( isset($yasai_count) ) { 16 $data['yasai_count'] = $yasai_count; 17} 18if ( isset($yasai_data) ) { 19 $data['yasai_data'] = $yasai_data; 20} 21 22// $data の値の書式 23$format = []; 24if ( isset($yasai_time) ) { 25 $format[] = '%d'; 26} 27if ( isset($yasai_name) ) { 28 $format[] = '%s'; 29} 30if ( isset($yasai_count) ) { 31 $format[] = '%d'; 32} 33if ( isset($yasai_data) ) { 34 $format[] = '%s'; 35} 36 37$data_keys = rtrim(implode(",",array_keys($data))); 38$formats = rtrim(implode(",",$format)); 39$data_vals = rtrim(implode(",",$data)); 40var_dump( $data_keys ); 41var_dump( $formats ); 42var_dump( $data_vals );

さて上のvar_dumpを確認できたのでその値を使い、
my_update_yasai()の変数をやめたバージョンとして次の
my_update_yasai_test()のように直接入れた関数を作ってみますと、
保存が実現できました。

php

1// 新規保存テスト 2function my_update_yasai_test( $yasai_name, $yasai_count, $yasai_data ) { 3 global $wpdb; 4 $sql = $wpdb->prepare("INSERT INTO $wpdb->yasai_table (yasai_name, yasai_count, yasai_data) values (%s, %d, %s)", $yasai_name, $yasai_count, $yasai_data); 5 var_dump($sql); // 【 ← 追記その2 】 6 $wpdb->query($sql); 7} 8my_update_yasai_test( '野菜Z', 77, '野菜Zはかなりレア' );

以上のことから推察するに、
該当のソースコードの$sqlの変数が原因ではないか?と考えています。

しかし、my_update_yasai()でできず、その変数部分を直接書いたmy_update_yasai_test()でできて、かといってmy_update_yasai()の変数をvar_dumpするとmy_update_yasai_test()に直接書いた値と同じですから、これ以上なにをすればいいのかと行き詰ってしまいました。

アドバイス頂けましたら幸いです。
宜しくお願い致します。

###追記
上のそれぞれの関数で
var_dump($sql); // 【 ← 追記その1 】
var_dump($sql); // 【 ← 追記その2 】
というvar_dumpを追記しました。

その結果は以下です。

↓うまくいってる場合のmy_update_yasai_test()var_dump($sql)
string(126) "INSERT INTO wp_yasai_table (yasai_name, yasai_count, yasa_data) values ('野菜テスト', 111, '野菜テストのデータ')"

↓ダメな場合のmy_update_yasai()var_dump($sql)
string(0) ""
string(0) ""
string(0) ""

後者でなぜ空になるのか…かなり戸惑っています。

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

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

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

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

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

tabuu

2020/01/23 08:20

パラメータではなく「$sql」という変数(文字列)は上手くいっている場合とダメな場合とそれぞれどうなっていますか?
marusankakun

2020/01/23 08:34

たしかに、var_dumpするなら「$sql」の方でしたね。ところで、ダメな場合の結果がかなり意味不明なことになりました。以下の通りです。なぜ空に…。 ↓うまくいってる場合の「my_update_yasai_test()」でvar_dump($sql) string(126) "INSERT INTO wp_yasai_table (yasai_name, yasai_count, yasa_data) values ('野菜テスト', 111, '野菜テストのデータ')" ↓ダメな場合の「my_update_yasai()」でvar_dump($sql) string(0) "" string(0) "" string(0) ""
tabuu

2020/01/23 23:12

上手くいっているときは「yasai_time」がありませんが、追加したらどうなるでしょうか?
guest

回答2

0

これではダメなのでしょうか?

PHP

1$insert="INSERT INTO $wpdb->yasai_table ( $data_keys ) values ( $formats )"; 2$sql = call_user_func_array([$wpdb,"prepare"],array_merge($insert,explode(",",$data_vals)));

※調整

投稿2020/01/23 06:22

編集2020/01/23 06:43
yambejp

総合スコア114583

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

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

yambejp

2020/01/23 06:34 編集

修正しました
marusankakun

2020/01/23 07:56

ありがとうございます。ご修正いただいたそちらですが call_user_func_array() expects parameter 2 to be array, null given in というエラーでした。よく見ますとarray_mergeの引数$insertがテキストであるためarray_mergeできず、よって上のエラーが出ているのではないかと。array_mergeはarray_marge(配列,配列)のように、引数には配列しか使えないみたいですね。 なのでarray_margeでなくテキストが追加できるarray_pushにしようと思ったのですが、でも、array_pushはarray_push(配列,文字列)という順で与えなければなりませんから、今回使えないですよね。これは一体どうすれば… もしよい書き方ございましたらお知恵を拝借できませんでしょうか。
guest

0

string(49) "1,野菜テスト,111,野菜テストのデータ"

上記は、以下の様に、文字列としてシングルクオート(')で括ったものにならないとエラーになるはずです。

string(49) "1,'野菜テスト',111,'野菜テストのデータ'"

投稿2020/01/23 04:43

sazi

総合スコア25138

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

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

marusankakun

2020/01/23 05:06

どう解決するのがベストでしょうか? 頂いたご指摘についての自分なりの解決策を考えますと以下の変更かと思ったのですが、スマートじゃないというかなんというか…、微妙ですよね? そもそも以下は空が返ってしまって解決できなかったので、よかったら具体的な方針を伺えればと。 $data_vals = rtrim(implode(",",$data)); ↓ 以下に変更 $data_vals = my_implode($data); function my_implode( $arr ){ $unit = ''; foreach ( $arr as $v ) { $type = gettype( $v ); if ( $type == 'string' ) { $unit .= '"' . $v . '"'; // シングルクオートで括っているつもり } elseif ( $type == 'integer' ) { $unit .= $v; } $unit .= ','; } return rtrim(",",$unit); // 空が返ってしまう? }
sazi

2020/01/23 06:15

空が返ってくるというより、エラーで実行されていないのでしょう。 例外を拾うようにした方が良いかと思います。 PHPは詳しくないので、識者の回答をお待ち下さい。
marusankakun

2020/01/23 07:57

なるほど。情報ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問