1

我有这个问题,我想知道它是 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();
?>

这是结果 - “从父级访问的成员: ”的预期输出应该类似于“资源 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_Connectionfopen(). 注意:它正在线程中工作!

<?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. 使用 pThread 库编译的 PHP

我必须根据这篇文章在线程中连接到 MySql:http: //php.net/manual/en/intro.pthreads.php

更新

我更改了代码:它正在打开/etc/php.ini而不是连接到 MySql 数据库。相同的结果 --> 从扩展类返回资源时它会丢失。这些示例现在以 1:1 的比例运行,无需更改/调整任何内容。

4

1 回答 1

1

我仍然认为这是一个错误。我现在找到了一种解决方法,当资源被显式分配给openFile()函数 asparent::而不是 as中的类成员时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
于 2014-11-08T18:45:24.263 回答