代码之家  ›  专栏  ›  技术社区  ›  Knownow

在PHP中处理脚本超时

php
  •  1
  • Knownow  · 技术社区  · 6 年前

    <?php foreach($links_array as $link_array): //$links_array are a tags
                    $link_array=str_replace("'", "\"", $link_array); // if href='link' instead of href="link"
                    $href= get_attribute($link_array, "href");
                    $resolved_address= resolve_address($href, $page_base);
                    $download_href= http_get($resolved_address,$ref );
                    $url=$download_href['STATUS']['url'];
                    $http_code=$download_href['STATUS']['http_code'];
                    $total_time=$download_href['STATUS']['total_time'];
                    $message=$status_code_array[$download_href['STATUS']['http_code']];
                    // $status_code_array is an array 
                    //if you refer to its index using the http code it give back the human
                    //readable message of the code 
                    ?>
                    <tr>
                    <td><?php echo $url ?></td>
                    <td><?php echo $http_code ?></td>
                    <td><?php echo $http_code ?></td>
                    <td><?php echo $total_time ?></td>
                    </tr>
               <?php endforeach;?>
    

    该脚本适用于具有少量href的页面,但如果一个页面具有许多href,则脚本将超时。我尝试过在php.ini中增加最大执行时间,但这似乎不是一个优雅的解决方案。我的问题是 1) 在这种需要很长时间才能执行的情况下,生产软件是如何工作的。 3) 另外,如果我可以对第一个href进行curl调用,检查代码,使用HTML打印它,然后对第二个href进行下一个curl调用,检查代码,打印它等等,这会更好。我该怎么做?

    请原谅我的无知,我对网络编程已经有三个月了。

    3 回复  |  直到 6 年前
        1
  •  1
  •   Dominic Wehrmann    6 年前

    您可以在php.ini文件中设置最大执行时间。确保使用的是正确的文件,因为可能有两个文件(一个用于fpm,一个用于cli)。

    您可以在此处查看您的文件:

    php --ini
    

    您还可以在脚本中设置执行时间。

    ini_set('max_execution_time', 300);
    

    或者,也可以在php命令中设置时间。

    php -dmax_execution_time=300 script.php
    

    在这种情况下,生产软件是如何工作的

    一种方法(在PHP中)是使用worker(RabbitMQ/AMQP)。这意味着您有一个脚本将消息“发送”到队列和n个工作进程。这些工作人员从该队列中提取消息,直到该队列为空。

    https://github.com/php-amqplib/php-amqplib

    我是否可以通过捕获致命的“超过60秒的最大执行时间”错误来继续执行CURL调用

    是的,但是没有抛出异常。您可以通过以下方式实现:

    if (curl_errno($ch)){
        echo 'Request Error:' . curl_error($ch);
    }
    
        2
  •  1
  •   Krzysztof Czerwiński    6 年前

    我建议用一个检查队列将链接存储在数据库、xml或json文件中。并创建一个脚本,该脚本将检查队列中的所有链接,并将http\代码响应和其他数据存储在此数据库或xml数据中。

    然后您需要一个ajax脚本,它将每隔X秒查询服务器,从xml文件或数据库获取所有新的选中链接,并将这些数据放到html页面上。

    您可以使用cron作业或rabbitMQ来启动链接检查脚本。

        3
  •  0
  •   skarb    6 年前

    卷发超时 您的更新代码:

    ini_set('max_execution_time', 0);
    
    foreach($links_array as $link){
        $start       = microtime(true);
        $link        = get_attribute( str_replace( '\'', '"', $link ), 'href' );
        $url         = resolve_address( $link, $page_base );
        $http_code   = getHttpCode( $url );
        $total_time  = microtime(true) - $start;
        if($http_code != 0){
            echo '<tr>
                    <td>' . $url . '</td>
                    <td>' . $http_code . '</td>
                    <td>' . $total_time . ' s. </td>
                </tr>';
        }
    }
    
    function getHttpCode( $url )
    {
        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_HEADER, true);
        curl_setopt($ch, CURLOPT_NOBODY, true);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_TIMEOUT, 10);
        $output = curl_exec($ch);
        $httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);
        return $httpcode;
    }