Cannot set debug = true when zend.assertions = -1

bin/cake version
5.0.5

In CakePHP 4 I had been able to have zend.assertions = -1 set and still use debug = true but now am finding warnings as follows in the browser and no HTML output

Warning: You should set `zend.assertions` to `1` in your php.ini for your development environment. in /var/www/dev/vendor/cakephp/cakephp/src/Core/Configure.php on line 104
Warning (2) : Cannot modify header information - headers already sent by (output started at /var/www/dev/vendor/cakephp/cakephp/src/Error/Renderer/HtmlErrorRenderer.php:37) [in /var/www/dev/vendor/cakephp/cakephp/src/Http/ResponseEmitter.php, line 192]

Is there a way to have 'debug' => true and avoid the above warnings in CakePHP 5.x?

The source code of where this error comes from looks like this:

if (isset($config['debug'])) {
    static::$_hasIniSet ??= function_exists('ini_set');

    if (static::$_hasIniSet) {
        ini_set('display_errors', $config['debug'] ? '1' : '0');
    }

    if ($config['debug'] && PHP_SAPI !== 'cli' && ini_get('zend.assertions') === '-1') {
        trigger_error(
            'You should set `zend.assertions` to `1` in your php.ini for your development environment.',
            E_USER_WARNING
        );
    }
}

So there may be a way to play with what that if evaluates to where it doesn’t trigger the error.

1 Like

Ahh thanks Alex,

With the above code (and to avoid editing it) I’m going to have to set up another instance of php:fpm for the directory serving this instance of CakePHP on the server with zend.assertions = 1 set. This is my staging install I test before deploying to live and I want to stay in debug mode and can’t change the zend assertion setting at runtime or per directory https://www.php.net/manual/en/ini.core.php#ini.zend.assertions

I’m using nginx so it looks like I will have to do a per directory php:fpm pool with zend.assertions = 1 just for that CakePHP instance in my staging/test/dev directory https://serverfault.com/a/836827/481914

Yeah, it looks like that.

I had the same error and was hoping I could just set that value locally with .user.ini to have the error shut up, but apparently zend.assertions is one of those flags that can’t be set on the per-directory level. So I had to configure it on the PHP-FPM level indeed just so I could move on. Maybe there’s a better way though.

For those coming from Google and willing to read more, here’s what ChatGPT had to say about it.

If settings like expose_php, zend.assertions, and previously mentioned display_errors in the .user.ini file don’t seem to have any effect, it could be due to the nature of these directives and how PHP-FPM processes .user.ini files.

Directive Scope and PHP-FPM

Some PHP directives cannot be changed using .user.ini files due to their scope. PHP directives are classified into different modes, indicating where they can be changed:

  • PHP_INI_USER: Can be set in user scripts, .htaccess, or .user.ini
  • PHP_INI_PERDIR: Can be set in .htaccess or .user.ini
  • PHP_INI_SYSTEM: Can only be set in php.ini or the server configuration file
  • PHP_INI_ALL: Can be set anywhere

expose_php and zend.assertions are examples of directives that have a PHP_INI_SYSTEM scope, meaning they can only be set in the php.ini file or through the server’s (or PHP-FPM’s) startup configuration. This is why changes to these directives in a .user.ini file do not take effect.

Understanding .user.ini Limitations

.user.ini files are very useful for overriding certain PHP settings on a per-directory basis when using PHP as CGI/FastCGI, such as with PHP-FPM. However, they have limitations:

  1. Scope: Only directives that are flagged as PHP_INI_ALL or PHP_INI_PERDIR can be overridden in .user.ini.
  2. Directive Nature: Some directives are intended to be set before PHP starts (system-level), and thus cannot be altered at runtime or through per-directory configurations.

Solutions and Workarounds

Given these limitations, if you need to change directives like expose_php or zend.assertions, you have to modify them in the php.ini file or, depending on your hosting environment, through a custom PHP configuration provided by your hosting service.

  • For php.ini: Edit your php.ini file directly to change these settings. Remember to restart your PHP-FPM service to apply these changes.
  • PHP-FPM Pool Configuration: For settings that affect PHP-FPM behavior or performance but are not changeable through .user.ini, consider editing the PHP-FPM pool configuration files directly (typically found in /etc/php/7.x/fpm/pool.d/ or a similar directory). Again, restart PHP-FPM after making changes.

Verifying Changes

To verify changes made directly to php.ini or PHP-FPM’s pool configuration files:

  • Use phpinfo() in a PHP script to output current configuration settings and verify that your changes have taken effect.
  • Ensure you’re editing the correct php.ini file or pool configuration file used by your PHP-FPM service, as there can be multiple versions of PHP installed on a server.

In conclusion, understanding the scope and limitations of PHP configuration directives is crucial for effective PHP configuration management, especially when working with PHP-FPM and .user.ini files. For system-level directives, modifications must be made directly within the php.ini file or through server-level configurations.

1 Like