csvファイルをMySQLにインポートしたい

このQ&Aのポイント
  • phpでcsvファイルをMySQLにインポートするプログラムを作成しています。
  • 以下のソースを実行したところエラーが発生しました。
  • フォルダ(files)にcsvファイルがアップロードされているところまでは確認できましたが、MySQLにインポートされていないようです。
回答を見る
  • ベストアンサー

csvファイルをMySQLにインポートしたい

phpでcsvファイルをフォルダにアップロードし、これをMySQLにインポートするプログラムを作成しています。 以下のソースを実行したところエラーが発生しました。 -----food.csv---------------------------------------------------------------------- "No","name","price" "1","うどん","100" "2","ぱすた","500" "3","カレー","300" ---------------------------------------------------------------------------------- -----BaseDAO.php------------------------------------------------------------------ <?php class BaseDAO{ function connect(){ try { $dsn = "mysql:host=localhost;dbname=food"; $option = array( // エラーモードを例外スローに設定 PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, // local ファイルからload可能にする PDO::MYSQL_ATTR_LOCAL_INFILE => true ); $user = 'username'; $password = 'password'; $pdo = new PDO($dsn, $user, $password, $option); $pdo->exec("SET NAMES utf8"); return $pdo; //var_dump($pdo); } catch (PDOException $ex) { print($ex->getMessage()); die("データベース接続に失敗しました"); } return null; } function disconnect($dao){ $dao = null; } } ?> ---------------------------------------------------------------------------------- ------uploadcsv.php----------------------------------------------------------------- <?php require_once 'BaseDAO.php'; //csvファイルのアップロード if (is_uploaded_file($_FILES["upfile"]["tmp_name"])) { //「files」という名前のフォルダを同じ階層に設置。ここにCSVファイルをアップロード if (move_uploaded_file($_FILES["upfile"]["tmp_name"], "files/" . $_FILES["upfile"]["name"])) { chmod("files/" . $_FILES["upfile"]["name"], 0644); //fileパス $file = "files/" .$_FILES["upfile"]["name"]; $sql_src = <<<SQL LOAD DATA LOCAL INFILE %s INTO TABLE `%s` CHARACTER SET sjis fields terminated by ',' enclosed by '"' lines terminated by '\\r\\n' IGNORE 1 LINES SQL; $table= 'food'; //テーブル名 $inport=new BaseDAO(); //インスタンス作成 $pdo=$inport->connect(); //pdoクラスに接続 $sql = sprintf($sql_src , $pdo->quote($file), $table); //sql文の実行 $stmt = $pdo->query($sql); echo "インポートが完了しました!"; //失敗したとき } else { echo "ファイルをアップロードできません。"; } } else { echo "ファイルが選択されていません。"; } ?> -----index.html--------------------------------------------------------------------- <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS"> <title>sample</title> </head> <body> <form action="uploadcsv.php" method="POST" enctype="multipart/form-data"> ファイル:<br> <input type="file" name="upfile" size="30"><br> <br> <input type="submit" value="アップロード"> </form> </body> </html> ---------------------------------------------------------------------------------- --------foodテーブルを作成するSQL文------------------------------------------------ CREATE TABLE IF NOT EXISTS `food` ( `No` int(11) NOT NULL, `name` varchar(50) NOT NULL, `price` varchar(50) NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8; ---------------------------------------------------------------------------------- 実行したところ以下のエラーが発生しました。 Warning: PDO::query() [pdo.query]: LOAD DATA LOCAL INFILE forbidden in C:\xampp\htdocs\food\uploadcsv.php on line 30 <当方のPC環境> phpMyAdmin:3.3.9 PHP: 5.3.5 Apache 2.2.17 MySQL 5.5.8 XAMPP version 1.7.4 フォルダ(files)にcsvファイルがアップロードされているところまでは確認できましたが、MySQLにインポートされていないようです。 BaseDAO.php内の「PDO::MYSQL_ATTR_LOCAL_INFILE => true」が効いていないように思えます。 初歩的な質問で凝縮ですが、原因を教えていただきたく存じます。

  • PHP
  • 回答数2
  • ありがとう数2

質問者が選んだベストアンサー

  • ベストアンサー
  • mpro-gram
  • ベストアンサー率74% (170/228)
回答No.2

xamppでload data local がエラーになるのは知ってましたが、日本語で検索してもでてきませんねぇ。 http://osdir.com/ml/ProfessionalPHPDevelopers/2011-03/msg00043.html なにやら linux でも同じ問題があるらしい。 →検索キーワード「PDO, mysqlnd bug load」で漸く、、、 https://bugs.php.net/bug.php?id=54158 mysqli では問題ないので pdo_mysql の問題のようです。 どうやら、pdo_mysql driver の再コンパイルが必要らしい。 でもって、php5.4でも配布版では直ってないらしいです。上記ページの最後に以下の記述が!。 >I still seem to have this problem on: PHP 5.4.17-1~precise+1 Ubuntu 12.04 windows での再コンパイルは、Cのコンパイラー持ってないと無理なので 対策1:load だけ、mysqli でやってしまう 対策2:windowsのlocalhost なら、php側ファイルであっても、絶対パスにすれば、mysql serverからも読み込み可能なので、local はずして、実行させる。 emulation mode (オプションの PDO::MYSQL_ATTR_DIRECT_QUERY =>true またはこのキー省略)で実行すればいけます。PDO::MYSQL_ATTR_DIRECT_QUERY =>false にすると、windowsのversionによってはまた違うエラーが出たりして、pdo_mysqlのload文への対応おかしいです。 <?php // ファイル名を絶対パスにする。$fileに相対パスが入ってるとする。 $file = dirname(__FILE__) .DIRECTORY_SEPARATOR. $file;

参考URL:
https://bugs.php.net/bug.php?id=54158
do79tama13
質問者

お礼

返信が大変遅くなってしまい申し訳ございません。 mysqli関数での接続と、絶対パスでのsql文実行の両方の方法でコードを修正して実行してみましたが、インポートされませんでした。sql文の中身を試しにechoで出力し、そのsql文をコピーしてmysqlから実行してみたところインポートできました。という事はsql文は正しいようです。そうなるとおっしゃる通りphp側のバグという事になります。 悩み続けましたがやむおえずPHPのバージョン5.4.19とMySQLのバージョン5.5.32にそれぞれバージョンアップ、質問に記載したコードをそのままコピペしただけで実行できました。どうやらバージョンによっては不具合が生じるようです。 ともかく解決しましたので非常に助かりました。ご返信の内容の中には当方のほかのコードの参考になる内容(PDO接続の際のオプション記載について)も含まれていましたのでさっそく修正させていただきました。 ありがとうございました(#^.^#)

その他の回答 (1)

  • yambejp
  • ベストアンサー率51% (3827/7415)
回答No.1

ちょっと疑問なのですが わざわざmove_uploaded_file()しないで、テンポラリフォルダの中から csvファイルを取り込んでみては?

do79tama13
質問者

お礼

返信が大変おそくなって申し訳ございません。 move_uploaded_file()しないで直接一時フォルダから取り出す方法も試作してみましたが、うまくsql文が実行されませんでした。 結局PHPのバージョンを上げたことで解決いたしました。 一緒に考えていただけて感謝しております。ありがとうございました(*^^*)

関連するQ&A

  • PHPでCSVファイルをUTF8に変換したい

    ブラウザからCSVファイルをアップロードし、MySQLのデータベースにインポートするプログラムをPHPで作成しています。 エクセルで作成したCSVファイルはsjis形式のため、UTF8に変換してからMySQLにインポートしてあげると文字化けせずにインポートする事が出来るのですが、毎回手動でUTF8に変換するのは面倒ですのでファイルをアップロードしたタイミングで自動的にsjis形式からUTF8に変換したいと考えております。 ファイルのアップロードまでは動作していますが、CSVファイルをsjisからUTF-8に変換するにはどうすればよいでしょうか? どなたかご教示いただければ幸いです。以下は作成中のコードです。 index.html <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS"> <title>sample</title> </head> <body> <form action="read.php" method="POST" enctype="multipart/form-data"> ファイル:<br> <input type="file" name="upfile" size="30"><br> <br> <input type="submit" value="アップロード"> </form> </body> </html> read.php <?php //csvファイルのアップロード if (is_uploaded_file($_FILES["upfile"]["tmp_name"])) {     //「files」という名前のフォルダを同じ階層に設置。ここにCSVファイルをアップロード if (move_uploaded_file($_FILES["upfile"]["tmp_name"], "files/" . $_FILES["upfile"]["name"])) { chmod("files/" . $_FILES["upfile"]["name"], 0644); //fileパス $file = "files/" .$_FILES["upfile"]["name"]; //DB接続 $sv = "localhost"; $dbname = "shop"; $user = "user"; $pass = "password"; $conn = mysql_connect($sv, $user, $pass) or die("コネクトエラー"); mysql_select_db($dbname) or die("DBセレクトエラー"); mysql_query("SET NAMES utf8"); //CSVデータの取り込み $sql = "LOAD DATA LOCAL INFILE '$file' INTO TABLE food"; $sql .= " FIELDS"; $sql .= " TERMINATED BY ',' "; //TERMINATED BY 区切り文字 $sql .= " ENCLOSED BY '\"' "; //ENCLOSED BY 囲み文字 $sql .= " LINES TERMINATED BY '\r\n' "; $sql .= " IGNORE 1 LINES"; $result = mysql_query($sql, $conn); if (!$result) { $message = 'Invalid query: ' . mysql_error() . "\n"; $message .= 'Whole query: ' . $sql; die($message); } echo "インポートが完了しました!"; //失敗したとき } else { echo "ファイルをアップロードできません。"; } } else { echo "ファイルが選択されていません。"; } ?> CSVファイル "No","food","price" "1","うどん","100" "2","カレー","300" "3","パスタ","500" MySQLテーブル CREATE TABLE IF NOT EXISTS `food` ( `No` int(11) NOT NULL, `food` varchar(50) NOT NULL, `price` int(11) NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 使用中のバージョン PHP/5.4.19 Apache/2.4.4 XAMPP v3.2.1 素人の質問で凝縮ですが、よろしくお願いいたします。

    • ベストアンサー
    • PHP
  • CSVファイルをMYSQLにインポート

    先日からMYSQL+PHPの勉強をはじめました。 データベース構築の際、以前作成したCSVファイルをMYSQLのテーブルとして 利用したいと考えております。 そこで、MYSQLコマンドより、 LOAD DATA LOCAL INFILE 'ファイル名.csv' INTO TABLE テーブル名 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\r\n'; Query OK, 0 rows affected (0.04 sec) Records: 102 Deleted: 0 Skipped: 102 Warnings: 0 とCSVファイル自体が悪いのかSQL文に問題がるのかインポートがうまくいきません。。 ちなみにCSVは  0,2011/6/2 0:00,80.94,81.32,80.55,80.92 0,2011/5/25 0:00,81.94,82.17,81.8,81.95 0,2011/5/23 0:00,81.77,82.04,81.32,81.99 環境はphpdevで一括でインストールした phpadmin: バージョン2.3.2 MYSQL: MySQL4 apache: 1.3.27 初心者で基本的な質問かもしれないですがどうかご教授お願いします。

    • ベストアンサー
    • MySQL
  • インターフェースからCSVを取り込んで、MySQLにインポート

    インターフェースからCSVを取り込んで、MySQLにインポート ブラウザのインターフェースからCSVファイルを選択して、MySQLにインポートするようにしたいのですが、 (1)ファイルのアップロード (2)サーバー上にある(アップロードされた)CSVファイルをMySQLにインポート という手順で処理するほかないでしょうか? ローカルのCSVファイルを直接MySQLにインポートするような画期的な方法(ライブラリなど)あったらいいなと思い質問します。 PHPのバージョン:5.2 MySQLのバージョン:5.1 です。 まだ基本設計の段階なので、具体的な質問になっておらず申し訳ありませんが、 よろしくお願いします。

    • 締切済み
    • PHP
  • PHPでのファイルアップロード。リネーム機能実装

    インターネット上でフリーで配布されていたPHPスクリプトです。 <?php if (is_uploaded_file($_FILES["upfile"]["tmp_name"])) { if (move_uploaded_file($_FILES["upfile"]["tmp_name"], "files/" . $_FILES["upfile"]["name"])) { chmod("files/" . $_FILES["upfile"]["name"], 0644); echo $_FILES["upfile"]["name"] . "をアップロードしました。"; } else { echo "ファイルをアップロードできません。"; } } else { echo "ファイルが選択されていません。"; } ?> --- files フォルダにファイルをアップロードするのですが このままアップロードすると、同じファイル名でアップした場合ファイルが上書きされてしまいます。 アップロードした時、[お腹すいた.zip] だった場合、[20120808-1958-お腹すいた.zip]のように 時間と日付を入れたいのですが、私の知識では調べて試してみたのですが、白紙になる限りで うまくいきません。 どなたかご教授頂けませんでしょうか。

    • ベストアンサー
    • PHP
  • ファイルアップロードを教えて下さい。

    お世話になります。 php初心者です。 初歩的な質問になると思いますが… ローカルでファイルのアップロードのスクリプトの練習をしてるのですが上手く行きません。 アップロードしたファイル名が全て同じになります。 ディレクトリ構成として htdocs  ├128.php  └phpbook(ディレクトリ)    └128-2.php ■128.phpの中身 <form action="./phpbook/128-2.php" enctype="MULTIPART/FORM-DATA" method="POST"> ファイル:<input type="FILE" name="upfile"> <input type="submit" value="アップロード"> </form> ■128-2.phpの中身 <?php if(move_uploaded_file($_FILES['upfile']['tmp_name'], "./htdocs/phpbook/") ==FALSE){ print "失敗しました。"; }else{ print ($_FILES['upfile']['name']); print "をアップロードしました。"; } ?> アップロードは出来てるのですが、phpbookディレクト内にphpbookという拡張子が何もついてないファイルがアップロードされてしまいます。 よろしくお願いします。

    • ベストアンサー
    • PHP
  • PHP ファイルupロードのセキュリティ

    ただいま ファイルUPロードするための簡単なPHPプログラムをせいさくしています 。 セキュリティの部分とか足らないところがるとは思うのですが、 下のプログラjムをどうやって改造すればいいのでしょうか? たとえば 容量を制限する。 ファイル種類を限定する等  おしえて頂きたいと思っています。 よろしくお願いたします。 <body> <p><?php if (is_uploaded_file($_FILES["upfile"]["tmp_name"])) { if (move_uploaded_file($_FILES["upfile"]["tmp_name"], "files/" . $_FILES["upfile"]["name"])) { chmod("files/" . $_FILES["upfile"]["name"], 0644); echo $_FILES["upfile"]["name"] . "をアップロードしました。"; } else { echo "ファイルをアップロードできません。"; } } else { echo "ファイルが選択されていません。"; } ?></p> </body> </html>

    • 締切済み
    • PHP
  • csvファイルを使ってMySQLのテーブルを更新し

    約2万件ある15個のカラムで構成されるMySQLのテーブルがあります。 このテーブルをcsvファイルを使って更新しようと考えています。 csvファイルにはレコードIDとあるカラムの変更する値の2つのセルで 構成されています。 行数は毎回異なりますが、だいたい300行前後です。 csvファイルの具体的イメージはこんな感じです。 id order ============ 2,  200 4,  10 7,  460 11,  35 MySQLのテーブルの方にも「id」と「order」というカラムが存在します。 java や PHP を使ってやる方法はわかるんですが、プログラムを作成しないで SQLだけで行いたいと考えています。 LOAD DATA LOCAL INFILE などがあることがわかったのですが、レコードを REPLACE  するのではなく、一部のカラムをアップデートしたい、ということです。 どなたか、教えて頂けると助かります。 よろしくお願い致します。

  • MySQLで連続csvファイルを読み込むために

    MySQL 5.6を最近使い始めました。 大量のcsvファイルで保存されているデータを読み込んで、データベースとして扱いたいのですが、どうすれば良いでしょうか? ファイル名は、 data1_1.csv data1_2.csv data1_3.csv data2_1.csv data2_2.csv といった形で、規則正しく並んでいるのですが、大量にあるため、ループを使って自動化したいと思っております。そのために、LOAD DATA INFILE ファイル名 を使って、このファイル名を順次変えて繰り返す方法がわかりません。 まず、ファイル名に変数が使えるのかと思って @file="data1_1.csv"としてファイル名を置き換えてみたのですが、エラーでした。これでは、この1_1を順次動かす以前に変数が無理なのかも?と思っています。 何かやり方があるようでしたら、どなたかお教えください。 どうぞよろしくお願いいたします。

    • ベストアンサー
    • MySQL
  • ファイルのアップロード処理を確認画面で確認後にアップロードするようにし

    ファイルのアップロード処理を確認画面で確認後にアップロードするようにしたいのですが、プログラムの書き方がわかりません。確認画面を通さずにやればアップロードできるのですが。どうすればいいのか教えてもらえるとうれしいです。 流れとしては「アップロード画面でファイルを指定」→「確認画面でアップロードボタンを押す」→「アップロード結果画面」です。作成中のソースは以下のようになっています。 ■upload.html(アップロード画面) <html><head><title>アップロード画面</title></head><body> <form action="kakunin.php" method="post" enctype="multipart/form-data"> ファイル:<br> <input type="file" name="upfile" size="30"><br> <input type="submit" value="確認画面へ"> </form></body></html> ■kakunin.php(確認画面)<未完成> <html><head><title>確認画面</title></head><body> <?php $upfile=$_POST['upfile']; print "選択したファイル: $upfile<br>\n"; ?> <br>この内容でよろしいですか?<br> よろしければ「アップロード」ボタンを押してください。<br> <form action="uploadkekka.php" method="post" enctype="multipart/form-data"> <input type="submit" value="アップロード"> </form></body></html> ■uploadkekka.php <html><head><title>アップロード結果</title></head><body> <p><?php if (is_uploaded_file($_FILES["upfile"]["tmp_name"])) { if (move_uploaded_file($_FILES["upfile"]["tmp_name"], "uploadfiles/" . $_FILES["upfile"]["name"])) { chmod("uploadfiles/" . $_FILES["upfile"]["name"], 0644); echo $_FILES["upfile"]["name"] . "をアップロードしました。"; } else { echo "ファイルをアップロードできませんでした。"; } } else { echo "ファイルが選択されていません。"; } ?> </p></body></html>

    • ベストアンサー
    • PHP
  • PHPでMysqlにCSVをインポートす文字化け

    お世話になります。 文字化けが解消できずに困っています。 PHPからローカルXAMPPのMYSQLにCSVでデータを上げたいのですが、日本語が文字化けして表示されます。秀丸テキストエディタで可能な限りのエンコードを試しましたが解決できず、サーバ側のエンコード設定も確認しましたがutf8_unicode_ciです。 Mysqlの管理画面のsqlから実行しても同様の結果です。 もう、色々やり過ぎてPHPが悪いのかMysqlサーバの設定なのかCSVの問題なのかわからず途方に暮れています。 諸先輩方でお分かりになられる方がいらっしゃいましたら是非、お知恵を貸してもらえませんか。 PHPのソースです。 ------------------------------ $host = "localhost"; $mysql_user = "root"; $mysql_password = "password"; $db = "utsun_db"; $cn = mysql_connect($host,$mysql_user,$mysql_password); if(!$cn){ die("db connect Error"); } if(!(mysql_select_db("$db"))){ die("db select error"); } $file = '"c:/tablea.csv"'; $sql = "LOAD DATA LOCAL INFILE $file INTO TABLE tablea FIELDS TERMINATED BY ',';"; $query = mysql_query($sql); mysql_close($cn); ----------------------------- CSVの中身 N551 佐々木 37 N552 伊藤 41 N553 斉藤 31 N554 井上 43 N555 阿倍 31 ----------------------------- Mysqlの方ではこのように表示されています N552 伊藤 41 N553 斉藤 31 N554 井上 43 N555 阿倍 31 ほんとうに困っております宜しくお願いします。 環境 Apache/2.4.3 (Win32) OpenSSL/1.0.1c PHP/5.4.7 phpMyAdmin バージョン情報: 3.5.2.2, 最終安定バージョン: 4.0.4.1

    • ベストアンサー
    • MySQL

専門家に質問してみよう