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

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

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

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

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

Я тоже этого не понял. что означает 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)

[EDIT 1]
Я также видел реализацию declare() другого раздела руководства по php Аргументы функции

[EDIT 2]
Также в разделе Управление процессами

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


person Nandakumar V    schedule 08.07.2015    source источник
comment
возможный дубликат Для чего используются тики в PHP?   -  person    schedule 08.07.2015
comment
@HoboSapiens Я видел этот пост SO и упомянул его в вопросе. У меня есть кое-что, чего я до сих пор не понял   -  person Nandakumar V    schedule 08.07.2015
comment
По сути, это тот же вопрос, который был задан на странице, на которую вы уже ссылались, где есть несколько хороших примеров использования tick. Если этот вопрос не отвечает на ваши вопросы, вам нужно будет яснее объяснить, что вы не понимаете.   -  person    schedule 08.07.2015
comment
@HoboSapiens Я скоро добавлю больше деталей к этому вопросу.   -  person Nandakumar V    schedule 08.07.2015
comment
@HoboSapiens Я добавил больше деталей. Надеюсь, это даст более четкое представление о моих сомнениях.   -  person Nandakumar V    schedule 08.07.2015


Ответы (3)


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

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

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

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

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

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

С 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;
}

Этот скрипт выведет: 1234x5678x9 Это так просто.

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

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

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

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

person nl-x    schedule 14.07.2015

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

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

person Community    schedule 08.07.2015
comment
Это новая функция, ожидаемая в PHP 7.0, который еще не выпущен. Я намеренно описываю только те функции, которые уже существуют в текущих версиях PHP. - person ; 08.07.2015

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

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

person vvondra    schedule 08.07.2015
comment
Извините, но заявление, которое вам нужно, неверно. вы могли бы, но действительно не должны были бы быть правильными. Обработчики тиков чрезвычайно дороги (или очень непредсказуемы) для перехвата сигналов. Вы должны (начиная с php 5.3, то есть давным-давно) использовать pcntl_signal_dispatch() (manual) для предсказуемой обработки сигналов. Я могу найти много утверждений о том, что тики даже устарели с версии 5.3, но, похоже, не могу найти никаких надежных источников, подтверждающих это - мой личный опыт говорит, что pcntl_signal_dispatch всегда лучше. - person Mikk3lRo; 15.07.2015
comment
@Mikk3lRo на самом деле пример с галочками и pcntl_signal взят из раздела официальных примеров в документации по php, посмотрите php.net/manual/en/function.pcntl-signal.php, поэтому я не знаю, откуда вы взяли эту информацию о том, что ее не следует использовать или что она устарела. - person Sasa Blagojevic; 13.05.2021
comment
@SasaBlagojevic Факсы существуют, и их работа хорошо задокументирована. Для очень специфических целей они лучше. Но утверждение, что вам нужно использовать факсимильный аппарат для связи, просто неверно. Устаревшие тики действительно кажутся не чем иным, как широко распространенным недоразумением, но погуглите php ticks deprecated, если вы действительно не знаете, откуда я взял эту идею... Я поддерживаю свой комментарий, что pcntl_signal_dispatch намного превосходит обработчики тиков почти во всех случаях использования случаи. - person Mikk3lRo; 15.05.2021