Prepared statements in SQL query while saving JSON data in PHP - mysql

I have simple php code for parsing some data from a JSON file and saving them into mysql database. But it's showing following error:
Parse error: syntax error, unexpected 'my_name' (T_STRING) in C:\xampp\htdocs\mycode.php on line 25
My php code is following:
$sql = "INSERT INTO table1 (my_name, hobby, other) VALUES ($row['my_name'], $row['hobby'], $row['other'])"; //line 25
mysqli_query ($conn, $sql);
Why is it showing syntax error? Is there anything wrong in the query?

You need to enclose interpolated placeholders in curly braces, i.e. $row['my_name'] -> {$row['my_name']}:
$sql = "INSERT INTO table1 (my_name, hobby, other) VALUES ({$row['my_name']}, {$row['hobby']}, {$row['other']})";
This addresses only PHP syntax.
The SQL syntax error you get now is the next issue.
The simplest thing to "fix" this would be to include additional apostrophes around placeholders, i.e.
$sql = "INSERT INTO table1 (my_name, hobby, other) VALUES ('{$row['my_name']}', '{$row['hobby']}', '{$row['other']}')";
BUT DON'T DO THAT, since this code is an example of a classic SQL Injection vulnerability.
Consider using a prepared statement instead — this eliminates the PHP's string interpolation altogether.

Related

Multiple Rows INSERT in MySQL

I'am trying to add multiple rows into DB using SQL and it goes wrong with a message
"You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ''imglist' ('urlImg', 'idProduct') VALUES('C//','1')('C//','1')('C//','1')('C//','1')' at line 1"
This is my code for this function
$sql = 'INSERT INTO \'imgList\' (\'urlImg\', \'idProduct\') VALUES';
for($i=0;$i<10;$i++){
$sql .= '(\'' . $_POST['urlImg'][$i] . '\',\''
. $_POST['idProduct'][$i] .'\')';
if ($i<count($_POST['urlImg']) - 1) {
$sql .= ',';
}
}
Well, first of all, like others said, never concatenate values into SQL string directly. Not only it puts you at risk of SQL injection, but also will fail if you have single quotes in your data.
If query you built fails, then output it using echo and examine it. That error you're seeing is because you put single quotes (') around your table and column names, which is wrong. You should either use backticks (`) or don't use anything - quotes are only for literal strings.
$sql = 'INSERT INTO `imgList` (`urlImg`, `idProduct`) VALUES ';
There are other problems with your code, though. for($i=0;$i<10;$i++){ will loop 10 times even if you only have 1 element in $_POST['urlImg'], resulting in errors. And judging by VALUES('C//','1')('C//','1')('C//','1')('C//','1') in error, this part of code:
if ($i<count($_POST['urlImg']) - 1) {
$sql .= ',';
}
doesn't even work properly, since commas aren't even inserted between (...). No idea why, though, it worked fine when I tried it myself, perhaps you didn't show something.

How to pass VALUES in MySQL from structure members

I want to write the values of structure members into a MySQL table. The problem I have is that I wish to read the values of the structure and write the value to the specific column.
string assetNumber = EGMSimulatorObj.EGMConfigurationObj.AssetNumber.ToString();
string query = "INSERT INTO egmtable (Asset_Number) VALUES($assetNumber)";
With the above, I get the following error:
Unknown column '$assetNumber' in 'field list'.
How can I use set VALUES from the structure members or from any local variable?
You need to replace
string query = "INSERT INTO egmtable (Asset_Number) VALUES($assetNumber)";
with something like
string query = "INSERT INTO egmtable (Asset_Number) VALUES("+assetNumber+")";
That is, if you are using Java as programming language. Other languages may require other concatenation notation.
Side note: you should maybe use prepared statements for this, for two reasons: security and execution speed.
At present MySQL is seeing $assetNumber and so is believing it to be a column name. It has not been replaced with the value. You may wish instead to concatenate the variable into the string. I am uncertain which language you are using though.
PHP
$query = "INSERT INTO egmtable (Asset_Number) VALUES (".$assetNumber.")";
Coldfusion
qryString = "INSERT INTO egmtable (Asset_Number) VALUES ("&assetNumber&")";
Java
string query = "INSERT INTO egmtable (Asset_Number) VALUES("+assetNumber+")";
In all these cases though, this is vulnerable to SQL injection. You would instead be better served using similar to cfqueryparam (CF) / mysqli->bind (PHP) to allow the language to ensure the value is properly escaped and so ensure your query is safe. So going down the java route and using passing parameters to a JDBC PreparedStatement as a starting point
query = con.prepareStatement("INSERT INTO egmtable (Asset_Number) VALUES( ? )");
query.setString(1, assetNumber);
If you are able to specify the language you are using then I can provide a more specific answer.

problem in where clause of mysql query

Hi
I am generating messahedigest with SHA1 of a file(having extension .eml, as it contains email info)and then storing it to the table named web_de in column messagedigest. Why can't I execute following query in mysql ?? and also not in java...
SELECT slno FROM `webcrawler`.`web_de`
where messagedigest='?Ê'?`®o1F±[øT¤?¿!€' ;
while I could execute query like
SELECT slno FROM `webcrawler`.`web_de`
where messagedigest= ')#Ä€ó…ªã³§°óÚdv~θ`';
Pl note that I am trying to execute that query in mysql workbench 5.2.32 and using mysql 5.1
Can anybody help me out here please ???
Thanks in advance
You have to escape that single quote in the first query:
where messagedigest = '?Ê''?`®o1F±[øT¤?¿!€' ;
Escaping is done by duplicating quotes:
''
(btw: as you see, even the stackoverflow syntax highlighter wasn't able to properly format your string...)
On the other hand, you shouldn't inline values in SQL for various reasons (security, performance). Since you're using Java, use a PreparedStatement instead:
// Prepare a statement with a bind variable : ?
PreparedStatement ps = connection.prepareStatement(
"SELECT slno FROM webcrawler.web_de WHERE messagedigest = ?");
// Bind your string to the first bind variable
ps.setString(1, "?Ê'?`®o1F±[øT¤?¿!€");
// ...
ResultSet rs = ps.executeQuery();
The ' is not being escaped. Replace it with double quotes '' so it reads as:
SELECT slno FROM `webcrawler`.`web_de`
where messagedigest='?Ê''?`®o1F±[øT¤?¿!€';
EDIT: Too slow! :P
You can also escape it by using \' also
the messagedigest value has a quote in it. If you escape the quote it should work, but...
you might be better off encoding the message digest before trying to write it to the database.

Inserting data using PHP into mysql when it contains a '

I am writing lots of info from an XML file into a database.
Everything works fine until I come across a field with the ' in the description, that insertion fails with an error
Error
1064:You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server
version for the right syntax to use
near 'd like you to feel that way too.
We'd love to have you visit us to view
over 100' at line 3
Is there a way to have this inserted without it failing? the import file could be large and change regularly so I cannot search and replace ' characters within it.
My actual PHP Statement is:
$query = mysql_query("REPLACE into list
(id, name, link, description, cost, date_added,type,myipaq,private,imgurl)
VALUES ('$id','$name','$link',"'$description'",'$cost','$date','$type','$myipaq','$private','$imgurl')");
thanks in advance,
Greg
This falls under the category of SQL injection.
In PHP a function: mysql_real_escape_string is used to encode a string so that none of it can affect the SQL statement it might be concatenated into.
so make sure all of your values go through the mysql_real_escape_string function and you will be fine.
API REF: http://php.net/manual/en/function.mysql-real-escape-string.php
Just pass your data through mysql_real_escape_string()
Use my handy dandy function:
function mysql_safe_string($value) {
if(is_numeric($value)) return $value;
elseif(empty($value)) return 'NULL';
elseif(is_string($value)) return '\''.mysql_real_escape_string($value).'\'';
elseif(is_array($value)) return implode(',',array_map('mysql_safe_string',$value));
}
function mysql_safe_query($format) {
$args = array_slice(func_get_args(),1);
$args = array_map('mysql_safe_string',$args);
$query = vsprintf($format,$args);
$result = mysql_query($query);
if($result === false) echo '<div class="mysql-error"><strong>Error: </strong>',mysql_error(),'<br/><strong>Query: </strong>',$query,'</div>';
return $result;
}
Like so:
mysql_safe_query('INSERT INTO table VALUES (%s, %s, %s)', $val1, $val2, $val3);
And forget about quoting or not quoting your strings, and writing out mysql_real_escape_string a dozen times.
The only really safe way of inserting or replacing or indeed interacting with anything on a database with PHP is to use prepared statements. There really is no excuse anymore for doing it any other way. Escaping strings using mysql_real_escape_string will give you some protection, but it is not bullet proof.
Prepared statements are not even hard. See the PHP manual page on them, and there are several wrappers to make life even easier, personally I like the codesense mysqli wrapper a lot and have been using it for a while with no problems - it's no harder than straight MySQL PHP code. EasyPDO looks promising too.
You should check out the related question "PHP: Is mysql_real_escape_string" sufficient for cleaning user input" for further details as to why you shouldn't be lazy.
Use: php.net/manual/en/function.addslashes.php
Addslashes prevent's just that!
And if you use that, just use
http://www.php.net/manual/en/function.stripslashes.php
to remove slashes from your string!

Why does my INSERT sometimes fail with "no such field"?

I've been using the following snippet in developements for years. Now all of a sudden I get a DB Error: no such field warning
$process = "process";
$create = $connection->query
(
"INSERT INTO summery (process) VALUES($process)"
);
if (DB::isError($create)) die($create->getMessage($create));
but it's fine if I use numerics
$process = "12345";
$create = $connection->query
(
"INSERT INTO summery (process) VALUES($process)"
);
if (DB::isError($create)) die($create->getMessage($create));
or write the value directly into the expression
$create = $connection->query
(
"INSERT INTO summery (process) VALUES('process')"
);
if (DB::isError($create)) die($create->getMessage($create));
I'm really confused ... any suggestions?
It's always better to use prepared queries and parameter placeholders. Like this in Perl DBI:
my $process=1234;
my $ins_process = $dbh->prepare("INSERT INTO summary (process) values(?)");
$ins_process->execute($process);
For best performance, prepare all your often-used queries right after opening the database connection. Many database engines will store them on the server during the session, much like small temporary stored procedures.
Its also very good for security. Writing the value into an insert string yourself means that you must write the correct escape code at each SQL statement. Using a prepare and execute style means that only one place (execute) needs to know about escaping, if escaping is even necessary.
Ditto what Zan Lynx said about placeholders. But you may still be wondering why your code failed.
It appears that you forgot a crucial detail from the previous code that worked for you for years: quotes.
This (tested) code works fine:
my $thing = 'abcde';
my $sth = $dbh->prepare("INSERT INTO table1 (id,field1)
VALUES (3,'$thing')");
$sth->execute;
But this next code (lacking the quotation marks in the VALUES field just as your first example does) produces the error you report because VALUES (3,$thing) resolves to VALUES (3,abcde) causing your SQL server to look for a field called abcde and there is no field by that name.
my $thing = 'abcde';
my $sth = $dbh->prepare("INSERT INTO table1 (id,field1)
VALUES (3,$thing)");
$sth->execute;
All of this assumes that your first example is not a direct quote of code that failed as you describe and therefore not what you intended. It resolves to:
"INSERT INTO summery (process) VALUES(process)"
which, as mentioned above causes your SQL server to read the item in the VALUES set as another field name. As given, this actually runs on MySQL without complaint and will fill the field called 'process' with NULL because that's what the field called 'process' contained when MySQL looked there for a value as it created the new record.
I do use this style for quick throw-away hacks involving known, secure data (e.g. a value supplied within the program itself). But for anything involving data that comes from outside the program or that might possibly contain other than [0-9a-zA-Z] it will save you grief to use placeholders.