【问题标题】:php wait till previous function has finishedphp 等到前一个函数完成
【发布时间】:2011-05-02 11:35:38
【问题描述】:

我正在尝试创建一些 xml ,基本上是通过阅读 rss 提要并向它们添加一些自定义标签。我制作了一个包含我的代码的函数,现在我想用不同的 rss url 多次调用该函数。每次调用都会生成一个不同的 .xml 文件。
我使用 DOMDocument 加载和解析 rss,并使用 simple_html_dom 加载和解析每个 rss 项的链接以从 html 中获取一些内容。
这是我的代码的简化示例:

<?php
include('simple_html_dom.php');
load_custom_rss('http://www.somesite.com/rssfeed/articles', 'articles.xml'); 
load_custom_rss('http://www.somesite.com/rssfeed/jobs', 'jobs.xml');
load_custom_rss('http://www.somesite.com/rssfeed/press', 'press.xml');
//up to 20 similar function calls here...

function load_custom_rss($link, $filename){

    $doc = new DOMDocument();
    $doc->load($link);

    $newDoc = new DOMDocument('1.0', 'UTF-8');

    $rss        = $newDoc->createElement('rss');
    $channel    = $newDoc->createElement('channel');
    $newDoc->appendChild($rss);
    $rss->appendChild($channel);

    foreach ($doc->getElementsByTagName('item') as $node) {

        //here is some code to read items from rss xml / write them to new xml document.
        //Code missing for simplicity

        //Next lines used to get some elements from the html of the item's link
        $html = new simple_html_dom();
        html->load_file($node->getElementsByTagName('link')->item(0)->nodeValue);
        $ret = $html->find('#imgId');       
    }
    $newDoc->formatOutput = true;
    $fh = fopen($filename, 'w') or die("can't open file");
    fwrite($fh, $newDoc->saveXML());
    fclose($fh);

    unset($doc);
    //unset ALL variables and objects created in this function...
    //........

}//function end
?>  

我的问题是函数的每次调用都会消耗相当多的内存,因此在函数 apache 的第 3 次或第 4 次调用之后会抛出致命错误,因为脚本消耗的内存量大于 memory_limit,即使我取消设置 ALL在函数中创建的变量和对象。如果我将函数调用减少到 1 或 2 次,一切正常。
有什么办法可以工作吗?我在想每个函数调用都在开始之前等待前一个函数调用完成,但这怎么能做到呢?

希望有人可以提供帮助。 提前致谢。

【问题讨论】:

  • 这必须从 apache 运行还是可以从命令行运行?如果是后者,你对时间和内存没有这么严格的限制。

标签: php function memory memory-management


【解决方案1】:

你想要的是 php 中的正常行为。它是从上到下完成的。每个函数都必须等待,直到前一个函数完成。我认为你的问题是 php.ini 中的内存限制。打开文件并搜索指令:memory_limit http://www.php.net/manual/en/ini.core.php#ini.memory-limit 增加它以满足您的需求。

【讨论】:

  • 嗨@faileN,感谢您的回复 :) 我不允许编辑 php.ini ;)
  • 你也可以使用 ini_set 函数来改变你的内存使用情况。也许这是允许的?
  • 那将是(在 php 代码中):ini_set('memory_limit', '2048M'); 例如。
【解决方案2】:

您正在取消设置 $doc 但不是 $newDoc,请尝试添加

unset($newDoc);

在该函数的末尾。

正如其他人所说,问题是您正在泄漏内存或超出内存限制;这与等待之前的代码完成无关。

或者,您可以将每个对 load_custom_rss() 的调用放入单独的请求中,以便脚本调用一个然后重新加载自身,即

$i = $_GET['i'];

if ($i==0)
    load_custom_rss('http://www.somesite.com/rssfeed/articles', 'articles.xml'); 
elseif ($i==1)
    load_custom_rss('http://www.somesite.com/rssfeed/jobs', 'jobs.xml');

... etc ...

else
    die("I'm done");

header("Location: myself.php?i=".($i+1));

当然,您重新加载脚本的方法可能会有所不同,具体取决于页面是否需要先呈现任何 HTML。

【讨论】:

  • 您好@Oliver,感谢您的回复!正如我在代码示例中所说,我取消了在函数中创建的所有对象 - $newDoc 也是如此。为了简单起见,我没有将所有未设置都放在代码中。该脚本不会通过任何浏览器运行,它将由第三方应用程序触发(我认为是通过 ajax)。你认为你的方法在某种程度上是可以实现的,所以当脚本被触发时它会调用自己(header() 不是这里的解决方案)?
  • 这会更难,但可能。在我让 PHP 通过exec 的命令行调用多个 PHP 'child' 脚本之前,我做过类似的事情。这行得通,但根据您的托管环境,可能会有点让人头疼。看看你是否可以使用exec("php &lt;scriptfilename&gt;") 调用你的脚本。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-08-30
  • 2019-11-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多