PHP 8.6: New clamp function
PHP 8.6 introduces a new clamp function that checks if a given value is within a given bound. If the value is within that bound, the original value is returned. If it is not within the bounds, clamp returns the closest bound.
In other words, the clamp function can "clamp" a given value to lower and higher bounds.
The new clamp function in PHP follows the same semantics as other programming languages such as C++ (std::clamp), C# (Math.Clamp), Go (cmp.Clamp), Java (Math.clamp), and Python (np.clip).
clamp function
function clamp(?mixed $value, ?mixed $min, ?mixed $max): ?mixed
The parameter $value is clamped inclusively within the range $min and $max.
- The function is declared in the global namespace.
- If the
$minvalue is larger than$max, aValueErrorexception is thrown. - Neither
$minnor$maxcan beNAN, otherwise, aValueErroris thrown. - When comparing values of different types, comparison rules are used. Note that they may not be as intuitive, especially when comparing arrays, objects, and boolean values.
Usage Examples
Integer clamping:
clamp(5, 0, 100); // 5
clamp(0, 0, 100); // 0
clamp(-5, 0, 100); // 0
clamp(100, 0, 100); // 100
clamp(105, 0, 100); // 100
clamp(105, 100, 100); // 100
Float clamping:
clamp(3.01, 1.6, 4.2); // 3.01
clamp(10.0, 1.6, 4.2); // 4.2
clamp(0, M_1_PI, M_2_PI); // 0.31830988618379
Integer and float clamping
clamp(5, 10, 12.5); // 10
clamp(5, 10.0, 12); // 10.0
clamp(3.14, 10, 20); // 10
clamp(3.14, 0, 20); // 3.14
Incompatible Type Comparisons
When comparing values of types other than int and float, the value is first compared to the upper bound ($max), and then against the lower bound ($min).
Comparing incompatible types
When the boundary values and the value parameters are of different types, the values are compared using the standard type coercion rules. They carry historical baggage, and are not intuitive. It is recommended to compare the values manually instead of using the
clampfunction when the boundaries and/or values are type-incompatible.
strict_typeshas no impact on this comparison behavior.
The clamp function does not introduce any new comparison semantics.
Internally, the upper bound is checked first ($value > $max). If this evaluates to true, the $max value is returned. Second, $value < $min, which returns $min if it evaluates to true. Finally, if both comparisons evaluated to false, the $value is returned.
This behavior explains the clamping behavior shown below across different types:
String values
If all three parameters are non-numeric strings, they are evaluated lexicographically:
clamp('P', 'A', 'Z'); // "P"
clamp('P', 'X', 'Z'); // "X"
clamp('P', 'A', 'C'); // "C"
clamp('AAA', 'AA', 'Z'); // "AAA"
Boolean values
clamp(5, false, true); // 5
clamp(true, false, true); // true
clamp(true, false, false); // false
clamp(false, true, true); // true
clamp(false, true, 5); // true
Arrays
clamp(5, [], []); // []
clamp(5, 0, []); // 5
clamp(5, false, []); // 5
clamp([3], [1], [5]); // [3]
clamp([1], [3], [5]); // [3]
clamp([1, 4], [3], [1, 5]); // [1, 4]
Objects
Objects are also compared with the same > and < operators. If the objects support overloaded comparisons, they are evaluated.
For example, the DateTime/DateTimeImmutable classes and BCMath\Number classes support comparing objects. They are compatible with the clamp function:
clamp(new DateTimeImmutable('2026-01-08'), new DateTimeImmutable('2026-01-01'), new DateTimeImmutable('2026-12-31'));
// DateTimeImmutable('2026-01-08')
clamp(new BCMath\Number('36'), new BCMath\Number('16'), new BCMath\Number('42'));
// BCMath\Number('36')
Userland Polyfill
The new clamp function can be trivially polyfilled with user-land PHP:
/**
* Return the given value if in range, otherwise return the nearest bound.
*/
function clamp(mixed $value, mixed $min, mixed $max): mixed {
if (\is_float($min) && \is_nan($min)) {
throw new \ValueError('clamp(): Argument #2 ($min) must not be NAN');
}
if (\is_float($max) && \is_nan($max)) {
throw new \ValueError('clamp(): Argument #3 ($max) must not be NAN');
}
if ($max < $min) {
throw new \ValueError('clamp(): Argument #2 ($min) must be smaller than or equal to argument #3 ($max)');
}
if ($value > $max) {
return $max;
}
if ($value < $min) {
return $min;
}
return $value;
}
Backward Compatibility Impact
The new clamp function is declared in the global namespace. Unless the PHP application declares a clamp function on its own, this change has no BC breakages.
It is possible to polyfill the clamp function in older PHP functions.