【问题标题】:How to increasingly show database results?如何越来越多地显示数据库结果?
【发布时间】:2013-07-19 10:18:01
【问题描述】:

我有一个工具,可以使用 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);

}

【问题讨论】:

  • 感谢@brasofilo 的建议。我会考虑的。
  • @brasofilo 和 RubensMariuzzo - 我很欣赏编辑,我不确定如何准确地表达所有内容,因为它对我来说有点新。我不是要问“最好的方式”,而是要“A方式”。
  • AFAIK,Ajax 是做到这一点的方式。从来没有做过这样的事情,但我想做一个 jQuery 循环并调度inserts 的范围就可以了。检查此搜索结果:stackoverflow.com/…
  • 浏览了那个搜索,也在谷歌上,但无济于事。也许我没有在寻找正确的东西,但我找不到答案。
  • 这是一个进度指示器,所以搜索jQuery进度条

标签: php jquery mysql ajax curl


【解决方案1】:

您实际上不需要做任何特别的事情来实现这一点。由于您已经只是保持连接打开并在文档底部转储数据,因此您应该能够在每个项目或每个 n 项目之后向客户端转储更多 javascript。

因此,您可以在文档中的某个位置转储一些 html,如下所示:

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

然后你的线程只需要输出 js 来更新视图,例如(为了简单起见使用 jQuery):

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

加载/隐藏进度条也是如此,直到客户端接收到 js 才会运行,因此最终效果就像一个进度条。

另请参阅: https://stackoverflow.com/a/2920207/486620

【讨论】:

    【解决方案2】:

    这样做的一种方法是使用 作业队列服务器,其中包含工作人员(完成工作的任务)和客户端,它们向这些工作人员询问流程的完成情况。 Gearman就是其中之一。

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

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

    隐式刷新并不总是有效。

    希望,它对你有用!

    【讨论】:

      【解决方案3】:

      一个简单的解决方案可能是在您的 list 表中维护一个数字 processed 列,您将在每次迭代时更新它:

      <?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”分隔的名称列表)。而是每个值存储一行(每个名称一行)。当您对数据进行规范化时,一切都会变得简单得多(而且通常效率更高),即使对于小型项目也是如此。

      【讨论】:

      • 我不能让用户将名称一一复制/粘贴到新输入中...他们一次复制/粘贴数千个名称的列表。
      • @Revolt 当然不是。但是你可以在插入之前自动解析他们的输入。
      • 嗯,可以。至于你的实际答案,我会在我回家拿文件时试一试。谢谢你,我会尽快检查它是否有效。
      • 如果您决定使用“每个名称一行”选项,请检查我的答案的第一个版本,当我假设这种结构时。
      • 我可以看到我建议的方法存在一些问题。第一个也是显而易见的,单击“运行”应该触发 Ajax POST,而不是常规的表单提交。否则,页面将在作业完成后才会加载。第二个问题与对同一会话的并发访问有关(我假设您将使用会话)。一次只有一个 PHP 线程可以访问给定的会话。会议应尽快结束。请查看我的更新答案。
      猜你喜欢
      • 1970-01-01
      • 2020-12-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-23
      • 1970-01-01
      • 2019-05-15
      • 2021-05-05
      相关资源
      最近更新 更多