我用一个返回mysqli_result子节点的查询方法写了一个mysqli的孩子。此结果子项将具有我的应用程序独有的其他方法。
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;
}
}
我无法弄清楚fetch_object()
是否使用缓冲或无缓冲的SQL数据。
在mysqli_result
中看不到mysqli.php
的构造函数,因此无法查看其是否正在调用$mysqli->store_result()
或$mysqli->use_result()
。
我尝试将这些方法添加到MySQL
但两种功能都没有被回应。
public function store_result($option='a') {
echo "STORE RESULT<br/>";
}
public function use_result($option='a') {
echo "USE RESULT<br/>";
}
这是否意味着mysqli_result
构造函数也没有调用?如果是这样,在调用fetch_object
时如何访问SQL数据?
................
我想要缓冲的SQL数据。如果我无法弄清楚子构造函数在做什么,我可能必须用调用$mysqli->store_result()
的装饰器替换结果子类。
我是PHP / OOP的新手,非常感谢反馈。谢谢。
答案 0 :(得分:1)
答案都不是。 mysqli_result
的构造函数不调用任何这些方法。但是,mysqli_query()
在内部调用 mysql_store_result()
或 mysql_use_result()
,它们是 C 级 API 函数。即使你扩展 mysqli 类,你也不会看到你的新方法被调用。您必须了解 mysqli 扩展是用 C 编写的,而不是用 PHP 编写的。代码的编写方式无法用 PHP 轻松表达。
如果您使用 mysqli::real_query()
来执行 SQL,那么您需要自行调用 mysqli_store_result()
或 mysqli_use_result()
函数。当然,这些函数将返回 mysqli_result
对象而不是您的 MySQL_Result
对象。从这个类继承将是不可能的。
您可以使用组合代替继承。您将从这两个函数中获得的 mysqli_result
对象传递给 MySQL_Result
类的构造函数。
例如:
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;
}
}
重要提示:您需要的功能已经在 PDO 中可用。如果您没有充分的理由使用 mysqli,请尝试使用 PDO。
答案 1 :(得分:0)
mysqli_result
uses buffered results from MySQL(强调我的)
查询默认使用缓冲模式。这意味着查询结果会立即从MySQL服务器传输到PHP,然后保存在PHP进程的内存中。这允许额外的操作,例如计算行数,以及移动(寻找)当前结果指针。它还允许在处理结果集时在同一连接上发出进一步的查询。缓冲模式的缺点是较大的结果集可能需要相当多的内存。内存将保持占用状态,直到未设置对结果集的所有引用或显式释放结果集,这将在请求结束时自动发生。术语&#34;存储结果&#34;也用于缓冲模式,因为整个结果集一次存储。
这个过程就是这个
mysqli_query
和mysqli_get_result
(预编译语句)会将此数据集加载到mysqli_result
对象您实际上必须不遗余力地执行异步查询
答案 2 :(得分:0)
看来mysqli_result正在使用缓冲的SQL数据。
我写了一个测试用例,它交替访问两个查询中的行。如果数据是无缓冲的,则SQL服务器将很忙,无法回答第二个查询。
/* Open a connection */
$mysqli = new MysqlDB("127.0.0.1", "phpuser", "phpuserpw", "wishlist");
if (mysqli_connect_errno())
return;
if ($result = $mysqli->query("SELECT * FROM wishers")) {
$res2 = $mysqli->query("SELECT * FROM wishes");
echo "Mem = ".memory_get_usage()."<br/>";
while($row = $result->fetch_row()) {
$row2 = $res2->fetch_row();
printf ("1: ID=%s, Name=%s, Pass=%s<br/>",$row[0],$row[1], $row[2]);
printf ("2: ID=%s, WisherID=%s<br/>", $row2[0], $row2[1]);
echo "Row Mem = ".memory_get_usage()."<br/>";
}
1:ID = 1,Name = Tom,Pass = tomcat
2:ID = 3,WisherID = 2
1:ID = 2,Name = Jerry,Pass = jerrymouse
2:ID = 4,WisherID = 2
1:ID = 6,Name = Tommy,Pass = tomcat
2:ID = 5,WisherID = 1
..........................
由于两个查询都有效,因此必须缓冲数据。