Declare(strict_types=1) vs error_reporting(-1)

The PHP 7 declare(strict_types=1); declared at the top of the file is even better than using error_reporting(-1);

Good: error_reporting(-1) in dev
Better: declare(strict_types=1);
Best: both :slight_smile:

They aren’t mutually exclusive and work best when both are enabled.

1 Like

I am surprised and look forward to discovering when error_reporting(…) succeeds and declare(…) fails. No doubt it won’t take long because my scripts usually need a great deal of error correcting :frowning:



echo substr(new stdclass(), 0, 1);

Just declaring strict types here doesn’t help, because substr is not defined in the current file, so strict doesn’t apply to it :slight_smile:

Sounds like you should start unit testing :slight_smile:


From memory (because tapping on a tablet and cannot test) strict_types manages to detect type juggling that error_reporting seems to miss.

ini_set('display_errors', '1'); // correct
ini_set('display_errors', 1); // no warning
ini_set('display_errors', true); // no warning

I think where it gets a bit complicated is the there is a default error_reporting setting define in php.ini. As a rule you don’t want to report errors in production but you do in development. When I see code posted on this board I often suggest adding an error_reporting line at the top just to ensure that it is turned on.

Here is another example though in this case the error is a warning:

error_reporting(-1);  // or 0
echo "A $a\n";

That’s apples and oranges.

declare(strict_types=1) defines that any type juggling must be reported as a fatal error, whereas error_reporting defines which kind of internal PHP notices/errors/warnings should be logged.

So whenever you have declare(strict_types=1); the value of error_reporting doesn’t even really matter, because no matter what it’s set to the script will stop when you pass an invalid type to a function.

Also, these kind of settings must be set in php.ini, not at runtime.

1 Like

Many thanks for the clarification about declare and error_reporting.

Am I correct in assuming declare(…); cannot be set in PHP.ini and only applies to the current file?

You are correct in assuming that currently there is no global php.ini entry for strict_types. Just introducing scalar types in php 7.0 was very controversial. Basically adding a global flag was considered to be a step to far. Maybe in a few years.

The “current file” portion of your question is somewhat interesting (to me at least). The calling file declare_types setting actually overrides any setting in the called file. Consider:

<?php declare(strict_types=1); # functions.php

function sum(int $a, int $b) : int
    return $a + $b;

<?php declare(strict_types=0); # main.php

require 'functions.php';

echo sum(1.1,'2.2') . "\n";

You might think that because sum has strict_types=1 then it can only be called with integers. But no. As the long as the main file has strict_types=0 then you can pretty much call it with whatever your want and the arguments will be silently coerced per the usual php rules.

Likewise, even if you set strict_types = 0 in functions.php, setting it to 1 in main.php will trigger the type errors. It can certainly be a bit confusing.

More info at:

This is for backwards compatibility purposes. Suppose if you added declare(strict_types=1) to your file and suddenly all code you’re calling (including frameworks, ORMs, libraries, etc) must be compatible with strict types. Nobody would use it, because it’s just not feasible to convert so much code all at once.

I would prefer an optional strict_type parameter of -1 which would pass the strictness to all included, required files, etc. Any file that failed could then be given the strict_type 0 parameter.

I’m sure the maintainers of Symfony, Laravel, Doctrine, etc would just plain hate that. Imagine all the tickets flooding them about all sorts of issues :confused:

OK, so make it a Tip similar to error_reporting(-1);

Passing in the value -1 will show every possible error, even when new levels and constants are added in future PHP versions. The E_ALL constant also behaves this way as of PHP 5.4.

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.