I am trying to store some form data to a SQL database using the following query:
$sql = "INSERT INTO attendees (first_name, surname, partner, phone) VALUES ($first_name, $surname, $partner, $phone)";
It works perfectly if I hard code the values to test it, but when using these variables, it breaks and gives me Error 1054
$first_name = $_POST['first_name'];
$surname = $_POST['surname'];
$partner = $_POST['partner'];
$phone = $_POST['phone'];
Could anyone help?
$sql = "INSERT INTO attendees (first_name, surname, partner, phone) VALUES ($first_name, $surname, $partner, $phone)";
should be
$sql = "INSERT INTO attendees (first_name, surname, partner, phone) VALUES ('$first_name', '$surname', '$partner', '$phone')";
you are missing quotes around field content.
Warning: your code is vulnerable to SQL injection attacks
try to use PHP Prepared statement and wiki page http://en.wikipedia.org/wiki/Prepared_statement . Or at-least use mysqli_real_escape_string
Err 1054 means that you are using a column name that doesn't exist.
In this case, as there doesn't seem to be anything wrong with your insert statement (assuming that all the variables have data in them) it means you have likely typo'ed a column name.
On second thoughts, you probably need single quotes around the strings, but the first part of my answer still stands.
First of all, stop using mysql_ functions and look for PDO and prepared statements: if you'll do as suggested, this problem will sort by itself.
Anyway, the problem is that the query will replace the values with the strings contained in your $_POST array... but without string delimiters.
This means that mysql will look at them as column names, and spaces will break them!
solution:
$sql = "INSERT INTO attendees (first_name, surname, partner, phone) VALUES ('$first_name', '$surname', '$partner', '$phone')";
NOTICE that this will leave you wide open to SQL injection attacks!
with PDO it'll look something similar to this:
$stmt = $db->prepare("INSERT INTO attendees (first_name, surname, partner, phone) VALUES (:fname, :sname, :partn, :phone)");
$stmt->execute(array(':fname' => $first_name, ':sname' => $surname_name, [the others]))
which will is much more secure and plainly better all around.
Please escape and verify your inputs, otherwise you'll be vulnerable to SQL injections.
Here's a list of good solutions on how to do that: http://bobby-tables.com/php.html
Basically try to use prepared statements if possible, otherwise use mysql_real_escape_string()
Related
I'm new here. I started PHP recently and I am wondering how I could insert variables, and put them into single quotes, into a double quotes string.
Here's what I tried :
$query = "INSERT INTO Table (Name, Activity) VALUES ('$name', '$activity');";
But when I check $query, it contains that : INSERT INTO Table (Name, Activity) VALUES (,);. I don't understand why it does that because when, instead of writing the above code, I write this one : $query = "INSERT INTO Table (Name, Activity) VALUES ($name, $activity);"; (without the single quotes), the string contains this : INSERT INTO Table (Name, Activity) VALUES (Robert, Book-seller);. Does anybody have a clue ?
how I could insert variables, and put them into single quotes, into a double quotes string.
Don't do that. It leaves you vulnerable to SQL injection attacks. Instead use prepared statements with bound parameters as described in this post.
I tried your statement:
$query = "INSERT INTO Table (Name, Activity) VALUES ('$name', '$activity');";
And It worked perfectly with me. I guess you need to check the values you passing in $name and $activity. (for Robert, Book-Seller its working nicely).
Still You may try this. It might help:
$query = "INSERT INTO Table (Name, Activity) VALUES (\"$name\", \"$activity\");";
And a note for caution: as Alex Howansky says, don't do that. it leaves you vulnerable to SQL injection attacks.
Hope it helps. All the best!
Im trying to remove xss scripting from my php forum i made. To do so i tried the strip_tags funciton. However when i tried it out. The tags still got posted and the xss scripting is not fixed . This is the code i tried . Whats wrong with it?
// get data that sent from form
$topic=$_POST['topic'];
$detail=$_POST['detail'];
$name=$_POST['name'];
$email=$_POST['email'];
$topic = strip_tags($topic);
$detail = strip_tags($detail);
$name = strip_tags($name);
$email = strip_tags($email);
$datetime=date("d/m/y h:i:s"); //create date time
$sql="INSERT INTO $tbl_name(topic, detail, name, email, datetime)VALUES('$topic', '$detail', '$name', '$email', '$datetime')";
$stmt = $dbh->prepare($sql);
$stmt->execute();
Edit: It seems I did not grasp the question, my mistake.
Use htmlspecialchars() for the inputs in your HTML form, rather than strip_tags() during/before the query and prepared statements; see my original answer for related links near the bottom.
Sidenote: Doing $stmt = $dbh->prepare($sql); with the word "prepare", doesn't qualify as a prepared statement. You need to use the full and proper syntax.
I.e.:
<input name="var" value="<?php echo htmlspecialchars($var)?>">
There are also a few articles you can read on the subject:
XSS Cross Site Scripting Prevention Cheat Sheet
https://www.owasp.org/index.php/PHP_Security_Cheat_Sheet
Original answer:
There are a few issues happening here.
Firstly, datetime and name are MySQL reserved words and you're not giving them special treatment.
wrap those column names in ticks
(topic, detail, `name`, email, `datetime`)
checking for errors would have signaled the syntax error(s).
MySQLi error checking: http://php.net/manual/en/mysqli.error.php
PDO error checking: http://php.net/manual/en/pdo.error-handling.php
It's unclear as to which MySQL API you're using to connect with, so use the appropriate error connection method.
What's also unclear is what $tbl_name is defined as.
If that table name contains spaces, or hyphens, or anything that MySQL will complain about, then wrap that variable in ticks also.
I.e.:
INSERT INTO `$tbl_name` (topic, detail, `name`, email, `datetime`)
If your date column is DATETIME, then MySQL stores those as YYYY-MM-DD HH:MM:SS so date("d/m/y h:i:s") will fail.
Ref: https://dev.mysql.com/doc/refman/5.0/en/datetime.html
Add error reporting to the top of your file(s) which will help find errors.
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
// rest of your code
Sidenote: Displaying errors should only be done in staging, and never production.
Using prepared statements
Help prevent injection by consulting:
How can I prevent SQL-injection in PHP? on Stack.
Use prepared statements, or PDO with prepared statements, they're much safer.
Sidenote: strip_tags() doesn't do anything to help prevent SQL injection.
Also make sure that your form does use a POST method and that your inputs bear the name attributes for them and not typos.
you should prevent sql-injection in this way:
replace
$topic = strip_tags($topic);
$detail = strip_tags($detail);
$name = strip_tags($name);
$email = strip_tags($email);
$datetime=date("d/m/y h:i:s"); //create date time
$sql="INSERT INTO $tbl_name(topic, detail, name, email, datetime)VALUES('$topic', '$detail', '$name', '$email', '$datetime')";
$stmt = $dbh->prepare($sql);
$stmt->execute();
with
$datetime=date("d/m/y h:i:s"); //create date time
$sql="INSERT INTO $tbl_name(`topic`, `detail`, `name`, `email`, `datetime`)VALUES(?, ?, ?, ?, ?)";
$stmt = $dbh->prepare($sql);
$stmt->execute([$topic, $detail, $name, $email, $datetime]);
and about xss-prevention you shoud use htmlspecialchars when OUTPUT text-fields TO BROWSER, somthing like:
NOT echo $topic; BUT echo htmlspecialchars($topic);
I'm getting the error: Column count doesn't match value count at row 1
I think, normally this error occurs if the count of the columns and the values aren't equal, but in my code they are...(3).
This is my php code:
$tempsongtitel = $_POST['songtitle'];
$tempinterpret = $_POST['interpret'];
$templink = $_POST['link'];
$query = mysql_query("insert into tMusic (Songtitel, Interpret, Link) values ('$tempsongtitel, $tempinterpret, $templink')") or die(mysql_error());
You missed some quotes. Should be:
$query = mysql_query("insert into tMusic (Songtitel, Interpret, Link) values ('$tempsongtitel', '$tempinterpret', '$templink')") or die(mysql_error());
Otherwise, you were trying to insert all three POST values into the first field.
Moreover, the mysql_ extension has been deprecated and is on the way out and is highly discouraged, especially if you are creating new software.
AND I'll presume you are first sanitizing your data? You're not really taking user input and placing it directly into the database, are you? Even if you don't do any data validation, you should escape your data in the query... easiest and most foolproof way to do that is by using parameterized queries.
The root cause is that your values are all in one set of quotes instead of quoted individually. I think this is a pretty common error, and in my experience it is an easy mistake to make, but not immediately obvious when scanning over your code. You can fix it like this (quick fix, still using deprecated mysql, but with post values escaped):
$tempsongtitel = mysql_escape_string($_POST['songtitle']);
$tempinterpret = mysql_escape_string($_POST['interpret']);
$templink = mysql_escape_string($_POST['link']);
$query = mysql_query("insert into tMusic (Songtitel, Interpret, Link)
values ('$tempsongtitel', '$tempinterpret', '$templink')") or die(mysql_error());
If you can, it would be much better to update your code to use PDO. You could use a prepared statement like this:
$stmt = $pdo->prepare("INSERT INTO tMusic (Songtitel, Interpret, Link) VALUES (?, ?, ?)");
$stmt->bindValue(1, $tempsongtitel);
$stmt->bindValue(2, $tempinterpret);
$stmt->bindValue(3, $templink);
$stmt->execute();
Among the many benefits of using this database extension rather than the old mysql functions it should not be possible to make an error like this in your code. In the prepared statement, there are no quotes around the parameter markers, so if you have VALUES ('?, ?, ?'), or even VALUES ('?', '?', '?') You would get bind errors when trying to bind the values, and the problem would become apparent pretty quickly.
I've found that, even though it's not 100% necessary and it's more time consuming, properly quoting and backticking EVERYTHING helps prevent this from happening.
$myQuery = "INSERT INTO `tMusic` (
`Songtitel`,
`Interpret`,
`Link`
) VALUES (
'$tempsongtitel',
'$tempinterpret',
'$templink'
);";
$runQuery = mysqi_query($DBi, $myQuery) or die(mysqli_error($DBi));
The formatting you use is up to you but this helps me make sure I have a one to one relationship and that I've quoted everything.
Of course that's using mysqli_* in place of the deprecated mysql_* functions AND that's assuming you've set $tempsongtitel, $tempinterpret and $templink properly.
Can't believe there are no questions like this... Must be something really simple, but I spend 2 days trying to figure this one out.
I have a table and one of the coloumns has values in a JSON format. In PHP my syntax is like this (it's in a class function):
$sql = "INSERT INTO users.users (username, class, settings, email, password) VALUES ($this->username, $this->class, ".json_encode($this->settings).", $this->email, $this->hashpwd);";
$STH = $DBH->prepare($sql);
$STH->execute();
However this one of course breaks because JSON format contains commas and these commas are also separating the Insert values, so it breaks the query. And escape functions (like PDO->quote or mysqli_real_escape_string) don't escape commas either.
Error I am getting is of course:
...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
'"usersetting1":"value","usersetting2":"value"}, email#interwebz.net, 712985cc'...
So is there any way to do this or do I have to use some kind of alt syntax for the query?
Try this:
$sql = "INSERT INTO users.users (username, class, settings, email, password) VALUES (:username, :class, :json, :email, :password);";
$STH = $DBH->prepare($sql);
$STH->bindParam(':username', $this->username);
$STH->bindParam(':class', $this->class);
$STH->bindParam(':json', json_encode($this->settings));
$STH->bindParam(':email', $this->email);
$STH->bindParam(':password', $this->hashpwd);
$STH->execute();
I have an PHP registration script with MySQLi and OOP.
But i get an mysql syntax error when executing an query.
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 '-mail, ip_register, ip_lastlogin, lastlogin) VALUES ('', Aarivex, ******, ****' at line 1
PHP Code:
$register_sql = "INSERT INTO users (id, username, password, pin, e-mail, ip_register, ip_lastlogin, lastlogin) VALUES ('', $username, $password, $pin, $email, $ip, $ip, $lastlogin)";
Wheres the problem?
...for the right syntax to use near '-mail
SQL's telling you where error starts ^ the offending character
You need to wrap/encapsulate the e-mail column in backticks since it contains a hyphen.
SQL figures you want to do math which translates to: e minus mail
Plus, missing quotes in your values
$register_sql = "INSERT INTO users (id, username, password, pin, `e-mail`, ip_register, ip_lastlogin, lastlogin) VALUES ('', '$username', '$password', '$pin', '$email', '$ip', '$ip', '$lastlogin')";
Those are strings and must be inside quotes.
Another option would be to rename your column to e_mail using an underscore as you did for some of the other columns. That way, you would not need to use backticks.
Look into using one of the following also:
Prepared statements
PDO with prepared statements.
Having used or die(mysqli_error($con)) to mysqli_query() would have signaled the error(s).
$con being your DB connection, this could/stand to be different than yours.
Adjust accordingly.
Identifiers (table/columns)
More on this topic: http://dev.mysql.com/doc/refman/5.0/en/identifier-qualifiers.html
Tip:
Try and avoid using hyphens, or spaces or any other character that SQL may complain about, this includes using a space in between words.
I.e.:
INSERT INTO your_table (column 1, column-2) <= will cause/throw an error
you would need to use backticks:
INSERT INTO your_table (`column 1`, `column-2`) <= correct / valid
Although spaces are allowed (yet discouraged), they too need to be encapsulated in backticks.
If you're going to have a dash in a column identifier (which is a bad idea) you must wrap it in ticks. Otherwise you are subtracting the value of the mail column from the e column which not not valid in an INSERT statement.
You're also missing quotes around your string values.
$register_sql = "INSERT INTO users (id, username, password, pin, `e-mail`, ip_register, ip_lastlogin, lastlogin) VALUES ('', '$username', '$password', '$pin', '$email', '$ip', '$ip', '$lastlogin')";
Try changing e-mail fieldname to email OR you need to encompass your that field name with back quotes like this:
`e-mail`
I suppose your id is set to Auto Increment.
If it is just remove the first column from the insert statement and it should work fine.
$register_sql = "INSERT INTO users (username, password, pin, e-mail, ip_register, ip_lastlogin, lastlogin) VALUES ($username, $password, $pin, $email, $ip, $ip, $lastlogin)";
And yes, change the e-mail field to `e-mail`.