[MySQL8.0.22]改行テキストをCSV・PDOでinsertしたい

mysql> select version();
+———–+
| version() |
+———–+
| 8.0.22 |
+———–+
1 row in set (0.00 sec)

まず適当にテーブルを作ります。

create table news(
	id int auto_increment PRIMARY KEY, 
	name varchar(20),
	body text
);

mysql> describe news;
+-------+-------------+------+-----+---------+----------------+
| Field | Type        | Null | Key | Default | Extra          |
+-------+-------------+------+-----+---------+----------------+
| id    | int         | NO   | PRI | NULL    | auto_increment |
| name  | varchar(20) | YES  |     | NULL    |                |
| body  | text        | YES  |     | NULL    |                |
+-------+-------------+------+-----+---------+----------------+
3 rows in set (0.01 sec)

insert intoでは\nで改行になる。

INSERT INTO news(name, body) VALUE ('NHK', '公務員に冬のボーナス 国家公務員平均約65万円 3年連続の減少');

INSERT INTO news(name, body) VALUE ('NHK', '公務員に冬のボーナス\n国家公務員平均約65万円 3年連続の減少');

### pdo
pdoで入れる際は、\r\nをつける。

$sql = 'INSERT INTO news (name, body) VALUE (:name, :body)';
$prepare = $pdo->prepare($sql);

$text = "公務員に冬のボーナス\r\n国家公務員平均約65万円 3年連続の減少";

$prepare->bindValue(':name', 'NHK', PDO::PARAM_STR);
$prepare->bindValue(':body', $text, PDO::PARAM_STR);
$prepare->execute();

echo "insert done";

### csv
L insertする前に、str_replace(‘\r\n’,”\r\n”,$csv);でエスケープする必要がある

$fp = fopen("test.csv", "r");

while(! feof($fp)){
	$csv = fgets($fp);
	$csv = trim($csv,'"');
	$csv = mb_convert_encoding($csv, "UTF-8", "utf-8");
	$csv = str_replace('"','',$csv);
	$csv = str_replace('\r\n',"\r\n",$csv);
	$csv_array = explode(",",$csv);
	

	$stmt = $pdo->prepare("INSERT INTO news (name, body) VALUE (:name, :body)");

	$stmt->bindValue(":name", $csv_array[0], PDO::PARAM_STR);
	$stmt->bindValue(":body", $csv_array[1], PDO::PARAM_STR);
	// $stmt->bindValue(":body", str_replace(["\\r","\\n"], ["\r", "\n"], $csv_array[1]), PDO::PARAM_STR);
	$stmt->execute();
	
}

fgetcsv
L fgetcsvだと、わざわざ\r\nを入れなくても、改行データをそのままmysqlに入れてくれる。

$fp = fopen("hoge.csv", "r");
while(($data[]=fgetcsv($fp))!==FALSE){
}
fclose($fp);

var_dump($data);

foreach($data as $result){
	$stmt = $pdo->prepare("INSERT INTO news (name, body) VALUE (:name, :body)");

	$stmt->bindValue(":name", $result[0], PDO::PARAM_STR);
	$stmt->bindValue(":body", $result[1], PDO::PARAM_STR);
	$stmt->execute();
}
echo "done";

素晴らしい。