|  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #71448 declare(ticks=1) limited to scope of file makes Signal handling difficult
Submitted: 2016-01-25 21:42 UTC Modified: 2017-03-14 13:03 UTC
Avg. Score:4.2 ± 0.9
Reproduced:16 of 17 (94.1%)
Same Version:7 (43.8%)
Same OS:10 (62.5%)
From: dave at atst dot io Assigned:
Status: Wont fix Package: PCNTL related
PHP Version: 7.0Git-2016-01-25 (Git) OS: Linux
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
Block user comment
Status: Assign to:
Bug Type:
From: dave at atst dot io
New email:
PHP Version: OS:


 [2016-01-25 21:42 UTC] dave at atst dot io
Not sure if this is intended behaviour or fallout from other declare directives intending to be scoped to a particular file.

The manual states:

The declare construct can also be used in the global scope, affecting all code following it (however if the file with declare was included then it does not affect the parent file).

I've attached a script that tries to show what I'm trying to do automatically, but you can remove the forking and just try and ctrl-c from your terminal.

Test script:


$start = time();
pcntl_signal(SIGINT, function() use ($start) {
    $diff = time() - $start;
    echo "SIGINT received after $diff seconds\n";

$id = posix_getpid();

$child = pcntl_fork();

if ($child) {
    include 'inc.php';
} else {
    posix_kill($id, SIGINT);

## inc.php


$a = 0;
$start = time();
while(time() < $start + 5) {
    $a = $a + 2; # something tickable

Expected result:
SIGINT received after 0 seconds

Actual result:
SIGINT received after 5 seconds


Add a Patch

Pull Requests

Add a Pull Request


AllCommentsChangesGit/SVN commitsRelated reports
 [2016-04-25 01:19 UTC] nathan dot renniewaldock at gmail dot com
I've noticed this too.
I've got an IRC bot in PHP, I'm handling SIGINT to clean up before exiting.
With declare(ticks=1] in an included file,
in 5.6.20: triggered near instant
in 7.0.4: can take up to 20 seconds. Near instant after moving declare to the main file. There's also no mention of this change in the migration guide.
 [2016-05-14 16:26 UTC] hamid dot a85 at gmail dot com
We were trying to add a timeout feature to laravel artisan command `queue:work`. But the tests failed in PHP 7.0:
Pull request:

A simpler test case that fails:


pcntl_signal(SIGALRM, function ($sig) {

require_once __DIR__ . '/loop.php';


while (true) {

Expected behavior: the code terminates after 2 seconds
Observed behavior: the code will never terminate.
 [2016-05-14 17:22 UTC]
-Status: Open +Status: Wont fix
 [2016-05-14 17:22 UTC]
Due to an implementation bug, the declare(ticks=1) directive leaked into different compilation units prior to PHP 7.0. This is not how declare() directives, which are per-file or per-scope, are supposed to work.

Using a single declare(ticks=1) in some class inside a multi-class autoloaded project doesn't make a lot of sense. Even on PHP 5.x declare(ticks=1) would only affect code that is compiled starting from that declaration, which means that depending on the loading order of classes your whole codebase might end up using ticks or maybe only a few classes that were loaded late. (Not to mention that using ticks will make your code many times slower, but that's a different issue.)

For PHP 7.1 we may make automatic pcntl signal handling work without ticks, as we now have a new internal mechanism for handling ordinary timeouts which we can reuse.
 [2017-03-14 13:03 UTC]
As an update on the previous comment: PHP 7.1 supports async signals, see It looks like pcntl_async_signals() is not documented yet. This allows handling signals without using ticks.
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sun Jul 21 05:01:30 2024 UTC