Что: У меня есть скрипт PHP, который ожидает подключения сокетов. Когда я подключаюсь к сокету, сценарий выдает идентификатор ресурса.
Проблема. Идентификатор ресурса не увеличивается на 1 вместо среднего на 306 000. Это, конечно, вызывает большую проблему и переполняет ее. Из-за того, что мой код в конечном итоге сломается.
Исследование: я не могу найти документацию, которая бы поддерживала бы меня (программиста), которая должна была бы контролировать это. Я нашел следующую ссылку : кто-то утверждает ту же проблему.
Мысли: я бы подумал, что система справится с этим. Если мне нужно управлять идентификатором ресурса, то как это сделать.
Код:
<?php chdir( dirname ( __FILE__ ) ); echo "Waiting for port!\n"; $file = 'change.txt';//change query do{ $sock = @socket_create_listen('12346'); //port im listening too sleep(1); } while(!(@socket_getsockname($sock, $addr, $port))); echo "Server Listening on $addr:$port\n"; socket_set_nonblock($sock); echo"Awaiting Connection\n"; while(true) { if($newc = @socket_accept($sock)) { socket_set_nonblock($newc); echo "Client $newc has connected\n"; } $current = file_get_contents($file); } ?>
Справка: Идея (если вы постоянно подключаетесь к сокету, идентификатор ресурса будет переполняться). Мой код очень большой, чтобы вставить его, но я уменьшил его, чтобы показать проблему:
A) Что может вызвать необычные приращения идентификатора ресурса.
B) Если определить первопричину необычной проблемы с приростом невозможно, возможно, это может помочь управление идентификатором ресурса.
Выводы: Последняя команда «file_get_contents …», если эта строка закомментирована, код работает правильно, и идентификатор ресурса увеличивается правильно. Если вы не закомментировали и не добавили сон, значение приращения будет намного лучше, но не корректно (т.е. скачок 5 или 6 значений). Я не уверен, что происходит на самом деле.
благодаря
PHP не повторно использует идентификаторы ресурсов внутри, поэтому, в конце концов, вы столкнетесь с проблемой с PHP, используя их все, в результате чего вы получите предупреждение. См. Отчет об ошибке . Поскольку куча вещей в PHP будет регистрировать ресурс, увеличивая идентификатор ресурса, эта ошибка легко встречается в длинных сценариях.
Максимальный идентификатор зависит от вашей архитектуры. Вы можете распечатать константу PHP_INT_MAX
чтобы получить номер для вашей установки, но на 32-битных системах это обычно 2,147,483,647. Это значительно выше на 64-битных системах. Шахта печатает 9,223,372,036,854,775,807. Вы вряд ли исчерпаете лимит ресурса ID на 64-битных системах.
Кроме того, вы вызываете file_get_contents
в своем неограниченном while (true)
цикле. У вас нет периода ожидания между каждой итерацией цикла while, поэтому цикл в основном выполняется так быстро, как может. Каждый вызов file_get_contents
приводит к тому, что указатель ID ресурса увеличивается на 2, поскольку он использует 2 ресурса под капотом. Пример:
<?php echo gmp_init("0x41682179fbf5"). "\n"; // Resource id #4 echo gmp_init("0x41682179fbf5"). "\n"; // Resource id #5 echo gmp_init("0x41682179fbf5"). "\n"; // Resource id #6 file_get_contents('/etc/hosts'); echo gmp_init("0x41682179fbf5"). "\n"; // Resource id #9 echo gmp_init("0x41682179fbf5"). "\n"; // Resource id #10 echo gmp_init("0x41682179fbf5"). "\n"; // Resource id #11
и<?php echo gmp_init("0x41682179fbf5"). "\n"; // Resource id #4 echo gmp_init("0x41682179fbf5"). "\n"; // Resource id #5 echo gmp_init("0x41682179fbf5"). "\n"; // Resource id #6 file_get_contents('/etc/hosts'); echo gmp_init("0x41682179fbf5"). "\n"; // Resource id #9 echo gmp_init("0x41682179fbf5"). "\n"; // Resource id #10 echo gmp_init("0x41682179fbf5"). "\n"; // Resource id #11