У меня есть эта проблема, когда я задаюсь вопросом, является ли это ошибкой 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();
?>
Это результат - ожидаемый вывод для "Member accessed from parent:" должен быть чем-то вроде "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
Требования для запуска примеров:
Мне нужно подключиться к MySql в потоке в соответствии с этой статьей: http://php.net/manual/en/intro.pthreads.php
ОБНОВЛЕНИЕ:
Я изменил код: он открывает /etc/php.ini
вместо подключения к базе данных MySql. Тот же результат → ресурс теряется при возврате его из расширенного класса. Примеры теперь работают 1:1 без изменения/адаптации чего-либо.
Я все еще думаю, что это ошибка. Я нашел теперь обходной путь, когда ресурс явно назначен члену класса в функции 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