PHP循环不会遍历每一行

时间:2015-04-11 05:00:05

标签: php mysql json curl mysqli

我编写了以下脚本:它的作用是进入一个输出JSON字符串,解码JSON字符串并将其数据存储在我的数据库中的网页。最外面的for循环在迭代$category之后立即迭代foreach$alpha循环,这只是整个字母+ %23的数组,其中是数字元素。每个已解码的JSON字符串$decoded->items都包含多个项目,因此内部还有一个foreach循环来迭代这些项目。但是,当我尝试echo $item->name时,它只回显了$alpha次迭代的部分的项目名称。

我知道问题不在于数据本身,因为每次运行它都会回显不同的项目。

有什么建议吗?

这是代码(数据库查询部分已注释,但除此之外,错误仍然存​​在):     

error_reporting(E_ERROR);

$alphas = array("%23", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z");

function get_bool($string) {
    return ($string == "true") ? TRUE : FALSE;
}

$DB = new mysqli("localhost", "root", "root", "drop_logger");

echo "<pre>";
for ($category = 0; $category <= 37; $category++) {
    foreach ($alphas as $alpha) {

        // Echoing the current category and alpha
        echo "category ".$category.", alpha ".$alpha." \n";         

        // Getting data
        $curl = curl_init();
        $post_url = "http://services.runescape.com/m=itemdb_rs/api/catalogue/items.json?category=".$category."&alpha=".$alpha;
        curl_setopt($curl, CURLOPT_URL, $post_url);
        curl_setopt($curl, CURLOPT_HEADER, 0);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        $data = curl_exec($curl);
        curl_close($curl);

        // Decoding the JSON data
        $decoded = json_decode($data);
        $decoded = $decoded->items;

        // Storing each new item into the database
        foreach ($decoded as $item) {
            echo $item->name."\n";/*
            $DB->query(
                "INSERT INTO GE_items (item_ID, item_name, item_icon, item_icon_large, item_type, item_type_icon, item_description, item_members)
                 VALUES ("
                    .$item->id.", '"
                    .$item->name."', '"
                    .$item->icon."', '"
                    .$item->icon_large."', '"
                    .$item->type."', '"
                    .$item->typeIcon."', '"
                    .$item->description."', "
                    .get_bool($item->members)
                 .")"
            );*/
        }

        @flush();
        @ob_flush();
    }
}
echo "</pre>";

编辑:以下是输出示例:

category 4, alpha y 
category 4, alpha z 
category 5, alpha %23 
category 5, alpha a 
category 5, alpha b 
category 5, alpha c 
category 5, alpha d 
category 5, alpha e 
category 5, alpha f 
category 5, alpha g 
category 5, alpha h 
category 5, alpha i 
category 5, alpha j 
category 5, alpha k 
category 5, alpha l 
category 5, alpha m 
category 5, alpha n 
category 5, alpha o 
Oak armchair
Oak armour case
Oak bed
Oak bench
Oak bookcase
Oak cape rack
Oak chair
Oak clock
Oak costume box
Oak dining table
Oak drawers
Oak dresser
category 5, alpha p 
category 5, alpha q 
category 5, alpha r 
category 5, alpha s 
category 5, alpha t 
category 5, alpha u 
category 5, alpha v 
category 5, alpha w 
category 5, alpha x 
category 5, alpha y 
category 5, alpha z 
category 6, alpha %23 
category 6, alpha a 
category 6, alpha b 

编辑2:我检查了数据库表,滚动时我遇到了:Warning: a form on this page has more than 1000 fields. On submission, some of the fields might be ignored, due to PHP's max_input_vars configuration.我不确定这是否与问题有关。

编辑3:我遇到了一些有趣的事情......我反复为同一类别运行脚本,35。每次都会返回134项完全相同的数据集。该类别本身包含164个项目。我浏览了此页面http://services.runescape.com/m=itemdb_rs/catalogue?cat=35下此类别下的项目,似乎脚本省略了其中30项(每次都是30项)。我使用了sleep(),我甚至改变了脚本,不再迭代有{0}项的$alpha,并且我一直得到相同的134项......

对于类别35,我检查了上面链接的页面,并比较了那里列出的项目和我的脚本输出的项目。在http://pastebin.com/9Aj9AtWL,我发布了一个包含所有164个项目的文件;标有两个星号的那些在我的输出中丢失了。模式似乎是在相同$alpha的12个项目(它们开头的字母)之后,省略了$alpha的其余项目。我甚至为该类别尝试了其他数字,模式是相同的:只有前$ 12个项目的每个$ alpha输出...

2 个答案:

答案 0 :(得分:0)

  

每个已解码的JSON字符串$ decoding-&gt;项目包含多个项目,   所以在里面有一个额外的foreach循环来迭代这些   项目

现在,例如,查看这两个网址的来源。

视图源:http://services.runescape.com/m=itemdb_rs/api/catalogue/items.json?category=5&alpha=o

视图源:http://services.runescape.com/m=itemdb_rs/api/catalogue/items.json?category=4&alpha=y

第一个根据需要工作。但第二个返回空项目。

{"total":15,"items":[]}

因此,大多数URL只返回空数组。看:

视图源:http://services.runescape.com/m=itemdb_rs/api/catalogue/items.json?category=4&alpha=c 视图源:http://services.runescape.com/m=itemdb_rs/api/catalogue/items.json?category=4&alpha=d 视图源:http://services.runescape.com/m=itemdb_rs/api/catalogue/items.json?category=4&alpha=e 视图源:http://services.runescape.com/m=itemdb_rs/api/catalogue/items.json?category=4&alpha=h

我发现了你的问题!

  1. 添加 set_time_limit(0); 以开始您的脚本。
  2. 运行脚本,等待10-20秒
  3. 尝试打开之前发布的所有网址。只需点击其中一个即可。你会看到空白页面。 OOOOPS!您的网络服务器崩溃了:)
  4. 最大的问题是服务器使用空白页面进行响应,但标题状态为200 OK

    事实上,服务器不是你的,最好的解决方案是使用sleep(); - 例如,在5秒内建立连接一次,并希望服务器能够使用它。

    试试这个。我也尝试重用CURL连接。这很慢因为sleep();但这是你能做到的唯一方法。

    <?php
    set_time_limit(0); // <--- SET NO TIME LIMIT
    error_reporting(E_ERROR);
    
    $alphas = array("%23", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z");
    
    function get_bool($string) {
        return ($string == "true") ? TRUE : FALSE;
    }
    
    // Getting data
    $curl = curl_init();
    
    // Open the text file
    $f = fopen("data.txt", "w");
    
    for ($category = 0; $category <= 37; $category++) {
        foreach ($alphas as $alpha) {
            fwrite($f, "category ".$category.", alpha ".$alpha." \n");
    
            $post_url = "http://services.runescape.com/m=itemdb_rs/api/catalogue/items.json?category=".$category."&alpha=".$alpha;
            curl_setopt($curl, CURLOPT_URL, $post_url);
            curl_setopt($curl, CURLOPT_HEADER, 0);
            curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($curl, CURLOPT_FORBID_REUSE, 1);
            curl_setopt($curl, CURLOPT_HTTPHEADER, array(
                'Connection: Keep-Alive',
                'Keep-Alive: 300'
            ));
            $data = curl_exec($curl);
    
            // Decoding the JSON data
            $decoded = json_decode($data);
            $decoded = $decoded->items;
    
            // Storing each new item into the database
            foreach ($decoded as $item) {
                fwrite($f, $item->name."\n");
            }
    
            sleep(5);
        }
    }
    
    // Close the text file
    fclose($f);
    
    curl_close($curl);
    
    echo "DONE";
    ?>
    

答案 1 :(得分:0)

这里记录了api: http://services.runescape.com/m=rswiki/en/Grand_Exchange_APIs

我猜你打电话给服务器太多了,这就是为什么它在几次电话后都会忽略你。

首先,我会改进我的代码,以便通过类似的查询询问给定类别的可用字母:

http://services.runescape.com/m=itemdb_rs/api/catalogue/category.json?category=1

它会为您提供此类别的所有可用字母。这样,您就不会对不可用的字母进行不成功的查询。 (并减少服务器垃圾邮件)。

如果还不够,您可以尝试在代码中使用sleep()来降低请求速度。