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

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

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

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

PDO

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

WordPress

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

PHP

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

Q&A

解決済

2回答

2436閲覧

phpからmysqlへInsertできません。

Tcandy

総合スコア12

MySQL

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

PDO

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

WordPress

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

PHP

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

0グッド

0クリップ

投稿2018/08/08 13:43

編集2018/08/10 05:27

Wordpressを使って取引所のAPIから仮想通貨の取引情報を表示するシステムをつくっています。
システムの流れは以下です。
1 : CoinexchangeのAPIを使用して、マーケット情報を取得
2 : mysql(phpmyadmin)にInsert
3 : index.phpにて読み込み

2番目のプログラムが書かれているファイルは、レンタルサーバーのcronを使って10分おきに更新し、データベースに保存するようにしています。

今回の問題は、「マーケット情報がmysqlにInsertされない」ということです。

状況はこんな感じです。
・cronはちゃんと作動している
・データベースには接続されている
・auto_incrementは設定済み
・エラーは表示されない

データベースにつなげるコード

php

1public function getPDO() { 2 try { 3 $pdo = new PDO ( 'mysql:host='.DB_HOST.';dbname='.DB_NAME.';charset=utf8', DB_USER, DB_PASSWORD ); 4 $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 5 6 return $pdo; 7 8 } catch (PDOException $e) { 9 echo 'データベースへの接続に失敗しました。:'. $e->getMessage(); 10 exit; 11 } 12 }

Insertするコード

php

1public function insertMarket($pdo, $data, $date) { 2 3 try { 4 $sql = ''; 5 $sql .= 'INSERT INTO '; 6 $sql .= 'markets '; 7 $sql .= '(board_history_id, symbole, pair, last_price, change_rate, high_price, low_price, bid_price, ask_price, volume, btc_volume, trade_count, buy_order_count, sell_order_count, insert_date, insert_datetime) '; 8 $sql .= 'VALUES '; 9 $sql .= '(NULL, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) '; 10 11 $stmt = $pdo->prepare($sql); 12 13 foreach ( $data as $key => $value ) { 14 $stmt->bindValue($key+1, $value, PDO::PARAM_STR); 15 } 16 $stmt->execute(); 17 18 } catch (Exception $e) { 19 echo $e->getMessage(); // 詳細なエラーを表示する 20 exit; 21 } 22 23 }

2日程度戦いましたが、原因がいまいちわからず積んでいます。
どなたかお助けいただけると幸いです!

よろしくお願いいたします。

追記
WHEREが使われているコード

PHP

1 /* 最新のマーケットサマリー情報取得*/ 2 public function getLatestMarket($pdo, $coins) { 3 4 try { 5 6 $sql = ''; 7 $sql .= 'SELECT '; 8 $sql .= '* '; 9 $sql .= 'FROM '; 10 $sql .= 'markets '; 11 $sql .= 'WHERE '; 12 $sql .= 'insert_datetime = '; 13 14 $sql .= '( '; 15 $sql .= 'SELECT '; 16 $sql .= 'insert_datetime '; 17 $sql .= 'FROM '; 18 $sql .= 'markets '; 19 $sql .= 'GROUP BY '; 20 $sql .= 'insert_datetime '; 21 $sql .= 'ORDER BY '; 22 $sql .= 'insert_datetime DESC '; 23 $sql .= 'LIMIT 1 '; 24 $sql .= ') '; 25 26 if ( $coins ) { 27 $sql .= 'AND pair IN ('.$coins.') '; 28 } 29 30 $sql .= 'ORDER BY '; 31 $sql .= 'symbole, '; 32 $sql .= 'pair, '; 33 $sql .= 'insert_datetime DESC '; 34 35 $stmt = $pdo->prepare($sql); 36 37 $stmt->execute(); 38 39 return $stmt->fetchAll(); 40 41 } catch ( Exception $e ) { 42 43 echo $e->getMessage(); 44 exit; 45 46 } 47 48 } 49 50 /* 指定期間のマーケットサマリー情報取得*/ 51 public function getBetweenMarket($pdo, $startDatetime, $endDatetime) { 52 53 try { 54 55 $sql = ''; 56 $sql .= 'SELECT '; 57 $sql .= '* '; 58 $sql .= 'FROM '; 59 $sql .= 'markets '; 60 $sql .= 'WHERE '; 61 $sql .= 'insert_datetime = '; 62 $sql .= '('; 63 $sql .= 'SELECT '; 64 $sql .= 'insert_datetime '; 65 $sql .= 'FROM '; 66 $sql .= 'markets '; 67 $sql .= 'WHERE '; 68 $sql .= 'insert_datetime BETWEEN ? AND ? '; 69 $sql .= 'GROUP BY '; 70 $sql .= 'insert_datetime '; 71 $sql .= 'ORDER BY '; 72 $sql .= 'insert_datetime DESC '; 73 $sql .= 'LIMIT 1 '; 74 $sql .= ') '; 75 $sql .= 'ORDER BY '; 76 $sql .= 'symbole, '; 77 $sql .= 'pair '; 78 79 $stmt = $pdo->prepare($sql); 80 $stmt->bindValue(1, $startDatetime, PDO::PARAM_STR); 81 $stmt->bindValue(2, $endDatetime, PDO::PARAM_STR); 82 83 $stmt->execute(); 84 85 return $stmt->fetchAll(); 86 87 } catch ( Exception $e ) { 88 89 echo $e->getMessage(); 90 exit; 91 92 } 93 94 } 95}

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

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

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

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

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

m.ts10806

2018/08/08 21:00

insertMarket() , getPDO() がどこからどう実行されるのかわからないのでそこも含めて全体がわかるコードを提示いただけますか?
退会済みユーザー

退会済みユーザー

2018/08/09 01:57

phpmyadminってDB管理するだけのよそのプログラムで、この件には全くかかわらないと思うのだけど。(訳:質問文やタグにつけるなよ。)
namda

2018/08/09 07:52

回答みてソース修正した場合、質問文のソースも修正してください。より回答が付きやすくなります。
退会済みユーザー

退会済みユーザー

2018/08/10 04:48

m6u 何でこの手のやからは PHP+MySQLのときに「phpmyadmin」をつけたがるんだろうね
m.ts10806

2018/08/10 05:31

横からすみませんが、XAMPPだとMySQL直接覗くことないですからね。
guest

回答2

0

echo 'データベースへの接続に失敗しました。';

こんな書き方ではなく、

echo $e->getMessage();

と書けば、なぜエラーなのかを特定できる(はず)。

php

1public function insertMarket($pdo, $data, $date) { 2 3 try { 4 $sql = ''; 5 $sql .= 'INSERT INTO '; 6 $sql .= 'markets '; 7 $sql .= '(board_history_id, symbole, pair, last_price, change_rate, high_price, low_price, bid_price, ask_price, volume, btc_volume, trade_count, buy_order_count, sell_order_count, insert_date, insert_datetime) '; 8 $sql .= 'VALUES '; 9 $sql .= '(NULL, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) '; 10 11 $stmt = $pdo->prepare($sql); 12 13 foreach ( $data as $key => $value ) { 14 $stmt->bindValue($key+1, $value, PDO::PARAM_STR); 15 } 16 $stmt->execute(); 17 18 } catch (Exception $e) { 19// echo 'データベースへの接続に失敗しました。'; 20 echo $e->getMessage(); // 詳細なエラーを表示する 21 exit; 22 } 23 24 }

cronを使って10分おきに更新

そもそもCronからPHP実行されていない可能性もある

投稿2018/08/08 13:46

編集2018/08/08 13:49
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

Tcandy

2018/08/08 13:53

ありがとうございます! しかし、エラーが表示されていないんです。 エラーが表示されていないということは、そもそもこのファイルが読み込めていないということなのでしょうか?
退会済みユーザー

退会済みユーザー

2018/08/08 13:55 編集

cron の設定が間違っていて、実行されていない可能性もあるけど、そうではないと原因の切り分けができているから、この質問内容なんでしょ?
Tcandy

2018/08/08 14:07

cronが作動しているかどうかは、file_put_contentsで他のファイルへの書き込みを確認できたので、動作していると判断しました。
退会済みユーザー

退会済みユーザー

2018/08/08 14:13 編集

そもそも、コマンドラインでPHPは正常に動作しているのですか? > file_put_contentsで他のファイルへの書き込みを確認 これは、insert しているファイルと同一のものですか?
Tcandy

2018/08/08 15:45 編集

Virtualbox&Vagrantで作った仮想環境上ではPHPは使えますが、ちょっと確かめてみます! >これは、insert しているファイルと同一のものですか? いえ、別に新しくtxtファイルをつくりました
退会済みユーザー

退会済みユーザー

2018/08/08 17:56

> いえ、別に新しくtxtファイルをつくりました file_put_contents を実行しているファイルは、insert しているファイルと同一のものですか?という意味ですよ。
Tcandy

2018/08/09 04:09

あ、すみません。 同じファイルに記入しています!
退会済みユーザー

退会済みユーザー

2018/08/09 04:14

insertMarket() 関数が呼ばれているかを確認しましょう public function insertMarket($pdo, $data, $date) { error_log('insertMarket', 3, 'log.txt'); try { ... こんな風にすれば、呼ばれているかどうかわかりますよね?
Tcandy

2018/08/09 06:28

ありがとうございます! 初心者なので、あまり詳しくなく... 色々調べながら試してみたところ、 $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); により、また新しく下記のエラーが表示されました。 SQLSTATE[42S22]: Column not found: 1054 Unknown column 'Array' in 'where clause' こちらに関しては、「Array」がカラムで見つからないということなのでしょうか?
退会済みユーザー

退会済みユーザー

2018/08/09 06:43

エラー自体は、`Array` ってカラムがありませんよというエラーです。 in 'where clause' ってあるので、INSERTでエラーになっているんじゃなくて、WHERE句のある、SELECTかUPDATE、DELETE文でエラーになっていると推測します。 どこか、配列をSQLにブチ込んでいる部分がありませんか?
Tcandy

2018/08/09 07:53

WHEREが使われているコードは追記いたしました。 function getLatestMarket($pdo, $coins) のところで、$coinsが配列なので、それが定義されているファイルを確認したところ、「s」が抜けていて「$coin」となっていたので直したのですが、解決されませんでした。 他に原因があるみたいです...
退会済みユーザー

退会済みユーザー

2018/08/09 08:51

$sql .= 'AND pair IN ('.$coins.') '; ここでエラーになっておることはご理解してます? 文字列 + 配列 + 文字列 これはダメだよねって話。
Tcandy

2018/08/09 15:44

理解していませんでした。。。 ('.$coins.') ' ここの部分でしょうか?
退会済みユーザー

退会済みユーザー

2018/08/09 16:21

そうですよ。
Tcandy

2018/08/09 17:05

ありがとうございます! $sql .= 'AND pair IN ("'.implode('","',$coins).'") '; implobeを用い文字列化してみたのですが、下記のエラーが発生してしまいます。 Warning: implode(): Invalid arguments passed 何か他の対策がありましたら、教えていただきたいです。
退会済みユーザー

退会済みユーザー

2018/08/09 17:10

あおそらくこうだろうという、50%程度の解決方法なら示せるけど、あなたから与えられた情報が少なすぎます。$coins に具体的にどんな値が入っているのか私には依然として不明です。まずはここを明示してください。 あと、あなたはこのSQLで最終的にどのような文字列を組み立てたいのかというゴールも示していません。 まずは、ここを提示してください。
Tcandy

2018/08/10 03:53

情報量不足の質問で申し訳ありません。 $coins = array('BTC', 'DOGE', 'ETH', 'ETC', 'LTC'); coinsには最大上記の値が入っていて、このコードでは「$coinsがpairに含まれているかどうか」を確認したいと思っています。
退会済みユーザー

退会済みユーザー

2018/08/10 03:55

「SQLで最終的にどのような文字列を組み立てたいのかというゴール」こちらも
退会済みユーザー

退会済みユーザー

2018/08/10 05:53 編集

「このコードでは「$coinsがpairに含まれているかどうか」を確認したいと思っています。」あなたはお客さんじゃなく、エンジニアとして、私が聞きたい、確認したいのは、あなたがここのWHERE句でどのようなSQL文を組み立てれば良いのかをわかっているかどうかです。 $sql .= 'AND pair IN (...........) '; ここでどんなSQLが作られることを期待しているのかということです。
Tcandy

2018/08/12 13:05

$sql .= 'AND pair IN ('BTC', 'DOGE', 'ETH', 'ETC', 'LTC') '; 上記のようなコードを作りたいと考えています
退会済みユーザー

退会済みユーザー

2018/08/12 13:12

変数を直接埋め込むのはNGです。SQLインジェクション脆弱性があるためです。ここは $sql .= 'AND pair IN (?, ?, ?, ?) '; のような文字列を生成しなければなりません。 array_fill() を使うことで、生成できます。 array_fill(0, count($coins), '?') こうすると、$coins の要素数に応じて ? を生成できます。 具体的な値 'BTC' などは、鉾のところで行なっているように $stmt->bindValue($index, $value, PDO::PARAM_STR); を使います。
Tcandy

2018/08/12 13:57

ありがとうございます。 ーーーーーーーーーーーーーーーーー $array = array_fill(0, count($coins), '?'); $sql .= 'AND pair IN ('.$array.') '; $stmt = $pdo->prepare($sql); $stmt->bindValue(1, $coins, PDO::PARAM_STR); $stmt->execute(); ーーーーーーーーーーーーーーーーーー 中々うまくいかないのですが、どこか間違えている箇所はありますでしょうか?
退会済みユーザー

退会済みユーザー

2018/08/12 14:06

$sql .= 'AND pair IN ('.$array.') '; var_dump($sql); $stmt = $pdo->prepare($sql); で出力されるSQLを確認してください。
Tcandy

2018/08/12 14:47

'SELECT * FROM markets WHERE insert_datetime = ( SELECT insert_datetime FROM markets GROUP BY insert_datetime ORDER BY insert_datetime DESC LIMIT 1 ) AND pair IN (Array) ORDER BY symbole, pair, insert_datetime DESC 「Array」と表示されていますね
退会済みユーザー

退会済みユーザー

2018/08/12 14:52 編集

何も変わってませんね。本当にこの部分でエラーになっているんですか? ああ、間違ってた。 $sql .= 'AND pair IN (' . implode(', ', $array . ') '; でしたね
Tcandy

2018/08/12 15:03

implodeを使用すると、sqlの値はしっかり入っていることが確認できました。 'SELECT * FROM markets WHERE insert_datetime = ( SELECT insert_datetime FROM markets GROUP BY insert_datetime ORDER BY insert_datetime DESC LIMIT 1 ) AND pair IN ("?","?","?","?","?") ORDER BY symbole, pair, insert_datetime DESC しかし、下記のエラーが出てきてしまいます。。。 「Warning: implode(): Invalid arguments passed in」
退会済みユーザー

退会済みユーザー

2018/08/12 15:30 編集

生成するSQLおかしいですよ。ダブルクォーテーション不要です。 var_dump($coins); の結果はどうなりますか?
Tcandy

2018/08/14 08:30

var_dump($coins); 0 => string 'BTC' (length=3) 1 => string 'DOGE' (length=4) 2 => string 'ETH' (length=3) 3 => string 'ETC' (length=3) 4 => string 'LTC' (length=3) というふうに出ました!
退会済みユーザー

退会済みユーザー

2018/08/14 08:33

一部じゃなくて全部書いてください。 0 => string 'BTC' (length=3) の前にも出力されているでしょうし、4 => string 'LTC' (length=3)の後ろにもvar_dump() で出力されているもう1行があるはずです。
Tcandy

2018/08/14 08:38

array (size=5) 0 => string 'BTC' (length=3) 1 => string 'DOGE' (length=4) 2 => string 'ETH' (length=3) 3 => string 'ETC' (length=3) 4 => string 'LTC' (length=3) ブラウザ上で確認できるのは、これだけでした
退会済みユーザー

退会済みユーザー

2018/08/14 08:47

OKです。 array (size=5) が重要。これは $coins という変数が、array = 配列であり、要素を5つ持っているという重要な情報です。 さきほど、SQLの出力で AND pair IN ("?","?","?","?","?") の部分は AND pair IN (?, ?, ?, ?, ?) のように出力されなければならないということは理解していますよね?ダブルクォーテーションは入ってはいけないということです。 $tmp = array_fill(0, count($coins), '?'); var_dump($tmp); // ? を5個、要素に持つ配列であることが確認できればOK $tmp = array_fill(0, count($coins), '?'); $tmp2 = implode(',', $tmp); var_dump($tmp2); // ここで ? が5個、「, 」でつながった String になっていればOKというように1行づつ書いては実行、というように繰り返してソースコードを組み立てるのがプログラミングです。 なん行も一度に書いて確認という横着をすると、問題点を見失います。
Tcandy

2018/08/14 09:19

ありがとうございます! 'SELECT * FROM markets WHERE insert_datetime = ( SELECT insert_datetime FROM markets GROUP BY insert_datetime ORDER BY insert_datetime DESC LIMIT 1 ) AND pair IN (?,?,?,?,?) ORDER BY symbole, pair, insert_datetime DESC ' 上のようにダブルクォーテーションなしで表記されました。 しかし、2つエラーが発生しています。 1 : $stmt->bindValue(1, $coins, PDO::PARAM_STR); のところで「 Notice: Array to string conversion in 」 2 : 「Invalid parameter number: number of bound variables does not match number of tokens」のエラーが発生してしまいました。
退会済みユーザー

退会済みユーザー

2018/08/14 09:23

エラーの意味を読み取ろうという意思はございますか? 毎回思うのですが、エラーが出るたび、条件反射のように聞いて来るように感じるのですが・
Tcandy

2018/08/16 07:56

読み取る意思がないわけではありません。 少し頼りすぎてしまった部分がありました、すみません。 下記のようにforeachを使って数をあわせることはできたので、エラーは回避できたのですが、まだINSERTが成功できませんでした。 foreach ( (array)$coins as $key => $value ) { $stmt->bindValue($key+1, $value, PDO::PARAM_STR); } 他に何か対処法はありますでしょうか。 また行き詰まってしまったので、返信致しましたが、、、
退会済みユーザー

退会済みユーザー

2018/08/16 08:03 編集

提示された情報では何もわかりません。エラーメセージなどがあればお手伝いできますが。 まず、今はSELECTが失敗しているという当初の質問とは無関係のところに問題があってそれを解消した段階。エラーが出なくなったと言っても、そこで正しい値が検索されて、取り出せているのか、など確認すべきことは他にもあるはず。 この段階でINSERTが堂の河野をいう段階ではない。 地道に一つ一つ確認してください。
guest

0

自己解決

なんとか解決しました。
アドバイスいただきありがとうござました。

<問題の原因>
Insertしたい要素の数があっていなかったため。
Insertしたい要素の数に対して、Apiにて引っ張ってきた情報の数が違かった。こちらを同じにしたら、無事Insertされました。

投稿2018/08/20 16:46

Tcandy

総合スコア12

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問