Why is this giving me a syntax error? PHP PDO [duplicate] - php

This question already has answers here:
When to use single quotes, double quotes, and backticks in MySQL
(13 answers)
Closed 3 years ago.
I'm usually good at this, and while I was finishing my project; I ran into an error. PDO was giving me a syntax error, that I couldn't wrap my head around. Maybe I'm just tired, but this is driving me crazy.
This is what I'm using for my PHP code:
$records = $conn->prepare('INSERT INTO users (username, email, password, limit) VALUES (:username, :email, :password, :theLimit)');
$records->bindParam(':username', $_POST['username']);
$records->bindParam(':password', password_hash($_POST['password'], PASSWORD_BCRYPT));
$records->bindParam(':email', $_POST['email']);
$records->bindParam(':theLimit', $_GET['amt']);
My database is as follows:
CREATE TABLE `users` (
`id` int(11) UNSIGNED NOT NULL,
`username` varchar(250) NOT NULL DEFAULT '',
`email` varchar(250) NOT NULL DEFAULT '',
`password` varchar(200) NOT NULL DEFAULT '',
`limit` varchar(200) NOT NULL DEFAULT '',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
The error I get is this:
Array ( [0] => 42000 [1] => 1064 [2] => 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 'limit) VALUES ('F', 'some_person#email.com', '$2y$10$gacC/a8zA3jCbPpKNTddtu4dBG' at line 1 )
And finally, the URL looks like this:
https://website.com/reg.php?serial=306019525D31&amt=10
I have even tried:
$records->bindParam(':theLimit', $_POST['email']);
thinking it might've been the URL. Same error.
I redid the database, same error.
Any ideas?
Thank you!

LIMIT is a reserved MySQL keyword, so you should escape it:
$sql = "INSERT INTO users (username, email, password, `limit`) ";
$sql .= "VALUES (:username, :email, :password, :theLimit)";
$records = $conn->prepare($sql);
Actually, you should avoid naming your objects using LIMIT or any other reserved keyword. Otherwise, you will always have to escape them as done above.

Related

Why am I getting an SQL error when trying to insert a null?

Ok when trying to execute the following insert I'm getting an 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 '2, 3, 4, 5)' at line 1
$insertSQL = sprintf("INSERT INTO applicants (id_file, address_file, photo, transcript, essay1, essay2) VALUES (%s, %s, %s, %s, %s, %s)",
$passport_file,
$address_file,
$photo_file,
$transcript_file,
$essay1_file,
$essay2_file);
mysqli_select_db($STCi, $database_STC);
$Result1 = mysqli_query($STCi, $insertSQL) or die(mysql_error($STCi));
Those variables are being set using the following code
$_FILES['id_file']['error'] == UPLOAD_ERR_OK?$passport_file=filesDB('id_file'):$passport_file = NULL;
$_FILES['address_file']['error'] == UPLOAD_ERR_OK?$address_file = filesDB('address_file'):$address_file = NULL;
$_FILES['photo']['error'] == UPLOAD_ERR_OK?$photo_file = filesDB('photo'):$photo_file = NULL;
$_FILES['transcript']['error'] == UPLOAD_ERR_OK?$transcript_file = filesDB('transcript'):$transcript_file = NULL;
$_FILES['essay1']['error'] == UPLOAD_ERR_OK?$essay1_file = filesDB('essay1'):$essay1_file = NULL;
$_FILES['essay2']['error'] == UPLOAD_ERR_OK?$essay2_file = filesDB('essay2'):$essay2_file = NULL;
filesDB is my own function I'm running to rename the uploaded files and move them into the correct locations and any that are running through that are fine. The problem comes out with 'address_file' as it is an optional file and whenever nothing is uploaded for it I get the error.
So basically MySQL is throwing an error when I'm trying to insert NULL, or am I missing something obvious?
CREATE TABLE `applicants` (
`applicant_id` int(11) NOT NULL AUTO_INCREMENT,
`id_file` varchar(200) CHARACTER SET latin1 DEFAULT NULL,
`address_file` varchar(200) CHARACTER SET latin1 DEFAULT NULL,
`photo` varchar(200) CHARACTER SET latin1 DEFAULT NULL,
`name_change` varchar(200) CHARACTER SET latin1 DEFAULT NULL,
`transcript` varchar(200) CHARACTER SET latin1 DEFAULT NULL,
`english_result` varchar(200) CHARACTER SET latin1 DEFAULT NULL,
`essay1` varchar(200) CHARACTER SET latin1 DEFAULT NULL,
`essay2` varchar(200) CHARACTER SET latin1 DEFAULT NULL,
`stage` varchar(20) DEFAULT 'New',
`date_applied` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`applicant_id`)
) ENGINE=InnoDB AUTO_INCREMENT=27 DEFAULT CHARSET=utf8;
use a prepared stamement instead of manually creating a query with sprintf:
if ($stmt = mysqli_prepare($STCi, "INSERT INTO applicants
(id_file, address_file, photo, transcript, essay1, essay2)
VALUES (?, ?, ?, ?, ?, ?)"))
{
mysqli_stmt_bind_param($stmt, "ssssss",
$passport_file,
$address_file,
$photo_file,
$transcript_file,
$essay1_file,
$essay2_file);
mysqli_stmt_execute($stmt) or die(mysql_error($STCi));;
}
You're doing an sprintf, and inserting 'NULL', meaning you have a PHP varaible that is NULL.
Your SQL query should look like this after the sprintf:
INSERT INTO applicants (id_file, address_file, photo, transcript, essay1, essay2)
VALUES (null, 2,3,4,5,6)"
but it looks like this:
INSERT INTO applicants (id_file, address_file, photo, transcript, essay1, essay2)
VALUES ( , 2,3,4,5,6)"
And that's an error.
To fix this, you could actually insert the string null here (if you insert it without ', it will not be seen as a string, as you are not using prepared statements). So you query would look like so:
INSERT INTO applicants (id_file, address_file, photo, transcript, essay1, essay2)
VALUES ( null , 2,3,4,5,6)"
Do this by not assiging NULL to the variable, but just assign 'null'. Verify by first echoing your query. It should have the null in it wihtout any quotes.
A better method is to use actual prepared statements: http://php.net/manual/en/mysqli.prepare.php
I think you are confusing the php null value and the mysql null value - they arent the same thing. I think you want something like:
$_FILES['id_file']['error'] == UPLOAD_ERR_OK?$passport_file=filesDB('id_file'):$passport_file = 'NULL';
Note I have quoted the "null". This will put a text null into the sql statement, which will then be interpreted as the keyword 'null' in mysql.
If you leave the php assignment as the value null then a sort of blanky thing is passed to mysql, when it wants the text string 'null' :)
in order to insert null values you should be using prepared statements
$stmt = $STCi->prepare("INSERT INTO applicants (id_file, address_file, photo, transcript, essay1, essay2) VALUES (?, ?, ?, ?, ?, ?)");
$stmt->bind_param("ssssss",
$passport_file,
$address_file,
$photo_file,
$transcript_file,
$essay1_file,
$essay2_file);
$stmt->execute();

What is the error in querying this? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
What's wrong on that code? -- It's keep refusing to create account.
$query = "
INSERT INTO `accounts`(`username`, `dispname`, `email`, `password`, `type`, `blocked`, `points`)
VALUES ($disname,$username,$email,$password,1,false,0)";
$result = mysql_query($query);
if($result){
$Registered = "You have registered successfully.";
} else {
$ERROREMAIL = "There Were an Error Registering your email, please contact our support.";
}
I am totally confused.
By the way this is the structure of the database, hopefully someone helps.
CREATE TABLE `accounts` (
`id` int(11) NOT NULL,
`username` varchar(255) DEFAULT NULL,
`dispname` varchar(255) NOT NULL DEFAULT 'someone',
`email` varchar(255) NOT NULL,
`password` varchar(255) NOT NULL,
`type` int(10) NOT NULL,
`blocked` tinyint(1) NOT NULL DEFAULT '0',
`points` int(10) NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
ALTER TABLE `accounts`
ADD PRIMARY KEY (`id`),
ADD UNIQUE KEY `username` (`username`);
ALTER TABLE `accounts`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=2;
Try this Query:
$query = "INSERT INTO `accounts`
(`username`, `dispname`, `email`, `password`, `type`, `blocked`, `points`)
VALUES ('$disname','$username','$email','$password',1,0,0)";
What change?
Adding single quote on string variables.
Also changed the value of blocked column as 0.
OP's comment:
"$connection = mysqli_connect($DBHOST, $DBUSER, $DBPASS, $DBNAME); also mysqli_query($connection, $query); – Ahmed Alaa 1 hour ago"
2 things wrong here. You're connecting with mysqli_ then querying with mysql_.
$result = mysql_query($query);
which should read as
$result = mysqli_query($connection, $query);
Those different APIs do NOT intermix. You must use the same one from connecting to querying.
Can I mix MySQL APIs in PHP?
Then, missing quotes around your variables (for strings) in values.
VALUES ($disname,$username,$email,$password,1,false,0)";
which should read as:
('$disname','$username','$email','$password',1,false,0)
But that leaves you open to SQL injection.
Use mysqli_* with prepared statements, or PDO with prepared statements.
Consult these following links http://php.net/manual/en/mysqli.error.php and http://php.net/manual/en/function.error-reporting.php
and apply that to your code during testing.
This does not help you during testing in order to get the real error(s):
else {
$ERROREMAIL = "There Were an Error Registering your email, please contact our support.";
}
This will:
else {
echo "Error: " . mysqli_error($connection);
}
You can set it back to your original method once there are no more errors.
You need to pass strings as strings not as integers
Try this:
$query = "
INSERT INTO `accounts`(`username`, `dispname`, `email`, `password`, `type`, `blocked`, `points`)
VALUES ('$disname','$username','$email','$password',1,false,0)";
Thanks for you all.
Solution is as it is.
Updating your php version to PHp 7_0_0.
Updating phpmyadmin to 4_5_2.
Updating MySql to 5_6_27.
Update the usage of old mysql -> PDO.

Using INSERT WHERE with variables

I am trying to make an SQL query that :
IF the $post_id exists then it updates the records,
IF NOT then then it creates the record
Here is my code
$vote_new_total = $vote_total + $vote;
$vote_count = $vote_count + 1;
$query = " INSERT INTO cute_review_vote (vote_total, vote_count)
VALUES ('$vote_new_total', '$vote_count')
ON DUPLICATE KEY UPDATE vote_total = $vote_new_total, vote_count = $vote_count
WHERE post_id = $post_id";
mysql_query($query) or trigger_error(mysql_error()." in ".$sql);
However, I keep getting the following error:
Notice: 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 'WHERE post_id = 214748364' at line 4 in in C:\xampp\htdocs\xbm-vote\do_vote.php on line 68
Is this an issue with my syntax or am I missing something more obvious than that?
Any help/advice would be greatly appreciated. Thanks.
There is no where with ON DUPLICATE statement. Always check syntax: http://dev.mysql.com/doc/refman/5.6/en/insert-on-duplicate.html
Also, that is not a secure query. Turn that into a prepared statement.
http://www.php.net/manual/en/mysqli.quickstart.prepared-statements.php
EDIT: Updating answer since OP didn't understand usage of ON DUPLICATE statement:
ON DUPLICATE will consider that you're trying to insert a KEY value.
Consider the example table:
CREATE TABLE `user` (
`email` varchar(50) NOT NULL,
`name` varchar(20) NOT NULL,
`is_active` tinyint(4) NOT NULL,
`datecreated` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`email`)
);
And the query:
INSERT INTO user (email, name, is_active) VALUES ("user#user.com", "User", 1)
ON DUPLICATE KEY UPDATE name = "User Edited", is_active = 0
Since we're setting PRIMARY KEY as email, and the insert statement is inserting a key, then, at the second time you run the query, ON DUPLICATE would run once a email is already on the table, because it is the KEY and you are trying to insert it again, but you defined a ON DUPLICATE KEY ....
If a table runs with a AUTO_INCREMENT column, is most likely you have to SELECT post_id applying some filter with WHERE statement.
Ok, I found my problem.
INSERT INTO cute_review_vote (post_id, vote_total, vote_count)
VALUES ('$post_id', '$vote_new_total', '$vote_count')
ON DUPLICATE KEY UPDATE vote_total = $vote_new_total, vote_count = $vote_count
I realized, thanks to Fabiano, that the WHERE clause is not required.
WHERE post_id = $post_id"
Is simply replaced by defining the database entry within the INSERT INTO command.

How to Insert in MySQLi in prepared statement

Hi! My table structure looks like this:
CREATE TABLE IF NOT EXISTS `search` (
`key` varchar(255) NOT NULL,
`id` int(15) NOT NULL auto_increment,
UNIQUE KEY `key` (`key`),
KEY `id` (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
And this is how I try to add data into my table:
$stmt = $mysqli->prepare("INSERT INTO search(key) VALUES (?)");
$stmt->bind_param('s',$keyword);
$stmt->execute();
$stmt->close();
This is what I got:
Call to a member function bind_param() on a non-object
But it works when I do this:
$stmt = $mysqli->prepare("INSERT INTO search VALUES (?,NULL)");
$stmt->bind_param('s',$keyword);
$stmt->execute();
$stmt->close();
Is there any other way besides putting NULL to the VALUES?
is there any necessity that i should put NULL to auto increments?
No.
And there is no necessity in finding an answer by means of wild guess either.
You have to get the error message instead.
For which purpose always have this line right before connecting to mysqli:
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
speaking for the certain query, key is a mysql keyword and have to be quoted in backticks
INSERT INTO search(`key`) VALUES (?)

PDO execute in PHP

Iam having some trouble with a PDO execute statement. My code looks like this:
try {
$stmt = $this->dbh->prepare("INSERT INTO smtp_servers (host, port, ssl, auth, username, password) VALUES(:host, :port, :ssl, :auth, :username, :password)");
$stmt->bindParam(':host', $serverOptions[0]);
$stmt->bindParam(':port', $serverOptions[1]);
$stmt->bindParam(':ssl', $serverOptions[2]);
$stmt->bindParam(':auth', $serverOptions[3]);
$stmt->bindParam(':username', $serverOptions[4]);
$stmt->bindParam(':password', $serverOptions[5]);
$stmt->execute();
} catch (PDOException $e) {
print("fail");
}
It dosen't print "fail" if i make a print before the $stmt->execute(); it prints the test, but if i make a print just after the execute line, it dosen't print the text.
Any ideas?
UPDATED:
I tried to throw the more generic Exception, without any luck, i implemented PDO::PARAM_INT where i am using integers. And also added the line:
$this->dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
Now my code looks like this:
try {
$stmt = $this->dbh->prepare("INSERT INTO smtp_servers (host, port, ssl, auth, username, password) VALUES(:host, :port, :ssl, :auth, :username, :password)");
$stmt->bindParam(':host', $serverOptions[0]);
$stmt->bindParam(':port', $serverOptions[1], PDO::PARAM_INT);
$stmt->bindParam(':ssl', $serverOptions[2], PDO::PARAM_INT);
$stmt->bindParam(':auth', $serverOptions[3], PDO::PARAM_INT);
$stmt->bindParam(':username', $serverOptions[4]);
$stmt->bindParam(':password', $serverOptions[5]);
$stmt->execute();
} catch (PDOException $e) {
debug("fail");
}
I quess it would help to see my db table design?
CREATE TABLE IF NOT EXISTS `smtp_servers` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`host` varchar(50) NOT NULL,
`port` int(11) DEFAULT NULL,
`ssl` smallint(11) DEFAULT NULL,
`auth` smallint(11) DEFAULT NULL,
`username` varchar(50) DEFAULT NULL,
`password` varchar(50) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
Now i am getting this error:
Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[42000]: Syntax error or access violation: 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 'ssl, auth, username, password FROM smtp_servers' at line 1' in /var/www/isms/php/communication/Mail.php on line 13 PDOException: SQLSTATE[42000]: Syntax error or access violation: 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 'ssl, auth, username, password FROM smtp_servers' at line 1 in /var/www/isms/php/communication/Mail.php on line 13 Call Stack: 0.0002 649056 1. {main}() /var/www/isms/index.php:0 0.0023 867336 2. include('/var/www/isms/php/settings/ismsSettings.php') /var/www/isms/index.php:88 0.0065 1091712 3. require_once('/var/www/isms/php/settings/MailSettings.php') /var/www/isms/php/settings/ismsSettings.php:29 0.0147 2288960 4. require_once('/var/www/isms/php/forms/settings/EditSmtpServer.php') /var/www/isms/php/settings/MailSettings.php:4 0.0155 2290456 5. Mail->getServers() /var/www/isms/php/forms/settings/EditSmtpServer.php:41 0.0156 2291888 6. PDOStatement->execute() /var/www/isms/php/communication/Mail.php:13
With addition to andrewsi's comment about "MySQL reserved words"...
[ssl is indeed a MySQL reserved word!]
As it stands your create table statement also fails as is, but formatted like so; does not
CREATE TABLE `smtp_servers` (
`id` INT( 11 ) NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`host` VARCHAR( 50 ) NOT NULL ,
`port` INT( 11 ) NOT NULL ,
`ssl` SMALLINT( 11 ) NOT NULL ,
`auth` SMALLINT( 11 ) NOT NULL ,
`username` VARCHAR( 50 ) NOT NULL ,
`password` VARCHAR( 50 ) NOT NULL
) ENGINE = MYISAM ;
Although, as I've been writing this I notice that StackOverflow uses the spacing grave for formatting! ( ` )(&#096)
So, in conclusion change your prepare statement line to the following:
$stmt = $this->dbh->prepare("INSERT INTO `smtp_servers`
(`host`, `port`, `ssl`, `auth`, `username`, `password`)
VALUES(:host, :port, :ssl, :auth, :username, :password)");
Note : only formatted this way for easier reading :)
In your code example, the fail print should only happen in case of a problem, when an Exception is thrown by the script inside the try block.
Assuming everything went smooth and the query succeeded, not seeing the line is a good sign.
If the query has not succeeded, and yet you are still not seeing the error message, try telling PDO to only throw PDOExceptions on errors:
$this->dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
Right after instantiating the PDO object.
Have you tried printing out the SQL of the query, replacing the named parameters with the actual parameters you're trying to insert, and running it from the command line?
The text of the exception implies that there's a problem with the SQL statement, rather than with the PDO connection, and running it from the command line will let you know if the SQL itself works.
It's probably because you are in a particular namespace right now. Try replacing } catch (PDOException $e) { with } catch (\PDOException $e) { and see if something changes.

Categories