※ ChatGPTを利用し、要約された質問です(原文:csvファイルをMySQLにインポートしたい)
csvファイルをMySQLにインポートしたい
このQ&Aのポイント
phpでcsvファイルをMySQLにインポートするプログラムを作成しています。
以下のソースを実行したところエラーが発生しました。
フォルダ(files)に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」が効いていないように思えます。
初歩的な質問で凝縮ですが、原因を教えていただきたく存じます。
お礼
返信が大変遅くなってしまい申し訳ございません。 mysqli関数での接続と、絶対パスでのsql文実行の両方の方法でコードを修正して実行してみましたが、インポートされませんでした。sql文の中身を試しにechoで出力し、そのsql文をコピーしてmysqlから実行してみたところインポートできました。という事はsql文は正しいようです。そうなるとおっしゃる通りphp側のバグという事になります。 悩み続けましたがやむおえずPHPのバージョン5.4.19とMySQLのバージョン5.5.32にそれぞれバージョンアップ、質問に記載したコードをそのままコピペしただけで実行できました。どうやらバージョンによっては不具合が生じるようです。 ともかく解決しましたので非常に助かりました。ご返信の内容の中には当方のほかのコードの参考になる内容(PDO接続の際のオプション記載について)も含まれていましたのでさっそく修正させていただきました。 ありがとうございました(#^.^#)