这是一项每晚工作了两年的工作。 PHP文件将txt文件导入MYSQL数据库。今天突然导入TXT文件时收到格式错误的数据包。我注意到服务器仅运行了23个小时,因此我认为GoDaddy可能已更新了一些内容。
MYSQL Ver = 5.6.43-cll-lve
local_infile = ON
没有“本地”,我会收到错误消息,“用户的访问被拒绝”,我尝试授予FILE权限,但是在通过SSH获取mysql CLI访问方面遇到了问题(以前从未需要过),而PHP MY Admin没有访问权限。
我花了整整一整天的时间,不知道该怎么办。我也尝试将文件设置为777。
我尝试删除截断部分并仅执行导入操作,使用以前有效的旧导入文件将导入文件缩减为3行-无法前后。
require('config_dev.php');
$path = '/home/pro/public_html/upload/IDUpload_dev.txt';
$mysqli = new mysqli($hostname,$username, $password, $dbname);
if ($mysqli->connect_error) {
die('Error : ('. $mysqli->connect_errno .') '. $mysqli->connect_error);
}
$sql1 = "TRUNCATE TABLE Accounts;";
if (!$mysqli->query($sql1)) {
echo "\nQuery execute failed: ERRNO: (" . $mysqli->errno . ") " . $mysqli->error;
} else {
echo ("Truncated<br>");
}
$sql2 = "LOAD DATA LOCAL INFILE '".$path."' INTO TABLE Accounts
FIELDS TERMINATED BY ','
LINES TERMINATED BY '\n'
IGNORE 1 LINES
(acct,type,zip)";
if (!$mysqli->query($sql2)) {
echo "\nQuery execute failed: ERRNO: (" . $mysqli->errno . ") " . $mysqli->error;
} else {
echo ("Imported.");
}
mysqli_close($mysqli);
答案 0 :(得分:3)
要使用LOAD DATA INFILE LOCAL
,必须在连接前启用MYSQLI_OPT_LOCAL_INFILE。
您应该SHOW GLOBAL VARIABLES LIKE 'local_infile'
来查看服务器上是否启用了此功能,这也是必需的。
答案 1 :(得分:0)
确保授予当前用户访问文件的权限:
先登录mysql
:
mysql -u root -p
然后
GRANT FILE ON *.* TO 'username'@'localhost';
答案 2 :(得分:0)
我遇到了同样的问题,一个运行良好 3 年的脚本突然开始失败并显示“格式错误的数据包”。我在带有 private database 的 OVH 托管服务器上运行。
遗憾的是,没有一个解决方案有效(GRANT
或 MYSQLI_OPT_LOCAL_INFILE
)。
在摆弄之后,我注意到该脚本在同一台服务器上的测试数据库上运行!
我比较了两个数据库的配置,我发现的唯一区别在于数据库整理。
SELECT @@collation_database
== latin1_swedish_ci
SELECT @@collation_database
== utf8_unicode_ci
我更改了生产数据库的排序规则...
ALTER DATABASE DB_PROD_NAME CHARACTER SET latin1 COLLATE latin1_swedish_ci;
它奏效了!(即使所有表都使用 utf8_unicode_ci
)
好吧,它可以工作,但所有字符都被破坏了。
但这迫使我研究编码问题,这使我找到了正确的解决方案。
使用 LOAD DATA LOCAL INFILE ... CHARACTER SET 'utf8mb4' ...
我能够得到真正的错误:
ERROR : Incorrect string value: '\xF0\x9F\x93\x8B' for column ...
\xF0\x9F\x93\x8B
value is actually a perfectly fine UTF8-encoded character:剪贴板表情符号?
但是,它是在 4 个字节上定义的(就像大多数表情符号一样)。
如前所述,我的表和列使用排序规则 utf8_unicode_ci
。所以应该不错吧?除了……不是! mySQL 的 utf8
实现存在严重缺陷,因为它只允许表示最多 3 个字节的 UTF8! See these links 了解更多背景信息。
在 mySQL 中新的、正确的现代 UTF8 实现称为 utf8mb4
。
所以最终的解决方案只是将所有表和列迁移到 utf8mb4_unicode_ci
排序规则,瞧!问题解决了。
最后,最大的问题是理解这个极具误导性的“Malformed packet”错误消息究竟意味着什么。