2016-08-05 5 views
1

У меня есть интересная проблема, с которой я не могу добраться до дна.прерывание петли foreach перед достижением конца петли

Мой код выглядит следующим образом:

public function __destruct() 
{ 
    foreach ($this->_queue as $index => $header) { 
     $result = socket_write($this->_socket, $header); 
     if (!$result) 
     { 
      $s_err = socket_last_error($this->_socket); 
      $str_err = socket_strerror($s_err); 
     } 
    } 
    socket_close($this->_socket); 
} 

Это используется для отслеживания событий на Google Analytics. Событие всегда состоит из трех разных строк заголовков, которые мне нужно записать в сокет.

Я тестировал 2 события, что означает, что $this->_queue содержит 6 строк.

Каждый раз, когда я просматриваю код, я когда-либо достигаю индекса [2] (Третий элемент), а затем конец цикла, линия socket_close($this->_socket); никогда не достигалась.

Я пробовал найти решения here и here без успеха, я установил размер буфера на 100000 и включил usleep (5), а также соответствующие символы возврата каретки.

Есть ли какая-либо другая причина, по которой мой код может покинуть foreach до его завершения?

Есть ли другой, лучше Способ для этого?

+0

Любая информация в консоли браузера? Разве сокет не ждет вас, чтобы прочитать ответ betwen пишет? –

+0

@SergioBernardo 'socket_write' просто возвращает целое число, которое сообщит мне, сколько байтов было написано, или' false', если произошла ошибка. Я отлаживался с помощью xdebug, и он каждый раз записывался успешно, я также ничего не нашел в руководстве по PHP или в другом месте, что означало бы, что он ждал чего-либо, что нужно прочитать. Это работает для первых 3 отдельных элементов в очереди, а затем выходит из не только цикла, но и после третьего элемента. – Skytiger

+0

В таком случае я бы заменил foreach (...) на что-то вроде: for ($ i = 0; $ i _ queue); $ i ++) {$ header = $ this -> _ queue [$ я]; ... Затем поместите печать («loop $ i - где-то \ n») в определенных местах, чтобы увидеть, где она остановится ... –

ответ

-1

Хммм ... 6 строк, и вы извлечения 2 строки в то время ($index и $header) Если $index значения пронумерованных от нуля, и последний один вы видите два, то петля запустить (0..1..2) = 3 раза, что это именно правильный номер: 2 * 3 = 6.

Но, в общем, самый простой способ отладки этих вещей является временно добавьте заявление print или два, чтобы вы могли см. что происходит.

С помощью PHP вы всегда должны проверять журналы для «предупреждений», потому что язык известен тем, что «держится» в ситуациях, когда он должен прекратить холод.

+0

Нет, я думаю, вы либо не поняли вопрос, либо имели небольшую икоту при представлении массива - 6 строк в массиве означает, что переменная '$ index' будет идти от 0 до 5, а не от 0 до 2. Я проверил предупреждения и возвращаемые значения из функции socket_write, которые указывают на то, что сама запись не удалась. Я разместил здесь в качестве последнего средства, а не потому, что это была легкая проблема, которую можно было решить с помощью простых советов по отладке PHP. Извините, если это звучит слишком жестко, но ваш ответ должен быть комментарием, а не ответом, это тоже не очень полезно. – Skytiger

0

Во-первых, я заметил, что сокет закрывается после существования цикла for, и для этого все операции в цикле должны быть завершены. Во-вторых, проблема может быть связана с результатом для элемента [2], который удерживает функцию зависанием, потому что:
if (! $ Result) {
$ s_err = socket_last_error ($ this -> _ socket);
$ str_err = socket_strerror ($ s_err);
}
может не возвращать захваченную погрешность .. проверьте, вызываются две вызываемые функции ошибки. таким образом, socket_last_error ($ this -> _ socket) и socket_strerror ($ s_err).

Использование «продолжать» в случае блок прыгать любые ошибки, которые могут быть причиной проблемы ... таким образом:
если (! $ Результат) {
продолжить;
}

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

+0

Проблема в том, что каждый раз, когда я тестирую, первые 3 элемента отличаются друг от друга, потому что я создаю их по-разному. Я несколько раз отлаживал проблему с помощью xdebug и не возвращал никаких ошибок ('$ result' никогда не был ложным), поэтому 2 функции ошибки никогда не называются фактически, поэтому у меня так много проблем, когда выясняется, что идет не так :) – Skytiger