rfc:throw_error_for_invalid_characters_for_number_base

PHP RFC: Throw ValueError for invalid characters in number base functions

Introduction

Functions that convert numbers from one base to another (`bindec()`, `octdec()`, `hexdec()`, and `base_convert()`) accept a string representation of a number and convert it. Historically, these functions have been very lenient with their inputs, silently ignoring characters that are invalid for the specified number base.

For example, `hexdec('z')` treats `'z'` as an invalid character, silently ignores it, and returns `int(0)`.

In PHP 7.4, an RFC titled [Base Convert Improvements](https://wiki.php.net/rfc/base_convert_improvements) introduced a deprecation notice (`E_DEPRECATED`) when invalid characters are passed to these functions, with the intention of eventually turning it into an exception. While the deprecation notice was successfully implemented, the exception step was never completed.

This RFC proposes to complete that transition by throwing a `ValueError` when invalid characters are passed to `bindec()`, `octdec()`, `hexdec()`, and `base_convert()`, starting in PHP 8.7.

Proposal

We propose changing the behavior of `bindec()`, `octdec()`, `hexdec()`, and `base_convert()` when they encounter characters that are invalid within the context of the requested number base. Instead of emitting a deprecation notice and returning a partial/fallback conversion, these functions will immediately throw a `ValueError`.

Affected functions:

  • `bindec()` - Binary to decimal
  • `octdec()` - Octal to decimal
  • `hexdec()` - Hexadecimal to decimal
  • `base_convert()` - Convert a number between arbitrary bases

Examples

Remember that the RFC contents should be easily reusable in the PHP Documentation. This means, if at all possible, they should be runnable as standalone, self-contained code with the proof-of-concept implementation.

Simple example:

<?php
var_dump(hexdec('z'));
 
// PHP 7.4 - 8.6:
// Deprecated: Invalid characters passed for attempted conversion, these have been ignored in ...
// int(0)
 
// PHP 8.7 (Proposed):
// Fatal error: Uncaught ValueError: hexdec(): Argument #1 ($hex_string) has invalid characters for attempted conversion in ...
?>

Backward Incompatible Changes

Code that relies on the legacy behavior of silently ignoring invalid characters (or catching the current `E_DEPRECATED` notice) will experience behavior changes. If invalid characters are passed, a `ValueError` will now be thrown, which must be handled using `try/catch` blocks if invalid inputs are expected from untrusted sources.

Impact

Code that currently relies on the lenient behavior of these functions will fail. I can imagine that legitimate use is primarily having separators in input strings: hexdec('1234-5678'). First, this already throws a deprecation warning since PHP 7.4. Second, this is easily solved with normal string manipulation functions.

Proposed PHP Version(s)

PHP 8.7

Future Scope

Other string-to-number or decoding functions (such as `base64_decode()`, `intval()`, etc.) are completely unaffected by this change.

Voting Choices

* Vote: Throw a `ValueError` for invalid characters in number base conversion functions (`bindec`, `octdec`, `hexdec`, `base_convert`) in PHP 8.6? (Yes / No)


Primary Vote requiring a 2/3 majority to accept the RFC:

Throw a `ValueError` for invalid characters in number base conversion functions?
Real name Yes No Abstain
Final result: 0 0 0
This poll has been closed.

Patches and Tests

Implementation

After the RFC is implemented, this section should contain:

  1. the version(s) it was merged into
  2. a link to the git commit(s)
  3. a link to the PHP manual entry for the feature

References

Links to external references, discussions, or RFCs.

Rejected Features

Keep this updated with features that were discussed on the mail lists.

Changelog

If there are major changes to the initial proposal, please include a short summary with a date or a link to the mailing list announcement here, as not everyone has access to the wikis' version history.

rfc/throw_error_for_invalid_characters_for_number_base.txt · Last modified: by sjoerd