我有这个问题,我想知道这是PHP错误还是故意的行为。如果我在子类中将MySQL资源分配给父成员,那么当作为线程运行时,该值就会丢失。
此代码不运行-MySQL资源应显示两次:
<?php
class MyFileAbstract extends Threaded
{
protected static $m_Connection;
public static function init() {
static::openFile();
echo "<br>Member accessed from parent: ";
print_r(self::$m_Connection); # the resource is empty
}
}
class MyFile extends MyFileAbstract
{
public static function openFile() {
self::$m_Connection = fopen("/etc/php.ini", "r");
echo "<br>Member accessed from child: ";
print_r(self::$m_Connection)."<br>"; # the resource has value
}
}
class MyThread extends Thread
{
public function run() {
MyFile::init();
}
}
$myThread = new MyThread();
$myThread->start();
echo "<br>Correct output:";
MyFile::init();
?>
这是结果-"从父级访问的成员:"的预期输出应该类似于"Resource id#2":
Member accessed from child: Resource id #2
Member accessed from parent:
Correct output:
Member accessed from child: Resource id #3
Member accessed from parent: Resource id #3
我必须更改它,然后成员$m_Connection
从fopen()
接收/保留资源。注意:它正在线程中工作!
<?php
class MyFileAbstract extends Threaded
{
protected static $m_Connection;
public static function openFile()
{
$sFileName = static::getFileName();
self::$m_Connection = fopen($sFileName, "r");
echo "Member accessed from parent: ";
print_r(self::$m_Connection); # the resource has value
}
}
class MyFile extends MyFileAbstract
{
public static function getFileName()
{
return "/etc/php.ini";
}
}
class MyThread extends Thread
{
public function run()
{
MyFile::openFile();
}
}
$myThread = new MyThread();
$myThread->start();
?>
输出:
Member accessed from parent: Resource id #2
运行示例的要求:
- 在启用线程安全的情况下编译的PHP
- 使用pThread库编译的PHP
根据这篇文章,我必须在线程中连接到MySql:http://php.net/manual/en/intro.pthreads.php
更新:
我更改了代码:它正在打开/etc/php.ini
,而不是连接到MySql数据库。同样的结果-->从扩展类返回资源时会丢失资源。这些示例现在以1:1运行,没有更改/调整任何内容
我仍然认为这是一个bug。我现在找到了一个解决方法,当资源被显式分配给openFile()
函数中的类成员为parent::
而不是self::
:时
<?php
class MyFileAbstract extends Threaded
{
protected static $m_Connection;
public static function init() {
static::openFile();
echo "<br>Member accessed from parent: ";
print_r(self::$m_Connection); # the resource is empty
}
}
class MyFile extends MyFileAbstract
{
public static function openFile() {
# the resource keeps now the value when using parent:: instead of self::
parent::$m_Connection = fopen("/etc/php.ini", "r");
echo "<br>Member accessed from child: ";
print_r(parent::$m_Connection)."<br>";
}
}
class MyThread extends Thread
{
public function run() {
MyFile::init();
}
}
$myThread = new MyThread();
$myThread->start();
echo "<br>Correct output:";
MyFile::init();
?>
现在的结果是正确的:
Member accessed from child: Resource id #2
Member accessed from parent: Resource id #2
Correct output:
Member accessed from child: Resource id #3
Member accessed from parent: Resource id #3