• ベストアンサー

PHPでCSVを読み込みMySQLに行追加・変更

PHPでCSVファイルを読み込み、MySQLにデータを追加する方法を教えてください。 その際に、新規の行はIDを指定せず、auto_incrementでidを設定するようにして、IDを指定した場合は、既存の行を変更するようにしたいです。 また、prepareメソッドを用いたいです。 よろしくお願いします。

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

  • ベストアンサー
noname#244856
noname#244856
回答No.2

日本語におかしなところがあるので、以下のように解釈して回答します。違う点があれば補足してください。 ・CSVファイル中に全てIDは含まれている。 ・データベース中に存在しないIDの場合は新規作成する。 ・データベース中に存在したIDの場合は変更する。 ---------------------------- 「REPLACE INTO」を使えばSQL1文でいけます。 <?php // データベース情報 $dsn = 'mysql:dbname=mydb;host=localhost;charset=utf8'; $username = 'root'; $password = ''; // ファイル名 $filename = 'data.csv'; try { // ファイルを読み込んでCSVとして読み取るモードに設定 $file = new \SplFileObject($filename); $file->setFlags(\SplFileObject::SKIP_EMPTY | \SplFileObject::DROP_NEW_LINE | \SplFileObject::READ_CSV); // データベースに接続して例外スローモードに設定 $pdo = new \PDO($dsn, $username, $password); $pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION); // プリペアドステートメントを生成 $stmt = $pdo->prepare('REPLACE INTO table(a, b, c) VALUES(?, ?, ?)'); // 1行ずつ処理 foreach ($file as $row) $stmt->execute($row); } catch (\RuntimeException $e) { // エラー発生時はここにジャンプ echo 'Error: ' . $e->getMessage() . PHP_EOL; }

h_mp
質問者

お礼

ありがとうございます。 解釈された通りの内容でございます。 ファイルをアップロードしたものにする場合はどういった処理を行えばよろしいでしょうか。

その他の回答 (5)

noname#244856
noname#244856
回答No.6

MySQLの関数を使えばいいと思います。 http://www.w3schools.com/sql/func_now.asp データベースの種類に依存させたくないなら、PHPで現在日時を取得する方法もあります。好みで選んでください。 http://qiita.com/mpyw/items/e42fa173e5a26220a785

h_mp
質問者

お礼

ありがとうございます。 こちらも今後参考にさせていただきます。

noname#244856
noname#244856
回答No.5

ごめんなさい、変数名のwithとwithout入れ替えてください(転記ミス)

noname#244856
noname#244856
回答No.4

あ、やっぱりID欄が空欄になっているケースもあるんですね。質問文からは「存在しないIDを指定した場合」の挙動が読み取れなかったので、「本当はこういうことを言いたかったのかな?」とかなりエスパーっぽい解釈をするに至りました。(解釈と異なるなら補足が欲しかったです…) 強引にSQL1文でまとめようと思いましたが困難なようなので、素直にPHPで分岐させてSQL2文使います。 // ループ外でプリペアドステートメントを2つ作成しておく $stmt_with_id = $pdo->prepare('INSERT INTO (a, b) VALUES (?, ?)'); $stmt_without_id = $pdo->prepare('REPLACE INTO (id, a, b) VALUES (?, ?, ?)'); ... // $row[0]がIDのカラム if ($row[0] === '') { array_shift($row); $stmt_without_id->execute($row); } else { $stmt_with_id->execute($row); }

h_mp
質問者

お礼

ご丁寧に誠にありがとうございます。 また、解釈の違いについて気づかずに、補足できず申し訳ありませんでした。 こちらで、無事動きました。 それと、更新日時のカラムがあるのですが、できればそれに現在の日時を入れたいので、そちらの方法も教えていただけると幸いです。 よろしくお願いいたします。

noname#244856
noname#244856
回答No.3

↓のSQL文替えるだけで実現できそうです http://qiita.com/mpyw/items/caa2568284b69d270f8b

h_mp
質問者

お礼

ご回答ありがとうございます。 これでやってみたのですが、idが空の場合、「SQLSTATE[HY000]: General error: 1366 Incorrect integer value: '' for column 'id' at row 1」というエラーが出ます。 それと、更新日時のカラムがあるのですが、できればそれに現在の日時を設定したいので、そちらの方法も教えていただけると幸いです。 よろしくお願いいたします。

  • t_ohta
  • ベストアンサー率38% (5292/13827)
回答No.1

fgetcsv() を使えばCSVファイルから1行ずつ読み込んでデータを配列として受け取れます。 http://php.net/manual/ja/function.fgetcsv.php 後は配列のデータを見てIDがあればupdate、無ければinsertを発行するだけです。

h_mp
質問者

お礼

fgetcsv()を使えば、配列として受け取って処理ができるんですね。 大変勉強になります。 ありがとうございます。

関連するQ&A