PDOStatement object with bindparam [PHP] - php

I have a method that I'm getting to see if a user is exists:
public function login_user($user_name, $user_password){
$this->statement = $this->conn->prepare('SELECT * FROM users WHERE user_name=:user_name AND user_password=:user_password');
$this->statement = $this->conn->bindParam(':user_name', $user_name);
$this->statement = $this->conn->bindParam(':user_password', $user_password);
$this->statement->execute();
return $this->statement->fetch(PDO::FETCH_ASSOC);
}
I have never used PDO before and I'm slightly confused. I am getting the error:
Call to undefined method PDO::bindParam().
I have seen an answer saying it's because it is part of the PDOStatement class.
By changing my code to this (removing $this->conn) fixes it:
$this->statement->bindParam(':user_name', $user_name);
$this->statement->bindParam(':user_password', $user_password);
However, I have no idea why? $this->conn is by PDO object. What have I just done to make this work?

just do
$this->statement->bindParam()
to bind your parameters, then you can call your execute statement

make the following changes to your function:
public function login_user($user_name, $user_password){
//prepare the query
$query='SELECT * FROM users WHERE user_name=:user_name AND user_password=:user_password';
$statement = $this->conn->prepare($query);
//bind the parameters
$statement->bindParam(':user_name', $user_name);
$statement->bindParam(':user_password', $user_password);
//excute & fetch the data
$statement->execute();
$result = $statement->fetch(PDO::FETCH_ASSOC);
return $result;
}

Related

Can fetch Data inside the class but when return it's send only boolean value php PDO?

I am trying to build database class using PDO this my first time using pdo so while i am building i am stuck in this problem i was able create and connect to database using class but problem is when i am trying to execute and fetch returned data error says
Call to a member function fetch() on boolean
and yet i can do this fetching inside the class this problem arise only when i am trying to fetch returned data and i have echoed the returned data it is returning 1
This is function that's trying to return (did not use parameters just using dummy)
public function init($query,$param =[]){
if(!$this->bConnected) { $this->Connect(); }
try{
$stmt = $this->pdo->prepare('SELECT * FROM business');
$stmt->execute();
return $stmt->execute();
}catch(Exception $e){
echo $e->getMessage();
}
}
Calling to class object name is $myobj
$stmt = $myobj->init('SELECT * FROM business',$value);
while($rows = $stmt->fetch(PDO::FETCH_ASSOC)){
echo( $rows['bs_name'] ." |" .$rows['bs_id']. "<br>");
}
This is same code only difference is this is inside the class.working without any errors
public function init($query,$param =[]){
if(!$this->bConnected) { $this->Connect(); }
try{
$stmt = $this->pdo->prepare('SELECT * FROM business');
$stmt->execute();
$result = $stmt->setFetchMode(PDO::FETCH_ASSOC);
while($rows = $stmt->fetch(PDO::FETCH_ASSOC)){
echo( $rows['bs_name'] ." |" .$rows['bs_id']. "<br>");
}
}catch(Exception $e){
echo $e->getMessage();
}
}
Your method returns the result of $stmt->execute() (a boolean indicating success/failure of the statement execution, not the query results).
$stmt = $this->pdo->prepare('SELECT * FROM business');
return $stmt->execute();
Instead, for the method to work the way you're using it, you need to execute the statement and then return the statement itself, not the result of execute().
$stmt = $this->pdo->prepare('SELECT * FROM business');
$stmt->execute();
return $stmt;

PDO bindParam return same result with wrong parameter

public function getStudent($id){
$sth = $this->con->prepare("SELECT * FROM students WHERE id=:id");
$sth->bindParam("id", $id, PDO::PARAM_INT);
$sth->execute();
$student = $sth->fetchObject();
return $student;
}
(1) http://localhost/slim-framework/public/api/v1/student/1
(2) http://localhost/slim-framework/public/api/v1/student/1fgff
With 'GET' request using the code above, URL 1 and 2 above gave me the same result which suppose not to be.
Please, any help on how I can make URL 2 to flag error since it is not an integer?
Hi I hope this will help you
In your case it will be
public function getStudent(int $id){
.......
}
If the id comes something else instead of int you will get php error
http://php.net/manual/en/functions.arguments.php#functions.arguments.type-declaration
public function getStudent($id){
if(is_numeric($id)) {
$sth = $this->con->prepare("SELECT * FROM students WHERE id=:id");
$sth->bindParam("id", $id);
$sth->execute();
$sth->fetchObject();
return true;
}else {
return false;
}
}
I got it working now by following #u_mulder and #Federkun suggestion by using the is_numeric() method to check if the id is an integer or not.
Thanks everyone for your effort.

stmt get_result another way

An example of one of my queries...
public function db_query_select($query, $params, $param_types){
$dbc = $this->dbConnect();
if($stmt = $dbc->prepare($query)){
//prepared.
//move the types to the front of the param array
array_unshift($params, $param_types);
//call the bind param function with the parameters passed in by reference
//bind_param only allows by reference.
call_user_func_array(array($stmt, "bind_param"), $this->paramsToRefs($params));
//binded.
//attempt to execute the sql statement.
if ($stmt->execute()){
$result = $stmt->get_result();
$stmt->close();
$dbc->close();
return $result;
}
}
//must have failed...
return NULL;
}
how can I change stmt get_result(); to something that is accepted by shared servers/hosts without the native driver... mysqlnd.
Anyone know? without changing all of my functions that use this database function.
Thanks.
UPDATED:::: Thanks to #your common sense, See Answer.
I believe this is what I was after. Hope it helps anyone that was having the same problem as myself. PDO vs MySQLi, seems simpler... no user call func or anything like that.
DB HANDLER:
private function dbConnect(){
$config = parse_ini_file($_SERVER['DOCUMENT_ROOT'].'/NTConfig.ini');
try {
$dbc = new PDO('mysql:host='.$config['DB_HOST'].';dbname='.$config['DB_DATABASE'].'', $config['DB_USER'], $config['DB_PASSWORD']);
$dbc->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
echo 'Connection failed: ' . $e->getMessage();
exit;
}
return $dbc;
}
public function db_query_select($query, $params){
$dbc = $this->dbConnect();
if($stmt = $dbc->prepare($query)){
//prepared.
//attempt to execute the sql statement.
if ($stmt->execute($params)){
$result = $stmt->fetch(PDO::FETCH_ASSOC);
print_r($result);
//$stmt->close();
//$dbc->close();
return $result;
}
}
//must have failed...
return NULL;
}
Outside the DBHANDLER
$query = "SELECT error_desc FROM nt_errors WHERE error_code = :ERROR_CODE LIMIT 1";
//array: holds parameters for the query.
$params = array(
':ERROR_CODE' => $code
);
$result = $db->db_query_select($query, $params);
if ($result == NULL){
$errorText = 'ERROR: Failed to retrieve error';
}
else{
//var_dump($result);
$errorText = $result['error_desc'];
PDO is not only much more user friendly than mysqli but also doesn't have any of such a nasty drawbacks. So I strongly suggest to use PDO instead of mysqli.
With DO, the function you're after should be as simple as this
function run($sql, $args = NULL)
{
$pdo = ...;//your means of getting the connection variable
$stmt = $pdo->prepare($sql);
$stmt->execute($args);
return $stmt;
}
After gettin the function's result, you can chain a fetch method to its call, fetchColumn() in your case.
Given your code is mostly procedural, let me suggest you a very simple PDO wrapper I wrote. So the full code would be:
$sql = "SELECT error_desc FROM nt_errors WHERE error_code = ?";
$errorText = DB::run($sql,[$code])->fetchColumn();
if (!$errorText){
$errorText = 'ERROR: Failed to retrieve error';
}
Here DB class is a better replacement of your dbConnect() function, and run() method is a replacement for db_query_select() that actually can be used for any query type, including insert, update or anything.

loop variable in param

i'm having an error "Call to a member function bind_param() on a non-object"
on this line $stmt->bind_param("ss", $influencer_id, $campaign_id);
public function getCouponDetailsMenu($influencer_id)
{
$stmt = $this->con->prepare("SELECT id, campaign_id, campaign_name, status, type_of_campaign, client, brand, influencers, max_coupons, distributed_coupons, expired_coupons, claimed_coupons, coupon_expiry, campaign_start_date, campaign_end_date FROM tbl_campaign WHERE influencers=?");
$stmt->bind_param("s",$influencer_id);
$stmt->execute();
$stmt->bind_result($id, $campaign_id, $campaign_name, $status, $type_of_campaign, $client, $brand, $influencers, $max_coupons, $distributed_coupons, $expired_coupons, $claimed_coupons, $coupon_expiry, $campaign_start_date, $campaign_end_date);
$campaigns = array();
while($stmt->fetch())
{
$temp['id']=$id;
$temp['campaign_id'] = $campaign_id;
$temp['campaign_name'] = $campaign_name;
$temp['status']=$status;
$temp['type_of_campaign']=$type_of_campaign;
$temp['client']=$client;
$temp['brand']=$brand;
$temp['influencers']=$influencers;
$temp['max_coupons']=$max_coupons;
$temp['distributed_coupons']=$distributed_coupons;
$temp['expired_coupons']=$expired_coupons;
$temp['claimed_coupons']=$claimed_coupons;
$temp['coupon_expiry']=$coupon_expiry;
$temp['campaign_start_date']=$campaign_start_date;
$temp['campaign_end_date']=$campaign_end_date;
$temp['logo'] = $this->getDistributedEmail($influencer_id, $campaign_id);
array_push($campaigns, $temp);
}
$stmt->close();
return $campaigns;
}
}
//Method to get distributed email
public function getDistributedEmail($influencer_id, $campaign_id)
{
$stmt = $this->con->prepare("SELECT user_email_address FROM tbl_coupons WHERE influencer_id=? and campaign_id=?");
$stmt->bind_param("ss", $influencer_id, $campaign_id);
$stmt->execute();
$stmt->bind_result($eadd);
$email = array();
while($stmt->fetch())
{
$temp = $eadd;
array_push($email, $temp);
}
$stmt->close();
return $email;
}
It seems $stmt not an object. try to debug it by using var_dump($stmt); right after your prepare-call.
I think it occurred because the sql statement sent to it is not valid in the current DB.
sounds like the prepare-call fails (don't know why) and so it returns
false - false is not an object, so you can't call bind_param() on
that.
If the database server successfully prepares the statement, PDO::prepare() returns a PDOStatement object. If the database server cannot successfully prepare the statement, PDO::prepare() returns FALSE or emits PDOException (depending on error handling).
fixed it by putting
$stmt->store_result();
after
$temp['campaign_end_date']=$campaign_end_date;

Prepared statement not letting me call $mysqli->stmt_init()

I have done this before but am quite new to mysqli and prepared statements (as I'm sure you can see from this issue).
Where am I going wrong?
here is my connection function (part of the 'Connect' class)
public function site_db()
{
// Connect to MySQL
$link = mysqli_connect(SITE_HOST, SITE_ID, SITE_PW, SITE_DB);
// Check for Errors
if(mysqli_connect_errno())
{
//echo mysqli_connect_error(); //shouldnt show client specific error information.
die('Error connecting to mysql database please report.');
}
}
Heres the function which is causing the error:
public function exists ($what, $who)
{
$query = "SELECT * FROM users WHERE ? = ?";
// Get instance of statement
$stmt = $mysqli->stmt_init();
// Prepare query
if($stmt->prepare($query))
{
// Bind Parameters
$stmt->bind_param("ss", $what, $who);
// Execute statement
$stmt->execute();
// Bind result variables
$stmt->bind_result($result);
// Fetch Value
$stmt->fetch();
// catch num_rows result as variable
$username_result = $result->num_rows;
// Close Statement
$stmt->close();
}
if ($username_result != 0)
{
return true;
echo 'true';
}
else
{
return false;
echo 'false';
}
}
the error I get:
PHP Fatal error: Call to a member function stmt_init() on a non-object in somefile.php on line X
It is referring to the line:
$stmt = $mysqli->stmt_init();
am I making a stupid error here? Howcome I can't call that?
EDIT//
NOTE: I didn't make this very clear, but these two functions are within different classes.
public function site_db()
{
// Connect to MySQL
$mysqli = mysqli_connect(SITE_HOST, SITE_ID, SITE_PW, SITE_DB);
// Check for Errors
if(mysqli_connect_errno())
{
//echo mysqli_connect_error(); //shouldnt show client specific error information.
die('Error connecting to mysql database please report.');
}
return $mysqli;
}
public function exists (Mysqli $mysqli, $what, $who)
{
$query = "SELECT * FROM users WHERE ? = ?";
// Get instance of statement
$stmt = $mysqli->stmt_init();
// Prepare query
if($stmt->prepare($query))
{
// Bind Parameters
$stmt->bind_param("ss", $what, $who);
// Execute statement
$stmt->execute();
// Bind result variables
$stmt->bind_result($result);
// Fetch Value
$stmt->fetch();
// catch num_rows result as variable
$username_result = $result->num_rows;
// Close Statement
$stmt->close();
}
if ($username_result != 0)
{
return true;
echo 'true';
}
else
{
return false;
echo 'false';
}
}
How to use:
Instantiate first class that have site_db() method
$db = new Class();
Then instantiate second class that have exist() method
$query = new Class();
Then simply
$query->exist($db->site_db(), $what, $who );
it's because your $mysqli is not declared inside function exists(). Try a global $mysqli inside function exists() if your $mysqli is declared outside the function.
Or, probably better - make $mysql an new object inside your Connect class:
$this->mysqli = mysqli_connect(SITE_HOST, SITE_ID, SITE_PW, SITE_DB);
and in your function exists()
$stmt = $this->mysqli->stmt_init();

Categories