diff --git a/ext/standard/basic_functions.stub.php b/ext/standard/basic_functions.stub.php index 540d88722c15c..09e67bc510565 100755 --- a/ext/standard/basic_functions.stub.php +++ b/ext/standard/basic_functions.stub.php @@ -1478,6 +1478,8 @@ function mail(string $to, string $subject, string $message, array|string $additi function abs(int|float $num): int|float {} +function clamp(int|float $num, int|float $min, int|float $max): int|float {} + function ceil(int|float $num): float {} function floor(int|float $num): float {} diff --git a/ext/standard/basic_functions_arginfo.h b/ext/standard/basic_functions_arginfo.h index 8b573cbe2dff3..127f224a8d8d0 100644 --- a/ext/standard/basic_functions_arginfo.h +++ b/ext/standard/basic_functions_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: b1c51fabe59bba6706500365f3eb7d9676d625f6 */ + * Stub hash: 810c067c37c6f7bbaf5726fcf201fdb0dde5d1d2 */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_set_time_limit, 0, 1, _IS_BOOL, 0) ZEND_ARG_TYPE_INFO(0, seconds, IS_LONG, 0) @@ -1602,6 +1602,12 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_abs, 0, 1, MAY_BE_LONG|MAY_BE_DO ZEND_ARG_TYPE_MASK(0, num, MAY_BE_LONG|MAY_BE_DOUBLE, NULL) ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_clamp, 0, 3, MAY_BE_LONG|MAY_BE_DOUBLE) + ZEND_ARG_TYPE_MASK(0, num, MAY_BE_LONG|MAY_BE_DOUBLE, NULL) + ZEND_ARG_TYPE_MASK(0, min, MAY_BE_LONG|MAY_BE_DOUBLE, NULL) + ZEND_ARG_TYPE_MASK(0, max, MAY_BE_LONG|MAY_BE_DOUBLE, NULL) +ZEND_END_ARG_INFO() + ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_ceil, 0, 1, IS_DOUBLE, 0) ZEND_ARG_TYPE_MASK(0, num, MAY_BE_LONG|MAY_BE_DOUBLE, NULL) ZEND_END_ARG_INFO() @@ -2660,6 +2666,7 @@ ZEND_FUNCTION(link); #endif ZEND_FUNCTION(mail); ZEND_FUNCTION(abs); +ZEND_FUNCTION(clamp); ZEND_FUNCTION(ceil); ZEND_FUNCTION(floor); ZEND_FUNCTION(round); @@ -3304,6 +3311,7 @@ static const zend_function_entry ext_functions[] = { #endif ZEND_FE(mail, arginfo_mail) ZEND_FE(abs, arginfo_abs) + ZEND_FE(clamp, arginfo_clamp) ZEND_FE(ceil, arginfo_ceil) ZEND_FE(floor, arginfo_floor) ZEND_FE(round, arginfo_round) diff --git a/ext/standard/math.c b/ext/standard/math.c index ad2823ea49bf6..b38842bf8b010 100644 --- a/ext/standard/math.c +++ b/ext/standard/math.c @@ -228,6 +228,32 @@ PHP_FUNCTION(abs) } /* }}} */ +/* {{{ Return the given value if in range of min and max */ +PHP_FUNCTION(clamp) +{ + zval *zvalue, *zmin, *zmax; + + ZEND_PARSE_PARAMETERS_START(3, 3) + Z_PARAM_NUMBER(zvalue) + Z_PARAM_NUMBER(zmin) + Z_PARAM_NUMBER(zmax) + ZEND_PARSE_PARAMETERS_END(); + + if (zend_compare(zmin, zmax) > 0) { + zend_argument_value_error(2, "must be smaller than or equal to argument #3 ($max)"); + RETURN_THROWS(); + } + + if (zend_compare(zmax, zvalue) == -1) { + RETURN_COPY_VALUE(zmax); + } else if (zend_compare(zvalue, zmin) == -1) { + RETURN_COPY_VALUE(zmin); + } else { + RETURN_COPY_VALUE(zvalue); + } +} +/* }}} */ + /* {{{ Returns the next highest integer value of the number */ PHP_FUNCTION(ceil) { diff --git a/ext/standard/tests/math/clamp_basic1.phpt b/ext/standard/tests/math/clamp_basic1.phpt new file mode 100644 index 0000000000000..321c9e4827032 --- /dev/null +++ b/ext/standard/tests/math/clamp_basic1.phpt @@ -0,0 +1,62 @@ +--TEST-- +Test clamp() function : basic functionality 01 +--FILE-- +getMessage(), "\n"; +} + +try { + var_dump(clamp(1, 3.5, 3.0)); +} catch (\ValueError $e) { + echo $e->getMessage(), "\n"; +} + +var_dump(clamp(0, null, 3.5)); + +try { + var_dump(clamp(5, 1, null)); +} catch (\ValueError $e) { + echo $e->getMessage(), "\n"; +} + +var_dump(clamp(-2, -5, 1)); +var_dump(clamp(-2.3, -3.0, 3.5)); +?> +--EXPECTF-- +*** Testing clamp() : basic functionality 01 *** +int(1) +int(2) +int(3) +int(4) +int(5) +float(1) +float(1.5) +float(2) +float(2.5) +float(3) +clamp(): Argument #2 ($min) must be smaller than or equal to argument #3 ($max) +clamp(): Argument #2 ($min) must be smaller than or equal to argument #3 ($max) + +Deprecated: clamp(): Passing null to parameter #2 ($min) of type int|float is deprecated in %s on line %d +int(0) + +Deprecated: clamp(): Passing null to parameter #3 ($max) of type int|float is deprecated in %s on line %d +clamp(): Argument #2 ($min) must be smaller than or equal to argument #3 ($max) +int(-2) +float(-2.3) diff --git a/ext/standard/tests/math/clamp_basic2.phpt b/ext/standard/tests/math/clamp_basic2.phpt new file mode 100644 index 0000000000000..8e2f4e3fd2c71 --- /dev/null +++ b/ext/standard/tests/math/clamp_basic2.phpt @@ -0,0 +1,55 @@ +--TEST-- +Test clamp() function : basic functionality 02 +--FILE-- +getMessage(), "\n"; +} +try { + var_dump(clamp(1, 0, NAN)); +} catch (\ValueError $e) { + echo $e->getMessage(), "\n"; +} +var_dump(clamp(0x10, 0x01, 2)); +var_dump(clamp(10, "-2.345e1", 2.345e1)); +var_dump(clamp(24.0, 027, 25)); +var_dump(clamp(2.345e1, "-2.345e1", 2.345e1)); +var_dump(clamp(0.0, null, 2)); +var_dump(clamp(0.0, null, null)); +var_dump(clamp(0.0, null, false)); +try { + var_dump(clamp(INF, false, NAN)); +} catch (\ValueError $e) { + echo $e->getMessage(), "\n"; +} +var_dump(clamp(NAN, 0, 2)); +?> +--EXPECTF-- +*** Testing clamp() : basic functionality 02 *** +int(0) +float(0) +clamp(): Argument #2 ($min) must be smaller than or equal to argument #3 ($max) +clamp(): Argument #2 ($min) must be smaller than or equal to argument #3 ($max) +int(2) +int(10) +float(24) +float(23.45) + +Deprecated: clamp(): Passing null to parameter #2 ($min) of type int|float is deprecated in %s on line %d +float(0) + +Deprecated: clamp(): Passing null to parameter #2 ($min) of type int|float is deprecated in %s on line %d + +Deprecated: clamp(): Passing null to parameter #3 ($max) of type int|float is deprecated in %s on line %d +float(0) + +Deprecated: clamp(): Passing null to parameter #2 ($min) of type int|float is deprecated in %s on line %d +float(0) +clamp(): Argument #2 ($min) must be smaller than or equal to argument #3 ($max) +float(NAN)