1

PHPのバグなのか意図的な動作なのか疑問に思うこの問題があります。子クラスで MySQL リソースを親メンバーに割り当てると、スレッドとして実行すると値が失われます。

このコードは実行されません。MySQL リソースが 2 回表示されます。

<?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_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. pThread ライブラリでコンパイルされた PHP

この記事に従って、スレッドで MySql に接続する必要があります: http://php.net/manual/en/intro.pthreads.php

更新

コードを変更し/etc/php.iniました。MySql データベースに接続する代わりに開いています。同じ結果 --> 拡張クラスからリソースを返すときにリソースが失われます。サンプルは現在、何も変更/適応することなく 1:1 で実行されています。

4

1 に答える 1

1

今でもバグだと思います。リソースがasではなく as として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
于 2014-11-08T18:45:24.263 に答える