【问题标题】:LOAD DATA LOCAL INFILE forbidden in... PHPLOAD DATA LOCAL INFILE 在... PHP 中被禁止
【发布时间】:2011-11-30 02:04:27
【问题描述】:

我正在尝试使用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,但我还没有找到解决方案。

附加信息:到目前为止,我找到的唯一帮助是open PHP bug

【问题讨论】:

  • 可能是文件权限问题?
  • 尝试设置绝对路径而不是相对路径。
  • 来自 mysql 客户端但不是应用程序?您是否使用相同的用户名/密码进行连接?
  • 麦克权限没问题,其实我把777放到文件里了。
  • 阿米尔我使用的是绝对路径

标签: php mysql


【解决方案1】:

查看文档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,
    ));

【讨论】:

  • 根据文档,它不能在准备时设置,只能在施工时设置。虽然这确实解决了问题,所以 +1。
  • 这仅适用于 PDO 构造函数。即使在构造后立即调用 PDO::setAttribute 也无法完成工作。
  • 这是唯一对我有用的东西,谢谢。是的 - 仅在施工中。
  • 你是我的英雄! ?
【解决方案2】:

今天遇到这个问题,通过在php.ini中设置如下解决了

mysqli.allow_local_infile = On

【讨论】:

  • 根据您的环境,可能需要重新启动 apache
  • 试过了,重启了apache,还是不行
  • 确保您更改了正确的 php.ini 文件。首先使用 phpnfo();确保您更改了正确的 php.ini 文件(在 apache2 文件夹中,而不是 cli 中)。执行“cat php.ini | grep 'mysqli.allow_local_infile ='。确保它没有被注释掉。在我的情况下它被注释掉了。
  • @GrowlingFlea 我做了所有这些,但它仍然不起作用
【解决方案3】:

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

通过添加到您的 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' 

【讨论】:

  • mysql_connect(server,user,code,false,128);适用于我的 php 版本。感谢 MaX 节省时间。
【解决方案4】:

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

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

【讨论】:

  • +1。这是我们采用的解决方案。这是让我们的代码工作的最快方法;只需将进行 DB 调用的原始代码行转换为 exec() 调用即可。这不是一个优雅的解决方案,但我可以确认它运行良好。
  • 很遗憾,after attempting every other solution,这是我唯一剩下的一个。谢谢。
  • 我不喜欢这个解决方案(因为主机现在需要 mysql 客户端),但正如@NobleUplift 所说,所有其他解决方案都不起作用。我尝试了 PDO、MySQLI 并且还弃用了 mysql。我目前需要使用 php 5.4,所以我不能说更现代的版本。
  • 在尝试了@sboye 建议的最后一个解决方案后,它现在可以工作了。好像和php mysql驱动有关。
  • 对于更高版本的 mysql 客户端,您还必须在 exec 行上传递 --local-infile 参数
【解决方案5】:

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

在 PHP >7.2.16 和 >7.3.3 中,mysqli.allow_local_infile 的默认 ini 配置控制了这一点,changed from '1' to '0'(因此现在默认禁用)。

此指令只能通过PHP_INI_SYSTEM 配置,因此ini_set()工作。

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

[MySQLi]
mysqli.allow_local_infile = On

【讨论】:

    【解决方案6】:

    根据the MySQL manual,MySQL 必须用--enable-local-infile 编译。来自该链接的评论:

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

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

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

    【讨论】:

    • Clive,但是我使用的是php的mysql原生驱动,如果我编译php的时候使用这个--with-mysql=mysqlnd --with-mysqli=mysqlnd --with-意味着什么pdo-mysql=mysqlnd,所以我不需要使用完整路径.....而且我从二进制源安装了 mysql,这意味着我不需要 --local-infile=1...,因为是通过默认...证明是,如果我使用mysql客户端的LOCAL选项它可以工作...所以local-infile正在工作...我知道问题出在php上,但我认为它应该是一个解决方案本机驱动程序。
    • 这里是php上mysql原生驱动的信息php.net/manual/en/mysqlnd.overview.php
    【解决方案7】:

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

    【讨论】:

      【解决方案8】:

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

      原文:LOAD DATA LOCAL INFILE 新/应该是:加载数据输入文件

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

      【讨论】:

      • 这对我有用。我尝试在 php.ini 文件中更改 mysqli.allow_local_infile = On 并且在 xampp 服务器上失败
      【解决方案9】:

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

      所以我用 MariaDB 的客户端替换了 MySQL 客户端,它工作正常。

      【讨论】:

        【解决方案10】:

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

        sudo apt-get install php5-mysqlnd

        【讨论】:

        • 尽管有 "exec(.." 解决方案,但这是在 php 5.4 下唯一适合我的解决方案
        【解决方案11】:

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

        【讨论】:

          【解决方案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 doc

          【讨论】:

            【解决方案13】:

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

            【讨论】:

              猜你喜欢
              • 2013-01-24
              • 1970-01-01
              • 2017-12-26
              • 2012-10-05
              • 1970-01-01
              • 1970-01-01
              • 2018-03-04
              • 2012-06-01
              • 1970-01-01
              相关资源
              最近更新 更多