【发布时间】:2015-09-05 14:32:03
【问题描述】:
新功能:
使用具有正确结构的 WinSCP 将实际的 .csv 文件上传到 /tmp 文件夹到服务器,然后从 mysql CLI 运行 LOAD DATA LOCAL INFILE 可以完美运行。但是,如果您从表单上传,我会触发“抱歉”错误。我已经 echo'ed 和 var_dumped 了几个全局 $_FILE 变量,下面是它们的结果:
$_FILES['csv']['tmp_name']:
dirname 是/tmp
basename 是 php8k4jFN(每次运行脚本时都不同,并且没有 .csv 结尾)
filename 是php8k4jFN
完整文件路径:
/tmp/php8k4jFN
$_FILES['csv']['error']:
0
权限:
mysql 和 www-data 是 root 组的一部分,并且都可以读/写 /tmp
在/tmp 中使用mycsv.csv 文件从mysql CLI 执行LOAD DATA INFILE LOCAL... 工作正常,但会出现一些警告(这会触发错误吗?)。
移除 apparmor 并授予 root 1775 权限 t /tmp
我的表单允许您上传 CSV 文件。
我使用LOAD DATA LOCAl INFILE 将 CSV 的内容上传到 MySQL 表中。
想法是:用户使用我的表单将他计算机上的本地 CSV 上传到我的远程 LAMP 服务器。
如果我在本地环境中测试所有内容(在我的计算机上运行 WAMP),那么一切正常。我已经解决了所有的语法、逻辑和 CSV 结构错误。
当我将整个源文件上传到远程 LAMP 服务器并尝试将 CSV 从我的笔记本电脑上传到它时,我触发了我的自定义错误:"Sorry, couldn't upload the CSV"。
我对其进行了测试,但从未在本地收到该错误。后来我发现我必须在LAMP服务器上的[mysqld]和[mysql]下的my.cnf里面启用local-infile才能让我使用LOCAL关键字。
在我进行该更改之前,我曾经得到:The used command is not allowed with this MySQL version。
我尝试在我的 PHP 脚本中回显查询并通过 mysql 命令行手动执行它并得到以下错误(这是有道理的,因为临时文件不再存在):
ERROR 2 (HY000): File '/tmp/phpINUea0' not found (Errcode: 2)
回显查询:
LOAD DATA LOCAL INFILE '/tmp/phpINUea0'
INTO TABLE mydb.suites
FIELDS TERMINATED BY ','
OPTIONALLY ENCLOSED BY '\"'
LINES TERMINATED BY '\n'
IGNORE 1 LINES
(suite, business_name, business_phone, business_email)
SET location_id = 2
然后我还尝试使用 PHP 的 echo、var_dump 和 print_r 调试我的表单,但所有三个语句都返回空/假:
$query_add_suite_csv = $this->db_connection->query($query);
echo $query_add_suite_csv; // returns nothing
var_dump($query_add_suite_csv); // returns boolean false
print_r($query_add_suite_csv); // return nothing
if ($query_add_suite_csv) {
// success message
}else{
echo "Sorry, couldn't upload the CSV"
}
目前不知道为什么会发生这种情况。以防万一,我使用THIS 指南来设置我的远程 LAMP 服务器。
文件上传PHP函数:
private function addSuiteCSV()
{
if (empty($_POST['suite_location_csv'])) {
$this->errors[] = "Must select location of suite";
}else{
// create a database connection
$this->db_connection = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME);
if (!$this->db_connection->set_charset("utf8")) {
$this->errors[] = $this->db_connection->error;
}
if (!$this->db_connection->connect_errno) {
$suite_location_csv = $this->db_connection->real_escape_string(strip_tags($_POST['suite_location_csv'], ENT_QUOTES));
if ($_FILES['csv']['size'] > 0) {
$file = addslashes($_FILES['csv']['tmp_name']);
$query =<<<EOF
LOAD DATA LOCAL INFILE '$file'
INTO TABLE mydb.suites
FIELDS TERMINATED BY ','
OPTIONALLY ENCLOSED BY '\"'
LINES TERMINATED BY '\n'
IGNORE 1 LINES
(suite, business_name, business_phone, business_email)
SET location_id = $suite_location_csv
EOF;
$query_add_suite_csv = $this->db_connection->query($query);
if ($query_add_suite_csv) {
// success
} else {
// sorry
}
}else{
// empty file
}
}else{
// db connection error
}
}
}
}
【问题讨论】:
-
你测试过是否收到文件吗?
-
@frz3993 如果我没记错的话,
/tmp在每次重启后都会被清除。从那以后我没有重新启动我的 LAMP 服务器,/tmp文件夹中没有任何内容。因此,我认为可以肯定地说没有收到文件。我还尝试手动将文件上传到/tmp以查看是否存在读/写权限问题,但我能够毫无问题地上传文件。 -
我认为
/tmp文件中的文件将在 PHP 脚本执行完毕后被删除。试试echo pathinfo($_FILES['filename']['tmp_name']);。看看你有没有得到什么。将文件名更改为您的 csv 文件名。 -
@frz3993
echoing 给了我Array的输出。我也在pathinfo()上做了var_dump并得到了这个:array(3) { ["dirname"]=> string(4) "/tmp" ["basename"]=> string(9) "php61HnlJ" ["filename"]=> string(9) "php61HnlJ" } -
表示文件已上传到服务器。您为什么不尝试将上传的文件移动到另一个文件夹。
标签: php mysql file-upload nginx permissions