Reputation: 8004
How do people usually turn mysqli results into objects?
I cannot find any examples with fetch_object() when using custom classes. Assume the following setup
class Test1 {
function __construct(array $data) { ... }
}
class Test2 {
function __construct(array $data) { ... }
}
Assume that I have multiple classes with the same constructors, how can I dynamically instantiate these classes?
I would imagine something like this:
function customQuery($query, $class) {
// Get some data by mysqli query, assume we get the data as $result object
...
// Now I would like to store the data in an array with instances of $class
$array = array();
while ($obj = $result->fetch_object($class, ???) {
$array[] = $obj;
}
// Return the array with instances of $class
return $array;
}
What do I use as arguments there for my question marks? I only know that both class constructors of Test1 and Test2 want an associative array as input (probably not the same length!).
In the end I simply want to do something like
$arr1 = customQuery('SELECT id, product FROM test1 LIMIT 10', 'Test1');
$arr2 = customQuery('SELECT id, name, address FROM test2 LIMIT 10', 'Test2');
Of course I would appreciate your input if you have better ideas to achieve my goal.
Upvotes: 3
Views: 14670
Reputation: 21
Here is the proper way to use it:
<?php
$res = $mysqli->query($q);
while($params = $res->fetch_assoc()):
endwhile;
$res->free();
$res = $mysqli->query($q);
while ($obj = $res->fetch_object('ClassName', array($params)):
$obj_list[] = $obj;
endwhile;
?>
mysqli::fetch_object()
doesn't send the fields names and values to the constructor, it just creates an object with the attributes without passing by the setters. If you want to pass by the constructor, you must first recover the result and give it to him in an array in parameters.
So what's happening if you want to pass by the constructor? At first, fetch_object()
will create the attributes then it will overwrite them passing by the constructor.
Upvotes: 0
Reputation: 86
The fetch_object() method will return an instance of stdClass. If you specify a class name, however, it'll return an instance of that class and populate attributes based on the data returned. You do NOT need to specify all of your columns in the class unless you want to change their visibility (i.e. protected or private). Otherwise they'll default to public.
Also, it's a good idea to have a static method within the class you want to instantiate to separate concerns neatly. See:
class Class_Name
{
public static function customQuery($query)
{
$return = array();
if ($result = $mysqli->query($query)) {
// not passing a class name to fetch_object()
// will return an instance of stdClass
while ($obj = $result->fetch_object('Class_Name')) {
// add the fetched object (as an instance of the
// 'Class_Name' class in this case) to the return array.
$return[] = $result;
}
return $return;
}
// return false if no results found
return false;
}
}
Call the static method thus and you'll get an array of 'Class_Name' objects:
$results = Class_Name::customQuery($query);
If you're only querying for 1 result the above would be like this:
class Class_Name
{
public static function customQuery($query)
{
$return = array();
if ($result = $mysqli->query($query)) {
return $result->fetch_object('Class_name');
}
// return false if no results found
return false;
}
}
With this you'll get a single 'Class_Name' object.
Note, if you're using a namespaced class apply the fully qualified namespaced class name.
Upvotes: 2
Reputation: 4320
Take a look at "fetch_object'
You have a argument $class_name
From the docs: The name of the class to instantiate, set the properties of and return. If not specified, a stdClass object is returned.
It will automaticly create an instance of the given class and it will set the properties. so no need to pass an array http://www.php.net/manual/en/mysqli-result.fetch-object.php
A bit more explanation,
The fetch_object just fills the private properties etc (PHP Magic... i don't like it).
If your object has required parameters in the constructor but you want to fetch it from the database the fetch_object lets you define arguments for the constructor so it can be constructed instead of throwing warnings/errors.
class Test {
private $title;
public function __construct($required) {
}
}
$mysql->fetch_object('Test'); //will trigger errors/warnings
$mysql->fetch_object('Test', array(null)); //won't
What you could do is simpel fetch an array and construct the object
function query($query, $class) {
$data = $query->fetch_assoc();
$instance = new $class($data);
return $instance;
}
Upvotes: 3
Reputation: 157839
There is not much use for this function.
Better make your object's constructor to accept an array with settings and use like this
while ($row = $result->fetch_assoc($res) {
$array[] = new Foo($row);
}
also note that fetch_assoc/fetch_object isn't always available with prepared statements.
Upvotes: 1
Reputation: 1754
You use fetch_object on a result. You do while ($obj = $result->fetch_query()) { ... }
function customQuery($query) {
if ($result = $mysqli->query($query)) {
while ($obj = $result->fetch_object()) {
# do stuff.
}
} else {
# raise some error, query did not make it.
}
}
If you specify param
, this is a class that will be instantiated to handle the results.
# $result->fetch_object('MyClass');
MyClass {
private $id;
public function __construct($id/* fields */) {
$this->id = $id; # say `id` is the only field
}
}
Upvotes: 0