Php singleton class :PDO Query result as array in php - php

I am working small php project and i am using singleton database class from this repo
The problem is i can't get query result as array value.Here is my code
Core.php
class Core extends Database
{
public static function run($sql)
{
return parent::getInstance()->getConnection()->query($sql);
}
public function getUniversities()
{
$sql = 'SELECT * FROM `adm_universities`';
return Core::run($sql);
}
}
//get the data from db
$result=Core::getUniversities();
print_r($result);
But the PDOStatement Object returns only the queryString not the result array.
what's wrong with this code?

You can either use foreach loop over PDOStatement or get a conventional array from it using fetchAll() method.
foreach ($result as $row) ...
// or
$data = $result->fetchAll();
print_r($data);
Note that this singleton class makes very little sense as it doesn't support prepared statements.
Also, there should be no getUniversities() in the Core class. That's bizarre thing for the OOP.

You have not used fetch or fetchall or find it seems.
Check the pdo manual properly.
You have to execute the query and then you have to use result functions to get the result array

Related

PHP7/PDO: Returning PDOStatement Object and fetch data later

I am currently in the process of updating my web application from PHP 5.6 to PHP 7, therefore I need to alter the database abstraction class that has been using the old MySQL-Extension.
The class has a method "Query()" where SQL statements are being prepared and executed and a method "Fetch()" which fetches a single row and returns it. See the simplified versions:
function Query($query='')
{
$result = $this->connection->Prepare($query);
$result->Execute();
return $result;
}
function Fetch($resource=null)
{
return $resource->Fetch(PDO::FETCH_ASSOC);
}
So basically what I am trying to do is this:
$statement = Query('SELECT * FROM Test');
$firstRow = Fetch($statement);
print_r($statement) shows me this:
PDOStatement Object
(
[queryString] => SELECT * FROM Test
)
But when I call "Fetch", there is no row returned. Can someone tell if it's possible to return PDOStatement objects and pass them into other functions/methods for "later use"?
PS: Of course I know that this is not best practice but I am trying to avoid having to alter thousands of lines of code in the application.

Cast codeigniter database result object to custom object

Codeigniter can return a database query as generic "Object" like:
$q = $this->db->get("some_table");
$obj = $this->q->row();
$var = $obj->some_property
In my case I want to make a PHP class who's public variables are 1 for 1 with the database columns, along with some public methods. Is there a quick one-shot way to cast or convert the generic "Row" object into my custom class object? I've read posts that hint that it is certainly possible, but most involve a really hacky serialize/deserialize solution. In the past I have just done:
public function __construct($row) {
$this->prop = $row->prop;
$this->id = $row->id;
$this->value = $row->value;
}
And I find this is very tedious and makes ugly code.
See the third section under result():
CodeIgniter User Guide: Generating Query Results
You can also pass a string to result() which represents a class to instantiate for each result object (note: this class must be loaded)
$query = $this->db->query("SELECT * FROM users;");
foreach ($query->result('User') as $row)
{
echo $row->name; // call attributes
echo $row->reverse_name(); // or methods defined on the 'User' class
}

Zend framework current method to get single row

i'm new to zend framework, in this simple function i want to get a single 'post' and then i want to find all the comments in the related table
public function getPost($idPost)
{
$db= Zend_Registry::get('db');
$select=$db->select()
->from($this->_name, '*')
->where("idPost= ".$db->quote($idPost, 'INTEGER'));
$stmt=$select->query();
$rowset=$stmt->fetchAll();
$post=$rowset->current();
//ora devo aggiungerci i commenti che questo post ha ricevuto
$comm=$post->findDependentRowset('commenti');
$ris=array($post, $comm);
return $ris;
}
in my index controller i i simply call this function, but i get this error:
Call to a member function current() on a non-object in C:\xampp\htdocs\...
where's the mistake?
I think you have a few misconceptions about how you're using Zend_Db.
1. You're not using the ORM, just the PDO wrapper
Which means, your queries won't return Zend rowsets and rows and therefore you can't use the methods of you can use on those.
2. The default fetch mode
The default fetch mode of the Zend_Db_Statement fetchAll() method is array, if you want it to return an object (stdClass), change the fetch mode before fetching the data:
$stmt->setFetchMode(Zend_Db::FETCH_OBJ);
3. Using fetchAll() when you actually want one row
If you just want one row, then don't fetch a whole table! With Zend_Db_Statement, use for example:
$row = $stmt->fetch();
or
$rowObj = $stmt->fetchObject();
... again, that's not a zend row object, just a stdClass instance, but you can do:
$rowObj->some_field;
on it.
On the other hand, if this is a method in your Post model, it should look something like:
public function getPost($idPost)
{
return $this->getRow($idPost);
}
This will return the post, then, if you've setup the table relationships correctly, you can also query for the dependent data or just get all comments with that id separately.
The problem is that unless you define a table class as was previously mentioned you can't uuse the dependent or parent rowsets.
To make your current function work would be best done with two functions, and keep it simple:
public function getPost($idPost)
{
$db= new Zend_Db_Table($this->_name);
$select=$db->select()
->where("idPost= ?", $idPost);
/*Fetch just the row you want, or use fetchAll() if you need to match return types*/
$row = $db->fetchRow($select);
return $row;
}
public function getComments($table='comments', $id) {
$db = new Zend_Db_table($table);
$select = $db->select()->where('post_id = ?', $id)->order('date ASC');
$rowset = $db->fetchAll($select);
return $rowset/* or you could return an array ->$rowset->toArray() */
}
Zend_Db_Table is going to attempt to use the current database adapter, so all you need to do is pass in the tablename.
One more note: you don't need to use any of the quote() function when using select() it's taken care of.
But it is really important, that if you are going to use Zend_Db, you need to learn about "Defining table classes". At least enough to use them in your own classes.
I hope this helps!
To get a rowset and dependent rowset you have to use Zend_Db_Table.
You only use the Zend_Db_Adapter with Zend_Db_Select.
Read from here.
So you have to define a class which extends from Zend_Db_Table_Abstract.
Example:
class Bugs extends Zend_Db_Table_Abstract
{
protected $_name = 'bugs';
protected $_primary = 'bug_id';
}
To get the Zend_Db_Table_Rowset object use:
$bugs = new Bugs();
$rowset = $bugs->fetchAll("bug_status = 'NEW'");
To find dependent rowsets you have to define the relation in your table class. Look here how to define relationships.

How is a PDO result set stored

I've been studying PHP for 2 months now as my first scripting language. For most of my problems i can easily find an answer online, but there's something about PDO that i can't seem to understand.
In order to retrieve data from a database I instantiate a new object of the PDO class and call the PDO::query() method on it. This returns a PDOStatement object which carries the result set from the SQL query. Here's where the problem starts. I can't seem to understand how and where the data from the result set is stored.
In the PHP Manual i learned to display the returned rows by iterating over the PDOStatement object with a foreach loop. However, the PHP manual clearly states that if an object is converted to an array, the result is an array whose elements are the object's properties. The PDOStatement only has one property - $queryString - containing the issued query string. So... where are the query results stored? And why can I reach them through an array with a foreach loop, but not outside of it?
// Instantiate new PDO object to establish a new connection with MySQL database
$db = new PDO('mysql:dbhost=localhost;dbname=world', 'root', 'secret');
// Execute SQL query - Returns a PDOStatement object
$result = $db->query("SELECT Name, Continent, Population FROM Country");
// Result set can be accessed with a foreach loop iterating over the PDOStatement object
foreach ($result as $row) {
echo "$row[Name] - $row[Continent] - $row[Population] <br />";
}
// Outside the foreach loop, $result cannot be accessed this way.
// This produces 'Cannot use object of type PDOStatement as array'
echo $result[0]['Name'];
The PDOStatement class implements the Iterator interface, which lets its objects be iterated through.
Iterator extends Traversable {
/* Methods */
abstract public mixed current ( void )
abstract public scalar key ( void )
abstract public void next ( void )
abstract public void rewind ( void )
abstract public boolean valid ( void )
}
For an object that implements the Iterator interface,
foreach($result as $row) {
// Code
}
is equivalent to
for ($result->rewind(); $result->valid(); $result->next()) {
$row = $result->current();
// Code
}

mysqli superglobal connection object, more than one connection at time

I've been using this solution to get a superglobal mysqli connection:
class blst_db {
private static $mysqli;
private function __construct(){} //no instantiation
static function cxn() {
if( !self::$mysqli ) {
self::$mysqli = new mysqli(...);
}
return self::$mysqli;
}
//use
blst_db::cxn()->prepare(....
I found it here and it was working fine but when I try to get two connections at the same time I get an error. For example, I've a class that runs a query like this one:
$query_points = blst_db::cnx()->prepare('SELECT point_id FROM points WHERE id=?');
$query_points->bind_param('i', $this->id);
$query_points->bind_result($point_id);
$query_points->execute();
while ($query_points->fetch()) {
$point = new blst_point ($point_id);
$points[] = $point; }
I'm creating various objects inside the while statement and that objects constructor runs another query each time (another $query=blst_db::cnx->prepare(...)) and that's the one that is not working and I can't find the problem. If I change the code and create an array inside the while statement and then, after closing that query, I create all the objects inside a foreach I get no problem but I don't like that solution.
Thank you!
I found the problem. I have to store the results from the first query so I can run the rest inside it. I just added:
$query_points->store_result();
after the execute() call and then I made a free_result() before closing the $query_points and it's working perfectly.
I've found the solution here.

Categories