I'm calling a mysql stored procedure with two input parameters. This is the code I have:
if (isset($_POST['button1'])) {
$con = mysql_connect("localhost:3306","root","");
if (!$con) {
echo '<b>Could not connect.</b>';
die(mysql_error()); // TODO: better error handling
} else {
mysql_select_db("php_database_1", $con);
$username_v = $_POST['username'];
$password_v = $_POST['password'];
$stmt = $dbh->prepare("CALL login(?, ?)");
$stmt->bindParam(2, $username_v, $password_v, PDO::PARAM_STR|PDO::PARAM_INPUT_OUTPUT, 4000);
// call the stored procedure
$stmt->execute();
print "procedure returned $username_v\n";
When executing, I get:
Notice: Undefined variable: dbh in E:\xampp\htdocs\php4\default.php on line 52
Fatal error: Call to a member function prepare() on a non-object in E:\xampp\htdocs\php4\default.php on line 52
How can I fix this?
Thanks.
Edited: After seeing more code, you have attempted to mix the mysql_() functions with PDO. You cannot do that -- instead, use PDO only. The two APIs do not work together, and the old mysql_*() API does not support prepared statements at all.
You have not connected to your database or instantiated a PDO object.
$username_v = $_POST['username'];
$password_v = $_POST['password'];
$dsn = 'mysql:dbname=testdb;host=127.0.0.1';
// You must first connect to the database by instantiating a PDO object
try {
$dbh = new PDO($dsn, 'root', 'root_db_pw');
} catch (PDOException $e) {
echo 'Connection failed: ' . $e->getMessage();
}
// Then you can prepare a statement and execute it.
$stmt = $dbh->prepare("CALL login(?, ?)");
// One bindParam() call per parameter
$stmt->bindParam(1, $username_v, PDO::PARAM_STR);
$stmt->bindParam(2, $password_v, PDO::PARAM_STR);
// call the stored procedure
$stmt->execute();
Having tried Michaels solution for another task and failed miserably with the CALL procedure telling that it expected 0 parameters and got 2, I'll just leave this workaround for others with the same issues:
$username_v = $_POST['username'];
$password_v = $_POST['password'];
$dsn = 'mysql:dbname=testdb;host=127.0.0.1';
// You must first connect to the database by instantiating a PDO object
try {
$dbh = new PDO($dsn, 'root', 'root_db_pw');
} catch (PDOException $e) {
echo 'Connection failed: ' . $e->getMessage();
}
// Then you can prepare a statement and execute it.
$stmt = $dbh->prepare("SET #username_v = '$username_v'; SET #password_v = '$password_v'; CALL login()");
// call the stored procedure
$stmt->execute();
If you want to call a stored procedure with IN parameter without PDO then below code might help you.
$stmt = $conn->prepare("CALL dataCreation(?)");
mysqli_stmt_bind_param($stmt, "s", $lastDate);
mysqli_stmt_execute($stmt);
Hope this will help someone.
Related
This question already has answers here:
Can I mix MySQL APIs in PHP?
(4 answers)
Closed 5 years ago.
I'm new to PHP but here's my code, and I'm getting :
Fatal error: Uncaught Error: Call to a member function bindParam() on boolean
I have tested and test, not sure what is going wrong, some pointers would really help to move on - thanks in advance.
$url_slot = parse_url($str);
$urlArray = explode('/',$url_slot['path']);
$passid = $urlArray['11']; // serial no
$deviceId = $urlArray['8'];
$passtype = $urlArray['10'];
$servername = "host";
$username = "user";
$password = "******";
$dbname = "db";
try {
// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$stmt = $conn->prepare("INSERT INTO Registrations (device_id, pass_id, pass_type) VALUES
(:device_id,:pass_id,:pass_type,:created,:modified)");
$stmt->bindParam(':device_id',$device_id);
$stmt->bindParam(':pass_id',$pass_id);
$stmt->bindParam(':pass_type',$pass_type);
$device_id = $deviceId;
$pass_id = $passid;
$pass_type = $passtype;
$stmt->execute();
$conn = null;
} catch (PDOException $e) {
print "Error!: " . $e->getMessage() . "<br/>";
die();
}
try {
$conn = new mysqli($servername, $username, $password, $dbname);
$stmt = $conn->prepare("INSERT INTO Devices (push_token) VALUES
(:push_token)");
$stmt->bindParam(':push_token',$push_token);
$push_token = $content['pushToken'];
$stmt->execute();
$conn = null;
} catch (PDOException $e) {
print "Error!: " . $e->getMessage() . "<br/>";
die();
}
?>
Any help would be great.
Whenever you get a Fatal error for sending the wrong type to a function, print the arguments you are trying to pass on the guilty line.
Whenever the wrong type in question is a boolean, check if you wrote tests for every function return that could hurt your program if the function had failed, because a variable that contains a boolean when it shouldn't usually does because the function that gave you that value failed and returned false.
In your case, it's even more simple : The error doesn't tell you that you try to pass a boolean to a function that awaits another type, it tells you that you try to call the method bind_param(), which means that you treat a boolean as an object.
$stmt->bindParam(':device_id',$device_id);
Therefore, it is $stmt which is empty.
$stmt = $conn->prepare("INSERT INTO Registrations (device_id, pass_id, pass_type) VALUES (:device_id,:pass_id,:pass_type,:created,:modified)");
The function that returns you the value you assign to $stmt being that one, I advise you to test if $stmt is different from false right after setting it, and to print the error type and message from $conn if it isn't.
In addition to that, I get the feeling that you aren't yet accustomed to work with API, you seem to lack some experience and are also trying to use PDO exceptions while working with MySQLi. Maybe you should spend some time reading their respective docmuentations.
Stack Overflow is also filled with various questions and docs regarding both.
I'm running through a tutorial where it uses MySQLi but instead I'm using PDO and I have been trying to pin the issue to why I am getting this error:
Fatal error: Call to a member function errorInfo() on string in D:\Program Files (x86)\xampp\htdocs\repos\bla\web\inboxPage.php on line 34
Here is where I am trying to call the errorInfo(), I had previously used mysql_error(); as per tutorial, but this also threw the same error. Before using errorInfo() I was looking around to see if there was a PDO equivelant to mysql_error() which lead me to what you see below - Me thinking it would work. But it didn't.
Tutorials example:
$query = "SELECT id, sender, subject, message FROM messages WHERE reciever='$user'";
$sqlinbox = mysql_query($query);
if(!$sqlinbox)
{
?>
<p><?php print '$query: '.$query.mysql_error();?></p>
<?php
}
My Example:
$sql = 'SELECT id, Sender, Subject, Message FROM privatemessages WHERE Receiver = :receiver';
$stmt = $conn->prepare($sql);
$stmt->bindParam(':receiver', $user);
$stmt->execute();
$result = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$result){
?>
<p><?php print '$sql: '.$sql.errorInfo(); ?></p>
<?php
}
Here is my connection to the database:
$servername = 'localhost';
$user = 'root';
$pass = '';
$database = 'tutor_database';
try {
$conn = new PDO("mysql:host=$servername;dbname=$database", $user, $pass);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch (PDOException $e){
echo "Connection failed: " . $e->getMessage();
}
In addition, I did try the first example from the PHP Manual website -> http://php.net/manual/en/pdostatement.errorinfo.php and found that doing so gave me:
PDO::errorInfo():
Notice: Array to string conversion in D:\Program Files (x86)\xampp\htdocs\repos\bla\web\inboxPage.php on line 37
$sql: Array
...instead.
Would appreciate some help on this as I'm clearly failing to see what is happening. Thanks in advance.
In PDO a completely different method for the error reporting have to be used. In short, PDO will report its errors already, without the need to write any code.
So just take out the error reporting part, leaving only
$sql = 'SELECT id, Sender, Subject, Message FROM privatemessages WHERE Receiver = :receiver';
$stmt = $conn->prepare($sql);
$stmt->bindParam(':receiver', $user);
$stmt->execute();
$result = $stmt->fetch(PDO::FETCH_ASSOC);
that's all you need.
I am trying to insert into a database through PHP. However, when I connect to the PHP file I get server 500 error. Would anyone be able to spot what I am doing wrong?
<?php
include 'db-security.php';
function db_login()
{
$userName = filter_input(INPUT_POST, "userName");
$password = filter_input(INPUT_POST, "password");
//binding the variable to sql.
$statement = $link->prepare("INSERT INTO user(username, password)
VALUES($userName, $password)");
//execute the sql statement.
$statement->execute();
}
db_login();
?>
Updated:
I have discovered the error occurs when i add filer_input or $_post to the php.
<?php
include 'db-security.php';
function db_login() {
global $conn;
// use my eaxmple to filter input to get the data out of the form, because security.
//$userName = filter_input(INPUT_POST, "userName");
$userName = $_POST['userName'];
$password = $_POST['password'];
//$password = filter_input(INPUT_POST, "password");
//binding the variable to sql.
$stmt = $conn->prepare("INSERT INTO user(username, password)VALUES(:usrname, :pswd)");
$stmt->bindParam(':pswd', $password);
$stmt->bindParam(':usrname', $userName);
$stmt->execute();
//execute the sql statement.
}
db_login();
?>
db-security.php
<?php
include_once 'conf.php';
function db_connect() {
// Define connection as a static variable, to avoid connecting more than once
static $conn;
// Try and connect to the database, if a connection has not been established yet
if(!isset($conn)) {
// Load configuration as an array. Use the actual location of your configuration file
try
{
$conn = new PDO("mysql:host=localhost;port=3307;dbname=database", DB_USERNAME,DB_PASSWORD);
// stores the outcome of the connection into a class variable
$db_msg = 'Connected to database';
}
catch(PDOException $e)
{
$conn = -1;
$db_msg = $e->getMessage();
}
//$conn = new PDO(DB_HOST,DB_USERNAME,DB_PASSWORD , MAIN_DB);
}
}
db_connect();
?>
Where is $link defined? In 'db-security.php'? If yes then you have a variable scope problem. Just pass $link in the function call. This would have to be done for all functions.
define function as = function db_login($link)
call function like = db_login($link);
EDIT:
Don't use a function for 'db-security.php' it should be like this:
<?php
$conn = new PDO('mysql:host=localhost;dbname=testdb;charset=utf8', 'username', 'password');
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$conn->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
?>
This is not complete code, just a sample. Now $conn is in the global variable scope and using global in the functions will work. Or just pass $conn to the function and not use global at all.
EDIT2:
Below are the working sample scripts. You need to change some information to match your setup. I'm not sure why the function is called db_login() since the function actually adds the user/password into the 'user' table.
conf.php
<?php
define('DB_USERNAME', 'test');
define('DB_PASSWORD', '123456');
?>
db-security.php
<?php
include_once 'conf.php';
try
{
$conn = new pdo("mysql:host=localhost; dbname=test; charset=utf8", DB_USERNAME, DB_PASSWORD);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
$conn->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
}
catch(PDOException $e)
{
die('Unable to connect to database!');
}
?>
main script
<?php
include 'db-security.php';
function db_login()
{
global $conn;
$userName = $_POST['userName'];
$password = $_POST['password'];
$stmt = $conn->prepare("INSERT INTO user(username, password) VALUES(:usrname, :pswd)");
$stmt->bindParam(':usrname', $userName);
$stmt->bindParam(':pswd', $password);
$stmt->execute();
}
db_login();
?>
So you need to bind your parameters after prepare statement
$stmt = $link->prepare("INSERT INTO user(username, password)VALUES(:usrname, :pswd)");
$stmt->bindParam(':pswd', $password);
$stmt->bindParam(':usrname', $userName);
$stmt->execute();
I have been looking at your code and I would advice you to try a different approach. I've been wrapping my head around this subject for a while when learning PHP. Best advice i've had is that you can best try when fetching information from the DB is using a try/catch statement everytime. Sounds annoying or problematic but it easy to overlook and well written maintained code because you know every try catch block will execute or catch the error atleast.
With PDO being one of the best solutions because it can connect with multiple databases the best way to execute getting information from the Database is this:*
I am gonna give you my example of something i wrote. I don't want to write it all out in your situation because i feel that's something you can better do to learn what went wrong and i hope this gives you a step in the right direction.
database.php
$serverName = "";
$dbName = "";
$userName = "";
$password = "";
try {
$db = new PDO("mysql:host=$serverName;dbname=$dbName", $userName, $password);
// Set the PDO error mode to exception
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$db->exec("SET NAMES 'utf8'");
}
catch(PDOException $e){
echo"Connection failed: " . $e->getMessage();
exit;
}
?>
index.php Executing a simple commmand get firstName from employers
<?php
require_once 'database.php';
try
{
$sQuery = "
SELECT
firstName
FROM
employees
";
$oStmt = $db->prepare($sQuery);
$oStmt->execute();
while($aRow = $oStmt->fetch(PDO::FETCH_ASSOC))
{
echo $aRow['firstName'].'<br />';
}
}
catch(PDOException $e)
{
$sMsg = '<p>
Regelnummer: '.$e->getLine().'<br />
Bestand: '.$e->getFile().'<br />
Foutmelding: '.$e->getMessage().'
</p>';
trigger_error($sMsg);
}
?>
Good luck and i hope my index.php is helpful in showing you how I find is the best way momentarily to talk to the database.
Getting this error:
PHP Fatal error: Call to a member function execute() on a non-object
while pushing new data to my openshit application.
function createAppInfo($title,$blog_link,$job_link,$description,$author,$status){
$db = dbopen();
$title = $db->real_escape_string($title);
$author = $db->real_escape_string($author);
$description = $db->real_escape_string($description);
$job_link = $db->real_escape_string($job_link);
$blog_link = $db->real_escape_string($blog_link);
$status = $db->real_escape_string($status);
$stmt = $db->prepare("INSERT INTO `app`(title,blog_link,job_link,description,author,status)
values('$title','$blog_link','$job_link','$description','$author','$status')");
$stmt->bind_param('s',$title,$blog_link,$job_link,$description,$author,$status); // bind inputs to the parameter
/* execute prepared statement */
$stmt->execute();
$stmt->close();
return true;
}
This is the code i am running, but it seems to me that Openshift is bloacking prepare or prepare is not working correctly i dont know..cause the code is working on local machine.
Also, its i change it to regular $db-query(INSERT) its working absolutely fine.
UPDATE:
dbcon.php file
<?php
function dbopen(){
$host="localhost"; // Host name
$username="**"; // Mysql username
$password="**"; // Mysql password
$db_name="***"; // Database name
$db= new mysqli($host, $username, $password, $db_name);
if (!$db)
{
die('Could not connect: ' . mysql_error());
}
return($db);
}?>
I am including this file to call dbopen()
see http://php.net/manual/fr/pdostatement.bindparam.php , there aren't as many parameters...
see #class comment: why bindparam for parameters that you already included in your request?
So maybe trying smthg like this should help? :
$stmt = $db->prepare("INSERT INTO `app` (title,blog_link,job_link,description,author,status) values(:title,:blog_link,:job_link,:description,:author,:status)");
$stmt->bind_param(':title',$title);
$stmt->bind_param(':blog_link', $blog_link);
etc...
$stmt->execute();
or simply let your prepare like you did, but forget about bind_param (but previous solution should be safer).
First of all, you do not need to use real_escape_string at all, prepared statements escapes all values automatically. Secondly, when binding your parameters, you need to specify the type for each (answer below assumes all are strings).
EDIT :
Upon doing some research, you must use the environment variables in the MYSQL cartridge when establishing a connection through openshift.
dbcon.php:
<?php
function dbopen(){
define('DB_HOST', getenv('OPENSHIFT_MYSQL_DB_HOST'));
define('DB_PORT', getenv('OPENSHIFT_MYSQL_DB_PORT'));
define('DB_USER', getenv('OPENSHIFT_MYSQL_DB_USERNAME'));
define('DB_PASS', getenv('OPENSHIFT_MYSQL_DB_PASSWORD'));
define('DB_NAME', getenv('OPENSHIFT_GEAR_NAME'));
$db= new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME);
if (!$db)
{
die('Could not connect: ' . mysql_error());
}
return($db);
}?>
MYSQL Query:
$db = dbopen();
$stmt = $db->prepare("INSERT INTO `app`(title,blog_link,job_link,description,author,status)
VALUES(?,?,?,?,?,?)");
$stmt->bind_param('ssssss',$title,$blog_link,$job_link,$description,$author,$status);
/* execute prepared statement */
$stmt->execute();
$stmt->close();
EDIT: The problem is that the errors are not being displayed. This is just to clarify everyting.
I just learned what a PDO is, and I decided to test how it works. From the tutorials I've checked, you have to use the following line to display errors: $DBH->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
So anyways, I used this line, made sure that my query had an error and it still didn't display any errors. The connection to the database works, it always returned me an error when it couldn't connect. Anyways, here my code:
<?php
// Connection to the mysql database using PDO
$mysql_host = "hidden";
$mysql_dbname = "hidden";
$mysql_username = "hidden";
$mysql_password = "hidden";
try {
$DBH = new PDO("mysql:host=$mysql_host;dbname=$mysql_dbname", $mysql_username, $mysql_password);
$DBH->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$DBH->prepare("SELECT username FROM username");
} catch (PDOException $e) {
echo "Error connecting to the database:" . $e->getMessage();
}
?>
You don't get any errors because
$DBH->prepare("DELETE use FROM blob");
doesn't execute, only prepares a query to be executed.
Replace that line of code with:
$stmt = $DBH->prepare("DELETE use FROM blob");
$stmt->execute();
You need to execute it
$stmt = $DBH->prepare("DELETE use FROM blob");
$stmt->execute();
Otherwise it doesn't actually run the query.