Есть ли способ заставить PHP ждать, пока функция не вернется, прежде чем продолжить?
Это мой код:
<?php set_time_limit(0); function waitforchange($nof) { $lfilemod=filemtime($nof); while(filemtime($nof) == $lfilemod) { clearstatcache(); usleep(10000); } } waitforchange('./blahblah.txt') sleep(5); echo 'done'; ?>
Предполагается, что до тех пор, пока blahblah.txt
изменится, подождите еще пять секунд после этого, затем распечатайте «сделанный», однако он выдает «сделан» через пять секунд, независимо от того, действительно ли файл был изменен.
PHP является однопоточным, что означает, что он выполняет одну команду за раз, прежде чем двигаться дальше. Другими словами, PHP, естественно, ждет завершения функции до того, как она будет продолжена с помощью следующего оператора.
Я попытался выполнить свой код на своей машине, и он должным образом ждал и дождался, пока я не изменю файл до завершения функции и не покажу сообщение.
Я даже не вижу ничего в вашем коде, который может быть неудачным. Поскольку создание $lfilemod
выполняется так же, как проверка цикла while, условие этого цикла вернет TRUE
и выполнит, даже если возникла проблема с файлом ( filemtime
вернет FALSE
для обеих ошибок, поэтому условие будет читать (FALSE == FALSE
, что, очевидно, TRUE
).
Создает ли ваш PHP-скрипт файл вообще, прежде чем запускать этот цикл? Если это так, то начальное значение, возвращаемое filemtime
может быть временем модификации с момента начала запуска скрипта. Когда вы запускаете clearstatcache
в цикле, вы получите новое время модификации, вызванное вашими изменениями ранее в скрипте.
Мой совет:
Попробуйте запустить clearstatcache
перед установкой значения $lfilemod
чтобы вы знали, что это значение чистое, и что вы сравниваете яблоки с яблоками с тем, что проверяется в цикле.
Убедитесь, что файл действительно не изменяется. Попробуйте поместить пару строк отладки в начале и конце вашего кода, который печатает последнее время модификации файла, а затем сравнивает их самостоятельно, чтобы узнать, сообщает ли PHP о времени изменения времени.
Это должно быть само собой разумеющимся, но вы должны убедиться, что PHP настроен на отображение всех ошибок во время разработки, поэтому вы сразу же показываете, когда и как все происходит неправильно. Убедитесь, что параметр display_errors
включен в файле php.ini
(или используйте ini_set()
если вы не можете изменить сам файл), и что для параметра error_reporting()
установлено значение E_ALL | E_STRICT
E_ALL | E_STRICT
для PHP <= 5.3 или E_ALL
для PHP 5.4 ( E_STRICT
является частью E_ALL
на этой версии). Лучше всего просто настроить отчет об ошибках на -1
который эффективно включает все отчеты об ошибках независимо от версии PHP.
Повторите этот код с этими изменениями. Если вы видите, что файл действительно изменяется, то вы знаете, что ваш код работает. Если файл не изменяется, вы должны, по крайней мере, иметь ошибку, которую можете найти, или спросите нас здесь.
Попробуйте назначить вызов функции переменной. Я думаю, что он не ждет возврата в противном случае.
Код выглядит хорошо; за исключением точки с запятой (;) после строки waitforchange. Я тестировал размещение (;) там, и скрипт вел себя так, как предполагалось. Может быть, это преступник? Я нахожусь в убытке, хотя объясню, как вы получили свой код для выполнения с этой ошибкой.