PDO execute in PHP - 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.

Related

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

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.

PDO prepared statement does nothing [duplicate]

This question already has answers here:
Why does this PDO statement silently fail?
(2 answers)
Closed last month.
I am trying to do a simple insert using PDO and a prepared statement but it doesn't insert the data, return an error, or anything. The logs are empty as well. Here is the code that is getting executed but doing nothing. The values are not null.
try {
$query = $this->db_handler->prepare('INSERT INTO submissions (firstname, lastname, email, phone, mailinglist) VALUES (:firstname, :lastname, :email, :phone, :mailinglist);');
$query->bindParam(':firstname', $values['firstname']);
$query->bindParam(':lastname', $values['lastname']);
$query->bindParam(':email', $values['email']);
$query->bindParam(':phone', $values['phone']);
$query->bindParam(':mailinglist', $values['mailinglist']);
$query->execute();
} catch (PDOException $e) {
echo "DB error: " . $e->getMessage();
}
Weirdly, this code is working fine, which is being executed right before the previous code on every request:
try {
$this->exec("CREATE DATABASE IF NOT EXISTS $this->db_name;");
$this->exec("USE $this->db_name;");
$this->exec("CREATE TABLE IF NOT EXISTS $this->table_name (
id INT(10) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
firstname VARCHAR(50) NOT NULL,
lastname VARCHAR(50) NOT NULL,
email VARCHAR(50) NOT NULL,
phone VARCHAR(12) NOT NULL,
mailinglist BOOLEAN NOT NULL,
submitdate TIMESTAMP
);");
} catch (PDOException $e) {
echo "DB error: " . $e->getMessage();
}
As MarcB pointed out in the comments, I had not been enabling exceptions in PDO. Using db_handler->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); after instantiating a PDO instance showed that there was an error with the query.
http://php.net/manual/en/pdo.error-handling.php

Constraint violation when using explicit data_type in PDO for SQLite foreign key

I am using PHP PDO with SQLite database. This is the schema of the table I am working on:
CREATE TABLE "quests" (
`id` TEXT,
`parent` TEXT,
PRIMARY KEY(id),
FOREIGN KEY(`parent`) REFERENCES quests(id)
)
... and contains one line which has hello as id.
And next is the PHP script I am using (less unrelated debug lines):
<?php
$dbhandle = new PDO("sqlite:sutori.sqlite3");
$dbhandle->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$dbhandle->exec("PRAGMA foreign_keys = ON;");
$sth = $dbhandle->prepare("INSERT INTO quests VALUES ( :id, :parent );");
$sth->bindValue(":id", "nouvelles", SQLITE3_TEXT);
$sth->bindValue(":parent", "hello", SQLITE3_TEXT);
$sth->execute();
die();
?>
The above script will return this SQL error:
PHP Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[23000]: Integrity constraint violation: 19 FOREIGN KEY constraint failed' in /var/www/html/sutori/sutori.php:56
But if I remove the data_type argument from bindValue of the foreign key field as below:
$sth->bindValue(":id", "nouvelles", SQLITE3_TEXT);
$sth->bindValue(":parent", "hello"); // SQLITE3_TEXT removed
... it works, so the INSERT is done.
I know the script would work as expected if I don't specify the data_type argument. But do you have any idea why I am getting this behavior? Is it a PDO bug/feature or is my script wrong?
Thank you for your inputs! :)

mysqli fatal error: No index used in query/prepared statement

I want to execute a simple prepared Statement using mysqli, but it won't work.
I have this table:
CREATE TABLE IF NOT EXISTS `account` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`email` varchar(100) COLLATE latin1_german2_ci NOT NULL,
`password` varchar(100) COLLATE latin1_german2_ci NOT NULL,
`created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_german2_ci AUTO_INCREMENT=4 ;
And want to print the id of a specific email.
$mysqli = new mysqli($server,$user,$pass,$db);
if(mysqli_connect_errno()) {
echo "Connection Failed: " . mysqli_connect_errno();
exit();
}
$user = "test#dada.com";
$pass = "dada";
/* Create a prepared statement */
if($stmt = $mysqli -> prepare("SELECT * FROM account WHERE email=?
AND password=?")) {
/* Bind parameters
s - string, b - blob, i - int, etc */
$stmt -> bind_param("ss", $user, $pass);
/* Execute it */
$stmt -> execute();
/* Bind results */
$stmt -> bind_result($result);
/* Fetch the value */
$stmt -> fetch();
echo $user . "id of user is " . $result;
/* Close statement */
$stmt -> close();
}
/* Close connection */
$mysqli -> close();
But i get following Error:
Fatal error: Uncaught exception 'mysqli_sql_exception' with message 'No index used in query/prepared statement SELECT * FROM account WHERE email=? AND password=?' mysqli_stmt->execute() #1 {main}
Your problem is that the query you are executing is going to be inefficient without using an INDEX.
SELECT * FROM account WHERE email=? AND password=?
There's no index on any of the two fields you have used in the WHERE clause. One solution would be to create an index on both fields which should make the error go away.
ALTER TABLE account ADD INDEX `index_on_email_and_password` (email, password);
In many situations, you know that the INDEX is not going to improve the performance, so you can safely ignore this error. To do so, replace the following line of code:
mysqli_report(MYSQLI_REPORT_ALL);
with one of these
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
// or
mysqli_report(MYSQLI_REPORT_ALL & ~MYSQLI_REPORT_INDEX);
This will keep on reporting normal SQL errors, but it will ignore all warnings about bad indexes.
Well I think you have to do this:
CREATE TABLE IF NOT EXISTS `account` (
`id` PRIMARY KEY int(11) NOT NULL AUTO_INCREMENT,
// the rest
The above code makes the id field of your table as PRIMARY KEY so it never repeats itself and it remains the index of your table.

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 (?)

Categories