Importing CSV data using PHP/MySQL - Mysqli syntax - php

IN THE BOTTOM OF THIS QUESTION THE FINAL CODE THAT FINALLY WORKED!
Trying to implement this (Importing CSV data using PHP/MySQL). I must be almost there...
notes1: my $sql came straight from copy/paste phpmyadmin (generate php code) and ran just fine in the phpmyadmin.
note2: If I comment the line $sql="DELETE FROM dbase" the code runs just fine (and the table is cleaned).
So if i know my sql is right and my code can run other sqls, why does the below does not run?! Im getting:
Call to a member function execute() on a non-object - for the line
$stmt->execute();
Full code:
<?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 in advance!
EDIT:
Made below changes and still not working!
new code:
<?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();
?>
What i see in my browser when I ran this is the following:
Default database is dbname.
LOAD DATA INFILE 'C:/xampp/htdocs/myfile.csv' INTO TABLE tab FIELDS TERMINATED BY ',' LINES TERMINATED BY '\r\n' IGNORE 1 LINES
Prepare failed: (1295) This command is not supported in the prepared statement protocol yetobject(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) "This command is not supported in the prepared statement protocol yet" ["error_list"]=> array(0) { } ["field_count"]=> int(1) ["host_info"]=> string(20) "localhost via TCP/IP" ["info"]=> NULL ["insert_id"]=> int(0) ["server_info"]=> string(6) "5.6.11" ["server_version"]=> int(50611) ["stat"]=> string(133) "Uptime: 7993 Threads: 2 Questions: 865 Slow queries: 0 Opens: 75 Flush tables: 1 Open tables: 68 Queries per second avg: 0.108" ["sqlstate"]=> string(5) "00000" ["protocol_version"]=> int(10) ["thread_id"]=> int(117) ["warning_count"]=> int(0) }
Note: If I copy paste the sql string echoed above in to mysql prompt, it runs just fine. That should mean that both the file location issue and the sql string itself are fine, no???
how can this be so hard?!
EDIT 3.
Tks for all answers and comments. Final code version below works:
<?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;
};
?>
useful notes:
note the file path uses frw-slash instead of windows-default back-slash. Orderwise will just note work. God knows how I figured that one out...
take advantage of the many debugging codes offered in the answers. i guess one effective way to check if your sql is right to echo (echo $sql) it and copy/paste in your sql prompt. don't trust phpmyadmin 'create php PHP code' functionality.
keep in mind 'Prepared stmts don't support LOAD DATA'

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).

You must use the root user of MySQL
If it still fails to run, use this code to check the error output
var_dump(mysqli_error($conn));

Related

PHP won't interface with MySQL in Apache on Raspberry Pi

I installed MySql on my Raspberry Pi 2 Model B+ a few days ago to see if I could use it, PHP, phpmyadmin, and Apache to make an accessible database to organize and catalog books that are around the house. I have a table in a MySQL database set up as a prototype with three columns; Booknumber (set to auto-increment), title, and authorLastName. I'm trying to use a form to insert books into table beta, in database bookProof.
Here's the code for the form:
<html>
<body>
<form action="catalog.php" method="POST">
<p>Book Title: <input type="text" name="title"></p>
<p>Author's Last Name: <input type="text name="authorlastname"></p>
</form>
</body>
</html>
Which links to "catalog.php", which is:
<?php
define('DB_NAME', 'bookProof');
define('DB_USER', 'root');
define('DB_PASSWORD', 'root');
define('DB_HOST', 'localhost');
$conn = new mysqli(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME);
if ($conn->connect_error) {
die("Could not connect: " . $conn->connect_error);
}
$value = $_POST["title"]
$value2 = $_POST["authorlastname"]
$sql = "INSERT INTO beta ('title', 'authorLastName') VALUES ('".$value."', '".$value2."')"
$query = mysqli_query($conn,$sql);
if ($conn->($sql) === TRUE) {
echo "New entry completed successfully";
} else {
echo "Error: " . $sql . "<br>" . $conn->error;
}
$conn->close();
?>
When demoform.php is opened, it functions normally, but when the "Add Books" button is clicked, it goes to catalog.php as intended, but the catalog.php page is blank, the table is unchanged, and Google Chrome's "Inspect" tool gives the error:
POST http://192.168.254.11/Library/catalog.php 500 (Internal Server Error) catalog.php:1
If anyone knows how to get the input to the database, please let me know.
Note: This is just a home system, so security is not a priority (I don't need SQL code injection protection).
Your note, "...security is not a priority (I don't need SQL code injection protection)" - you might think that, but you should do it anyways. Not only does it protect your database should your system be exposed (or made public at a later time), it will handle strings automatically for you, so that your query won't break if your strings have quotes ' in them.
One issue is that you're using singlequotes around column and table names. This should be backticks, or none at all. Then you were missing a semicolon ; after defining your $value, $value2 and $sql strings.
Then you're doing something a bit odd - which is also causing a parse-error (Had you enabled error-reporting and checked your logs, you'd see a "Parse error: syntax error, unexpected (" error in your logs), you're querying the table with mysqli_query(), but then you try to do it again - except you're trying to query on the querystring, and not the query method. Note the comments I've added in the code below.
// Don't use singlequotes ' for columns and table-names
// Use backticks ` - quotes are for strings
$sql = "INSERT INTO beta (`title`, `authorLastName`) VALUES ('".$value."', '".$value2."')"; // You were also missing a semicolon here!
// $query = mysqli_query($conn,$sql); // Remove this line, as you're attempting to query it twice
if ($conn->query($sql) === TRUE) { // You're missing the query() method here
echo "New entry completed successfully";
} else {
echo "Error: " . $sql . "<br>" . $conn->error;
}
Using prepared statements won't be that much of a difference, and you really should do it. There's absolutely no reason to not use prepared statements! Look how little changes that have to be made!
$sql = "INSERT INTO beta (title, authorLastName) VALUES (?, ?)";
if ($stmt = $conn->prepare($sql)) {
$stmt->bind_param("ss", $value, $value2);
$stmt->execute();
$stmt->close();
} else {
echo "Error: " . $sql . "<br>" . $conn->error;
}
You've also got some invalid HTML which would cause issues - the following line had a missing quote to close off the type attribute.
<input type="text" name="authorlastname">
I suggest you read the following documentation and articles
When to use single quotes, double quotes, and backticks in MySQL
How can I prevent SQL injection in PHP?
PHP manual on mysqli_stmt::bind_param
How to get useful error messages in PHP?
PHP Parse/Syntax Errors; and How to solve them?
As a final note, you should check that the form was submitted and that it has values before inserting into the database. Also, using variable-names like $value and $value2 are not really descriptive - you should avoid it and use proper names for your variables.

Query not executing. No errors

$query = "SELECT `ip` FROM `banned` WHERE `ip` = '$ip'";
$retval = mysqli_query($conn, $query);
if(!$retval){
die("Could not Execute Query: " . mysqli_error($conn));
} else {
if(mysqli_num_rows($retval) == 0){
echo "test";
} else {
header('Location: http://www.teutonic-development.net/index.php?p=banned');
}
}
when I'm running this code all that's printed out is: "Could not Execute Query:"
I really have absolutely no idea why it's doing this. I'm connecting fine in my init.php file. Which is where this file is.
My other script which just adds a log entry works fine. And if I run my $query in phpmyadmin's sql interpreter it runs perfectly fine (when I replace the $ip part with an actual ip of course)
Any suggestions?
Normally one would say that hey your query failed to execute story finish. But this case is interesting.
Your code is
die("Could not Execute Query: " . mysqli_error($conn));
and your error message is
Could not Execute Query:
Notice even though you have mysqli_error($conn) but there is no mysql error being shown. That confirms 100% that $conn is not properly established (contrary to what you think)
So take a look at your code again and see if $conn is really a mysqli resource and is available to your file in proper variable scope.

Need to upload stats data from a csv file to sql database automatically every day?

Ok so im trying to use phpjobscheduler to update stats every day, It runs a command every day to open the php page and updates the db.
I have Googled and this is the code I managed so far:
<?php
$mysqli = new mysqli('localhost','xxxxx','xxxxx','xxxxx');
/* check connection */
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
$query = "LOAD DATA LOCAL INFILE 'xxxxx.CSV' REPLACE INTO TABLE `Stats_Day` FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' LINES TERMINATED BY '\n' IGNORE 1 LINES (#txdate, department, code, descript, QTY, Total) SET txdate = STR_TO_DATE(#txdate, '%Y/%m/%d')";
$res = $mysqli->query($query);
if ($mysqli->error) {
try {
throw new Exception("MySQL error $mysqli->error <br> Query:<br> $query", $msqli->errno);
} catch(Exception $e ) {
echo "Error No: ".$e->getCode(). " - ". $e->getMessage() . "<br >";
echo nl2br($e->getTraceAsString());
}
}
mysqli_close($con);
?>
This however is not working it gives me a blank page,
and nothing is updated on the SQL-database?
it connects to the db
(enter wrong details it shows incorrect user details)
but is not updating the db ? and shows no errors?
Please assist?
all I need to do is to update the db with the data from the .csv file every day at 1am.
You need to escape the double quote at ENCLOSED BY part. Without that, you terminated your string.
$query = "LOAD DATA LOCAL INFILE 'xxxxx.CSV' REPLACE INTO TABLE `Stats_Day` FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '\"' LINES TERMINATED BY '\n' IGNORE 1 LINES (#txdate, department, code, descript, QTY, Total) SET txdate = STR_TO_DATE(#txdate, '%Y/%m/%d')";
Note
Use error_reporting(E_ALL), and ini_set('display_errors', 1); to cactch your errors while developing.

mysql load data infile through php script - not working

I am trying to use the mysql LOAD DATA LOCAL INFILE to get some csv data into my mysql database through a php script using mysqli. This is what my sql string looks like:
LOAD DATA LOCAL INFILE '/var/www/html/dashmaker/uploads/HHdata.csv' INTO TABLE dashmaker.HHdata FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '\"' LINES TERMINATED BY '\n' IGNORE 1 LINES;
This is what my php script looks like:
$sql = "LOAD DATA LOCAL INFILE '/var/www/html/dashmaker/uploads/HHdata.csv'
INTO TABLE dashmaker.HHdata
FIELDS TERMINATED BY ','
OPTIONALLY ENCLOSED BY '\"'
LINES TERMINATED BY '\n'
IGNORE 1 LINES;";
$con=mysqli_connect("localhost","[user]","[password]","[database]");
// Check connection
if (mysqli_connect_errno()) {
echo "Failed to connect to MySQL: " . mysqli_connect_error();
};
$result = mysqli_query($sql, $con);
if (mysql_affected_rows() == 1) {
$message = "The data was successfully added!";
} else {
$message = "The user update failed: ";
$message .= mysql_error();
};
echo $message;
mysqli_close($con);
I found that I needed to set the mysql my.cnf to include local-infile under [mysql] and [mysqld] - so I have done that.
When I run the sql query through the shell it works. When I try to do it through the php script the error message ($message) I now get says:
The user update failed: Access denied for user ''#'localhost' (using password: NO)
One weird thing is that it doesn't show any user name before the #'localhost'. Can't understand why. Besides this, I use the same connection setting to run regular SELECT queries from the database using php scripts. The user also has FILE privileges.
I have searched extensively but haven't found anything that can explain what's going on. Any advice would be much appreciated.
You're mixing MySQL APIs with mysql_ and mysqli_ functions in a few instances.
mysql_affected_rows()
mysql_error()
They do not mix together; use mysqli_ exclusively.
Plus, you're not using brackets in [user] etc, are you? That is MSSQL syntax, remove them.
Plus, in mysqli_, DB connection comes first, invert these $result = mysqli_query($sql, $con); to read as $result = mysqli_query($con, $sql);
$sql = "LOAD DATA LOCAL INFILE '/var/www/html/dashmaker/uploads/HHdata.csv'
INTO TABLE dashmaker.HHdata
FIELDS TERMINATED BY ','
OPTIONALLY ENCLOSED BY '\"'
LINES TERMINATED BY '\n'
IGNORE 1 LINES;";
$con=mysqli_connect("localhost","user","password","database");
// Check connection
if (mysqli_connect_errno()) {
echo "Failed to connect to MySQL: " . mysqli_connect_error();
};
$result = mysqli_query($con, $sql);
if (mysqli_affected_rows($con) == 1) {
$message = "The data was successfully added!";
} else {
$message = "The user update failed: ";
$message .= mysqli_error($con);
};
echo $message;
mysqli_close($con);

import glob text file from php to mysql

My glob code finds the file and attempts to insert it into the table but fails. I couldn't find anyone that is asking the same question. I will have many files that need to be inserted into the same table. It is a coma delimited text file.
Updated code*
The following code works as long as I rem the load data line. When I use the load data command manually, it works. I have not found a post example that has solved the problem "Why does the load data command not work?"
$con = new mysqli('localhost', 'username', 'password', 'schaadan_hash');
if (mysqli_connect_errno($con))
{
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
else
{
echo "Connected. ";
echo "<br />";
}
$upload = "LOAD DATA LOCAL INFILE 'ntlmhash2_1.txt' INTO TABLE ntlm2 FIELDS TERMINATED BY ',' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n'(`clear` , `hash`);";
mysqli_query($con,$upload);
?>

Categories