1

我有一个工具,可以使用 cURL 检查游戏中的可用名称,它应该向运行检查的用户显示可用名称,并关闭那些已使用的名称。基本上,当您对名称列表运行测试时,它会检查所有名称并将它们插入数据库中并显示它们的可用性,0 表示已使用或 1 表示可用。

现在,页面在检查完成之前不会加载,然后它们都作为一个整体插入到数据库中。我希望它动态显示检查的状态(即“检查名称 405/4938”)并在检查名称时显示加载图像,同时在检查时显示可用名称。然后在最后,删除加载图像,并获得现在完整的可用名称列表。

我该怎么做呢?我不太了解 jQuery/AJAX。现在它们最后都显示为一个质量并不理想。

这是名称检查线程上的代码。

<?php
$query = mysql_query("SELECT * FROM `lists` WHERE id = '$id'");
while($row = mysql_fetch_assoc($query)) {

    $id = $row['id'];
    $list = $row['list'];

    foreach(explode("\n", $list) as $listItem) {
        checkname_RS(trim($listItem));
    }
}

这是检查的功能。

<?php   
function checkname_RS($name) {

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, "http://services.runescape.com/m=hiscore/compare.ws?user1=" . $name);
    curl_setopt($ch, CURLOPT_HTTPGET, TRUE); 
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    $output = curl_exec($ch);


    if (stristr($output,"Skill Stats")) {
        mysql_query("INSERT INTO names (name, plat, status) VALUES ('$name', 'Runescape', '0')") or die(mysql_error());
    }
    if (stristr($output,"Member Rankings")) {
        mysql_query("INSERT INTO names (name, plat, status) VALUES ('$name', 'Runescape', '1')") or die(mysql_error());
    }

    curl_close($ch);

}
4

3 回答 3

0

You don't really need to do anything special in order to make this happen. Since you're already just keeping the connection open and dumping data at the bottom of the document, you should just be able to dump more javascript to the client after each item or each n items.

So you could dump some html like the following at some point in the document:

<div id="progressMessage"></div> 
<ul id="availableNames"></ul>

Then your thread would just need to output js to update the view as it goes along, for instance (jQuery used for simplicity):

$("#progressMessage").text("1 of 5999");
$("#availableNames").append("<li>matchedName</li>");

The same goes for loading/hiding the progress bar, the js doesn't get run until the client receives it so the net effect is like a progress bar.

See also: https://stackoverflow.com/a/2920207/486620

于 2013-07-23T16:48:47.310 回答
0

这样做的一种方法是使用Job Queue Server,带有工作人员(完成工作的任务)和客户端,它们向这些工作人员询问该过程的完成情况。Gearman就是其中之一。

另一种方法是使用 cURL 自己运行任务,但不要等待完成并使用 set_time_limit(0),然后自己查询状态,例如,将作业的状态保存在 mysql 表中。

这里有一些关于多线程的例子:
https ://github.com/petewarden/ParallelCurl
http://semlabs.co.uk/journal/object-orientation-curl-class-with-multi-threading

隐式刷新并不总是有效。

希望这对你有用!

于 2013-07-23T19:00:04.960 回答
0

一个天真的解决方案可能是在表中维护一个数字processedlist,您将在每次迭代时更新:

<?php
    // user clicks on "run" (Ajax POST'ing of the input form)

    // load whatever you need from $_SESSION here and then
    session_write_close();
    // so as to allow access to the session to the later Ajax polling

    // reset counter
    mysql_query("UPDATE lists SET processed = 0 WHERE id = $id");
    // then the rest of your current script


    function checkname_RS($name) {
        // your current code here
        // then increment the counter
        mysql_query("UPDATE lists SET processed = processed + 1 WHERE id = $id");
    }

然后让 Ajax 调用不时地轮询数据库,以检查当前作业的状态。Ajax 调用将从这样的脚本中读取状态:

<?php
    // script handling the Ajax call

    // get the number of names already checked
    mysql_query("SELECT processed FROM lists WHERE id = $id");

    // proposed trick to count the number of names in this list
    mysql_query("SELECT CHAR_LENGTH(names) - CHAR_LENGTH(REPLACE(names, '\n', '')) +1 AS cnt FROM lists WHERE id = $id");
    // better computing this number once and for all at the beginning
    // of the process and (eg.) store it in session

    // generate the response to the Ajax call here

结果可以显示在 中div,或用于更新 JQuery UI 进度条,或以您认为合适的任何方式。


只是关于你的结构的一条建议。始终避免将非标量数据存储在列中(例如以“\n”分隔的名称列表)。而是每个值存储一行(每个名称一行)。当您对数据进行规范化时,即使对于小型项目,一切都会变得如此简单(并且通常更有效)。

于 2013-07-23T22:13:38.540 回答