PDO prepared statement does nothing [duplicate] - php

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

Related

Create table with PDO

I get this error:
Uncaught Error: Call to undefined method PDO::execute()
My code:
<?php
session_start();
require("../connecting-to-database.php");
$query = "CREATE TABLE `classes`(
`ID_class` int(11),
`name` varchar(255),
PRIMARY KEY(`ID_class`))";
$pdo->execute($query);
What is my problem?
Execute is for prepared statements not executing directly.
Also don't forget to catch your exception.
Try the following:
<?php
session_start();
require("../connecting-to-database.php");
try {
$query = $pdo->prepare("CREATE TABLE `classes`(
`ID_class` int(11),
`name` varchar(255),
PRIMARY KEY(`ID_class`))");
$query->execute();
}
catch (PDOException $e) {
echo $e->getMessage();
}

users storing own data . Mysql table name taken from session variable [duplicate]

This question already has answers here:
PHP parse/syntax errors; and how to solve them
(20 answers)
Closed 6 years ago.
Can someone help me with that code, any directions welcome
I want every user who passed session to create table(every user creates own table -others cant see it).
<?php
session_start();
if($_SESSION['user']==''){
header("Location:login.php");
}else{
$dbh=new PDO('mysql:dbname=something;host=127.0.0.1', 'something', 'something');
$sql=$dbh->prepare("SELECT * FROM users WHERE id=?");
$sql->execute(array($_SESSION['user']));
while($r=$sql->fetch()){
$sql = "CREATE TABLE .'$r['username'].'" (
id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
firstname VARCHAR(30) NOT NULL,
lastname VARCHAR(30) NOT NULL,
email VARCHAR(50),
reg_date TIMESTAMP
)";
$conn->exec($sql);
echo " created successfully";
}
catch(PDOException $e)
{
echo $sql . "<br>" . $e->getMessage();
}
$conn = null;
}
}
?>
You can try to fix your php code and get something like this:
<?php
session_start();
if($_SESSION['user']==''){
header("Location:login.php");
}else{
$dbh=new PDO('mysql:dbname=something;host=127.0.0.1', 'something', 'something');
$sql=$dbh->prepare("SELECT * FROM users WHERE id=?");
$sql->execute(array($_SESSION['user']));
while($r=$sql->fetch()){
$sql = "CREATE TABLE `".$r['username']."` (
id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
firstname VARCHAR(30) NOT NULL,
lastname VARCHAR(30) NOT NULL,
email VARCHAR(50),
reg_date TIMESTAMP
)";
try {
$dbh->exec($sql);
echo " created successfully";
} catch(PDOException $e) {
echo $sql . "<br>" . $e->getMessage();
}
}
$conn = null;
}
?>
You have some error in your query string. You have one double quote you should remove, and the table name should be wrapped with ` instead of '. So your code should look like:
$sql = "CREATE TABLE `{$r['username']}` (
id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
firstname VARCHAR(30) NOT NULL,
lastname VARCHAR(30) NOT NULL,
email VARCHAR(50),
reg_date TIMESTAMP
)";
And even if its not really related to the topic you should ask yourself if create a table per user is the best solution.

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.

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.

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