php - цикл повторяется / выходит из последовательности - PullRequest
0 голосов
/ 15 ноября 2018

Я очень новичок в PHP, делаю ошибки и учусь по ходу дела. Пожалуйста, будьте нежны! :)

Я хочу получить доступ к некоторым данным из API Blizzard.com. Для этого конкретного набора данных это не блок данных в JSON, а каждый объект имеет свой собственный URL для доступа. По моим оценкам, существует около 150000 объектов, однако я не знаю начальную или конечную точки диапазона номеров. Таким образом, я должен принять 1 и работать после наибольшего числа, которое я знаю (269065)

Чтобы получить данные, мне нужно получить доступ к данным каждого объекта через файл JSON, который я прочитал, получить содержимое & drop в текстовый файл (это также можно записать как вставку в базу данных SQL, как я могу это сделать, если проблема заключается в текстовом файле). Но, честно говоря, я бы хотел понять, почему это происходит так же, как и все!

Я не собирался запускать ~ 250000 итераций в цикле for, думал, что попробую кое-что, что я считаю маленьким, 2000.

Цикл for начинается с $ a как 1, использует $ a как часть URL-адреса, загружает и декодирует JSON, проверяет, установлено ли первое поле (ID) в объекте, и записывает несколько полей для data.txt, и если первое поле (ID) не установлено, оно просто записывает $ a в data.txt (так что я знаю, что это пустое значение для других целей, не описанных здесь).

Simple! Или я подумал, что после примерно 183 итераций данные, записанные в текстовый файл, будут ошибочными, как видно из приведенной ниже цитаты. Это не в последовательности и начинается с 1 снова, затем возвращается к 184 до тошноты. Тогда цикл кажется заблокированным в каком-то бесконечном цикле выполнения, выводя в случайном порядке, пока я не закрою страницу 10-20 минут спустя.

Я, очевидно, совершил большую ошибку! Но я понятия не имею, что я сделал неправильно, что вызвало это. Во время моих попыток я переписал код с новыми именами переменных, поэтому новый текст не конфликтует с кодом, который может выполняться в памяти.

Я попытался сбросить переменные на пустые в конце цикла на случай, если что-то повторно использовалось, что вызывало проблему.

Если бы кто-нибудь мог указать на какие-либо ошибки в моем коде или предложить что-то для меня, чтобы обработать большие циклы, которые были бы блестящими. Я предполагаю, что моей проблемой может быть тайм-аут или проблема с памятью. Но я не знаю, с чего начать, и надеялся найти здесь несколько советов.

Если это актуально, я пока использую 000webhostapp.com в качестве хост-провайдера, пока мне не заплатят за хостинг.

1 ... 182 183 1 184 2 3 185 4 186 5 187 6 188 7 189 190 8 191

for ($a = 1; $a <= 2000; $a++)      {
    $json = "https://eu.api.battle.net/wow/recipe/".$a."?locale=en_GB&<MYPRIVATEAPIKEY>";
    $contents = file_get_contents($json);
    $data = json_decode($contents,true);

        if (isset($data['id'])) {
            $file = fopen("data.txt","a");
            fwrite($file,$data['id'].",'".$data['name']."'\n");
            fclose($file);
        } else {    
            $file = fopen("data.txt","a");
            fwrite($file,$a."\n");
            fclose($file);  
        }
}   

Содержимое файла, к которому я пытаюсь получить доступ,

{"id": 33994, "name": "Precise Strikes", "профессию": "Enchanting", "icon": "spell_holy_greaterheal"}

Я отказался от первоначального плана и написал это вместо этого. Еще раз спасибо, кто нашел время, чтобы помочь и предложить предложения!

$b = $mysqli->query("SELECT id FROM `static_recipes` order by id desc LIMIT 1;")->fetch_object()->id;

if (empty($b)) {$b=1;};
$count = $b+101;

$write = [];
for ($a = $b+1; $a < $count; $a++)      {
     $json = "https://eu.api.battle.net/wow/recipe/".$a."?locale=en_GB&apikey=";
     $contents = @file_get_contents($json);
     $data = json_decode($contents,true);
     if (isset($data['id'])) {
     $write [] = "(".$data['id'].",'".addslashes($data['name'])."','".addslashes($data['profession'])."','".addslashes($data['icon'])."')";

 } else {    
   $write [] = "(".$a.",'a','a','a'".")";
 }
} 
$SQL = ('INSERT INTO `static_recipes` (id, name, profession, icon) VALUES '.implode(',', $write));
$mysqli->query($SQL);
$mysqli->close();

Ответы [ 3 ]

0 голосов
/ 15 ноября 2018
$write = [];
for ($a = 1; $a <= 2000; $a++)      {
    $json = "https://eu.api.battle.net/wow/".$a."?locale=en_GB&<MYPRIVATEAPIKEY>";
    $contents = file_get_contents($json);
    $data = json_decode($contents,true);
    if (isset($data['id'])) {
      $write [] = $data['id'].",'".$data['name']."'\n";
    } else {    
      $write [] = $a."\n";
    }
} 
$file = fopen("data.txt","a");
fwrite($file, implode('', $write));
fclose($file);  

Кроме того, почему вы думаете, что некоторые IDS не дублируются в нескольких "https://eu.api.battle.net/wow/[N]" urls data?

Также, если вы I wasn't going to try and run ~250000, подумайте о curl_multi_init(): http://php.net/manual/en/function.curl-multi-init.php

0 голосов
/ 16 ноября 2018

В вашем исходном коде нет ничего, что могло бы вызвать такое поведение.PHP не будет произвольно изменять значение переменной.Вы открываете этот файл в режиме добавления, уверены, что не смотрите на старые данные?Может быть, выводить некоторые отладочные сообщения при обработке данных.Скорее всего, вы столкнетесь с некоторым ограничением скорости на сервере API, поэтому установка где-то паузы может повысить надежность.

Единственное существенное изменение, которое я бы предложил вашему коду, - это открыть файл один раз изакрывая его, когда вы закончите.

$file = fopen("data_1_2000.txt", "w");
for ($a = 1; $a <= 2000; $a++)      {
    $json = "https://eu.api.battle.net/wow/recipe/$a?locale=en_GB&<MYPRIVATEAPIKEY>";
    $contents = file_get_contents($json);
    $data = json_decode($contents, true);
    if (!empty($data['id'])) {
        $data["name"] = str_replace("'", "\\'", $data["name"]);
        $record = "$data[id],'$data[name]'";
    } else {
        $record = $a;
    }
    fwrite($file, "$record\n");
    sleep(1);
    echo "$a "; if ($a % 50 === 0) echo "\n";
}
fclose($file);
0 голосов
/ 15 ноября 2018

Я действительно не вижу ничего явно неправильного в вашем коде, но не могу его запустить, поскольку у меня нет JSON

Возможно, что с вами возникли какие-то условия гонки.Вы очень быстро открываете и закрываете один и тот же файл сотни раз.

Файловые операции могут показаться атомарными, но это не обязательно так - вот интересная тема SO:

PHP ожидает файловую системукакие операции (например, file_put_contents) завершить, прежде чем двигаться дальше?

Как и некоторые другие советуют - может быть, просто откройте файл, прежде чем войти в цикл, затем закройте файл, когда цикл прервется.

Сначала я попробую и посмотрю, поможет ли это.

...