Importing CSV data using PHP/MySQL - Mysqli syntax

霸气de小男生 提交于 2019-12-03 20:46:23

EDIT for Probable Solution: Prepared stmts don't support LOAD DATA.

If you use mysqli_query - instead of mysqli->prepare ..->execute(); this should work.

So:

//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;
}

useful still to var_dump($mysqli) here to see result I got access denied as in my env we disallow LOAD FILE, but that tells me the engine successfully parsed and attempted to execute the query.

You need to get better error info, there is a bit that could be going on, here is how I would dig in:

Diagnosis Process to get to this Point:

$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();

Results on my Box (not the best representation):

  object(mysqli)#1 (18) {
  ...
  string(68) "This command is not supported in the 
              prepared statement protocol yet"

2. Other possible errors you would see

Insufficient FILE privs or Improper Directory of file Loc

phpMyAdmin is pretty sandboxed and will work completely differently than mysqli/php.

Address the following from MySQL Docs, and read up on this section. Like I said, LOAD..FILE is a very sensitive operation with a lot of restrictions. LOAD...FILE MySQL Docs

For security reasons, when reading text files located on the server, the files must either reside in the database directory or be readable by all. Also, to use LOAD DATA INFILE on server files, you must have the FILE privilege. See Section 6.2.1, “Privileges Provided by MySQL”. For non-LOCAL load operations, if the secure_file_priv system variable is set to a nonempty directory name, the file to be loaded must be located in that directory.

You should probably put guards in to detect when a prepare call fails:

/* Prepared statement, stage 1: prepare */
if (!($stmt = $mysqli->prepare("INSERT INTO test(id) VALUES (?)"))) {
    echo "Prepare failed: (" . $mysqli->errno . ") " . $mysqli->error;
}

Source: http://www.php.net/manual/en/mysqli.quickstart.prepared-statements.php

I'd also check the path for the LOAD DATA INFILE command. Phpmyadmin might be setting a different path variable. If you try to temporarily put the absolute unix path (and ensure mysql has appropriate permission to that directory), it may clear up the problem.

However, in either case, you should output the error from the mysql client to give you a better idea of what's causing the issue.

Lastly, I'd try to execute the command directly in the MySQL command line client. If there's any "magic" happening in phpmysql or the mysqli php client, it will show up by using the mysql cli client as two of the clients will succeed where one will fail (compared to your assumptions).

I've run into a similiar issue before and it ended up being MySQL's odd way of escaping the delimiter, so I'd look to see that you're escaping the TERMINATED BY parameters correctly.

What Homer6 states, and probably:

$sql = "LOAD DATA INFILE './myfile.csv' INTO TABLE tab"
. " FIELDS TERMINATED BY ','"
. " LINES TERMINATED BY '\\r\\n'"
. " IGNORE 1 LINES";

Might need to check the path to the file as well. I don't know what the ./ is relative to in the query. Maybe not the location of the PHP file(s).

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!