Error in my PDO function - php

I'm new to PDO CLASS programming, here's my question, I have this class that retrive some infos from DB and I really need something like that, I get the error on title:
Call to a member function prepare() on a non-object on query line:
$stmt = $this->db->prepare()
What I'm doing wrong?
class map{
private $db;
public $dir;
public $query;
function mapWant($query,$db,$dir){
$stmt = $this->db->prepare("SELECT ".$this->query." WHERE ID = :dir");
$stmt->execute(array(':dir'=>$this->dir));
$row=$stmt->fetch(PDO::FETCH_LAZY);
echo $row[0]; //I want retrive the only field that the result has
}
}
$map = new map();
$map->mapWant($dir,$db,"Breve");
$dir is a $_GET method that retrive only a number
$db = is PDO connection (that's work);
thank you in advance.

You are passing the $db reference as a parameter, but then trying to access it within the scope of your class. The same goes for $query and $dir.
You seem to be under the impression that any parameters passed to a method will be applied as class properties. This is not the case.
The following line:
$stmt = $this->db->prepare("SELECT ".$this->query." WHERE ID = :dir");
Should simply be:
$stmt = $db->prepare("SELECT ".$query." WHERE ID = :dir");
Provided that $db passed to $map->mapWant() is a valid database resource.

Related

query mysql database from inside a class using properties

Hi this is kind of an upgraded version of this question:
query mysql database from inside a class
The difference from the previous question, is i need a dynamic query not a static one or l$query = "SELECT col_1 FROM db.table"; So in order to have a dynamic query i need to use properties (or variables) so i can call different tables from that same class, or something like this "SELECT ‘$data’ FROM ‘$table’ ";
So far my class looks like this, similar to the previous question:
$mysqli = new mysqli("localhost", "root", "", "intranetpugle");
class crudmum {
private $table;
private $data;
private $mysqli;
function __construct($mysqli) {
$this->mysqli = $mysqli;
}
function runQuery($data2, $table2)
{
$this->table = $table2; $this->data = $data2;
$query = "SELECT '$this->data' FROM '$this->table' ";
$stmt = $this->mysqli->prepare($query);
$stmt->execute();
$stmt->bind_result($r);
while($stmt->fetch())
{
echo "<option>" . $r . "</option>";
}
}
};
This is how i run it:
$showme = new crudmum($mysqli);
$showme->runQuery("priority", "trackboards" );
Note: When i dont use variables or properties inside the query or somethng like this, SELECT priority FROM trackboards, the query does work, only when i input the properties or variables (like the given example) it does not work.
I get this error:
Fatal error: Call to a member function prepare() on a non-object in C:\xampp\htdocs\devserv\i+d\bootstrap\functions.php on line 76
Anyone see what am i doing wrong, of course there is a mistake with the database query any ideas on how to query the database right in a dynamic way within a class, sorry new with OOP with PHP!
found the mistake which was to add 'quotes' on the variables, like shown below:
$query = "SELECT '$this->data' FROM '$this->table' ";
The correct way would be to take out those 'quotes' on the variables or like this:
$query = "SELECT $this->data FROM $this->table ";
With that fix, the query runs just fine, guess i lacked attention to detail, thanx everyone for their help.

PDO SQL Placeholder issue [duplicate]

This question already has answers here:
Can PHP PDO Statements accept the table or column name as parameter?
(8 answers)
Closed 9 years ago.
Is it possible to bind a table name?
I want to make a class to read the columns from a tables and, depending on field type, generate the form inputs for me. When I do $form = new form("users");, the constructor is supposed to start with getting the field names from the table with the following code:
class form{
public function __construct($table, $skip = array("id")){
$pdo = new PDO('mysql:host=localhost;dbname=site;',USER,PASS);
$query = $pdo->prepare("DESCRIBE :table");
$query->bindValue(':table', $table, PDO::PARAM_STR, strlen($table));
$query->execute();
while($field = $query->fetch(PDO::FETCH_NUM)){
var_dump($field);
echo "<br /><br />";
}
unset($pdo);
}
}
This works just fine when I specify "users" instead of ":table" in the prepare statement, but the bind it's working, and I'm pretty sure it's because it's trying to bind a table name. Also, this needs to be binded because I'd like to have the ability to pass my table names through $_GET and the such.
Is it possible to bind a table name?
No.
You have to whitelist table names. I doubt you want to let a user to browse any table from your database.
Given you are using a class, it will be no-brainer to add a table name as a property. It will be simple, elegant and safe. Create an abstract parent class first
abstract class abstractTable {
private $table;
private $db;
public function __construct($pdo){
$this->db = $pdo;
}
public function describe() {
return $db->query("DESCRIBE `$this->table`")->fetchAll();
}
}
Then create a specific class for your table
class someTable extends abstractTable {
private $table = 'sometable';
}
and so you will be able to get the required list of columns
$pdo = new PDO(...);
$table = new someTable($pdo);
$fields = $table->describe();
simple, concise, powerful, safe.
There is a PDO wrapper class at - http://www.phpclasses.org/package/5997-PHP-Database-access-abstraction-layer.html that lets you do this (though I am new to PDO so maybe it isnt using prepared statements)
His suggested usage is:
$db = new DatabaseConnection('someMysqlServer', 'user', 'pass', 'database');
$result = $db->exec($db->filterForSql('SELECT * FROM '.$tableName.';'));
I would interested if others think this is a 'safe' way of using PDO or not.

Bind_param() on a non-object-error when using variables as input

trying to do an update using mysqli, by calling a class function like this:
$nyVaegt = 10;
$navn = 'Ord';
$nyOevelse = new oevelse();
$nyOevelse->opdaterOevelse( $nyVaegt, $navn );
And this is the corresponding class function:
public function opdaterOevelse (
$nyVaegt,
$navn)
{
$this->nyVaegt = $nyVaegt;
$this->navn = $navn;
global $mysqli;
$stmtopdaterOevelseIHistorik = $mysqli->prepare("UPDATE oevelser SET `vaegt12reps`=? WHERE `navn`='?' VALUES (?, ?)");
var_dump($stmtopdaterOevelseIHistorik);
$stmtopdaterOevelseIHistorik->bind_param(
"ds",
$nyVaegt,
$navn);
$stmtopdaterOevelseIHistorik->execute();
if ( $stmtopdaterOevelseIHistorik )
echo "Query success!<br>";
else
echo "Query failed!<br>";
}
If I run it like this, it fails saying that:
Call to a member function bind_param() on a non-object
The error refers to this line:
$stmtopdaterOevelseIHistorik->bind_param(
var_dump responds: bool(false)
So, something goes wrong while binding the parameters, it seems.
If I bypass the variables and call like this:
$stmtopdaterOevelseIHistorik = $mysqli->prepare("UPDATE oevelser SET `vaegt12reps`=100 WHERE `navn`='Ord'");
it works fine...
Tried all kinds of '', ""-variations, but I can't make it work... - any advice from you good people of SO...?
Far as I know, UPDATE doesn't use VALUES:
http://dev.mysql.com/doc/refman/5.0/en/update.html
INSERT does: http://dev.mysql.com/doc/refman/5.6/en/insert.html
Plus, remove the quotes in ='?' which is the main cause for:
Call to a member function bind_param() on a non-object
Change your existing line to the following:
$stmtopdaterOevelseIHistorik = $mysqli->prepare("UPDATE oevelser SET `vaegt12reps`=? WHERE `navn`=?");

PHP arrays of objects with mySQL

Is there an easy way to make an array of objects in php when you have the objects attributes come from a mySQL query?
My code is below in order to show you what I'm doing. I'm probably far off because I'm not used to php at all and I can't grasp it for some reason.
public function loadMeals(){
$stmt = $this->conn->prepare("SELECT id, dishName, ingredients FROM meals");
$stmt->execute();
$stmt->bind_result($id, $dishName, $ingredients);
$meals = array();
while ($stmt->fetch()) {
$this->id = $id;
$this->dishName = $dishName;
$this->ingredients = $ingredients;
$meals[] = $this;
}
return $meals;
}
Keep in mind that this is all in a class Meals.
Thanks guys.
Based on how you are using it (creating an array of Meal objects, the method should be declared as a static method, called without $this context. The loop may create Meal objects via new self() and set the appropriate properties before appending onto the array.
If you think about it, this method's purpose is not to act on a single Meal, so it makes sense for it to be static.
Since it is called without $this context, you will need to pass the MySQLi connection as a parameter
public static function loadMeals($conn) {
// Do the query/fetch like you already have
// except that $conn is a local param, not a class prop.
$stmt = $conn->prepare("SELECT id, dishName, ingredients FROM meals");
$stmt->execute();
$stmt->bind_result($id, $dishName, $ingredients);
$meals = array();
while ($stmt->fetch()) {
// Create a new Meal object
$meal = new self();
// And set its properties
$meal->id = $id;
$meal->dishName = $dishName;
$meal->ingredients = $ingredients;
// Append it to the array
$meals[] = $meal;
}
// Return it
return $meals;
}
To use it, outside the class:
// Call the function statically.
// You'll need to pass the database connection to it
$meals = Meal::loadMeals($conn);
I'll point out that while it is very good to be in the habit of doing prepare()/execute(), you do not actually need it here since you are not passing any input into the query. You can just call $conn->query(), eliminating some complexity from MySQLi's bind_result() variable references.
$result = $conn->query("SELECT id, dishName, ingredients FROM meals");
if ($result) {
// Fetch and instantiate a Meal object in one go.
while ($meal = $result->fetch_object('Meal')) {
$meals[] = $meal;
}
}
This might be a short solution to your problem but consider using mysql_fetch_assoc when grabbing your elements from the database.
For more reading and example:
mysql_fetch_assoc documentation from php.net
For PDO:
public function loadMeals(){
$stmt = $this->conn->prepare("SELECT id, dishName, ingredients FROM meals");
$stmt->execute();
$meals = array();
while ($obj = $stmt->fetch(PDO::FETCH_OBJ)) {
$meals[] = $obj;
}
return $meals;
}
or $meal = $stmt->fetchObject('MyMeal', $ctor_args); See this from PHP manual. Also note the first comment about constructors there, to expect the unexpected results that using this may cause.

pdo fetchAll() returns empty array() [duplicate]

This question already has an answer here:
Having issue with matching rows in the database
(1 answer)
Closed 2 years ago.
I have been trying for over a day now to get FetchAll() method to help me display array from database. But all my efforts have failed. Instead of the print_r() returning an array, it gives me this array(). Kindly, help me out.
The code in class page :
class Article {
public function fetch_all(){
global $conn;
$ass = $conn->prepare("SELECT * FROM articles");
$ass->execute();
return $ass->fetchAll();
}
}
while the code in display page is:
$article = new Article;
$articles = $article->fetch_all();
print_r($articles);
$query is not defined in your code, $ass->fetchAll(); is what you should have.
$query is not defined. Consider injecting your database object into the Article object to avoid using globals.
class Article {
public function fetch_all(PDO $conn){
$ass = $conn->prepare("SELECT * FROM articles");
$ass->execute();
return $ass->fetchAll();
}
}
$article = new Article;
$articles = $article->fetch_all($conn);
print_r($articles);
Injecting your PDO object can make changing the code easier down the line.
I have tried the following code below it works perfect.
class Article {
public function fetch_all(){
global $connection;
$ass = $connection->prepare("SELECT * FROM test");
$ass->execute();
return $ass->fetchAll();
}
}
$article = new Article;
$articles = $article->fetch_all();
print_r($articles);
As you see above i have used my $connection and it works perfect.
So, the problem is definitely on your $conn (connection).
check your connection again.
It has eventually started returning full array. All I did was to uninstal the WAMPserver I was using and replace it with another one.

Categories