unable to display search results OOP - php

This code section is used on another page where results are to be displayed.
<?php
require 'core/init.php'; //all classes are contained in here.
$general->logged_out_protect();
$search = $_POST['search'];
if ($users->user_exists($_POST['search']) == false) {
$errors[] = "Sorry that username doesn't exists";
} else
if ($users->user_exists($_POST['search']) == true) {
// i would like to display username which is in the user_exists if the above condition is met.
}
}
?>
//This is function user_exists in which i determine if username is in database then after i display the username.
public function user_exists($username) {
$query = $this->db->prepare("SELECT COUNT(`id`) FROM `users` WHERE `username`= ?");
$query->bindValue(1, $username);
try{
$query->execute();
$rows = $query->fetchColumn();
if($rows == 1){
return true;
}else{
return false;
}
} catch (PDOException $e){
die($e->getMessage());
}
}

You either use PDO and execute: http://php.net/manual/en/pdo.prepare.php
$sth->execute(array(':calories' => 150, ':colour' => 'red'));
or mysqli and bind param and then execute: http://php.net/manual/en/mysqli.prepare.php
if ($stmt = $mysqli->prepare("SELECT District FROM City WHERE Name=?")) {
/* bind parameters for markers */
$stmt->bind_param("s", $city);
/* execute query */
$stmt->execute();
note if you use prepare:
you don't need to escape your input string
you need to use ? as placeholder or :placeholder : http://php.net/manual/en/mysqli-stmt.bind-param.php
Query debugging:
to get mysqli errors use: or die(mysqli_error($db) after your execute or query call.
solution
change the order of your execute() and bind_param() (first bind_param() then execute())
your sql query should be: "SELECT * FROM users WHERE username like '%$?%'"

Several programming suggestions.
PHP is dynamic typed, so a variable or function result value, may return different variable types, stick to single type.
In some circumstances null could be used, instead of the predefined type, for example,
returning null when a search is not found, instead of an integer value.
For PHP, use comments to determine which data type a function receives or returns.
Before.
public function user_exists($username) {
After.
public /* bool */ function user_exists(/* string */ $username) {
It doesn't change your code logic, but, helps any programmer, either you or another person, to understand the logic of the function.
When using a "try" sentence in a function that returns a value (non void function), only use a single "try" sentence.
When using a "try" sentence in a function that returns a value (non void function), declare the local variables with empty values before the "try", and make all assignaments inside the "try":
Before.
public function user_exists($username) {
$query = $this->db->prepare("SELECT COUNT(`id`) FROM `users` WHERE `username`= ?");
$query->bindValue(1, $username);
try{
$query->execute();
$rows = $query->fetchColumn();
if($rows == 1){
return true;
}else{
return false;
}
} catch (PDOException $e){
die($e->getMessage());
}
}
After.
public function user_exists($username) {
$query = null;
try{
$query = $this->db->prepare("SELECT COUNT(`id`) FROM `users` WHERE `username`= ?");
$query->bindValue(1, $username);
$query->execute();
$rows = $query->fetchColumn();
if($rows == 1){
return true;
}else{
return false;
}
} catch (PDOException $e){
die($e->getMessage());
}
}
This allows you to read their values in the catch section when an exception is generated,
or to clean them either in the catch sections or finally sections.
Even that the PHP enviroment is garbaged collected as: Java, ".Net", and other programming enviroments, some good "House Cleaning" is welcome, and helps you have more control of your programming logic.
When using a "try" sentence in a function that returns a value (non void function), assign the exception result to a local variable, and transfer the die to a "finally" section.
Example:
public function user_exists($username) {
$query = null;
$ExceptionMsg = "";
$AnyException = false;
try{
$query = $this->db->prepare("SELECT COUNT(`id`) FROM `users` WHERE `username`= ?");
$query->bindValue(1, $username);
$query->execute();
$rows = $query->fetchColumn();
if($rows == 1){
return true;
}else{
return false;
}
} catch (PDOException $e){
$ExceptionMsg = $e->getMessage();
$AnyException = true;
} finally{
if ($AnyException)
die($ExceptionMsg);
}
}
Cheers.

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;

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.

PDOstatement::execute() expect parameter 1 to be array, string given in

Please help me to correct this code.
error at line
$stmt->execute($params = [], $query);
and when i open the file with dreamweaver every "$params=[]" is error.
-Databasse.php-
<?php
include_once('connection.php'); //my connection is here
class Database extends connection{
public function __construct(){
parent::__construct();
}
public function getRow($params = [], $query){
try {
$stmt = $this->datab->prepare($query);
$stmt->execute($params);
return $stmt->fetch();
} catch (PDOException $e) {
throw new Exception($e->getMessage());
}
}
public function getRows($query, $params = []){
try {
$stmt = $this->datab->prepare($query);
$stmt->execute($params);
return $stmt->fetchAll();
} catch (PDOException $e) {
throw new Exception($e->getMessage());
}
}
this is half of the source code database.php
Need to see more of the code - what is your query string, what array w/ what values are you trying to feed into it?
Typically your query will have question marks ? or might have keywords with colons :mykeyword as place holders for values, and then your array holds the values that are "prepared" and executed.
$query="select name from users where name=? and passwordHash=?";
$res=$connection->prepare($query);
$res->execute(array(
"myuser",
"dd02c7c2232759874e1c205587017bed"),
);
// OR
$query="select name from users where name=:name and passwordHash=:passwordHash";
$res=$connection->prepare($query);
$res->execute(array(
":name" => "myuser",
":passwordHash" => "dd02c7c2232759874e1c205587017bed"),
);
This does the query preparation, escaping, etc. and the "myuser" value replaces the first question mark and the hash string replaces the second.

MySQL's session handler difficulties

Watching this online tutorial about MYSQL's session handler and got really confused about this part:
table_XXX == Table XXX;
col_XXX == Column XXX;
sid == Session id
Read method:
public function read($session_id)
{
$this->db->exec('SET TRANSACTION ISOLATION LEVEL READ COMMITTED');
$this->db->beginTransaction();
/**
* the data is selected and no other ppl can interfere
* the writing process until COMMIT is reached
*/
$sql = "SELECT $this->col_expiry, $this->col_data
FROM $this->table_sess
WHERE $this->col_sid = :sid FOR UPDATE";
$selectStmt = $this->db->prepare($sql);
$selectStmt->bindParam(':sid', $session_id);
$selectStmt->execute();
$results = $selectStmt->fetch(\PDO::FETCH_ASSOC);
if ($results) {
if ($results[$this->col_expiry] < time()) {
// return empty if data out of date
return '';
}
return $results[$this->col_data];
}
return $this->initializeRecord($selectStmt);
}
Protected method:
protected function initializeRecord(\PDOStatement $selectStmt)
{
try {
$sql = "INSERT INTO $this->table_sess
($this->col_sid, $this->col_expiry, $this->col_data)
VALUES (:sid, :expiry, :data)";
$insertStmt = $this->db->prepare($sql);
$insertStmt->bindParam(':sid', $session_id);
$insertStmt->bindParam(':expiry', $this->expiry); // expiry is defined
$insertStmt->bindValue(':data', '');
$insertStmt->execute();
return '';
} catch(\PDOException $e) {
$this->db->rollBack();
throw $e;
}
}
Write method:
public function write($session_id, $data)
{
try {
$sql = "INSERT INTO $this->table_sess ($this->col_sid,
$this->col_expiry, $this->col_data)
VALUES (:sid, :expiry, :data)
ON DUPLICATE KEY UPDATE
$this->col_expiry = :expiry,
$this->col_data = :data";
$stmt = $this->db->prepare($sql);
$stmt->bindParam(':expiry', $this->expiry, \PDO::PARAM_INT);
$stmt->bindParam(':data', $data);
$stmt->bindParam(':sid', $session_id);
$stmt->execute();
return true;
} catch (\PDOException $e) {
if ($this->db->inTransaction()) {
$this->db->rollback();
}
throw $e;
}
}
In 'Protected method', line 8, there is a $session_id, and clearly no $session_id is passed to the protected method, so bindParam() for that line simply binded nothing?
So initializeRecord() simply initiated a row that has expiry time but nothing else? And then the sid and data is inserted after write method is called?
This is doing a lot of string-construction trickery with WHERE $this->col_sid = :sid and so forth, as it creates SQL statements.
You might try echoing or dumping those SQL statements to see what they contain right before you run ->execute() on them. That will help you troubleshoot.
It's pretty clear your protected method is missing $session_id. Is it possible there's a value for $this->sid you could use there?

I keep getting error on fetch_assoc() in PHP

I am trying to create a login/register feature on my android app. One of my files contains a two functions that are being used by register and login. I keep getting an error, the same error when I try to do both. I am getting this error from my error_log file and I have tried google for a while now and can't seem to find a solution to my particular issue. The error I get is:
Call to a member function fetch_assoc() on a non-object in DB_Functions.php
and the parts I get the error are here:
Login:
public function getUserByEmailAndPassword($email, $password) {
$stmt = $this->conn->prepare("SELECT * FROM users WHERE email = ?");
$stmt->bind_param("s", $email);
if ($stmt->execute()) {
$user = $stmt->get_result()->fetch_assoc(); <----THIS LINE
$stmt->close();
return $user;
} else {
return NULL;
}
}
Register:
if ($result) {
$stmt = $this->conn->prepare("SELECT * FROM users WHERE email = ?");
$stmt->bind_param("s", $email);
$stmt->execute();
$user = $stmt->get_result()->fetch_assoc(); <----AND THIS LINE
$stmt->close();
return $user;
} else {
return false;
}

Categories