This question already has an answer here:
What to do with mysqli problems? Errors like mysqli_fetch_array(): Argument #1 must be of type mysqli_result and such
(1 answer)
Closed 2 years ago.
Having trouble with line 27, Don't quite know why as I am very new to PHP/MySQL.
Was wondering if anybody can advise me why I am getting the error;
"Fatal error: Call to a member function execute() on a non-object in
C:\xampp\htdocs\testscripts\usercreate.php on line 27"
in the following code:
<?php
$name = $_POST["name"];
$psswrd = $_POST["psswrd"];
$username = "root";
$password = "hidden";
$hostname = "localhost";
$table = "testtable";
// create connection to database
// ...
$db= new mysqli($hostname, $username, $password, $table);
// sanitize the inputs
// ...
// create an MD5 hash of the password
$psswrd = md5($psswrd);
// save the values to the database
$sql = "INSERT INTO accounts (name, psswrd) VALUES (:name, :psswrd)";
$stmt = $db->prepare($sql);
$stmt->execute(array(
":name" => $name,
":psswrd" => $psswrd
));
->prepare returns false if an error occurred. Since $stmt->execute is complaining of being called on a non-object, it's reasonable to assume that something went wrong with the query.
Check $db->error.
Try this :
$db= new mysqli($hostname, $username, $password, $table);
if ($db->connect_errno) {
throw new Exception($db->connect_error, $db->connect_errno);
}
$psswrd = md5($psswrd);
// save the values to the database
$sql = "INSERT INTO accounts (name, psswrd) VALUES (:name, :psswrd)";
$stmt = $db->prepare($sql);
if (!$stmt) {
throw new Exception($db->error);
}
$stmt->execute(array(
":name" => $name,
":psswrd" => $psswrd
));
Show your all exception for better idea of given error.
First thing, the fourth parameter the MySQLi class takes is the database name, not the table name.
So, change the$table = 'testtable'; to something like this : $dbname = 'dbname';
Also, in your code, you are using named parameters (:name and :passwrd). This won't work because MySQLi doesn't support named parameters. PDO (PHP Data Objects) supports named parameters. If you use the PDO class to connect to the database, your script will work fine!
If you want to connect to the database using the MySQLi class, do this :
$name = $_POST['name'];
$psswrd = $_POST['psswrd'];
$username = "root";
$password = "";
$hostname = "localhost";
$dbname = "dbname";
// create connection to database
// ...
$db= new mysqli($hostname, $username, $password, $dbname);
// sanitize the inputs
// ...
// create an MD5 hash of the password
$psswrd = md5($psswrd);
// save the values to the database
$sql = "INSERT INTO `testtable` (id, name) VALUES (?, ?)";
$stmt = $db->prepare($sql);
$stmt->bind_param('ss', $name, $psswrd);
$stmt->execute();
Try that. Use question marks instead of named parameters.
In the bind_param() function, I've written the first parameter as 'ss'. The two 's' here stands for Strings. If you had an integer data, you could have replaced 's' with 'i'.
It's pretty self explanatory as to why there are two 's'. It's because you are binding two variables to the SQL query, both of them are strings. Hence the two 's'.
Related
I have a loop in which I have to do multiple inserts to the database, it appears that I have to bind the data array every time I get new data and the data changes. I though we could bind once and insert multiple times.
Further research has shown that PDO might be better suited to this task, but I'm curious why its like this with mysqli, and if there is a way to bind array once and execute multiple times.
See comments in code for more detail.
<?php
//usual db stuff
$DBhost = 'localhost';
$DBname = 'test';
$DBuser = '';
$DBpass = '';
//error reporting for mysql
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
//connect to database
$conn = new mysqli($DBhost, $DBuser, $DBpass, $DBname);
//prepare this is a dummy table in a dummy database
//actual table is quite complicated
$stmt = $conn->prepare('INSERT INTO `users` (`fname`,`lname`,`city`) VALUES(?,?,?)');
//create a variable to store the data
// so we can bind it before going further
$data=array_fill(0,3,'');
//bind params use array expansion
$stmt->bind_param('sss', ...$data);
//this part runs in a loop
// mock loop for just to show idea
for($i=0;$i<1;$i++)
{
//get the data
$data = get_data();
//already binded $data before the loop
//so execute this should insert the data just returned
//except this doesnt, it inserts blanks
//it acts as if the data still has the blank array from line 20
$stmt->execute();
//bind it again
$stmt->bind_param('sss', ...$data);
//execute
//this inserts the data
$stmt->execute();
}
//mock function to return data the actual function
//returns a multi dimesional array for multiple tables
function get_data()
{
return(array("dinesh","chand","nadi"));
}
any help or ideas highly appreciated
When you run $stmt->execute(); for the first time, inside the for loop, you are executing what you have bind before starting the for loop. So what you have to do is.
Bind what you want $stmt->bind_param('sss', ...$data);
Then execute $stmt->execute();
In your code above, first, remove $stmt->execute(); (first inside the for loop). Then add it after you bind the parameters for the first time(above the for loop). As follows,
Note: What I have changed are marked with ########
<?php
//usual db stuff
$DBhost = 'localhost';
$DBname = 'test';
$DBuser = '';
$DBpass = '';
//error reporting for mysql
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
//connect to database
$conn = new mysqli($DBhost, $DBuser, $DBpass, $DBname);
//prepare this is a dummy table in a dummy database
//actual table is quite complicated
$stmt = $conn->prepare('INSERT INTO `users` (`fname`,`lname`,`city`) VALUES(?,?,?)');
//create a variable to store the data
// so we can bind it before going further
$data=array_fill(0,3,'');
//bind params use array expansion
$stmt->bind_param('sss', ...$data);
$stmt->execute(); //########
//this part runs in a loop
// mock loop for just to show idea
for($i=0;$i<1;$i++)
{
//get the data
$data = get_data();
//already binded $data before the loop
//so execute this should insert the data just returned
//except this doesnt, it inserts blanks
//it acts as if the data still has the blank array from line 20
//$stmt->execute(); ########
//bind it again
$stmt->bind_param('sss', ...$data);
//execute
//this inserts the data
$stmt->execute();
}
Sometimes it sucks when you have these ; " ' (semicolon, single and double quotation marks) everything in a string.
Question is simple what is the easiest way to send those sting into the database.
base64_encode();
base64_decode();
// Is not an option. I need to keep those data just same as it is.
You need
addslashes('your text') // in your php page
PDO statements is the best solution to your problem of executing SQL queries to your database with values that have single/double quotation marks... but more importantly PDO statements help prevent SQL injection.
To show you how this works, this very simple example gives you a basic understanding of how PDO statements work. All this example does is make the connection to the database and insert the username, email and password to the users table.
<?php
// START ESTABLISHING CONNECTION...
$dsn = 'mysql:host=host_name_here;dbname=db_name_here';
//DB username
$uname = 'username_here';
//DB password
$pass = 'password_here';
try
{
$db = new PDO($dsn, $uname, $pass);
$db->setAttribute(PDO::ERRMODE_SILENT, PDO::ATTR_EMULATE_PREPARES);
error_reporting(0);
} catch (PDOException $ex)
{
echo "Database error:" . $ex->getMessage();
}
// END ESTABLISHING CONNECTION - CONNECTION IS MADE.
$username = $_POST['username'];
$email = $_POST['email'];
$password = $_POST['password'];
$hashed_password = password_hash($password, DEFAULT_BCRYPT);
//Validation on inputs here...
// Your SQL query... here is a sample one.
$query = "INSERT INTO users (userName, email, password) VALUES (:userName, :email, :password)";
$statement = $db->prepare($query);
// The values you wish to put in.
$statementInputs = array("userName" => $username, "email" => $email, "password" => $hashed_password);
$statement->execute($statementInputs);
$statement->closeCursor();
?>
You could put the establishing connection part in a separate file and require_once that file to avoid having to write the same code, again and again to establish a connection to your database.
Use mysqli_real_escape_string
$someText = mysqli_real_escape_string($con,"It's a test.");
where $con is your database connection variable.
This question already has answers here:
What is the difference between bindParam and bindValue?
(7 answers)
Closed 6 years ago.
Edit: My issue has been resolved. I did not know or think of bindValue(), that is why I do not think this is a duplicate question. Thanks for the help!
I am learning how to register users with PHP and it seems like password_hash is giving me the "Only Variables should be passed by reference" error message. I've seen many people with the same error, but it does not seem to apply to my case (in my opinion).
connecting to database
$server = 'localhost';
$username ='root';
$password ='root';
$database = 'register_test';
try{
$conn = new PDO("mysql:host=$server;dbname=$database;" , $username, $password);
} catch(PDOException $e){
die ("Connection failed" . $e->getMessage());
}
Registering user
require 'database.php';
if(!empty($_POST['email']) && !empty($_POST['password'])):
$pass = $_POST['password'];
$email = $_POST['email'];
$sql = "Insert into user (email, password) values (:email, :password)";
$stmt = $conn->prepare($sql);
$stmt ->bindParam(':email', $email);
$stmt ->bindParam(':password', password_hash($pass, PASSWORD_BCRYPT)); //error showns here
if($stmt -> execute() ):
die('Success');
else:
die('Fail');
endif;
endif;
If you guys need more information please let me know.
Use PDOStatement::bindValue() instead of PDOStatement::bindParam().
From the docs:
Unlike PDOStatement::bindValue(), the variable is bound as a reference and will only be evaluated at the time that PDOStatement::execute() is called.
So, your code becomes:
$stmt->bindValue(':email', $email);
$stmt->bindValue(':password', password_hash($pass, PASSWORD_BCRYPT));
The result of a function cannot be passed by reference when E_STRICT mode is enabled, without triggering a warning. By using bindValue() instead, we pass the return value of the function as a copy, basically.
I've spent most of the day trying to get data from a form into a MySQL Database, everything I have tried so far has not worked, can anyone figure out what is wrong? The database is connecting fine, it just cannot add any data into the mysql database (current errors are at the bottom)
EDIT: Updated Code Below (Still not working!)
<?php
$host = "localhost"; // Host name
$username = "root"; // Mysql username
$password = ""; // Mysql password
$db_name = "report"; // Database name
$tbl_name = "tbl_nonconformance"; // Table name
// Connect to server and select database.
mysql_connect($host, $username, $password) or die("cannot connect");
mysql_select_db("$db_name") or die("cannot select DB");
echo "Database Connected ";
$name = $_POST['name'];
$email = $_POST['email'];
$supplier = $_POST['supplier'];
$PONum = $_POST['PONum'];
$Part = $_POST['Part'];
$Serial = $_POST['Serial'];
$tsf = $_POST['tsf'];
$Quantity = $_POST['Quantity'];
$probclass = $_POST['probclass'];
$desc = $_POST['desc'];
$sql="INSERT INTO tbl_nonconformance (sno, Date, Name, Email, Supplier, PONum, Part, Serial, TSF, Quantity, probclass, desc)
VALUES
('$sno', '$date', '$name', '$email', '$supplier', '$PONum', '$Part', '$Serial', '$TSF', '$Quantity', '$probclass', '$desc')";
$result = mysql_query($sql);
// if successfully insert data into database, displays message "Successful".
if($result){
header('Location: ../thankyou.php');
}
else {
echo "ERROR";
}
// close mysql
mysql_close();
?>
First you should change
mysql_connect("$host", "$username", "$password") or die("cannot connect");
to:
$con = mysql_connect($host, $username, $password) or die("cannot connect");
You are calling $con but you never defined it. You want to save your MySQL connection (con) as $con for what you are trying to do here.
You should also really consider upgrading to MySQLi as MySQL is deprecated from PHP and will likely be removed from future versions. Here's a resource to get you started. http://www.php.net/manual/en/book.mysqli.php
Edit July 9 2014: You updated your code, and I do not recall what your original code was. Still, if it's not "working", it's best to describe how it's not working. After you call $result, do this:
if( !$result || !mysql_affected_rows() )
die( mysql_error() );
header('Location: ../thankyou.php'); //this will only occur if there are no SQL errors and the result actually inserted something
mysql_close();
echo "We couldn't forward you automatically. Click here to proceed {insert HTML/JS here}";
This will return the MySQL error message which will help you in your debugging.
You got your argument parsing wrong.
$name = mysql_real_escape_string($con, $_POST['name']);
$con is not defined first of all.
Secondly you are trying to escape $_POST['name'].
mysql_real_escape_string expects 2 arguments, 1st one is mandatory and second one is optional. First argument is the string you want to escape, the second specifies a mysql connection (optional as you may have one open already).
So your statement needs to look like
$name = mysql_real_escape_string($_POST['name']);
Perhaps $con is your mysql connection? Which if it is the case you may want to
$con = mysql_connect ........ and so on
you're using un-secure depreciating methods too. You should research PDO object. It separates variables from your query so they aren't sent at the same time. It also cleans code considerably. I see a few problem areas in his code... You pass in $sno, $date, but they don't exist in your code. $tsf has a different case in instantiation then what you're using in your query. You're using single quotes which can't interpolate data (place values where variable names are). Double quotes do that...
hmmm...
check this out.
<?php
$host = "localhost"; // Host name
$username = "root"; // Mysql username
$password = ""; // Mysql password
$db_port = "3306" // Mysql port
$db_name = "report"; // Database name
$dsn = "mysql:dbhost=$host;dbport=$db_port;dbname=$db_name";
//add sno variable declaration here.
$name = $_POST['name'];
$email = $_POST['email'];
$supplier = $_POST['supplier'];
$PONum = $_POST['PONum'];
$Part = $_POST['Part'];
$Serial = $_POST['Serial'];
$TSF = $_POST['tsf'];
$Quantity = $_POST['Quantity'];
$probclass = $_POST['probclass'];
$desc = $_POST['desc'];
$date = date('d-m-Y');
// Connect to server and select database.
$dbConnect = new PDO($dsn, $username, $password, array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
$sqlStatement = $dbConnect->prepare("INSERT INTO tbl_nonconformance (sno, Date, Name, Email, Supplier, PONum, Part, Serial, TSF, Quantity, probclass, desc)VALUES('?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?')");
try{
$sqlStatement->execute(array($sno, $date, $name, $email, $supplier, $PONum, $Part, $Serial, $TSF, $Quantity, $probclass, $desc));
header('Location: ../thankyou.php');
}catch(\PDOException $e){
echo 'Error: Could not connect to db.';
}
?>
PDO object is really easy. create $dbConnect = new PDO(). You see the arguments there. dsn, username, password. The last argument is just an associative array setting PDO's error mode with constants. This allows us to use the try catch block to do error handling. IF PDO can't connect we get the catch block to fire...otherwise the try block which is where our data is sent to the db... You see we have a variable called $sqlStatement.. this is made through $dbConnect->prepare(). This function takes the statement... notice variables are excluded for question marks. Inside the try block we call execute from the statement...this takes and array of values that will replace the question marks in order.
remember to create sno variable. I added date for you. also be sure all cases and spellings are right. One letter in your query string, whether spelled wrong, or even just cased wrong will cause a failure.
let me know if there's any errors or questions. jeremybenson11#gmail.com
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
On my adventure through the jungles of PHP: Data Objects I've encountered a problem with executing MySQL queries through prepared statements.
Observe the following code:
$dbhost = "localhost";
$dbname = "pdo";
$dbusername = "root";
$dbpassword = "845625";
$link = new PDO("mysql:host=$dbhost;dbname=$dbname","$dbusername","$dbpassword");
$statement = $link->prepare("INSERT INTO testtable(name, lastname, age)
VALUES('Bob','Desaunois','18')");
$statement->execute();
This is me, and I want to be in my database.
However I keep getting lost in.. well.. I don't know!
According to google this is the way to do it, though my database stays empty.
Am I missing something here? Because I've been stuck for a good hour now and would like to continue studying PDO!
You should be using it like so
<?php
$dbhost = 'localhost';
$dbname = 'pdo';
$dbusername = 'root';
$dbpassword = '845625';
$link = new PDO("mysql:host=$dbhost;dbname=$dbname", $dbusername, $dbpassword);
$statement = $link->prepare('INSERT INTO testtable (name, lastname, age)
VALUES (:fname, :sname, :age)');
$statement->execute([
'fname' => 'Bob',
'sname' => 'Desaunois',
'age' => '18',
]);
Prepared statements are used to sanitize your input, and to do that you can use :foo without any single quotes within the SQL to bind variables, and then in the execute() function you pass in an associative array of the variables you defined in the SQL statement.
You may also use ? instead of :foo and then pass in an array of just the values to input like so;
$statement = $link->prepare('INSERT INTO testtable (name, lastname, age)
VALUES (?, ?, ?)');
$statement->execute(['Bob', 'Desaunois', '18']);
Both ways have their advantages and disadvantages. I personally prefer to bind the parameter names as it's easier for me to read.
I have just rewritten the code to the following:
$dbhost = "localhost";
$dbname = "pdo";
$dbusername = "root";
$dbpassword = "845625";
$link = new PDO("mysql:host=$dbhost;dbname=$dbname", $dbusername, $dbpassword);
$link->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$statement = $link->prepare("INSERT INTO testtable(name, lastname, age)
VALUES(?,?,?)");
$statement->execute(array("Bob","Desaunois",18));
And it seems to work now.
BUT. if I on purpose cause an error to occur, it does not say there is any.
The code works, but still; should I encounter more errors, I will not know why.
Please add try catch also in your code so that you can be sure that there in no exception.
try {
$hostname = "servername";
$dbname = "dbname";
$username = "username";
$pw = "password";
$pdo = new PDO ("mssql:host=$hostname;dbname=$dbname","$username","$pw");
} catch (PDOException $e) {
echo "Failed to get DB handle: " . $e->getMessage() . "\n";
exit;
}
Thanks to Novocaine88's answer to use a try catch loop I have successfully received an error message when I caused one.
<?php
$dbhost = "localhost";
$dbname = "pdo";
$dbusername = "root";
$dbpassword = "845625";
$link = new PDO("mysql:host=$dbhost;dbname=$dbname", $dbusername, $dbpassword);
$link->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
try {
$statement = $link->prepare("INERT INTO testtable(name, lastname, age)
VALUES(?,?,?)");
$statement->execute(array("Bob","Desaunois",18));
} catch(PDOException $e) {
echo $e->getMessage();
}
?>
In the following code instead of INSERT INTO it says INERT.
this is the error I got.
SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'INERT INTO testtable(name, lastname, age) VALUES('Bob','Desaunoi' at line 1
When I "fix" the issue, it works as it should.
Thanks alot everyone!