2014-02-01 4 views
0

Я использую PHP для получения содержимого API. Проблема в том, что иногда API просто отправляет обратно ошибку 502 Bad Gateway, и PHP-код не может разобрать JSON и правильно установить переменные. Есть ли способ, которым я могу продолжать попытки, пока это не сработает?Могу ли я повторить file_get_contents(), пока он не откроет поток?

+1

завернуть его в какой-то цикл, как 'в то время как ($ thatdamngatewayisntproperlyresponding) {...}'? – fvu

+0

«Я могу продолжать пытаться, пока это не сработает ...», или вы получите запрет, и он никогда не будет работать снова. Лучше сделать что-то другое в своем приложении при сбое API, например: заменить значения по умолчанию, серость соответствующих вычисленных полей, записать блокировку интерфейса, использовать последние значения и т. Д. – bishop

+0

Интересно ... что он делает, это экономит цену на мой сервер. На самом деле нет значения по умолчанию там, но я полагаю, я мог бы получить предыдущую строку MySQL и вставить ее снова. – Burrito411

ответ

3

Поскольку вы не предоставили никакого кода, вам сложно помочь. Но вот один из способов сделать это.

$data = null; 

while(!$data) { 
    $json = file_get_contents($url); 
    $data = json_decode($json); // Will return false if not valid JSON 
} 

// While loop won't stop until JSON was valid and $data contains an object 
var_dump($data); 

Я предлагаю вам бросить какое-то приращение переменной там, чтобы прекратить попытки после X сценариев.

+0

Спасибо, я попробую это сейчас. У меня это работает на работу cron, поэтому потребуется несколько минут для тестирования. – Burrito411

4

Это непростой вопрос, поскольку по умолчанию PHP является синхронным.

Вы можете сделать это:

$a = false; 
$i = 0; 
while($a == false && $i < 10) 
{ 
    $a = file_get_contents($path); 
    $i++; 
    usleep(10); 
} 

$result = json_decode($a); 

Добавление usleep(10) позволяет серверу, чтобы не получить на колени каждый раз, когда API будет недоступен. И ваша функция будет сдаваться после 10 попыток, что предотвратит ее полностью заморозить в случае большой недоступности.

0

Основываясь на ваш комментарий, вот что я хотел бы сделать:

  1. У вас есть PHP скрипт, который делает вызов API и, в случае успеха, регистрирует цену и, когда эта цена была приобретена
  2. Вы поместите этот скрипт в задание cronjob/schedule, которое выполняется каждые 10 минут.
  3. Ваш взгляд на PHP вытаскивает самую последнюю цену из базы данных и использует ее для любых отображаемых/вычислений, которые ей нужны. Если уместно, также покажите дату/время, когда была зафиксирована цена.

Другие ответы предлагают сделать цикл. Комбинированный подход, вероятно, лучше всего работает здесь: в вашем скрипте вставляйте несколько циклов на всякий случай, если интерфейс отключен для короткого перехода. Если после минуты не говорят, используйте старое значение до следующей попытки.

+0

Он делает, он работает отлично. У меня есть он, где он записывается в базу данных после цикла while, если $ lasttradeprice (моя переменная, которую я получаю от JSON)! == 0. – Burrito411

+0

Тогда вам будет хорошо идти ко мне! – bishop

+0

Хорошо, приятно слышать, что меня не будут запрещать - надеюсь. Все запросы, похоже, дали число, не достигнув максимального предела запроса, установленного мной (10). – Burrito411

1

Петля может решить эту проблему, но так может рекурсивная функция как этот:

function file_get_contents_retry($url, $attemptsRemaining=3) { 
    $content = file_get_contents($url); 
    $attemptsRemaining--; 

    if(empty($content) && $attemptsRemaining > 0) { 
     return file_get_contents_retry($url, $attemptsRemaining); 
    } 

    return $content; 
} 

// Usage: 
$retryAttempts = 6; // Default is 3. 
echo file_get_contents_retry("http://google.com", $retryAttempts); 
+0

Не забудьте использовать строгое сравнение: if ($ content === false). Если ответ содержит «0», то он вызывает ложный ответ. –

+0

@DenisBobrovnikov поднимает превосходный момент.В моем случае я получал код состояния 200 с пустым ответом на строку и мне нужно было продолжать повторную попытку, пока я не получил фактический ответ. Ваш прецедент может отличаться и может требовать строгого логического сравнения возвращаемого значения. – Eric

Смежные вопросы