В НИЖНЕЙ ЧАСТИ ЭТОГО ВОПРОСА ОКОНЧАТЕЛЬНЫЙ КОД, КОТОРЫЙ НАКОНЕЧНО РАБОТАЕТ!
Попытка реализовать это ( импорт CSV-данных с использованием PHP / MySQL ). Я должен быть почти там …
notes1: мой $ sql пришел прямо из копии / вставки phpmyadmin (сгенерировал PHP-код) и отлично работал в phpmyadmin.
note2: Если я прокомментирую строку $ sql = "DELETE FROM dbase", код работает просто отлично (и очищается таблица).
Так что, если я знаю, что мой sql прав, и мой код может запускать другие sqls, почему нижеследующее не работает ?! Я получаю:
Вызов функции-члена execute () для не-объекта – для строки
$stmt->execute();
Полный код:
<?php $mysqli = new mysqli('localhost','root','pass','dbase'); /* check connection */ if (mysqli_connect_errno()) { printf("Connect failed: %s\n", mysqli_connect_error()); exit(); } $sql = "LOAD DATA INFILE \'./myfile.csv\' INTO TABLE tab\n" . " FIELDS TERMINATED BY \',\'\n" . " LINES TERMINATED BY \'\\r\\n\'\n" . " IGNORE 1 LINES"; //$sql="DELETE FROM dbase"; $stmt=$mysqli->prepare($sql); $stmt->execute(); $stmt->close(); $mysqli->close(); ?>
tks заранее!
РЕДАКТИРОВАТЬ:
Сделано ниже изменений и до сих пор не работает!
новый код:
<?php $mysqli = new mysqli('localhost','root','pass','dbase'); /* check connection */ if (mysqli_connect_errno()) { printf("Connect failed: %s\n", mysqli_connect_error()); exit(); } /* return name of current default database */ if ($result = $mysqli->query("SELECT DATABASE()")) { $row = $result->fetch_row(); printf("Default database is %s.\n", $row[0]); $result->close(); } $sql = "LOAD DATA INFILE 'C:/xampp/htdocs/myfile.csv' INTO TABLE tab FIELDS TERMINATED BY ',' LINES TERMINATED BY '\\r\\n' IGNORE 1 LINES"; echo "<br>"; echo "<br>"; echo $sql; echo "<br>"; echo "<br>"; $stmt=$mysqli->prepare($sql); /* Prepared statement, stage 1: prepare */ if (!($stmt = $mysqli->prepare($sql))) { echo "Prepare failed: (" . $mysqli->errno . ") " . $mysqli->error; } // NOTE HERE WE'RE DUMPING OUR OBJ TO SEE THAT IT WAS // CREATED AND STATUS OF PREPARE AND THEN KILLING SCRIPT var_dump($mysqli); exit(); //$sql="DELETE FROM intrasdump $stmt=$mysqli->prepare($sql); $stmt->execute(); $stmt->close(); $mysqli->close(); ?>
То, что я вижу в своем браузере при запуске, это следующее:
База данных по умолчанию – dbname.
LOAD DATA INFILE 'C: /xampp/htdocs/myfile.csv INTO TABLE ВЛИЯНИЕ НА ЛИНИИ «,» ЛИНИИ, ПРЕКРАЩЕННЫЕ «\ r \ n» IGNORE 1 LINES
Подготовить неудачно: (1295) Эта команда не поддерживается в подготовленном протоколе whileobject (mysqli) # 1 (19) {["affected_rows"] => int (-1) ["client_info"] => string (79) " mysqlnd 5.0.11-dev – 20120503 – $ Id: 40933630edef551dfaca71298a83fad8d03d62d4 $ "[" client_version "] => int (50011) [" connect_errno "] => int (0) [" connect_error "] => NULL [" errno "] => int (1295) ["error"] => string (68) "Эта команда еще не поддерживается в подготовленном протоколе оператора" ["error_list"] => array (0) {} ["field_count"] => int (1) ["host_info"] => строка (20) "localhost через TCP / IP" ["info"] => NULL ["insert_id"] => int (0) ["server_info"] => string ( 6) "5.6.11" ["server_version"] => int (50611) ["stat"] => string (133) "Время работы: 7993 Темы: 2 Вопросы: 865 Медленные запросы: 0 Открывает: 75 Таблицы Flush: 1 Открытые таблицы: 68 запросов в секунду avg: 0.108 "[" sqlstate "] => string (5)" 00000 "[" protocol_version "] => int (10) [" thread_id "] => int (117) [" warning_count "] => int (0)}
Примечание. Если я скопирую вставку строку sql, указанную выше в приглашении mysql, она работает просто отлично. Это должно означать, что проблема как с расположением файлов, так и с строкой sql в порядке, нет ???
как это может быть так сложно ?!
ИЗМЕНИТЬ 3.
Tks для всех ответов и комментариев. Следующая версия кода ниже:
<?php $mysqli = new mysqli('localhost','root','pass','dbname'); /* check connection */ if (mysqli_connect_errno()) { printf("Connect failed: %s\n", mysqli_connect_error()); exit(); } $sql = "LOAD DATA INFILE 'C:/xampp/htdocs/myfile.csv' INTO TABLE tab FIELDS TERMINATED BY ',' LINES TERMINATED BY '\\r\\n' IGNORE 1 LINES"; //Try to execute query (not stmt) and catch mysqli error from engine and php error if (!($stmt = $mysqli->query($sql))) { echo "\nQuery execute failed: ERRNO: (" . $mysqli->errno . ") " . $mysqli->error; }; ?>
полезные примечания:
обратите внимание, что путь к файлу использует frw-slash вместо обратного коса чернил по умолчанию. По порядку просто заметьте работу. Бог знает, как я это понял …
используйте многие коды отладки, предлагаемые в ответах. Я думаю, один эффективный способ проверить, правильно ли ваш sql для эха ( echo $sql
) и скопировать / вставить в вашу SQL-строку. не доверяйте функциям phpmyadmin 'create php PHP code'.
имейте в виду «Подготовленные stmts не поддерживают LOAD DATA»
EDIT для возможного решения: подготовленные stmts не поддерживают LOAD DATA
.
Если вы используете mysqli_query
– вместо mysqli->prepare
..-> execute (); это должно сработать.
Так:
//Connect as normal above $sql = "LOAD DATA INFILE '/myfile.csv' INTO TABLE tab" . " FIELDS TERMINATED BY ','" . " LINES TERMINATED BY '\r\n'" . " IGNORE 1 LINES"; //$sql="DELETE FROM dbase"; // $stmt = $mysqli->query($sql); // Integrate other posters good recc to catch errors: //Try to execute query (not stmt) and catch mysqli error from engine and php error if (!($stmt = $mysqli->query($sql))) { echo "\nQuery execute failed: ERRNO: (" . $mysqli->errno . ") " . $mysqli->error; }
полезный еще для var_dump ($ mysqli) здесь, чтобы увидеть результат. Мне был отказан доступ, так как в моем env мы запрещаем LOAD FILE, но это говорит мне, что движок успешно разобрался и попытался выполнить запрос.
Вам нужно получить лучшую информацию об ошибке, есть немного, что можно было бы сделать, вот как я буду копаться:
Процесс диагностики, чтобы добраться до этой точки:
$sql = "LOAD DATA INFILE ..."; echo $sql; $stmt=$mysqli->prepare($sql); // NOTE HERE WE'RE DUMPING OUR OBJ TO SEE THAT IT WAS // CREATED AND STATUS OF PREPARE AND THEN KILLING SCRIPT var_dump($mysqli); exit();
Результаты на моем ящике (не лучшее представление):
object(mysqli)#1 (18) { ... string(68) "This command is not supported in the prepared statement protocol yet"
2. Другие возможные ошибки, которые вы увидите
Недостаточно файлов FILE или неправильного каталога файла Loc
phpMyAdmin довольно песочница и будет работать совершенно иначе, чем mysqli / php.
Обратите внимание на следующее из документации MySQL и прочитайте в этом разделе. Как я уже сказал, LOAD..FILE – очень чувствительная операция с множеством ограничений. LOAD...FILE
MySQL Docs
По соображениям безопасности при чтении текстовых файлов, расположенных на сервере, файлы должны либо находиться в каталоге базы данных, либо читаться всеми. Кроме того, чтобы использовать LOAD DATA INFILE для файлов сервера, вы должны иметь привилегию FILE. См. Раздел 6.2.1 «Привилегии, предоставляемые MySQL». Для операций загрузки, отличных от LOCAL, если системная переменная secure_file_priv установлена на непустое имя каталога, загружаемый файл должен быть расположен в этом каталоге.
Вероятно, вы должны установить защитников, чтобы обнаружить, когда вызов готово:
/* Prepared statement, stage 1: prepare */ if (!($stmt = $mysqli->prepare("INSERT INTO test(id) VALUES (?)"))) { echo "Prepare failed: (" . $mysqli->errno . ") " . $mysqli->error; }
Источник: http://www.php.net/manual/en/mysqli.quickstart.prepared-statements.php
Я также проверил бы путь для команды LOAD DATA INFILE
. Phpmyadmin может устанавливать другую переменную пути. Если вы попытаетесь временно установить абсолютный путь unix (и убедитесь, что mysql имеет соответствующее разрешение для этого каталога), это может устранить проблему.
Однако в любом случае вы должны вывести ошибку из клиента mysql, чтобы дать вам лучшее представление о том, что вызывает проблему.
Наконец, я попытаюсь выполнить команду непосредственно в клиенте командной строки MySQL. Если в phpmysql или в mysqli php-клиенте происходит какое-либо «волшебство», оно будет отображаться с помощью клиента mysql cli, так как два из клиентов будут успешны, если вы потерпите неудачу (по сравнению с вашими предположениями).
Раньше я сталкивался с подобной проблемой, и в конечном итоге это был нечетный способ MySQL избегать разделителя, поэтому я бы посмотрел, что вы правильно TERMINATED BY
параметры TERMINATED BY
.
Что говорит Гомер6, и, вероятно:
$sql = "LOAD DATA INFILE './myfile.csv' INTO TABLE tab" . " FIELDS TERMINATED BY ','" . " LINES TERMINATED BY '\\r\\n'" . " IGNORE 1 LINES";
Также необходимо проверить путь к файлу. Я не знаю, что такое ./ относительно запроса. Возможно, не расположение файлов PHP.