第1119行

时间:2016-02-07 10:01:54

标签: php oop dom pthreads simple-html-dom

这就是我正在做的事情 我正在使用

  • pthreads来自 - pthreads.org
  • php Simple Html DOM解析器来自 - simplehtmldom.sourceforge.net

现在我(将)所做的是:

  1. 我正在阅读大量来自文本文件的链接。
  2. 我初始化一个线程以拥有一个单独的进程
  3. 我正在为这个帖子创建一个日志文件,以便我知道以后会发生什么。
  4. 现在,这是我的线程类的代码。

    class ReadLinks extends Thread {
    
    private $conn;
    private $links;
    private $fileObj;
    
    public function __construct($conn, $links, $fileObj) {
        //.. well just asign this to the global variables
    }
    
    public function run() {
        try {
            $this->logMsg("Start Reading Reviews");
            $this->readLinks();
        } catch (Exception $ex) {
            $this->logMsg($ex);
        }
        $this->closeLog();
    }
    
    private function readLinks() {
        $this->logMsg("Links");
        foreach ($this->links as $link) {
            $link = trim(preg_replace('/\s\s+/', ' ', $link));
            $this->logMsg("Link: " . $link);
            $html = html_readLink($link);
           break;
        }
    }
    
    private function logMsg($msg) {//something to write on the text file
    }
    
    private function closeLog() {//closes the textfile
    }}
    

    $ conn - 是我将来拥有数据库操作的mysqli链接

    $ links - 是一个要读取的链接数组。

    $ fileObj-是来自fopen()的资源返回。 (以及写入文件)

    现在谁是那个html_readlink, 它的外部功能是这样的:

    function html_readLink($link) {
        return file_get_html($link);}
    

    基本上它是由简单的html dom解析器

    中的函数返回的资源

    现在,我还有一个函数可以单独读取一个链接来完成另一个(不同的业务需求),并且我可以轻松地使用简单的html dom解析器。

    使用pthreads,我尝试编写文件(首先记录日志),以便我可以确保一切正常。 关于联系db的问题还不确定。如果运行良好,请尽量弄明白,但从逻辑上说它应该可行。

    现在当我打电话给这个班级时:它是这样的:

    try {
        $thread = new readLinks($conn, $Links, createlog());
        if ($thread->start()) {
            $thread->join();
        } else {
            echo "something i need to research if this happens";
        }
    } catch (Exception $err) {
        echo $err; //something i need to research as well if this happens
    }
    

    我收到了这个错误

    Warning: Invalid argument supplied for foreach() in C:\my\path\to\simplehtmldom_1_5\simple_html_dom.php on line 1119
    

    simplehtmldom代码是:

    function clear()
    {
        foreach ($this->nodes as $n) {$n->clear(); $n = null;}
        // This add next line is documented in the sourceforge repository. 2977248 as a fix for ongoing memory leaks that occur even with the use of clear.
        if (isset($this->children)) foreach ($this->children as $n) {$n->clear(); $n = null;}
        if (isset($this->parent)) {$this->parent->clear(); unset($this->parent);}
        if (isset($this->root)) {$this->root->clear(); unset($this->root);}
        unset($this->doc);
        unset($this->noise);
    }
    

    现在这是来自简单的html dom的源代码。 foreach是返回错误的那个。现在我的其他代码使用简单的html dom并没有简单的html dom的问题。但是使用pthreads我得到了这个错误。

    另外,当我更改我的代码并且没有使用pthread时,(进行了一些修改: 在pthreads上:

    class ReadLinks {// extends Thread {
    //insert other codes
    public function readLinks() {
            $this->logMsg("Links");
            foreach ($this->links as $link) {
                $link = trim(preg_replace('/\s\s+/', ' ', $link));
                $this->logMsg("Link: " . $link);
                $html = html_readLink($link);
                $this->logMsg(getTitle($html));
    //           
                break;
            }
        }
    

    并改变这样调用的方式:

    try {
            $thread = new ReadLinks($conn, $revLinks, createlog());
            $thread->readLinks();
    //        if ($thread->start()) {
    //            $thread->join();
    //        } else {
    //            echo "something i need to research if this happens";
    //        }
        } catch (Exception $err) {
            echo $err; //something i need to debug and research if this happens
        }
    

    一切正常,我得到了理想的结果。

    pthreads是我需要使用的东西,因为加载批量链接并阅读每个链接是一个非常耗时的过程。我需要它在一个单独的线程上。现在我不知道这些pthreads或简单的html dom解析器有什么问题。我做了一些不必要/错误的事情吗?还有其他办法吗?

    任何人??

    <小时/> 修改

    我按照Prafulla Kumar Sahu的回答: 简单的html dom函数clear()的新代码是:

    function clear() {
        if (is_array($this->nodes) || $this->nodes instanceof Traversable) {
            foreach ($this->nodes as $n) {
                $n->clear();
                $n = null;
            }
        }
        // This add next line is documented in the sourceforge repository. 2977248 as a fix for ongoing memory leaks that occur even with the use of clear.
        if (isset($this->children))
            foreach ($this->children as $n) {
                $n->clear();
                $n = null;
            }
        if (isset($this->parent)) {
            $this->parent->clear();
            unset($this->parent);
        }
        if (isset($this->root)) {
            $this->root->clear();
            unset($this->root);
        }
        unset($this->doc);
        unset($this->noise);
    }
    

    结果是:它消除了错误 但它不是理想的结果 使用功能时

    $x=$resource->find($selector,0); 
    //resource is the return obj of file_gets_content, selector is my css selector string
    

    它返回null / empty,实际上它应该有一个值。

    我已经检查了一个单独的函数,它在我更新代码后使用了简单的html dom,似乎没有受到影响,并且它正常工作。但是使用我的pthread类,它无法正常工作。

2 个答案:

答案 0 :(得分:0)

我所拥有的代码在1119行没有预告;也许你有一个旧版本。您只是收到警告,您在结果中看到了哪些问题?

1117    // save dom as string
1118    function save($filepath='')
1119    {
1120        $ret = $this->root->innertext();
1121        if ($filepath!=='') file_put_contents($filepath, $ret, LOCK_EX);
1122        return $ret;
1123    }

答案 1 :(得分:0)

如果您尝试使用foreach遍历的变量不是irritable,则会发生这种情况,因此请检查您的变量是array还是instanceof Traversable类。

*可能是因为您没有获得要遍历的变量的任何值。

所以,我建议你在foreach之前使用is_array( $whatever ) || $whatever instanceof Traversable

if( is_array( $whatever ) || $whatever instanceof Traversable ){
    foreach( $whatever as $what ){
       //some code
    }
}

在你的情况下,它是

   function clear()
    {
        foreach ($this->nodes as $n) {$n->clear(); $n = null;}
        // This add next line is documented in the sourceforge repository. 2977248 as a fix for ongoing memory leaks that occur even with the use of clear.
        if (isset($this->children)) foreach ($this->children as $n) {$n->clear(); $n = null;}
        if (isset($this->parent)) {$this->parent->clear(); unset($this->parent);}
        if (isset($this->root)) {$this->root->clear(); unset($this->root);}
        unset($this->doc);
        unset($this->noise);
    }

来源: - https://github.com/jalbertbowden/simplehtmldom/blob/master/simplehtmldom_1_5/simple_html_dom.php#L1119

这意味着您无法正确获取$ this-&gt;节点,因此请在调用函数clear之前或foreach之前使用var_dump。