LOAD DATA LOCAL INFILE 禁止在...PHP的

LOAD DATA LOCAL INFILE forbidden in... PHP

提问人:Richard Pérez 提问时间:10/4/2011 最后编辑:hopperRichard Pérez 更新时间:7/6/2023 访问量:88061

问:

我正在尝试将一些记录插入到表中。不幸的是,它不起作用。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安装的数据目录中查找该文件。

现在,如果我尝试使用该选项执行指令,它仅在我使用 mysql 客户端时有效,但不能从 PHP 中起作用:LOCAL

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错误

PHP 的MySQL

评论

1赞 Mike B 10/4/2011
也许是文件权限问题?
2赞 Amir Raminfar 10/4/2011
尝试将路径设置为绝对路径而不是相对路径。
0赞 Marc B 10/4/2011
mysql客户端很好,但应用程序不行?您是否使用相同的用户名/密码进行连接?
0赞 Richard Pérez 10/4/2011
Mike Permission 没关系,实际上我把 777 放到了文件中。
0赞 Richard Pérez 10/4/2011
阿米尔:我正在使用绝对路径

答:

5赞 Clive 10/4/2011 #1

根据MySQL手册,MySQL必须用 编译。从该链接的评论中:--enable-local-infile

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

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

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

评论

1赞 Richard Pérez 10/4/2011
Clive,但我使用的是php的mysql原生驱动程序,如果我在编译php时使用这个 --with-mysql=mysqlnd --with-mysqli=mysqlnd --with-pdo-mysql=mysqlnd,这意味着什么,所以我不需要使用完整路径.....我从二进制源代码安装了mysql,这意味着我不需要--local-infile=1...,因为默认情况下是启用的...证明这一点是,如果我使用mysql客户端的LOCAL选项,它可以工作...所以 local-infile 正在工作......我知道问题出在 php 上,但我认为它应该是本机驱动程序的解决方案。
0赞 Richard Pérez 10/4/2011
以下是有关php php.net/manual/en/mysqlnd.overview.php 上的mysql本机驱动程序的信息
10赞 Gadelkareem 11/13/2012 #2

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

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

评论

0赞 Spudley 6/20/2013
+1.这就是我们采用的解决方案。这是让我们的代码正常工作的最快方法;只需将进行数据库调用的原始代码行转换为调用即可。不是一个优雅的解决方案,但我可以确认它运行良好。exec()
0赞 NobleUplift 2/6/2015
可悲的是,在尝试了所有其他解决方案之后,这是我唯一剩下的解决方案。谢谢。
1赞 cb0 2/10/2016
我不喜欢这个解决方案(因为主机现在需要mysql客户端),但正如@NobleUplift所说,所有其他解决方案都不起作用。我尝试了 PDO、MySQLI,也弃用了 mysql。我目前需要使用 php 5.4,所以我不能说更现代的版本。
1赞 cb0 2/10/2016
在尝试了@sboye建议的最后一个解决方案后,它现在可以工作了。似乎与php mysql驱动程序有关。
0赞 rymo 2/25/2016
对于更高版本的 MySQL 客户端,您还必须在 exec 行上传递参数--local-infile
1赞 Michael Härtl 4/4/2013 #3

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

因此,我用MariaDB中的客户端替换了MySQL客户端,并且它起作用了。

2赞 michael kinuthia 4/25/2013 #4

LOAD DATA LOCAL INFILE执行,而不考虑警告。它适用于MySQL客户端,因为它允许执行查询,忽略警告。虽然它后来打印出警告。不过,它在 PHP 中拒绝,因为警告会停止脚本。

16赞 MaX 5/28/2013 #5

我没有收到您得到的确切错误,但您无需确保以下几点:

通过向 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' 

评论

0赞 AbdulBasit 4/1/2015
mysql_connect(服务器,用户,代码,false,128);适用于我的 php 版本。感谢您节省 MaX 的时间。
60赞 Nomas Prime 7/2/2013 #6

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,
    ));

评论

8赞 Drahcir 12/7/2013
根据文档,它不能在准备时设置,只能在施工时设置。虽然这确实解决了问题,所以+1。
2赞 Jonathan Lidbeck 7/26/2015
这仅适用于 PDO 构造函数。即使在构造后立即调用 PDO::setAttribute 也无法完成工作。
0赞 Richard 6/8/2019
这是唯一对我有用的东西,谢谢。是的,只有在施工时。
0赞 Martin Zvarík 1/4/2020
你是我的英雄!💕
0赞 Robby Alvian Jaya Mulia 6/23/2022
它对我有用。但我想知道,在使用此解决方案之前,php.ini处的“mysqli.allow_local_infile”是否应该为“开”?
2赞 tanay jha 1/28/2014 #7

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

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

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

评论

1赞 DBeck 1/4/2020
这对我有用。我尝试在php.ini文件中更改 mysqli.allow_local_infile = On,但在 xampp 服务器上失败了
1赞 Rey0bs 12/17/2014 #8

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

sudo apt-get install php5-mysqlnd

评论

0赞 cb0 2/10/2016
尽管有“exec(...)”解决方案,但这是在 php 5.4 下唯一适合我的解决方案
35赞 Sebastian 4/15/2019 #9

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

mysqli.allow_local_infile = On

评论

0赞 Sebastian 1/29/2021
根据您的环境,可能需要重新启动 Apache
1赞 Gunaseelan 3/5/2021
试了一下,然后重新启动了apache,仍然无法得到它
0赞 Growling Flea 4/15/2021
确保您正在更改正确的 php.ini 文件。首先使用 phpnfo();确保您更改的是正确的 php.ini 文件(在 apache2 文件夹中,而不是 CLI 中)。做一个“猫php.ini |grep 'mysqli.allow_local_infile ='。确保它没有被注释掉。在我的情况下,它被注释掉了。
0赞 mLstudent33 6/4/2021
@GrowlingFlea我做了所有这些,但它仍然不起作用
0赞 nicholas.alipaz 11/18/2022
今天从 php 7.3 升级到 7.4 时,这发生在我身上,我收集他们在版本之间添加了此配置选项,并且此解决方案修复了它。我还应该注意,这是一个很好的安全补充,因为我可以为我的 php 命令行脚本启用它,而无需为 apache 提供的网站启用。
9赞 chris 1/28/2020 #10

2019+ 相关答案,背景更丰富:

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

此指令只能通过以下方式进行配置,因此不起作用PHP_INI_SYSTEMini_set()

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

[MySQLi]
mysqli.allow_local_infile = On
0赞 wiotrek 5/29/2020 #11

取消注释 'mysqli.allow_local_infile = On' in php.ini.

1赞 hailong 6/10/2020 #12

为了解决 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 文档

评论

0赞 David 1/11/2023
适用于 SF 4.4 👍
3赞 Maka 12/10/2020 #13

对我有用的解决方案如下。需要在已设置相同脚本的第二台服务器上添加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);
0赞 RonyRyan 7/6/2023 #14

2023 版答案:

未捕获mysqli_sql_exception:禁止加载数据本地 INFILE;

Ubuntu Linux 和 Windows 的最佳解决方案

  • 让我们通过命令检查服务器上运行的PHP版本
php -i | grep php.ini
  • 在终端上:复制提供的路径,例如 Loaded Configuration File => /etc/php/8.2/cli/php.ini

  • 只需复制文件路径并运行以下命令并编辑php.ini文件即可。我正在使用 nano 编辑器

sudo nano /etc/php/8.2/fpm/php.ini

注意!取消注释该行

mysqli.allow_local_infile = On
  • 按 ctrl+s 保存,按 ctrl+x 退出

  • 现在刷新php.ini文件以影响我们所做的更改

service php8.2-fpm restart

在 Windows 上

  • 只需以管理员身份打开php.ini文件并取消注释下面的行,然后保存即可。限制已解决。
mysqli.allow_local_infile = On

恭喜您现在可以加载文件数据