PHP Pthread-cand';取不到文件

PHP Pthread-cand';取不到文件,php,pthreads,Php,Pthreads,我正在尝试编写php线程。我正在构造函数中创建一个DOMDocument,但是由于某种原因,新创建的文档虽然分配给了一个成员变量,但是消失了 代码清单1: class workerThread extends Thread { private $document; private $i; public function __construct($i){ $this->document = new DOMDoc

我正在尝试编写php线程。我正在构造函数中创建一个DOMDocument,但是由于某种原因,新创建的文档虽然分配给了一个成员变量,但是消失了

代码清单1:
    class workerThread extends Thread {

        private $document;
        private $i;
        public function __construct($i){
            $this->document = new DOMDocument();
            $this->i = $i;
        }

        public function run(){
            try{
                $root = $this->document->createElement("Root");//can't fetch this
                $this->document->appendChild($root);
            }catch(RuntimeException $e){
                return false;
            }
        }

        public function getRoot(){
            return $this->document->documentElement;
        }
    }

    for($i=0;$i<10;$i++){
        $workers[$i]    = new workerThread($i);
        $workers[$i]->start();
    }

    for($i=0;$i<10;$i++){
        $workers[$i]->join();
    }

?>
我希望能够在线程外部或内部(无论是在构造函数、运行函数还是其他函数中)创建DOMDocument,在运行函数中使用它,并从处理它的线程外部检索它的根

  class workerThread extends Thread {

        private $document;
        private $i;
        public function __construct($i){
            $this->document = new DOMDocument();
            $this->i = $i;
        }

        public function run(){
            try{
                $root = $this->document->createElement("Root");//can't fetch this
                $this->document->appendChild($root);
                $this->xml = $this->document->saveXML();  // <---
            }catch(RuntimeException $e){
                return false;
            }
        }

        public function getRoot(){
            return $this->document->documentElement;
        }
    }

    for($i=0;$i<10;$i++){
        $workers[$i] = new workerThread($i);
        $workers[$i]->start();
    }

    for($i=0;$i<10;$i++){
        $workers[$i]->join();
        $workers[$i]->xml; // <---
    }
请阅读完整文档

问题是该类无法可靠地序列化。根据功能手册:

请注意,许多内置PHP对象无法序列化。但是,具有这种能力的人要么实现可序列化接口,要么实现magic _sleep()和_wakeup()方法。如果一个内部类不满足这些要求中的任何一个,它就不能可靠地序列化

正如我们所看到的,
DOMDocument
类(以及它的父类,
DOMNode
)没有实现可序列化接口,也没有实现所需的
sleep
wakeup
方法。因此,我们不应该序列化
DOMDocument

那么,序列化与这个问题有什么关系呢?pthreads在内部序列化所有非
线程化的
类(除了
闭包
)和
线程化的
对象的属性数组。这意味着在将新的
DOMDocument
对象分配给
workerThread::$document
属性时,pthreads会在内部序列化此属性并将其存储为字符串。获取此属性时,pthreads将其取消序列化,以便正常使用。(这只是pthreads为了在多线程环境中安全工作而必须采用的众多黑客之一。)

因此,在构造函数内部、类外部或
workerThread::run
方法内部分配此属性并不重要,但仍然会遇到相同的问题

那么,解决办法是什么呢?嗯,你可以做几件事。您可以只将生成的XML保存到
workerThread::$document
属性,也可以使用可序列化的友好类扩展DOMDocument类,并将其用于
workerThread::$document
属性。最终,这两种解决方案都要求您将DOMDocument对象转换为XML,因为这是将其存储为
线程化
属性(直接或间接)的唯一安全方法

应用第一个(也是更简单的)解决方案,下面是
workerThread
类的工作版本:

class workerThread extends Thread
{
    private $document;
    private $i;

    public function __construct($i)
    {
        $this->i = $i;
    }

    public function run()
    {
        $document = new DOMDocument();

        try {
            $root = $document->createElement("Root");
            $document->appendChild($root);
        } catch (RuntimeException $e) {
            return false;
        }

        $this->document = $document->saveXML();
    }

    public function getRoot()
    {
        $document = new DOMDocument();
        $document->loadXML($this->document);

        return $document->documentElement;
    }
}

这个解决方案是错误的(见我下面的答复)。另外,你链接到的博客文章已经过时了,目标是pthreadsv2(不再受支持)。v3需要php7.v2php5,v3php7。这是一个不断变化的性能和php版本。代码是有效的。
  class workerThread extends Thread {

        private $document;
        private $i;
        public function __construct($i){
            $this->document = new DOMDocument();
            $this->i = $i;
        }

        public function run(){
            try{
                $root = $this->document->createElement("Root");//can't fetch this
                $this->document->appendChild($root);
                $this->xml = $this->document->saveXML();  // <---
            }catch(RuntimeException $e){
                return false;
            }
        }

        public function getRoot(){
            return $this->document->documentElement;
        }
    }

    for($i=0;$i<10;$i++){
        $workers[$i] = new workerThread($i);
        $workers[$i]->start();
    }

    for($i=0;$i<10;$i++){
        $workers[$i]->join();
        $workers[$i]->xml; // <---
    }
<?php
class SearchGoogle extends Thread
{
    public function __construct($query)
    {
        $this->query = $query;
    }

    public function run()
    {
        $this->html = file_get_contents('http://google.fr?q='.$this->query);
    }
}
$job = new SearchGoogle('cats');
$job->start();

// Wait for the job to be finished and print results
$job->join();
echo $job->html;
class workerThread extends Thread
{
    private $document;
    private $i;

    public function __construct($i)
    {
        $this->i = $i;
    }

    public function run()
    {
        $document = new DOMDocument();

        try {
            $root = $document->createElement("Root");
            $document->appendChild($root);
        } catch (RuntimeException $e) {
            return false;
        }

        $this->document = $document->saveXML();
    }

    public function getRoot()
    {
        $document = new DOMDocument();
        $document->loadXML($this->document);

        return $document->documentElement;
    }
}