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

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

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

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

Q&A

解決済

2回答

3332閲覧

phpのエラーについて

aine

総合スコア12

PHP

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

0グッド

0クリップ

投稿2015/10/08 06:11

phpからmysqlへのinsertでエラーが出て困っております。
LOAD DATA LOCAL INFILEをしたいのですが、

Fatal error: Call to a member function query() on null in /var/www/html/php/IN_DATA_test2.php on line 16

のエラーが解決できません。
$stmt = $dbh->prepare($sql);時点で、dbhの持つ値に問題があるということなのでしょうか。

現在、フォームからの値の入力はできているためドライバ関連のエラーはなく、
sql文単体では問題なく動作していることを確認済みです。

どなたか、お知恵を貸していただけないでしょうか。

<?php try{ $dbh = new PDO('mysql:dbname=GPS;host=tk2-218-18679.vs.sakura.ne.jp', 'root', array(PDO::MYSQL_ATTR_LOCAL_INFILE => true)); print('<br>'); if ($dbh == null){ print('接続に失敗しました。<br>'); }else{ print('接続に成功しました。<br>'); } $dbh->query('SET NAMES utf8'); $sql = 'LOAD DATA LOCAL INFILE "/GPS_log.csv" INTO TABLE test FIELDS TERMINATED BY "," LINES TERMINATED BY "\n";'; $stmt = $dbh->prepare($sql); $stmt->execute(); }catch (PDOException $e){ print('Error:'.$e->getMessage()); die(); } $dbh = null; ?>

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2015/10/08 06:30 編集

「on line 16」の16行目にあるセンテンスは何でしょうか?
aine

2015/10/08 06:41

下記が16行目です。 $sql = 'LOAD DATA LOCAL INFILE "/GPS_log.csv" INTO TABLE test FIELDS TERMINATED BY "," LINES TERMINATED BY "\n";';
guest

回答2

0

ベストアンサー

エラーそのものは、16行目のPDO::queryメソッドで発生しています。

php

1$dbh->query('SET NAMES utf8');

しかし、問題の本質はこの部分では無いようです。

まず、PDOの使い方が誤っています。
例示されたコードで、PDOの初期化を行っている箇所を見やすく改行すると、以下のようになります。
(以降のコードでは安全のため、ホスト名をexample.comに置き換えています)

php

1$dbh = new PDO( 2 'mysql:dbname=GPS;host=example.com', 3 'root', 4 array(PDO::MYSQL_ATTR_LOCAL_INFILE => true) 5);

第一引数にDSN(mysql:dbname=GPS;host=example.com)、第二引数にusername(root)を指定しているところまでは問題ありませんが、第三引数にはpasswordの文字列を指定します。
しかしこのコードでは、第四引数に指定するはずのoptionsを第三引数に指定してしまっています。

PHP: PDO::__construct - Manual

簡単にいえば、パスワードの指定忘れです。これがこのコードがエラーとなる直接の原因です。

また別の問題として、エラー処理が不適切という点も挙げられるでしょう。
10~14行目で、PDOの初期化に失敗した場合にエラーメッセージが表示されるようになっていますが、「接続に失敗しました。」と表示した後も処理を続けています。

php

1if ($dbh == null){ 2 print('接続に失敗しました。<br>'); 3}else{ 4 print('接続に成功しました。<br>'); 5}

正しく実装するならば、「接続に失敗しました。」と表示した時点で例外を投げるなりして処理を終了するべきでしょう。

私ならば以下のように書きます。

php

1<?php 2 3try{ 4 /** 5 * PDOのコンストラクタに指定する引数を正しく指定。 6 * また文字セットのutf8は、DSNで指定する。 7 * (文字セットをDSNで指定するやり方は、PHP5.3.5以前ではできません) 8 */ 9 $dbh = new PDO( 10 'mysql:dbname=GPS;host=example.com;charset=utf8', 11 'root', 12 'password', 13 array( 14 // 発生したエラーが例外としてスローされるよう指定 15 PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, 16 PDO::MYSQL_ATTR_LOCAL_INFILE => true, 17 ) 18 ); 19 20 /** 21 * PDOへの接続に失敗した場合、エラーを例外としてスロー(投げる) 22 */ 23 if (!$dbh) { 24 throw new RuntimeException('接続に失敗しました。'); 25 } 26 27 echo '接続に成功しました。'; 28 29 $sql = 'LOAD DATA LOCAL INFILE "/GPS_log.csv" INTO TABLE test FIELDS TERMINATED BY "," LINES TERMINATED BY "\n";'; 30 // ユーザ入力を伴わず、また結果を必要としていないため、PDO::execメソッドを使用 31 $dbh->exec($sql); 32} catch (PDOException $e) { 33 /** 34 * PDOで発生した例外の処理 35 */ 36 echo 'PDO Error: ' . $e->getMessage(); 37} catch (Exception $e) { 38 /** 39 * PDO以外で発生した例外の処理 40 */ 41 echo 'Error: ' . $e->getMessage(); 42}

参考:

投稿2015/10/08 07:03

編集2015/10/08 07:15
sounisi5011

総合スコア697

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

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

sounisi5011

2015/10/08 07:12

解答そのものからはズレますが、ホスト名を直接記載するのは危険です。 ホスト名だけでも、質問のコードがどこのサーバのMySQLに接続しようとしているのかおおよその検討がついてしまいます。 私の解答のように、ホスト名を別のものに置き換えたほうが良いでしょう… (example.comは例示用に確保されているものなので、安全です)
aine

2015/10/08 07:18

ありがとうございます。無事insertでき、解決しました。
aine

2015/10/08 07:18

ホスト名についてもありがとうございます。書き換えます。
guest

0

pdoが接続に失敗しています。
そのため、$dbhがnullとなり、nullに対してquery()というメンバ関数を呼ぼうとしています。

投稿2015/10/08 06:37

orange0190

総合スコア1698

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

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

aine

2015/10/08 06:47

確認した所、おっしゃるとおり、接続失敗のエラーがありました。 下記コードでは接続成功でしたが・・・arrayをつけたことで、書き方を変えたのがいけなかったでしょうか。 $dsn = 'mysql:dbname=men;host=tk2-218-18679.vs.sakura.ne.jp'; $user = 'root'; $password = ''; try{ $dbh = new PDO($dsn, $user, $password); 可能であれば、正しい書き方を教えていただけませんか。
orange0190

2015/10/08 07:06

sounisi5011さんの回答を参考にしてください。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.49%

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

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

質問する

関連した質問