I wrote a child of mysqli with a query method that returns a child of mysqli_result. This result child will have additional methods unique to my app.
public MySQL extends mysqli
{
public function query($query)
{
if ($this->real_query($query)) {
if ($this->field_count > 0) {
return new MySQL_Result($this);
}
return true;
}
return false;
}
}
class MySQL_Result extends mysqli_result
{
public function fetch_objects() {
$rows = array();
while($row = $this->fetch_object())
$rows[$row->id] = $row;
return $rows;
}
}
What I can't figure out is whether fetch_object()
uses buffered or unbuffered SQL data.
The constructor of mysqli_result
isn't visible in mysqli.php
, so I can't see if its calling $mysqli->store_result()
or $mysqli->use_result()
.
I tried adding these methods to MySQL
but neither function is echoed.
public function store_result($option='a') {
echo "STORE RESULT<br/>";
}
public function use_result($option='a') {
echo "USE RESULT<br/>";
}
Does this mean that the mysqli_result
constructor doesn't call either? If so, how does it access the SQL data when fetch_object
is called?
I want buffered SQL data. If I can't figure out what the child constructor is doing, I may have to replace the result child class with a decorator that calls $mysqli->store_result()
.
The answer is neither. The constructor of mysqli_result
doesn't call any of these methods. However, mysqli_query()
internally calls mysql_store_result()
or mysql_use_result()
which are C level API functions. Even if you extend mysqli class, you won't see your new methods getting called though. You have to understand that mysqli extension is written in C, not in PHP. The way that the code is written cannot be expressed in PHP very easily.
If you are using mysqli::real_query()
to execute SQL then you need to take care of calling either mysqli_store_result()
or mysqli_use_result()
function yourself. Of course, these functions will return mysqli_result
object instead of your MySQL_Result
one. It's going to be impossible to inherit from this class.
You can use composition instead of inheritance. You would pass mysqli_result
object you get from either of these two functions into the constructor of your MySQL_Result
class.
For example:
class MySQL
{
private mysqli $mysqli;
public function __construct(string $host, string $username, string $passwd, string $dbname)
{
$this->mysqli = new mysqli($host, $username, $passwd, $dbname);
}
public function query(string $query): MySQL_Result | bool
{
if ($this->mysqli->real_query($query)) {
if ($this->mysqli->field_count > 0) {
return new MySQL_Result($this->mysqli->store_result());
}
return true;
}
return false;
}
}
class MySQL_Result
{
public function __construct(private mysqli_result $result)
{
}
public function fetch_objects()
{
$rows = array();
while ($row = $this->result->fetch_object()) {
$rows[$row->id] = $row;
}
return $rows;
}
}
Important: The functionality that you require is already available with PDO. If you don't have a good reason to use mysqli, try using PDO instead.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With