Ошибка PHP в многопоточной среде, присваивающей значение родительскому статическому члену в том же потоке?

0

У меня есть эта проблема, когда я задаюсь вопросом, является ли это ошибкой 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

Требования для запуска примеров:

  1. Скомпилированный PHP с включенной безопасностью потока
  2. PHP, скомпилированный с помощью библиотеки pThread

Мне нужно подключиться к MySql в потоке в соответствии с этой статьей: http://php.net/manual/en/intro.pthreads.php

ОБНОВЛЕНИЕ:

Я изменил код: он открывает /etc/php.ini вместо подключения к базе данных MySql. Тот же результат → ресурс теряется при возврате его из расширенного класса. Примеры теперь работают 1:1 без изменения/адаптации чего-либо.

Теги:
pthreads
extending-classes

1 ответ

0
Лучший ответ

Я все еще думаю, что это ошибка. Я нашел теперь обходной путь, когда ресурс явно назначен члену класса в функции 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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню