Вот пример использования контроллера, введенного Guice.
/**
* Loads a FXML file and injects its controller from the given Guice {@code Provider}
*/
public abstract class GuiceFxmlLoader {
public GuiceFxmlLoader(Stage stage, Provider<?> provider) {
mStage = Objects.requireNonNull(stage);
mProvider = Objects.requireNonNull(provider);
}
/**
* @return the FXML file name
*/
public abstract String getFileName();
/**
* Load FXML, set its controller with given {@code Provider}, and add it to {@code Stage}.
*/
public void loadView() {
try {
FXMLLoader loader = new FXMLLoader(getClass().getClassLoader().getResource(getFileName()));
loader.setControllerFactory(p -> mProvider.get());
Node view = loader.load();
setViewInStage(view);
}
catch (IOException ex) {
LOGGER.error("Failed to load FXML: " + getFileName(), ex);
}
}
private void setViewInStage(Node view) {
BorderPane pane = (BorderPane)mStage.getScene().getRoot();
pane.setCenter(view);
}
private static final Logger LOGGER = Logger.getLogger(GuiceFxmlLoader.class);
private final Stage mStage;
private final Provider<?> mProvider;
}
Вот конкретная реализация загрузчика:
public class ConcreteViewLoader extends GuiceFxmlLoader {
@Inject
public ConcreteViewLoader(Stage stage, Provider<MyController> provider) {
super(stage, provider);
}
@Override
public String getFileName() {
return "my_view.fxml";
}
}
Обратите внимание, что этот пример загружает представление в центр BoarderPane, который является корнем сцены в рабочей области. Это не относится к примеру (деталь реализации моего конкретного варианта использования), но решил оставить его, поскольку некоторые из них могут оказаться полезными.
Ваши единственные варианты - увеличить допустимое время выполнения (установка его на 0 делает его бесконечным, но это не рекомендуется) скрипта или порождает новый поток и надеется на лучшее.
причина в том, что это не увлекательно, так это то, что его не бросают. Ни одна строка кода не вызвала ошибку, скорее, PHP сказал: «Нет, простите, это слишком долго. Пора прекратить сейчас». И это имеет смысл. Представьте, что у вас есть сценарий с максимальным временем выполнения 30 секунд, который поймает эту ошибку и займет еще 30 секунд ... в плохо разработанной программе, которая открывает некоторые довольно неприятные возможности для использования. Как минимум, это создаст возможности для DOS атак.
Как пробовать в качестве документации PHP (ну ... хотя бы один из ее читателей) сказать:
<?php
function shutdown()
{
$a=error_get_last();
if($a==null)
echo "No errors";
else
print_r($a);
}
register_shutdown_function('shutdown');
ini_set('max_execution_time',1 );
sleep(3);
?>
Посмотрите на следующие ссылки:
Это не исключение, это ошибка. Существуют важные различия между исключениями и ошибками, прежде всего ошибки не могут быть захвачены семантикой try / catch.
PHP-скрипты построены вокруг парадигмы короткого времени выполнения, поэтому по умолчанию PHP настроен на то, чтобы предположить, что если скрипт работает более 30 секунд, он должен быть пойман в бесконечном цикле и, следовательно, должен быть прекращено. Это делается для предотвращения ошибочного PHP-скрипта, вызывающего отказ в обслуживании, либо случайно, либо злонамеренным намерением.
Однако для сценариев иногда требуется больше времени работы, чем по умолчанию.
Вы можете попробовать изменить максимальное время выполнения, используя set_time_limit()
или изменив значение max_execution_time
в php.ini
файл для повышения лимита. вы также можете полностью удалить предел, установив время выполнения равным 0, хотя это не рекомендуется.
set_time_limit()
может быть отключен такими механизмами, как disable_functions
, поэтому он может быть недоступен для вас, также у вас может не быть доступа к php.ini
. Если это так, тогда вам следует обратиться за помощью к своему хозяину.
Исключением являются PHP-скрипты, запущенные из командной строки. В этих условиях работы скрипты PHP могут быть интерактивными и нуждаются в длительной обработке данных или ожидании ввода. По этой причине по умолчанию для скриптов, запущенных из командной строки, не существует предела max_execution_time
.
РЕДАКТИРОВАТЬ ДОБАВИТЬ: обработка ошибок PHP 7 прошла капитальный ремонт. Я считаю, что ошибки и исключения теперь являются подклассами Throwable. Это может сделать вышеизложенное больше не актуальным для PHP7 +, хотя мне придется более внимательно изучить особенности обработки ошибок теперь.
Да, я протестировал решение TheJanOnline. sleep () не учитывает время выполнения php, поэтому здесь находится версия WORKING с неопределенным циклом:
<?php
function shutdown()
{
$a=error_get_last();
if($a==null)
echo "No errors";
else
print_r($a);
}
register_shutdown_function('shutdown');
ini_set('max_execution_time',1 );
while(1) {/*nothing*/}
// will die after 1 sec and print error
?>
Вы ничего не можете с этим поделать. но вы можете иметь изящное выключение, используя register_shutdown_function
<?php
ini_set('display_errors', '0');
ini_set("max_execution_time",15 ); //you can use this if you know your script should not take longer than 15 seconds to finish
register_shutdown_function('shutdown');
function shutdown()
{
$error = error_get_last();
if ($error['type'] === E_ERROR) {
//do your shutdown stuff here
//be care full do not call any other function from within shutdown function
//as php may not wait until that function finishes
//its a strange behavior. During testing I realized that if function is called
//from here that function may or may not finish and code below that function
//call may or may not get executed. every time I had a different result.
// e.g.
other_function();
//code below this function may not get executed
}
}
while(true)
{
}
function other_function()
{
//code in this function may not get executed if this function
//called from shutdown function
}
?>
other_function()
вызываться во время выключения, если он был объявлен перед бесконечным циклом?
– Douglas.Sesar
28 July 2014 в 14:47
поместите это в начало файла php
<?php
set_time_limit(0);
EDIT 1
, но сначала проверьте, нет ли такого кода:
while (1=1) {
echo '=)';
}
EDIT 2
, чтобы поймать эту ошибку. set_error_handler
Я придумал это на основе ответа @ pinkal-vansia. Поэтому я не претендую на оригинальный ответ, но ответ с практическим приложением. Мне нужен был способ обновить страницу в случае таймаута. Поскольку я наблюдал достаточное количество тайм-аутов моего скрипта cURL, чтобы знать, что код работает, но иногда по какой-либо причине он не может подключиться к удаленному серверу или полностью прочитать обслуживаемый html, и что при обновлении проблема исчезнет, я все в порядке, когда скрипт обновляется, чтобы «вылечить» максимальную ошибку таймаута выполнения.
<?php //script name: scrape_script.php
ini_set('max_execution_time', 300);
register_shutdown_function('shutdown');
function shutdown()
{
?><meta http-equiv="refresh" content="0; url=scrape_script.php"><?php
// just do a meta refresh. Haven't tested with header location, but
// this works fine.
}
FYI, 300 секунд не слишком длинный для скрипта скремблирования, который я запускаю, что занимает чуть меньше что для извлечения данных из типов страниц я соскабливаю. Иногда это происходит через несколько секунд только из-за неравномерности соединения. Зная, что это время соединения, которое иногда терпит неудачу, а не обработку скриптов, лучше не увеличивать таймаут, а просто просто обновлять страницу и повторять попытку.
В некоторых случаях есть небольшой сложный способ обработки «Неустранимая ошибка: максимальное время выполнения 30 секунд» в качестве исключения:
function time_sublimit($k = 0.8) {
$limit = ini_get('max_execution_time'); // changes even when you set_time_limit()
$sub_limit = round($limit * $k);
if($sub_limit === 0) {
$sub_limit = INF;
}
return $sub_limit;
}
В коде вы должны измерить время выполнения и бросить исключение может быть вызвано фатальной ошибкой таймаута. $ k = 0.8 - это 80% от допустимого времени выполнения, поэтому у вас есть 20% времени для обработки исключения.
try{
$t1 = time(); // start to mesure time.
while (true) { // put your long-time loop condition here
time_spent = time() - $t1;
if(time_spent >= time_sublimit()) {
throw new Exception('Time sublimit reached');
}
// do work here
}
} catch(Exception $e) {
// catch exception here
}