繁体   English   中英

LOAD DATA LOCAL INFILE 禁止在... PHP

[英]LOAD DATA LOCAL INFILE forbidden in... PHP

我正在尝试使用LOAD DATA INFILE将一些记录插入到表中。 不幸的是,它不起作用。

这里有一些细节

如果我使用这个指令:

LOAD DATA INFILE 'file.txt'
INTO TABLE table_ex
FIELDS TERMINATED BY ','
LINES TERMINATED BY '\n'
(field1, field2, field3, field4);

它使用 MySQL 客户端程序和 PHP 应用程序工作。 通过这种方式,它将在我的 MySQL 安装的数据目录中查找该文件。

现在,如果我尝试使用LOCAL选项执行指令,则它仅在我使用 mysql 客户端时才有效,而在 PHP 中无效:

LOAD DATA LOCAL INFILE 'path/to/file/file.txt'
INTO TABLE table_ex
FIELDS TERMINATED BY ','
LINES TERMINATED BY '\n'
(field1, field2, field3, field4);

再次.. 它适用于 MySQL 客户端,但不适用于 PHP 应用程序...我收到此错误:

LOAD DATA LOCAL INFILE forbidden in /path/to/my/application

我读到问题与PHP的编译和使用mysqlnd有关。 我使用的是 PHP 5.3.8 和 MySQL 5.5.15,但我还没有找到解决方案。

附加信息:到目前为止,我发现的唯一帮助是一个开放的 PHP 错误

检查文档http://php.net/manual/en/ref.pdo-mysql.php

基本上你需要:

PDO::MYSQL_ATTR_LOCAL_INFILE => true

在实例化时设置。

例子:

    $conn = new \PDO("mysql:host=$server;dbname=$database;", "$user", "$password", array(
        PDO::MYSQL_ATTR_LOCAL_INFILE => true,
    ));

今天遇到了这个问题并通过在php.ini中设置以下内容解决了它

mysqli.allow_local_infile = On

我没有得到你得到的确切错误,但你不需要确保以下几点:

通过添加到您的 my.cnf 启用:

[mysql]
local-infile=1

[mysqld]
local-infile=1

告诉 PHP 中的连接它可能使用 LOCAL INFILE

使用 mysql:

mysql_connect(server,user,code,false,128); // 128 enables LOCAL INFILE
mysql_select_db(database);

使用 mysqli:

$conn = mysqli_init();
mysqli_options($conn, MYSQLI_OPT_LOCAL_INFILE, true);
mysqli_real_connect($conn,server,user,code,database);

授予 MySQL 用户 FILE 权限

但是,当使用 LOCAL 时,这不是必需的。 LOCAL 表示该文件位于客户端服务器(安装了 PHP 的位置),否则它会查看服务器位置(安装 MySQL 的位置)。

GRANT FILE ON *.* TO 'mysql_user'@'localhost' 

更简单的解决方法是使用 exec()

exec("mysql -u myuser -pMyPass -e \"USE mydb;TRUNCATE mytable;LOAD DATA INFILE '" . $file . "' IGNORE  INTO TABLE mytable;\"; ");

2019+ 相关答案,有更多背景信息:

在 PHP >7.2.16 和 >7.3.3 中,用于控制这一点的mysqli.allow_local_infile的默认 ini 配置从“1”更改为“0” (因此现在默认禁用)。

这个指令只能通过配置PHP_INI_SYSTEM这样ini_set()无法工作。

唯一的选择是将以下指令添加到您的 php.ini 文件中,不要忘记重新加载 apache。

[MySQLi]
mysqli.allow_local_infile = On

根据MySQL 手册MySQL 必须使用--enable-local-infile编译。 来自该链接的评论:

您必须使用 MySQL 的完整路径编译 PHP,否则它将使用它的内部处理程序,这些处理程序不适用于“新的”负载数据。

--with-mysql=/usr/local/mysql(假设您的 MySQL 位于此处)

您必须使用选项“--local-infile=1”启动 MySQL 守护进程

不管警告如何, LOAD DATA LOCAL INFILE执行。 它适用于 mysql 客户端,因为它允许执行查询,而忽略警告。 虽然它后来打印出警告。 但它在 PHP 中拒绝,因为警告将停止脚本。

可能适用于某些服务器的最简单的解决方案是删除 LOCAL,例如:

原文:LOAD DATA LOCAL INFILE 新建/应该是:LOAD DATA INFILE

奇怪,但我发现这个解决方案可以在我的本地机器上使用 xampp 但它在带有 CentOS 的实时服务器上不起作用,所以我将恢复代码并添加“本地”。

在 RDS 上访问 MySQL 时,我在 EC2 Ubuntu 12.04 LTS 实例上遇到了完全相同的问题: LOAD DATA LOCAL INFILE...在 mysql 控制台上工作正常,但在 PHP 上无法正常工作。 偶然地我发现它在另一台使用MariaDB 的几乎相同的机器上运行良好(替代 MySQL 的二进制兼容下降)。

所以我用 MariaDB 的客户端替换了 MySQL 客户端并且它工作了。

如果您使用 Ubuntu 服务器,您可以尝试安装php5-mysqlnd

sudo apt-get install php5-mysqlnd

要解决 PHP Symfony 应用程序中的相同问题,需要在 yml 配置文件中启用此标志。 下面是一个例子:

# Doctrine Configuration
doctrine:
    dbal:
        driver:   pdo_mysql
        options:
            !php/const PDO::MYSQL_ATTR_LOCAL_INFILE: true
        # Skip the rest

还要注意如何在 yml 文件中引用 PHP 常量,这种格式用于 Symfony 3.4。 对于旧版本,请查看 Symfony 文档

对我有用的解决方案如下。 在第二台服务器上需要添加 mysqli_options 我已经设置了相同的脚本。

$mysqli = new 
mysqli("$db_server_name","$db_user_name","$db_password","$database_name");
// force LOCAL_INFILE
mysqli_options($mysqli, MYSQLI_OPT_LOCAL_INFILE, true);

在 php.ini 中取消注释 'mysqli.allow_local_infile = On'。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM