polyfill
polyfill copied to clipboard
[PHP 8.2] Add `ini_parse_quantity` function
Polyfill taken from PHP.Watch - PHP 8.2: New ini_parse_quantity function
Tries to mimic the native warnings with E_USER_WARNING errors, and overflow/underflow conditions by inspecting the int to float type change.
Tried adding the following tests, but they don't seem to work for some reason:
/**
* @covers \Symfony\Polyfill\Php82\Php82::ini_parse_quantity
*/
public function testIniParseQuantityWarningsInvalidCharactersIgnored()
{
$this->expectWarning();
$this->expectWarningMessageMatches('/Invalid quantity "5em", interpreting as "5m" for backwards compatibility/');
ini_parse_quantity('5em');
}
/**
* @covers \Symfony\Polyfill\Php82\Php82::ini_parse_quantity
*/
public function testIniParseQuantityWarningsNoDigits()
{
$this->expectWarning();
$this->expectWarningMessageMatches('/Invalid quantity "NOVALUE": no valid leading digits, interpreting as "0" for backwards compatibility/');
ini_parse_quantity('NOVALUE');
}
/**
* @covers \Symfony\Polyfill\Php82\Php82::ini_parse_quantity
*/
public function testIniParseQuantityUnknownMultiplier()
{
$this->expectWarning();
$this->expectWarningMessageMatches('/Invalid quantity "123R": unknown multiplier "R", interpreting as "123" for backwards compatibility/');
ini_parse_quantity('123R');
}
Tried adding the following tests, but they don't seem to work for some reason
you can try add anchors /^...$/i or use expectWarningMessage()
only the error message seems to be slightly different than on PHP 8.2.
If it wasn't for the error-messages, this would be a trivial function to polyfill :-)
Here is a simple, brute-force test script I wrote while trying to create my own implementation.
<?php
require 'src/Php82/Php82.php';
use Symfony\Polyfill\Php82\Php82;
function do_test($test) {
error_clear_last();
$x = @ini_parse_quantity($test);
$err_x = error_get_last()['message'] ?? '';
error_clear_last();
$y = @Php82::ini_parse_quantity($test);
$err_y = error_get_last()['message'] ?? '';
if ($x !== $y || $err_x !== $err_y) {
echo 'FAIL: "', $test, '"', PHP_EOL, $x, PHP_EOL, $y, PHP_EOL, $err_x, PHP_EOL, $err_y, PHP_EOL;
exit;
}
}
$chars = [' ', '-', '+', '0', '1', '7', '9', 'a', 'b', 'o', 'f', 'g', 'k', 'm', 'x', 'z'];
do_test('');
foreach ($chars as $char1) {
do_test($char1);
foreach ($chars as $char2) {
do_test($char1 . $char2);
foreach ($chars as $char3) {
do_test($char1 . $char2 . $char3);
foreach ($chars as $char4) {
do_test($char1 . $char2 . $char3 . $char4);
foreach ($chars as $char5) {
do_test($char1 . $char2 . $char3 . $char4 . $char5);
foreach ($chars as $char6) {
do_test($char1 . $char2 . $char3 . $char4 . $char5 . $char6);
}
}
}
}
}
}
What's the status on this?
The C implementation is here: https://github.com/php/php-src/blob/master/Zend/zend_ini.c#L590
Would anyone be interested in porting this to PHP? I suppose @Ayesh is not available to finish this PR.
I'm closing to signal that someone else should take over. PR welcome.
Would anyone be interested in porting this to PHP?
I have done this and have a working solution. (I need it for one of my own projects.)
Using the brute-force test technique above, it gives the same output and errors as the core function for all strings up to 7 characters.
- The tests only run on PHP82, as they require the core function as a reference.
- The code follows the C source - including
gotos and pointer-based string access.
Would you want me to create a PR now (with this rather hideous code) or wait until I have time to clean it up (which might not be soon)?
I've submitted PR #439