# RFC: Deprecate remains of string evaluated code assertions

- Status: Implemented (PHP 8.3)
- Authors: George Peter Banyard, girgias@php.net
- Date: 2023-05-31
- Version: 0.9
- Target: PHP 8.3
- Original: https://wiki.php.net/rfc/assert-string-eval-cleanup
- Page: https://externals.io/rfc/assert-string-eval-cleanup
- More for agents: search with https://externals.io/search.md?q={query} · RFCs at https://externals.io/rfc.md · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

## Votes

### Accept Deprecate remains of string evaluated code assertions RFC? (closed)

Yes: 24 · No: 0

Voters: alcaeus (Yes), ashnazg (Yes), brzuchal (Yes), bwoebi (Yes), colinodell (Yes), crell (Yes), dharman (Yes), galvao (Yes), girgias (Yes), imsop (Yes), kalle (Yes), kocsismate (Yes), levim (Yes), mauricio (Yes), nicolasgrekas (Yes), ocramius (Yes), petk (Yes), ramsey (Yes), sebastian (Yes), sergey (Yes), svpernova09 (Yes), theodorejb (Yes), timwolla (Yes), trowski (Yes)

## Discussions on the mailing list

- [\[RFC\] Deprecate remains of string evaluated code assertions](https://externals.io/message/120487.md) — started on 2023-05-31, 9 messages
- [\[RFC\] \[VOTE\] Deprecate remains of string evaluated code assertions](https://externals.io/message/120714.md) — started on 2023-06-28, 3 messages

---

## Introduction

Prior to PHP 7 assertions via the assert function could only operate on boolean values or with strings, in which case the string was evaluated and the result of it would be interpreted. The behaviour used by `assert()` is dependent on various INI settings that can also be set using the `assert_options()` function.

PHP 7 introduced “Expectations” which work with arbitrary expressions without needing to use `eval()` internally by utilizing the newly introduced AST. To preserve backwards compatibility, none of the previous assert INI settings were removed to allow the usage of “legacy” code assertions while migrating to the expression based one. In doing so, 2 new INI settings were introduced, `zend_assertions` and `assert.exception`.

Moreover, the “legacy” code assertions were deprecated in PHP 7.2 and have been removed in PHP 8.0. However, only the `assert.quiet_eval` INI setting and corresponding `ASSERT_QUIET_EVAL` have been removed. None of the other INI settings related to those assertions had been deprecated nor removed. Moreover, with the removal of the code assertions in PHP 8.0 some subtle behavioural changes were made if one continues to use the legacy INI settings.

Thus, the proposal is to deprecate those INI settings, the `assert_options()` function that allows to set them, and the relevant `ASSERT_*` constants.

The INI settings and constants in question are:

- `assert.active` and `ASSERT_ACTIVE`
- `assert.warning` and `ASSERT_WARNING`
- `assert.bail` and `ASSERT_BAIL`
- `assert.callback` and `ASSERT_CALLBACK`
- `assert.exception` and `ASSERT_EXCEPTION` which were introduced in PHP 7.0

We will now explain what each of these settings does:

### assert.active

Enabled by default. If disabled, any call to the `assert()` function will immediately return `true`. Otherwise, the assertion is executed.

### assert.warning

Enabled by default. If enabled, a warning is emitted if an assertion fails. As of PHP 7, this setting only has an effect if `assert.exception` is disabled.

### assert.bail

Disabled by default. If enabled, the engine bails out when an assertion fails. One needs to remember that prior to PHP 7, the engine didn't throw exceptions and thus this was the only way to abort execution on assertion failure.

### assert.callback

`null` by default. This setting allows defining a function (as a string) that should be called when an assertion fails. The only way to assign a more generic callable (e.g. an object having an `__invoke()` magic method) is by using the `assert_options()` function.

### assert.exception

Enabled by default. If enabled, an `AssertionError` or a custom exception is thrown if an assertion fails.

## Behavioural changes between PHP 7 and 8

With the removal of the string evaluated assertion in PHP, some unintended behavioural changes were made.

### Providing a custom exception short-circuits assert()

As of PHP 8.0, if a custom exception to be thrown is passed as a second argument to `assert()` the only INI setting that has any effect is `assert.active`, because if the assertion fails the custom exception is immediately thrown.

Moreover, the potentially set callback is not called.

### Signature change of the assertion callback

In PHP 7 and previously, the assertion callback signature was as follows:

```php
fn (string $filename, int $line_number, string $code, string $description = ?)
```

Where `$code` represents the string evaluated assertion if provided or an empty string.

As of PHP 8.0, the signature of the callback is as follows:

```php
fn (string $filename, int $line_number, null $code, string $description = ?)
```

Because the `assert()` function now always provides `null` instead of an empty string for the code argument.

## Formal Proposal

- Formally deprecate the `assert_options()` function that was “soft deprecated” in PHP 7.0, by emitting an `E_DEPRECATED` notice when it is called.
- Deprecate the `assert.active` INI setting and `ASSERT_ACTIVE` constant, the `zend_assertions` INI setting has superseded it for a while.
- Deprecate the `assert.warning` INI setting and `ASSERT_WARNING` constant
- Deprecate the `assert.bail` INI setting and `ASSERT_BAIL` constant
- Deprecate the `assert.callback` INI setting and `ASSERT_CALLBACK` constant, thus deprecating this feature completely.
- Deprecate the `assert.exception` INI setting and `ASSERT_EXCEPTION` constant
- Change the return value of `assert()` from `bool` to `void` when those features have been removed

The behaviour of a deprecated INI setting is as follows:

A deprecation notice is *only* emitted if the value set in an INI file, or at runtime via `ini_set()` differs from its default value.

## Proposed PHP Version

Next minor version, i.e. PHP 8.3.

## Proposed Voting Choices

As per the voting RFC a yes/no vote with a 2/3 majority is needed for this proposal to be accepted.

Voting started on 2023-06-28 and will end on 2023-07-12.

**Vote: Accept Deprecate remains of string evaluated code assertions RFC?** — Yes: 24 · No: 0 (closed)

## Implementation

Implemented in PHP 8.3:

1. Commit: <https://github.com/php/php-src/commit/3d4ff5ae22e73a3f4c41a26c0d2eb11646ecdd88>
2. a link to the PHP manual entry for the feature
