PHP - prepared statements result as an object [duplicate] - php

This question already has answers here:
Is it possible to use mysqli_fetch_object with a prepared statement
(3 answers)
Closed 6 years ago.
So, I have the following function:
private function getUserData($user_nickname)
{
if ($this->databaseConnection()) {
$stmt1=$this->dbh->prepare('SELECT * FROM users WHERE nickname = ?');
$stmt1->bind_param('s', $user_nickname);
$stmt1->execute();
return $stmt1->fetch_object();
}
else {
return false;
}
}
And I get the following error: Fatal error: Uncaught Error: Call to undefined method mysqli_stmt::fetch_object()
I did a little research and I didn't find any fetch object in mysqli_stmt
http://php.net/manual/en/class.mysqli-stmt.php
Does it means that if I use prepared statements, I can't use result as an object? I really want it to work as an object.
P.S. I use mysqli.

Mysqli is not a very usable API.
You can try to use get_result() but it could be unavailable on your system.
Let me suggest you to use PDO instead of mysqli:
private function getUserData($user_nickname)
{
$stmt = $this->dbh->prepare('SELECT * FROM users WHERE nickname = ?');
$stmt->execute([$user_nickname]);
return $stmt->fetch(PDO::FETCH_OBJ);
}
Among other benefits over mysqli, PDO can return not only an anonymous stdObject but can create an instance of an existing class, passing parameters to constructor. Say, if you have a User class, you may write
private function getUserData($user_nickname)
{
$stmt = $this->dbh->prepare('SELECT * FROM users WHERE nickname = ?');
$stmt->execute([$user_nickname]);
return $stmt->fetchObject('User');
}

Related

How to delete a row in a database with pdo ($stmt stated false) [duplicate]

This question already has answers here:
delete using where and or
(4 answers)
Why does this PDO statement silently fail?
(2 answers)
Closed 4 years ago.
I'm coding a blog to get experience with php.
I want the admin to be able to delete a post, but when I click the delete-button which should actually bring me to a function that deletes the post I get the error Call to a member function execute() on boolean.
Here is the code of the postsRepository.php which interacts with the database and the function in the postsAdminController.php:
public function deletePost($id)
{
$table = $this->getTableName();
$model = $this->getModelName();
$stmt = $this->pdo->prepare("DELETE * FROM `{$table}` WHERE id = :id");
$stmt->execute([
'id' => $id
]);
}
public function deletePost()
{
$id = $_GET['id'];
if ($this->postsRepository->deletePost($id)) {
header("Location: posts-admin");
return;
} else {
}
}
I've var_dumped the $id right before the $stmt, it's correct and the shown error says the it is because of $stmt->execute([.
The $stmt is stated as false when I var_dumped it, but why?
The correct syntax for DELETE is
DELETE FROM tableName WHERE ...
Remove the * in your query.
$stmt is false because "If the database server cannot successfully prepare the statement, PDO::prepare() returns FALSE or emits PDOException (depending on error handling)."
For more informations, check the documentation

Handle PHP objects on declaration file for every method call [duplicate]

This question already has answers here:
What to do with mysqli problems? Errors like mysqli_fetch_array(): Argument #1 must be of type mysqli_result and such
(1 answer)
MySQLi prepared statements error reporting [duplicate]
(3 answers)
Closed 4 years ago.
I am looking for a way to build a handler or edit a php object, the following is an example for mysqli
I have a system with many files using the mysqli object in a variable
$my_var=new mysqli($host, $user, $pass, $base);
Files call this to do queries and get the results like this:
$q=$my_var->query("SELECT * FROM table");
$q->fetch_assoc();
if there is an error on the query, $my_var->error will be populated on the first line and will throw an error 500 on the second line.
I am looking for a way to build a handler for $my_var->error and throw the error before any fetch_* method is called, so,
is there any way to build a handler/listener for $my_var->error?
if this is not possible, is there any way to override mysqli fetch_assoc(), fetch_row() and fetch_array() methods to check if $my_var->error is true and show the error before continue?
I know about try{}catch(), throw new Exception and or die() methods, but these mean to edit every fetch_* in the system, I would like to do it editing the connection file only.
Thank you!
---editing---
I think prepared statements are not what I am looking for.
---editing 2---
And no, I am not looking how to get mysqli errors.
Thank you for your help fyrye!
---Answer Final Code---
class mysqli2{
private $c;
function __construct(...$args){ // open connection
$this->c=new mysqli(...$args);
if(!empty($this->c->error)){ // check for errors
echo("<script>console.error(\"MySQL: ".$this->c->error."\");</script>");
}
}
function query($query, $resultmode = MYSQLI_STORE_RESULT){
$r=$this->c->query($query, $resultmode); // make query
if(!empty($this->c->error)){ // check for errors
echo("<script>console.error(\"MySQL: ".$this->c->error."\");</script>");
}
return $r; // returns query results
}
function __call($method, $args){ // calls others mysqli methods
return $this->c->$method(...$args);
}
function __get($name){ // get all the properties
return $this->c->$name;
}
function __set($name, $value){ // set all the properties
if (property_exists($this->c, $name))$this->c->$name = $value;
}
}
To suggest a best practice, when using either PDO or MySQLi extensions, it is suggested to always check the return results from any of the usable methods, before moving on to a method that relies on its result.
As mysqli::query returns false on an error, it should be checked before using fetch_assoc, instead of assuming it is not false. The same applies to using fetch_assoc, as it can return NULL;
if (!$q = $my_var->query($sql)) {
//something went wrong - handle the error here.
}
if ($data = $q->fetch_assoc()) {
echo $data['column'];
}
However as I suggested, you would need to create an abstraction layer.
Since $q would be false on error, the exception from the code in your question would be:
Fatal error: Call to a member function fetch_assoc() on boolean
Meaning you would not be able to override the fetch_* methods, without overriding mysqli::query to always return an object.
Please do not use in production code.
This is only an example of how to override the mysqli::query method with your own. You would also need to override all other mysqli::*** methods, like prepare, commit, etc.
Example https://3v4l.org/PlZEs
class Conn
{
private $conn;
public function __construct(...$args)
{
$this->conn = new mysqli(...$args);
}
public function query($query, $resultmode = \MYSQLI_STORE_RESULT)
{
$d = $this->conn->query($query, $resultmode);
if (!empty($this->conn->error)) {
throw new \RuntimeException($this->conn->error);
}
return $d;
}
}
//Your connection code
$con = 'my_var';
$$con = new Conn('host', 'user', 'pass', 'base');
//example usage of valid query
$q = $my_var->query('Valid Query');
$q->fetch_assoc();
//example use of invalid query throwing an exception before `fetch_assoc`
$q = $my_var->query('This is not valid');
$q->fetch_assoc();
Results
I was successful
-----
Fatal error: Uncaught exception 'RuntimeException' with message 'Expected "Valid Query"' in /in/PlZEs:51
Stack trace:
#0 /in/PlZEs(70): Conn->query('This is not val...')
#1 {main}
thrown in /in/PlZEs on line 51
This approach uses PHP 5.6 argument packing and unpacking, to match the function call arguments, to prevent having to manually define them.
It is possible to expand on this to write a message to log file, send an email, trigger an event, or display a friendly error message instead of throwing an exception. As well as overriding the mysqli_stmt responses with your own Statement object(s).

Difference between $con->prepare versus $con->sqli->prepare [duplicate]

This question already has answers here:
What does the variable $this mean in PHP?
(11 answers)
Closed 4 years ago.
I was always taught and used $con->prepare for prepared statements. However, this article two answers posted people where using $con->sqli->prepare. I also saw a few others using it in other articles.
Is this something to be concerned with?
What is the difference?
Usually some people make database connection class with constructor of connection. It means that when you initialize the object of that class, the constructor is executed automatically.
For example here is Database class
<?php
class db
{
public $conn;
public function __construct()
{
$this->conn=mysqli_connect("localhost","root","","prepared");//A constructor is a function that is executed after the object has been initialized (its memory allocated, instance properties copied etc.). Its purpose is to put the object in a valid state.
if($this->conn)
{
echo "";
}
else{
echo $this->conn->error;
}
}
}
$db = new db();
?>
Child class
include("db.php");
class childclass extends db
{
public function database_query()//here you don't need to put $conn in parameters
{
$sql = "SELECT * FROM table";
$result = $this->conn->query($sql);//Here you can see how we can call conn from db class
print_r($result);
}
}
I hope you got my point.

PDO prepeared statements PHP Call to undefined method PDO::execute() [duplicate]

This question already has an answer here:
Call to undefined method PDO::execute()
(1 answer)
Closed 5 years ago.
I am new to php mysqli ect and i have done my best to arrange a prepeared statement function to no avail. All i get is the following Error.
Call to undefined method PDO::execute()
I donnot understand why this is happening.
The values are being passed and echo'd but i still get this error.
It does not retrieve data from database either as error is called before doing so.
Can anybody see from the code what the problem is.. iv searched about on the net ect. and the closest i got what about checking the Isset of the inputs, but i had allready done this so thats not the issue.
im baffled.
Thanks for any advice... Its probly really simple. But so am i.
<?php
//include('conect.php')
$dbh = new PDO("mysql:host=localhost;dbname=classifieds", 'root', '');
$type=$_POST['type'];
$price=$_POST['price'];
if (isset($type) && isset($price)) {
echo $type;
echo $price;
$dbh->prepare('SELECT * FROM testdata WHERE type=? AND price=?');
$stm = $dbh->execute(array($type, $price));
if(($row = $stm->fetchObject())) {
$type=$row['type'];
$price=$row['price'];
echo $type;
echo $price;
} else
{ echo "none recieved"; }
} else
{echo "invalid"; }
?>
You have to assign $dbh->prepare('SELECT * FROM testdata WHERE type=? AND price=?'); to a variable and then call execute() method on it.
Example:
$smth = $dbh->prepare('SELECT * FROM testdata WHERE type=? AND price=?');
$result = $smth->execute(array($type, $price));
That's because PDO doesn't have execute method but PDOStatement object resolved from prepare method does.

Prepared statement returns bind_param() on a non-object [duplicate]

This question already has answers here:
Call to a member function bind_param() on a non-object [duplicate]
(6 answers)
Closed 7 years ago.
I'm trying to create a simple api which adds views to a table. i've then tried to use prepared statements inorder to avoid SQL injections, but cant seem to make it work. It keep returning following error: (Fatal error: Call to a member function bind_param() on a non-object in)
$con = new mysqli('host','user','pass','db');
$type = $_GET['type'];
$identifier = $_GET['identifier'];
$news = $_GET['newsid'];
$check = $con->prepare("SELECT * FROM news WHERE news.news_id =? OR news.type =? OR news.identifier=?");
$check->bind_param("iss", $news, $type, $identifier);
$check->execute();
if ($check->fetchColumn() > 0) {
$add_view = $con->prepare("INSERT INTO views VALUES (:news_id, :identifier, :type, CURRENT_TIMESTAMP())");
$add_view->bindValue(':news_id', $news);
$add_view->bindValue(':identifier', $identifier);
$add_view->bindValue(':ntype', $type);
$add_view->execute();
}
I think you are mixing mysqli and PDO implementation here. You should use bind_param for mysqli. bindParam and bindValue are PDOs.
Turn on warnings. You have an error somewhere in your syntax. So $con->prepare returns false and issues a warning.
You can find the text of the error in $con->error.

Categories