0
<?php

require_once( dirname(__FILE__) . '/shared.php');

function tabelle_holen_hosters( $condition = "" ) {
    global $wpdb;
    $sql = "SELECT * FROM whatever" . $condition;

    if( $table = $wpdb->get_results( $sql, ARRAY_A ) ) {
        return $table;
    } else {
        echo "SQL ERROR in tabelle_holen()";
        var_dump( $table );
        return false;
    }
}

$test = tabelle_holen_hosters( " WHERE working=1 AND alexacheck=0 LIMIT 200" );
?>
<table>
<tbody>
<?php
foreach ( $test as $row ){
    $rank = (int) alexaRank( $row['hoster'] );

    if ($rank == 0)
        $rank = 999999999;

    echo '<tr>';
    echo '<td>' . $row['hoster_id'] . '</td>';
    echo '<td>' . $row['hoster'] . '</td>';
    echo '<td>' . $rank . '<td>';
    echo '</tr>';

    $wpdb->update(
    'fhw_filehosters',
        array(
            'alexa' => $rank,
            'alexacheck' => 1
        ),
        array( 'hoster_id' => $row['hoster_id'] ),
        array(
            '%d',
            '%d'
        ),
        array( '%d' )
    );
    flush(); // <----- NOT working.
}
?>
</tbody>
</table>
<?php
function alexaRank( $url ) {
    $request_url = "http://data.alexa.com/data?cli=10&url=".$url;
    $xml = simplexml_load_file($request_url) or die("feed not loading");
    return $xml->SD->POPULARITY['TEXT'];
}

我有这个脚本,我使用没有 wordpress的 wordpress 数据库类。我将行限制为 200,因为否则我会遇到诸如页面加载需要数年的问题,并且可能 php 执行时间来自 alexa 函数的 xml 需要很长时间。我在该数据库中有很多要检查的 url,我想用一个操作来更新它们,这意味着删除 200 限制。我该怎么做才能让它像一次做 50 个,然后输出然后继续?阿贾克斯?我该怎么做?

更新1:

正如我在评论中所说,我正在寻找一些东西来使我的网站(在后台)发生这种情况,我实际上并不确定此时是否涉及 php 执行时间限制,但对于“一次性”解决方案我刚刚在队列末尾测试了 flush() 并且它不起作用!

但是我正在寻找一个常规功能,现在我更新了问题,答案非常通用,我不是那个 exp。我很想看到一些实际的代码。如果那太多并且往往是“给我写一个程序”,那么我必须通过挖掘一段时间来解决这个问题。然后,我将接受最有帮助的答案。

4

7 回答 7

2

您的直接问题(如何在脚本运行时开始输出)很容易回答:

flush();

但如果 PHP 执行时间限制限制了你,它不会解决你的问题。所以剩下的就是 AJAX:

  • 将脚本分成两个文件:一个包含空文件<table>和 JavaScript,另一个将通过 AJAX 调用,执行实际处理并返回表行。
  • 像这样限制处理的行数:LIMIT $start, 50,其中$start通过 GET/POST 参数提供
  • 在 JavaScript 中,首先调用 start=0 的 PHP 脚本,然后处理完响应后,再次调用 start 增加 50。重复,直到响应为空。
于 2013-03-12T13:43:38.073 回答
0

如果您只想更新行并且想知道更新了哪些项目,则不需要网络服务器。您可以使用 logger -> KLogger代替“echo”,并将更新信息写入磁盘。在这种情况下,使用PHP CLI具有优势。您可以设置 max_execution_time(0) 并增加 memory_limit。另外,我认为它比使用 apache 或 nginx 快一点。您想进行批量更新吗?看看这篇文章。或者,您可以使用MySQL。如果 working 和 alexacheck 有很多不同的状态,不要忘记对它们进行索引。

于 2013-03-13T09:02:21.847 回答
0

以下是您应该考虑的方式:

  • 创建一个伟大的上帝之母循环。
  • 保留一个 $total 计数器和一个 $temp 计数器。
  • 遍历循环 100 (n) 次并每次增加计数器。
  • 一旦达到 100 个数字限制(或 50 或 200 或其他),您将重置临时计数器。
  • 你让程序进入睡眠状态 3 秒(或类似的东西)。
  • 您再次遍历 temp 变量 n 次,但您请求与 $total 计数器对应的数据。

或者

  • 创建一个伟大的上帝之母循环。
  • 有一个柜台。
  • 在每次循环迭代中增加计数器。
  • 一旦计数器达到您定义的最大值,您就将其重置。
  • 睡觉。
  • 重复。

无论哪种方式都可以获利。

现在,因为您需要一些代码和一些解释:

PHP手册说:

int sleep ( int $seconds )
"Delays the program execution for the given number of seconds."

所以程序执行是延迟的,如果你延迟了执行时间,你就无法达到限制。

所以你可以这样做:

$i = 0;
$max = 50;
$sleepTime = 3;

foreach ( $test as $row ){
    $rank = (int) alexaRank( $row['hoster'] );

    if ($rank == 0)
    $rank = 999999999;

    echo '<tr>';
    echo '<td>' . $row['hoster_id'] . '</td>';
    echo '<td>' . $row['hoster'] . '</td>';
    echo '<td>' . $rank . '<td>';
    echo '</tr>';

    $wpdb->update('fhw_filehosters', array(
        'alexa' => $rank,
        'alexacheck' => 1
    ),
    array(
        'hoster_id' => $row['hoster_id']
    ),
    array(
        '%d',
        '%d'
    ),
    array( '%d' )
    );
    ii($i === $max)
    {
        $i = -1;
        sleep($sleepTime);
    }
    $i++;
}

至少尝试一下,最好的学习方式就是体验。

于 2013-03-15T01:03:35.357 回答
0

像这样的长时间运行的进程可能是作业队列的候选者。

  1. 一次将 50 个 URL 排入队列。
  2. 让每个作业队列工作人员在完成后将结果发送到您的主应用程序。
  3. 然后,您的应用程序将处理从队列中进入的结果的显示。

这一切都应该异步完成。

当应用程序进入“维护”模式时。您仍然可以使用相同的作业队列。就像提到的其中一条评论一样,您甚至可以拥有一个每天两次将作业发送到队列的 cron 作业。

于 2013-03-15T07:16:37.953 回答
0

我通常使用函数ob_startob_flush。它对我有用。

于 2013-03-16T04:21:15.960 回答
0

首先,将工作机智库和前端代码分开会很好:

  1. ajax.getdata.php //这里我们根据给定的参数获取数据

    $page = $_GET["page"]; // I skip the validation, you should do it be yourself
    
    require_once( dirname(__FILE__) . '/shared.php');
    
    function tabelle_holen_hosters( $condition = "" ) {
        global $wpdb;
        $sql = "SELECT * FROM whatever" . $condition;
    
        if( $table = $wpdb->get_results( $sql, ARRAY_A ) ) {
            return $table;
        } else {
            echo "SQL ERROR in tabelle_holen()";
            var_dump( $table );
            return false;
        }
    }
    
    function alexaRank( $url ) {
    
        $request_url = "http://data.alexa.com/data?cli=10&url=".$url;
        $xml = simplexml_load_file($request_url) or die("feed not loading");
        return $xml->SD->POPULARITY['TEXT'];
    }
    
    $limit = 200;
    
    $start= $page*$limit;
    
    $test = tabelle_holen_hosters( " WHERE working=1 AND alexacheck=0 LIMIT $start,$limit" );
    
    
    
     $str = '<table>';
    
    foreach ( $test as $row ){
    
        $rank = (int) alexaRank( $row['hoster'] );
    
        if ($rank == 0)
            $rank = 999999999;
    
        $str.= '<tr>';
        $str.= '<td>' . $row['hoster_id'] . '</td>';
        $str.= '<td>' . $row['hoster'] . '</td>';
        $str.= '<td>' . $rank . '<td>';
        $str.= '</tr>';
    
        $wpdb->update(
        'fhw_filehosters',
            array(
                'alexa' => $rank,
                'alexacheck' => 1
            ),
            array( 'hoster_id' => $row['hoster_id'] ),
            array(
                '%d',
                '%d'
            ),
            array( '%d' )
        );
    
    }
    
    $str.='</table>';
    
    echo $str;
    
    exit;
    
    ?>
    
  2. index.html // 构建前端视图,向服务器发送ajax请求。

    <div id="content">
    </div>
    
    <div id="controls">
    <span onCLick="goPrev()">
    Prev
    </span>
    <span onCLick="goNext()">
    Next
    </span>
    </div>
    
    <script>
    var page=0;
    
    //this functions can be moved to separate file
    
    function goNext(){
    page++;
    //here should be some limit for max page
    readData();
    }
    
    function goPrev(){
    if(page==0) return false;
    page--;
    readData();
    }
    
    function readData(){
    $.ajax({
    "url":"/path/to/ajax.getdata.php?page="+page,
    }).done(function(data){
    $("#content").html(data);
    });
    }
    
    readData();
    </script>
    
    </body>
    </html>
    

所以现在您可以自己定义一次显示多少条记录,并且可以通过控件单击转到下一页或上一页。

于 2013-03-19T10:05:04.520 回答
0

您可以想到的另一种方式:对于访问该站点的单个人,我是否只能更新某些行?为了得到幻觉,它都在更新。

在在线浏览器游戏中,这种情况很多。他们给人的错觉一切都是最新的,但实际上只是玩家信息已更新。

或者,您可以查看您的服务器主机是否有“预定脚本”选项,我知道有一些允许这样做。它会触发一个脚本以间隔或一天中的某些时间运行。

我希望这在某种程度上有所帮助。

于 2013-03-19T12:03:30.777 回答