LOAD DATA LOCAL INFILE запрещен в... 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-ошибку:

Ответы

Ответ 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,
    ));

Ответ 2

Легче работать с exec()

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

Ответ 3

Согласно руководство MySQL MySQL должен быть скомпилирован с помощью --enable-local-infile. Из комментария по этой ссылке:

Вы ДОЛЖНЫ компилировать PHP, используя полный путь к MySQL, иначе это будет использовать его внутренние обработчики, которые не работают с "новым" LOAD ДАННЫЕ.

- с-mysql =/usr/local/mysql (предполагается, что ваш MySQL находится здесь)

Вы ДОЛЖНЫ запустить демон MySQL с опцией '--local-infile = 1'

Ответ 4

Я не получил точную ошибку, которую вы получили, но вам не нужно гарантировать следующее:

Включить, добавив в свой файл 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);

Предоставить разрешение пользователя FILE для пользователя

При использовании LOCAL это не обязательно. LOCAL говорит, что файл находится на клиентском сервере (там, где установлен PHP), в противном случае он смотрит на местоположение сервера (где установлен MySQL).

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

Ответ 5

У меня была точно такая же проблема на экземпляре EC2 Ubuntu 12.04 LTS при обращении к MySQL на RDS: LOAD DATA LOCAL INFILE... отлично работает на консоли mysql, но не с PHP. Случайно я узнал, что он отлично работал на другой почти идентичной машине, которая использовала MariaDB (двоичное совместимое падение в замене MySQL).

Итак, я заменил клиентов MySQL теми, что были у MariaDB, и это сработало.

Ответ 6

LOAD DATA LOCAL INFILE выполняется независимо от предупреждений. он работает с клиентом mysql, поскольку он позволяет выполнять запросы, игнорируя предупреждения. Хотя позже он выдает предупреждения. Он отказывается от PHP, потому что предупреждение остановит script.

Ответ 7

Если вы используете сервер Ubuntu, вы можете попробовать установить php5-mysqlnd:

sudo apt-get install php5-mysqlnd

Ответ 8

Самое простое решение, которое может работать на некоторых серверах, - это удалить LOCAL, например:

Оригинал: LOAD DATA LOCAL INFILE Новое/Это должно быть: LOAD DATA INFILE

Странно, но я нашел это решение для работы на моей локальной машине с помощью xampp, но он не работал на реальном сервере с CentOS, поэтому я должен был вернуть код обратно и добавить "LOCAL".

Ответ 9

имел эту проблему сегодня и решил ее, установив следующее в php.ini

mysqli.allow_local_infile = On