Подтвердить что ты не робот

Понимание PHP declare() и тиков

Сегодня я просматривал руководство по php и наткнулся на структуру управления declare.

Конструкция declare используется для установки директив выполнения для блока кода

Это то, что должен делать declare. Честно говоря, я этого не понимал. При повторном чтении он обнаружил новую вещь Ticks

Тик - это событие, которое происходит для каждого N низкоуровневого тикающего операторов, выполняемых парсером в блоке declare. Значение для N задается с помощью ticks = N в директиве block объявления раздел.

Я тоже этого не понимал. что это означает N low-level tickable statements Если бы был хороший образец кода, тогда это было бы легко понять. Но ничто не было найдено в руководстве. Я нашел некоторые на SO Q1, что на самом деле увеличило мое любопытство и путаницу. Так может кто-нибудь, для чего это и где мы можем это использовать.

Моя реальная путаница с этим утверждением (из связанного сообщения) you can declare a tick-function which checks each n executions of your script whether the connection is still alive or not. Поэтому, когда я регистрирую функцию галочки с тиком = 20 в файле php и выполняю ее, файл будет сохранен до завершения выполнения 20 (получил эту идею, если она была ошибочно рассмотрена как многопоточная). Это идея, которую я получил, я не думаю, что она правильная..

Или это простая замена для while($x = 20)

[ИЗМЕНИТЬ 1]
Я также видел реализацию declare() другого раздела справочника php Аргументы функции

[ИЗМЕНИТЬ 2]
Также в Process Control

Вы используете оператор declare() для указания местоположений в своем где возможны обратные вызовы. Это позволяет минимизировать накладные расходы на обработку асинхронных событий

4b9b3361

Ответ 1

Когда PHP выполняет ваш script, выполнение можно рассматривать как множество выполняемых операторов. Большинство заявлений вызывают тик, хотя это не всегда все утверждения. (Руководство говорит: Typically, condition expressions and argument expressions are not tickable.)

Этот блок обычно вызывает 5 тиков, так как вы выполняете 5 операторов:

$a = 1;
$B = 2;
$a = 3;
$B = 4;
$a = 5;

И этот блок обычно вызывает 5 тиков, а еще один тик, так как конец цикла while также считается выражением /tick:

while ($i < 5)
    $a++;

С помощью declare(ticks=N) и register_tick_function() теперь вы можете выполнять код между операторами/тиками. Функция register_tick_function указывает, какую функцию следует вызывать при возникновении события галочки. И declare устанавливает, сколько клещей должно пройти, прежде чем произойдет событие tick.

С помощью declare(ticks=1) и register_tick_function('someFunction'); вы вызываете код someFunction() между каждым утверждением/тиком.

Если вы используете declare(ticks=3), то someFunction() будет выполняться на каждом третьем утверждении/тике.

Пример:

function handler(){
    echo "x";
}
register_tick_function("handler");
$i = 0;
declare(ticks = 4) {
    while ($i < 9)
        echo ++$i;
}

Этот script будет выводить: 1234x5678x9 Это просто.

Теперь, что подразумевается в связанном вопросе с "существует ли связь еще жива", на самом деле не интересна сама по себе и на самом деле не связана с вышеупомянутым. Это всего лишь то, что вы МОЖЕТЕ делать на каждом тике. Но вы также можете сделать что-то совершенно другое. То, что упоминается, просто заключается в том, что некоторые сценарии могут занять довольно много времени и что во время выполнения клиент может отключиться. (Представьте, что вы закрываете браузер, а script все еще работает.) PHP по-прежнему будет продолжать работу script, даже если клиент отключился. Вы можете использовать функцию connection_aborted(), чтобы определить, отключен ли клиент. Это то, что вы также можете делать без использования тиков вообще.

Теперь скажем, например, что вы хотите, чтобы ваш script прекратил работу, как только клиент отключится. Просто используйте...

function killme() {
    if (connection_aborted()) {
        die();
    }
}
register_tick_function('killme');
declare(ticks=1);

... и ваш script вызовет killme() после каждого утверждения вашего кода. killme() проверяет, все ли подключен клиент, и die(), если это не так.

Ответ 2

На практике: игнорировать директиву declare(). Если вы не используете код, который его использует, что очень редко, вы можете спокойно забыть, что он когда-либо существовал.

Это, как говорится, здесь подробности. Директива declare() в настоящее время используется для двух совершенно несвязанных вещей:

  • Как declare(encoding=…), для объявления кодировки файла PHP. (В этом смысле он сопоставим с версией <meta charset="…"> на стороне сервера.)

    Но не используйте это. В большинстве случаев кодировка script не имеет значения. Если это произойдет, PHP-кодирование должно быть установлено глобально (надеюсь, "UTF-8" ) с помощью значения конфигурации zend.script_encoding. Установка его на уровне файла является запутанной и ненужной.

  • Как declare(ticks=…), для определения частоты, с которой вызываются функции тика. Функции Tick вызываются периодически интерпретатором PHP и настраиваются с помощью register_tick_function.

    Хотя некоторые комментарии на php.net предлагают использовать его для реализации тайм-аутов при доступе к сети, это не работает должным образом, так как тики не запускаются, когда интерпретатор заблокирован в вызове собственной функции. Он может иметь некоторые приложения в бенчмаркинге, но за пределами этого он в основном бесполезен. Я бы избегал этого.

Ответ 3

Одно использование, не упомянутое в этом или возможном дублированном ответе, - это сигналы catch.

Если у вас CLI script и вы хотите поймать пользовательские сигналы (например, SIGHUP или SIGTERM (CTRL + C)), вам нужно declare(ticks... вместе с pcntl_signal https://secure.php.net/manual/en/function.pcntl-signal.php, который позволяет вам поймать эти сигналы (такие же, как в сценариях оболочки)