I'm getting the following error :
2016-04-26 15:11:56 --- DEBUG: Error ocurred where inserting user data to the legacy db :Database_Exception [ 0 ]: [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 ')' at line 1 ~ APPPATH/classes/database/mysqli.php [ 179 ]
For the php query :
$result = $usdb->query(Database::INSERT, "INSERT INTO users (id, `password`, group_id , active, created, updated) VALUES ({$user['id']}, {$user['password']}, {$user['group_id']}, {$user['active']}, {$user['created']}, {$user['updated']})");
Here are the column types :
id : int AI PK
password : varchar
group_id : int
active : tinyint
created : int
updated : int
You need to have single quotes ' around your values in your SQL query, assuming they're strings (not integers) in the database.
Columns and table references can be encapsulated with backticks, though they don't have to, assuming they're not using a reserved keyword. Values, on the other hand, generally need single quotes around them (unless, of course, you're preparing your values through prepared statements; or if you're certain the database schema uses the integer type).
Putting single quotes around integers works just as well, so it's probably safe just to surround any value with a single quote, like so:
$result = $usdb->query(
Database::INSERT,
"INSERT INTO users (id, `password`, group_id , active, created, updated)
VALUES (
'{$user['id']}',
'{$user['password']}',
'{$user['group_id']}',
'{$user['active']}',
'{$user['created']}',
'{$user['updated']}'
)
"
);
Note:
You should ALWAYS be using parameterized queries (prepared statements). It is extremely unsafe to inject raw PHP variables into a SQL query. If you have a variable with a single quote, it will break the logic of your SQL statement.
You can read more about prepared statements in the PHP manual.
So what your SQL should really look like is this:
$sql = "
INSERT INTO users (id, `password`, group_id , active, created, updated)
VALUES (
:id,
:password,
:group_id,
:active,
:created,
:updated
)
";
And then bind your actual values into the prepared statement.
Since the password column is of type VARCHAR the value $user['password'] should be encapsulated in single quotes. And since the rest of the columns are of type INT or TINYINT single quotes aren't necessary.
So your query should be like this:
$result = $usdb->query(Database::INSERT, "INSERT INTO users (`id`, `password`, `group_id` , `active`, `created`, `updated`)
VALUES (" . $user['id'] . ", '"
. $user['password'] . "', "
. $user['group_id'] . ", "
. $user['active'] . ", "
. $user['created'] . ", "
. $user['updated']
. ")");
You should use backticks (`) for table and column names, single quotes (') for strings. Backticks are only needed when your table name or column name is a MySQL reserved word, but it's a best practice to avoid reserved words.
Sidenote: Use PDO prepare to prevent your database from any kind of SQL Injection.
From the PDO::prepare
Calling PDO::prepare() and PDOStatement::execute() for statements that will be issued multiple times with different parameter values optimizes the performance of your application by allowing the driver to negotiate client and/or server side caching of the query plan and meta information, and helps to prevent SQL injection attacks by eliminating the need to manually quote the parameters.
Related
Hello i'm a beginner so please at least try to give me a hint,a example.
English isn't my main language so please endure it.
If somebody type " Hello my name is J'hon ' the text don't insert in database, but if he type 'Hello my name is jhon' it does. I think it is something about '
Ok so i'm having the problem that if someone types
'Hello my name is J[color=#FF0000]'[/color]hon J'onz. ' is not inserted in the database..
This is the script:
mysqli_query($DB_H, "INSERT INTO tickets (name, continutscurt, continut,type,status) VALUES ('".$_SESSION['username']."', '".$_POST['titlu']."', '".$_POST['continut']."', $numar, 0)");
You should really use prepared statements when dealing with any kind of user-input. If you for any weird reason isn't using prepared statements, take a look at the function mysqli::real_escape_string. This will deal with special characters, such as ', which may break the SQL.
With using prepared statements, your code would look like
if ($stmt = $DB_H->prepare("INSERT INTO tickets (`name`, continutscurt, continut, `type`, `status`) VALUES (?, ?, ?, ?, ?)")) {
$stmt->bind_param("ssssi", $_SESSION['username'], $_POST['titlu'], $_POST['continut'], $numar, 0);
$stmt->execute();
$stmt->close();
} else {
echo mysqli_error($DB_H);
}
If you however want to use mysqli::real_escape_string, you'll need to bind the SESSIONs and POSTs to a variable where in you insert instead, like this (you can also do it directly in the query, but this makes for cleaner code).
$username = mysqli_real_escape_string ($DB_H, $_SESSION['username']);
$titlu = mysqli_real_escape_string ($DB_H, $_POST['titlu']);
$continut = mysqli_real_escape_string ($DB_H, $_POST['continut']);
$numar = mysqli_real_escape_string ($DB_H, $numar);
if (!mysqli_query($DB_H, "INSERT INTO tickets (`name`, continutscurt, continut, `type`, `status`) VALUES ('$username', '$titlu', '$continut', '$numar', 0")) {
echo mysqli_error($DB_H);
}
I also put backticks ` around name, status and type, as these are keywords in SQL. This isn't strictly necessary, but it's good practice with words that are listed as either reserved words or keywords, more info on this list of keywords.
You shouldn't take for granted that your queries are successful, so I added an if-block around them. Errors shouldn't be displayed unless in production/development.
References:
http://php.net/manual/en/mysqli.real-escape-string.php
http://php.net/manual/en/mysqli.prepare.php
How can I prevent SQL injection in PHP?
https://dev.mysql.com/doc/refman/5.7/en/keywords.html
The issue is SQL Injection.
You have potentially unsafe values being included within the SQL text.
To see this, break up the code a little bit.
$sql = "INSERT INTO tickets ...'" . $val . "' ... ";
echo $sql;
The echo is there just as a way to see what's going on, for you to examine the contents of the string containing the SQL text. And then take that string over to another client, and test it. And you will see what the the problem is.
... VALUES ( ..., 'J'onz. ', ...
isn't valid. That single quote is ending the string, so the string is just 'J', and the next part, MySQL is going to try to interpret as part of the SQL, not the string value. (This is a nefarious vulnerability. Cleverly constructed strings and wreak havoc on your application and your database.)
One approach to fixing that is to sanitize the values, so they can be safely included.
... VALUES ( ..., 'J\'onz. ', ...
^^
... VALUES ( ..., 'J''onz. ', ...
^^
As a simple demonstration try these queries:
SELECT 'J\'onz. '
SELECT 'J''onz. '
SELECT 'J'onz. '
(The first two will return the string you expect, and the third will cause an error.)
The take away is that potentially unsafe values that are going to included in the text of a SQL statement need to be properly escaped. Fortunately, the MySQL client library includes mysqli_real_escape_string function. Variables that may potentially contain a single quote character can be run through that function, and the return from the function can be included in the SQL text.
$sql = "INSERT INTO tickets ...'"
. mysqli_real_escape_string($DB_H,$val)
. "' ... ";
Again, echo out the $sql and you can see that a single quote has been escaped, either by preceding it with a backslash character, or replacing it with two sinqle quotes.
There's a much better pattern than "escaping" strings. And that's to use prepared statements with bind placeholders.
The SQL text can be a static string:
$sql = 'INSERT INTO mytable (mycol) VALUES ( ? )'
And then you msyqli_prepare the statement.
And then supply values for the placeholders with a call to mysqli_bind_param.
And then call mysqli_execute.
With this pattern, we don't need to mess with running the "escape string" function to sanitize the inputs.
Getting really confused surrounding this INSERT INTO. It should insert three fields into the table, userID, activateKey and isActivated.
The activateKey is a 25 letter randomly generated key such as 63n20kw24ba1mlox34e8n2awv
The userID comes from another table and is set by auto_increment.
The isActivated is always 0 at this stage.
It seems like quite a simple INSERT statement
if (!mysqli_query($con,"INSERT INTO activations (userID,activationKey,isActivated) VALUES (".$userID.",".$activateKey.",'0')"))
{
echo("Error description: " . mysqli_error($con));
}
However it doesn't work when I include the $activateKey field. What it does is try to search the string variable $activateKey as a column name. The error I get is:
Error description: Unknown column '63n20kw24ba1mlox34e8n2awv' in 'field list'
Of course there is no such column as 63n20kw24ba1mlox34e8n2awv, this is the data I'm trying to insert, hence why it's in the VALUES section. Any ideas why it's trying to search this as the column name?
Edit to clarify: the var is activateKey, the column name is activationKey
I would put the query in a different variable to avoid confusion, and PHP automatically substitutes variable names in strings in double quotes.
Try this:
<?php
$query = "INSERT INTO activations (userID,activationKey,isActivated) VALUES($userID,'$activateKey','0')
if (!mysqli_query($con,$query)
{
echo("Error description: " . mysqli_error($con));
}
You are not surrounding the values with quotes, that's why they get interpreted as variable names.
Use single quotes, like this:
"INSERT INTO activations (userID,activationKey,isActivated) VALUES
('".$userID."','".$activateKey."','0')"
However, be aware that stringing together query strings exposes you to SQL injection attacks, if that's a concern in your code you should use parameterized queries. In fact, using parameterized queries is always better.
Change your query to this:
"INSERT INTO activations
(userID,activationKey,isActivated)
VALUES ('$userID','$activateKey','0')"
You dont need to use the concatenation (.) operator as variables will be interpolated into the string.
The single quotes tell mysql to treat the variables as literals instead of column names.
As a side note you would be better to use parameterized queries. See How can I prevent SQL injection in PHP?
Solved!
It was a case of not properly wrapping the dynamic fields (the vars in the VALUES section) in ticks:
if (!mysqli_query($con,"INSERT INTO activations (userID,activationKey,isActivated) VALUES ('".$userID."','".$activateKey."','0')"))
Instead of
if (!mysqli_query($con,"INSERT INTO activations (userID,activationKey,isActivated) VALUES (".$userID.",".$activateKey.",'0')"))
Might be a difficult one to spot. The variables still need to be 'in ticks' or they won't register as strings.
As activationKey is a string column, you must use single quotes for $activationKey.
Try with:
if (!mysqli_query($con,"INSERT INTO activations (userID,activationKey,isActivated)
VALUES (".$userID.",'".$activateKey."','0')"))
Recently I'm getting an error message that I don't know how to deal with. It's very vague.
The PostgreSQL statement I use is:
$result = pg_query($ruledbconnection, "INSERT INTO INPUT(num, pkts, bytes ,
target,prot, opt, \"in\", out, source, destination, id)
VALUES('$num','$bytes','$pkts','$target', '$opt', '$protocol', '$in', '$out',
'$source', '$destination', '$id')");
All seems fine, right? However, when I execute this query with variables:
ERROR: syntax error at or near "'INPUT'" LINE 1: INSERT INTO 'INPUT'(num, pkts, bytes ,
target, prot, opt, "i... ^
I've been stuck on this for a while and it might be due escaping in PHP, or maybe something else?
The table that I want to manipulate is called INPUT in my database..
The SQL you showed doesn't match the error. The SQL doesn't have quotes around the table name, the error does.
ERROR: syntax error at or near "'INPUT'" LINE 1: INSERT INTO 'INPUT'(num, pkts, bytes ,
So. Single quotes (apostrophes, ') are for SQL values, not identifiers. Identifiers are quoted with double quotes ("). So you'd write:
INSERT INTO "INPUT" (...) VALUES (...)
Note that quoting the table name will preserve case. So if you double quote it here, you must double quote it everywhere you refer to it from. You will save your sanity if you instead just use lower case:
INSERT INTO input (...) VALUES (...)
and even better, a descriptive table name:
INSERT INTO packets_received (...) VALUES (...)
Your syntax error is the least of your problems, though. Let me introduce you to a classic:
Your query follows the pattern:
pg_query($conn, 'INSERT INTO sometable (col) VALUES ($user_input)')
and thus, is a classic example of an SQL injection vulnerability.
Read:
Bobby Tables
PHP manual on SQL injection
Solved by making sure that I escape the quotes around my table name.
"INSERT INTO INPUT (num, pkts, bytes , target, prot, opt, \"in\", out, source, destination, id)
Should be:
"INSERT INTO \"INPUT\" (num, pkts, bytes , target, prot, opt, \"in\", out, source, destination, id)
I am trying to use PHP variables in an INSERT SQL statement. Ive seen previous answers to this but can not get mine to work. Here is the code..
mysql_query("INSERT INTO message (message_id, from, content) values ('', " . $uid . ", 'test message content')");
The main problem is that from is a reserved word and should be in backticks.
mysql_query("INSERT INTO message (message_id, `from`, content) VALUES ...");
But I'd also advise you to stop using the deprecated mysql_* functions. I'd recommend that you take a look at PDO and prepared statements with parameters.
If message_id is primary key, you don't need to include it in the query unless you have a value..
mysql_query("INSERT INTO message (`from`, `content`) values (" . $uid . ", 'test message content')");
There are at least three issues in your query. Two of them are syntax errors and one is a huge vulnerability.
To make the query work, you should write it as follows:
mysql_query("INSERT INTO message (message_id, `from`, content) values ('', '" . $uid . "', 'test message content')");`
Here's a summary of the errors:
- As another user indicated, "from" is a keyword and you should not use it to name table columns. If you really want to use such name, you must use backticks to indicate it in the query.
- The value of $uid should be enclosed by single quotes.
- The third, and most important error, is that your query is vulnerable to SQL Injection. You should use prepared statements, which would protect you from such attacks.
I am simply trying to insert these objects into a table with php.
$sql = 'INSERT INTO table VALUES( '.$active.' , '.$id.' , '.$time.' , '.$url.' ,"some string" )';
The url in the above code is: http://www.youtube.com/watch?v=sAYc3gGjYW8
When I leave the url column empty it works, when I put an url in it then it doesnt work and I get the following error.
"Error: 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
'://www.youtube.com/watch?v=sAYc3gGjYW8 ,"some string" )'
at line 1."
QUESTION:
Why does the url not insert just like a normal string?
Is there some sort of function I need to perform on the url_string before it is accepted by MySQL?
PS - the url column is currently VARCHAR(256).
Any help appreciated guys...
You're not escaping your inputs. mysqli_real_escape_string() is your friend.
Remember all input is evil. Validate and sanitize, otherwise you're going to be subject to a whole host of nastiness, from data that's out of bounds (124 char long strings when the field is varchar(10), for example) to opening your code up to SQL injection exploits.
Example:
$safe_url = mysqli_real_escape_string($database_connection_object, $url);
Also, you might want to save yourself some keystrokes, change that string to a double quoted one and interpolate the variables - i.e. "blah blah $some_var foo foo" is the same as 'blah blah ' . $some_var . ' foo foo'
While I completely agree with the mysql_real_escape_string() comments, it looks like you forgot to wrap the URL in quotes just like any other string should be.
$sql = 'INSERT INTO table VALUES( '.$active.' , '.$id.' , '.$time.' , "'.$url.'" ,"some string" )';
You can tell by looking at the MySQL error:
://www.youtube.com/watch?v=sAYc3gGjYW8 ,"some string" )
There is no quote at the end of the URL :)
You need to escape your input. Have a look at mysql_real_escape_string or mysqli_real_escape_string. You might also want to look at a database abstraction layer like PDO.
Assuming you're using the mysql_* procedural functions, and after you've connected to the database, your script should look like this:
$sql = 'INSERT INTO table VALUES( '.$active.' , '.$id.' , '.$time.' , "'.mysql_real_escape_string($url).'" ,"some string" )';
I would also strongly recommend escaping the other values as well:
$sql = 'INSERT INTO table VALUES( "'.mysql_real_escape_string($active).'" , "'.mysql_real_escape_string($id).'" , "'.mysql_real_escape_string($time).'" , "'.mysql_real_escape_string($url).'" ,"some string" )';
unless they are SQL expressions or you have previously escaped them.
Make sure you've escaped all of the inputs into the DB using something like mysql_real_escape_string($string). It'll stop you being open to SQL injection attacks and make sure strings are being read correctly.
$id = $_GET['id'];$name = $_GET['name'];$lat = $_GET['lat'];$long = $_GET['long'];
$query = mysql_query("INSERT INTO dbname.tablename (id,name,lat,long) VALUES ('".$id."','".$name."','".$lat."','".$long."')");