php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #74339 BOGUS: Fatal error: strict_types declaration must be the very first statement
Submitted: 2017-03-30 11:47 UTC Modified: 2020-05-04 17:24 UTC
From: spam2 at rhsoft dot net Assigned:
Status: Not a bug Package: Scripting Engine problem
PHP Version: 7.1.3 OS: Linux
Private report: No CVE-ID: None
 [2017-03-30 11:47 UTC] spam2 at rhsoft dot net
Description:
------------
for cli scripts it's no problem to start with a #!/usr/bin/php shebang followed by <?php declare(strict_types=1); as first line, in case of mod_php the sample below throws "PHP Fatal error:  strict_types declaration must be the very first statement in the script"

*it is* because PHP has no business to claim anything outside <?php ?> as part of "the script"

Test script:
---------------
<html>
 <head><title>Test</title></head>
 <body>
<?php declare(strict_types=1);

?>
 </body>
</html>


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2017-03-30 11:57 UTC] peehaa@php.net
-Status: Open +Status: Not a bug
 [2017-03-30 11:57 UTC] peehaa@php.net
This is defined behavior and is not a scripting engine problem
 [2017-03-30 12:01 UTC] daverandom@php.net
Shebangs are explicitly ignored. Everything else that appears outside PHP tags is considered to be script output. This is the way that PHP has always worked.

To make your code work, do this:

<?php declare(strict_types=1); ?>
<html>
 <head><title>Test</title></head>
 <body>
<?php
    // code here
?>
 </body>
</html>
 [2017-04-02 11:15 UTC] spam2 at rhsoft dot net
than at least ignore shebangs also with mod_php

#!/usr/bin/php
<?php declare(strict_types=1);
if(PHP_SAPI != 'cli')
{
 exit('CLI ONLY');
}
?>

is also broken when called via browser which leads to fatal erros and so flood logs which is bad in case of emial reporting every 30 minutes when any of some hundret vhsost triggers any php-warning/error
 [2017-04-07 12:18 UTC] narf at devilix dot net
You shouldn't have CLI scripts within your webroot in the first place ...
 [2017-04-07 13:14 UTC] spam2 at rhsoft dot net
> You shouldn't have CLI scripts within your webroot in the first place ...

really?

#!/usr/bin/php
<?php declare(strict_types=1);
switch(PHP_SAPI}
{
 case 'cli': break;
 default: break;
}
...shared..code....
?>

i have ton of examples where this works pretty fine by intention while in cron mode the only output are errors and when runnigng in the browser authenticated against the CMS you get runtime informations

maybe i am the only guy on this planet which is using PHP and cli heavily for a decade and write any code so that it is 100% cli capable including the whole CMS bootstrap but that don't change the fact that "You shouldn't have CLI scripts within your webroot" is nonsense

and frankly on shared hosting you have usually no way to run CLI or palce something outside the webroot at all and so you need to make sure that these tasks can be called via web and be it that your conjob running somewhere else running curl('https://url/cron.php?username=bla&pwd=bla'); and you break that all for no reason with claim "declare(strict_types=1)" is not the first line while IT IS and even bobody would care about "#!/usr/bin/php" in the output when called via websevrer

#!/usr/bin/php
<?php declare(strict_types=1);
 [2019-01-18 16:36 UTC] stefansobick at gmx dot de
Convert the file to utf without BOM, than it should work fine, when you have done it like this: 

<?php declare(strict_types=1); ?>
<!DOCTYPE html>
	<html>
		<head>
			<meta charset="utf-8">
			<title>Page title</title>
		</head>
		<body>
...
 [2019-01-19 17:50 UTC] spam2 at rhsoft dot net
all the workarounds are fine but the first php staement is after <?php no matter how many shebangs and BOM are before and when i read something like "You shouldn't have CLI scripts within your webroot in the first place" i just get upset since the whole purpose of if(PHP_SAPI === 'cli') is to write proper software which bheaves corretly in CLI as well as in web-mode (require a web-login versus just do the job as example)
 [2019-10-07 13:38 UTC] kevin at kevinlocke dot name
This issue also occurs when CLI scripts are read from stdin by php (e.g. for linting).  For example, if mycli.php has the following content:

#!/usr/bin/php
<?php
declare(strict_types=1);
echo "Hello World\n";

Running `php -l mycli.php` prints "No syntax errors detected in mycli.php".

Running `php -l < mycli.php` (as some lint tools like ALE do) prints "PHP Fatal error:  strict_types declaration must be the very first statement in the script in Standard input code on line 3".
 [2019-10-07 15:04 UTC] nikic@php.net
@kevin at kevinlocke dot name: The stdin issue will be fixed in PHP 7.4.
 [2020-05-04 17:06 UTC] everx80 at gmail dot com
@nikic@php.net i didn't want to open another bug if not neccesary, however with PHP 7.4.5 the following code from cli still doesn't work and gives the same error:


#!/usr/bin/php
<?php
declare(strict_types=1);
echo "Hello World\n";
 [2020-05-04 17:24 UTC] nikic@php.net
@everx80: When you say "from cli", what exactly do you mean? Invoking a file with CLI binary? Piping it as stdin? Entering it in interactive mode?
 [2020-05-04 18:29 UTC] everx80 at gmail dot com
@nikic@php.net Here in full detail:

$ /usr/bin/php -v
PHP 7.4.5 (cli) (built: Apr 30 2020 04:42:29) ( ZTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
    with Zend OPcache v7.4.5, Copyright (c), by Zend Technologies

$ cat test.php
#!/usr/bin/php
<?php declare(strict_types=1);
echo "test";

$ chmod +x test.php

$ file test.php 
test.php: PHP script, UTF-8 Unicode text executable

$ ./test.php
PHP Fatal error:  strict_types declaration must be the very first statement in the script in /home/test/test.php on line 2
 [2020-05-04 18:36 UTC] everx80 at gmail dot com
@nikic@php.net I am sorry. After re-checking everything once more, it seems that an invisible UTF-8 character somehow snuck into the file, before the <?php

So it's actually not an issue, but quite difficult to see the reason. It would be nice if PHP could somehow point that out, but idk if it's worth it...
 [2020-12-15 10:14 UTC] andergmartins at gmail dot com
I started having this fatal error for a file UTF-8 without BOM. I have tried diverse charsets, with no success.

I'm running PHP 7.3.5 but tried with 7.4.1. Same result.

It say's:
-------------
PHP Fatal error:  strict_types declaration must be the very first statement in the script in ..../vendor/php-di/php-di/src/ContainerBuilder.php on line 3
-------------

And here are the first lines of the file:
-------------
<?php

declare(strict_types=1);
-------------

I looked for any hidden char, but didn't find anything:

-------------
$ hexdump -n 20 -C "...../vendor/php-di/php-di/src/ContainerBuilder.php"
00000000  3c 3f 70 68 70 0a 0a 64  65 63 6c 61 72 65 28 73  |<?php..declare(s|
00000010  74 72 69 63                                       |tric|
00000014
--------------

Then I tried moving the declare statement to the first line:

--------------
<?php declare(strict_types=1);

namespace DI;
--------------

Same error, but on line 1:
--------------
PHP Fatal error:  strict_types declaration must be the very first statement in the script in ..../vendor/php-di/php-di/src/ContainerBuilder.php on line 1
--------------


And here is the hexdump:

--------------
$ hexdump -n 20 -C "..../vendor/php-di/php-di/src/ContainerBuilder.php"
00000000  3c 3f 70 68 70 20 64 65  63 6c 61 72 65 28 73 74  |<?php declare(st|
00000010  72 69 63 74                                       |rict|
00000014
--------------

If I remove the "declare(strict_types=1)", then it stops on a next file.

This issue started a few days ago... I wasn't having problems before that. And it happens for other libraries like PHP Unit, or even for new files I create to test.
 [2021-12-13 23:45 UTC] jake at qzdesign dot co dot uk
> You shouldn't have CLI scripts within your webroot in the first place ...

Are you also saying the Composer-installed 3rd party libraries should be in a separate part of the filesystem?  Because in `vendor/bin` it places several files with a shebang which cause this error (with the reported PHP version).  Perhaps you'd like to take that issue up with the folk at Composer.

By extension, what you're actually saying is that there shouldn't be any PHP files whatsoever within your web root, and the `.htaccess` file (or whatever) should invoke a PHP file in a different part of the filesystem.  That is surely ridiculous.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri Mar 29 07:01:28 2024 UTC