我正在构建一个从Mysql表中输出CSV的PHP脚本,但它每次都会在mysql/data/export.csv
路径而不是指定的路径中保存文件。我究竟做错了什么 ?我正在使用XAMPP本地服务器。
PHP代码:
<?php
require_once __DIR__ . DIRECTORY_SEPARATOR . "master.php";
$export_path = __DIR__ . DIRECTORY_SEPARATOR . "export" . DIRECTORY_SEPARATOR . "export.csv";
$query = <<<SQL
SELECT op,cid,lac,rnc,lat,lng,ratio,data,rfu
FROM cells
INTO OUTFILE '?'
FIELDS TERMINATED BY ';'
LINES TERMINATED BY '\n';
SQL;
$statement = db()->prepare($query);
$statement->execute([$export_path]);
header('Content-Type: application/csv');
header('Content-Disposition: attachment; filename="export.csv";');
readfile($export_path);
P.S。如果我从INTO OUTFILE '?'
中的问号中删除引号,则会出现此错误:
PDO :: prepare():SQLSTATE [42000]:语法错误或访问冲突: 1064您的SQL语法有错误;检查手册 对应于您的MySQL服务器版本,以便使用正确的语法 靠近'? FIELDS终止于';'在3号线的'''终止的线路 第14行的C:\ xampp \ htdocs \ celldb \ export.php
答案 0 :(得分:0)
它不是clearly documented但我怀疑SELECT... INTO OUTFILE
构造不支持绑定参数。这就是为什么当你运行固定代码时,占位符出现在错误消息中的原因(在原始代码中传递文字'?'
字符串显然没有机会工作 - 事实上我&#39;我很惊讶你在错误的目录中得到了正确的文件名。)
如果让PHP模拟预准备语句,它确实有效:
$pdo = new PDO(..., [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_EMULATE_PREPARES => true,
]);
...因为这是一种客户端操作。但是在项目生命周期中这样做会破坏其他事情。一个更安全的选择是避免在这里准备好陈述:
$query = sprintf(<<<SQL
SELECT op,cid,lac,rnc,lat,lng,ratio,data,rfu
FROM cells
INTO OUTFILE '%s'
FIELDS TERMINATED BY ';'
LINES TERMINATED BY '\n';
SQL
, $db()->quote($export_path));