Skip to content

Commit f6f03d3

Browse files
committed
PHP8 updates
1 parent 86c0f6a commit f6f03d3

File tree

4 files changed

+79
-35
lines changed

4 files changed

+79
-35
lines changed

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,6 @@
4444
"fix-style": "phpcbf src tests"
4545
},
4646
"provide": {
47-
"ext-bcmath": "7.3.5"
47+
"ext-bcmath": "8.0.0"
4848
}
4949
}

lib/bcmath.php

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,4 +149,37 @@ function bcsub($left_operand, $right_operand, $scale = 0)
149149
{
150150
return BCMath::sub($left_operand, $right_operand, $scale);
151151
}
152+
}
153+
154+
// the following were introduced in PHP 7.0.0
155+
if (!class_exists('Error')) {
156+
class Error extends Exception
157+
{
158+
}
159+
160+
class ArithmeticError extends Error
161+
{
162+
}
163+
164+
class DivisionByZeroError extends ArithmeticError
165+
{
166+
}
167+
168+
class TypeError extends Error
169+
{
170+
}
171+
}
172+
173+
// the following was introduced in PHP 7.1.0
174+
if (!class_exists('ArgumentCountError')) {
175+
class ArgumentCountError extends TypeError
176+
{
177+
}
178+
}
179+
180+
// the following was introduced in PHP 8.0.0
181+
if (!class_exists('ValueError')) {
182+
class ValueError extends Error
183+
{
184+
}
152185
}

src/BCMath.php

Lines changed: 29 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -149,8 +149,9 @@ private static function mul($x, $y, $scale, $pad)
149149
private static function div($x, $y, $scale, $pad)
150150
{
151151
if ($y == '0') {
152-
trigger_error("bcdiv(): Division by zero", E_USER_WARNING);
153-
return null;
152+
// < PHP 8.0 triggered a warning
153+
// >= PHP 8.0 throws an exception
154+
throw new \DivisionByZeroError('Division by zero');
154155
}
155156

156157
$temp = '1' . str_repeat('0', $scale);
@@ -173,8 +174,9 @@ private static function div($x, $y, $scale, $pad)
173174
private static function mod($x, $y, $scale, $pad)
174175
{
175176
if ($y == '0') {
176-
trigger_error("bcmod(): Division by zero", E_USER_WARNING);
177-
return null;
177+
// < PHP 8.0 triggered a warning
178+
// >= PHP 8.0 throws an exception
179+
throw new \DivisionByZeroError('Division by zero');
178180
}
179181

180182
list($q) = $x->divide($y);
@@ -261,7 +263,9 @@ private static function pow($x, $y, $scale, $pad)
261263
private static function powmod($x, $e, $n, $scale, $pad)
262264
{
263265
if ($e[0] == '-' || $n == '0') {
264-
return false;
266+
// < PHP 8.0 returned false
267+
// >= PHP 8.0 throws an exception
268+
throw new \ValueError('bcpowmod(): Argument #2 ($exponent) must be greater than or equal to 0');
265269
}
266270
if ($n[0] == '-') {
267271
$n = substr($n, 1);
@@ -364,18 +368,11 @@ public static function __callStatic($name, $arguments)
364368
];
365369
if (count($arguments) < $params[$name] - 1) {
366370
$min = $params[$name] - 1;
367-
trigger_error(
368-
"bc$name() expects at least $min parameters, " . func_num_args() . " given",
369-
E_USER_WARNING
370-
);
371-
return null;
371+
throw new \ArgumentCountError("bc$name() expects at least $min parameters, " . func_num_args() . " given");
372372
}
373373
if (count($arguments) > $params[$name]) {
374-
trigger_error(
375-
"bc$name() expects at most {$params[$name]} parameters, " . func_num_args() . " given",
376-
E_USER_WARNING
377-
);
378-
return null;
374+
$str = "bc$name() expects at most {$params[$name]} parameters, " . func_num_args() . " given";
375+
throw new \ArgumentCountError($str);
379376
}
380377
$numbers = array_slice($arguments, 0, $params[$name] - 1);
381378

@@ -390,6 +387,12 @@ public static function __callStatic($name, $arguments)
390387
$ints = $numbers;
391388
$numbers = [];
392389
$names = ['base', 'exponent', 'modulus'];
390+
break;
391+
case 'sqrt':
392+
$names = ['num'];
393+
break;
394+
default:
395+
$names = ['num1', 'num2'];
393396
}
394397
foreach ($ints as $i => &$int) {
395398
if (!is_numeric($int)) {
@@ -398,10 +401,7 @@ public static function __callStatic($name, $arguments)
398401
$pos = strpos($int, '.');
399402
if ($pos !== false) {
400403
$int = substr($int, 0, $pos);
401-
trigger_error(
402-
"bc$name(): non-zero scale in $names[$i]",
403-
E_USER_WARNING
404-
);
404+
throw new \ValueError("bc$name(): Argument #2 (\$$names[$i]) cannot have a fractional part");
405405
}
406406
}
407407
foreach ($numbers as $i => $arg) {
@@ -411,18 +411,18 @@ public static function __callStatic($name, $arguments)
411411
case is_string($arg):
412412
case is_object($arg) && method_exists($arg, '__toString'):
413413
case is_null($arg):
414+
if (!is_bool($arg) && !is_null($arg) && !is_numeric("$arg")) {
415+
trigger_error("bc$name: bcmath function argument is not well-formed", E_USER_WARNING);
416+
}
414417
break;
415418
default:
416-
trigger_error(
417-
"bc$name() expects parameter $i to be integer, " . gettype($arg) . " given",
418-
E_USER_WARNING
419-
);
420-
return null;
419+
$type = is_object($arg) ? get_class($arg) : gettype($arg);
420+
throw new \TypeError("bc$name(): Argument #$i (\$$names[$i]) must be of type string, $type given");
421421
}
422422
}
423423
if (!isset(self::$scale)) {
424424
$scale = ini_get('bcmath.scale');
425-
self::$scale = $scale !== false ? intval($scale) : 0;
425+
self::$scale = $scale !== false ? max(intval($scale), 0) : 0;
426426
}
427427
$scale = isset($arguments[$params[$name] - 1]) ? $arguments[$params[$name] - 1] : self::$scale;
428428
switch (true) {
@@ -431,15 +431,13 @@ public static function __callStatic($name, $arguments)
431431
case is_string($scale) && preg_match('#0-9\.#', $scale[0]):
432432
break;
433433
default:
434-
trigger_error(
435-
"bc$name() expects parameter {$params[$name]} to be integer, " . gettype($scale) . " given",
436-
E_USER_WARNING
437-
);
438-
return null;
434+
$type = is_object($arg) ? get_class($arg) : gettype($arg);
435+
$str = "bc$name(): Argument #$params[$name] (\$scale) must be of type ?int, string given";
436+
throw new \TypeError($str);
439437
}
440438
$scale = (int) $scale;
441439
if ($scale < 0) {
442-
$scale = 0;
440+
throw new \ValueError("bc$name(): Argument #$params[$name] (\$scale) must be between 0 and 2147483647");
443441
}
444442

445443
$pad = 0;

tests/BCMathTest.php

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,11 @@ public function testMul(...$params)
8787
public function testDiv(...$params)
8888
{
8989
if ($params[1] === '0' || $params[1] === '-0') {
90-
$this->setExpectedException('PHPUnit_Framework_Error_Warning');
90+
if (version_compare(PHP_VERSION, '8.0.0') >= 0) {
91+
$this->setExpectedException('DivisionByZeroError');
92+
} else {
93+
$this->markTestSkipped('< PHP 8.0.0 has different behavior than >= PHP 8.0.0');
94+
}
9195
}
9296

9397
$a = bcdiv(...$params);
@@ -102,7 +106,11 @@ public function testDiv(...$params)
102106
public function testMod(...$params)
103107
{
104108
if ($params[1] === '0' || $params[1] === '-0') {
105-
$this->setExpectedException('PHPUnit_Framework_Error_Warning');
109+
if (version_compare(PHP_VERSION, '8.0.0') >= 0) {
110+
$this->setExpectedException('DivisionByZeroError');
111+
} else {
112+
$this->markTestSkipped('< PHP 8.0.0 has different behavior than >= PHP 8.0.0');
113+
}
106114
}
107115

108116
$a = bcmod(...$params);
@@ -156,12 +164,17 @@ public function generatePowModParams()
156164
['9', '9', '17'],
157165
['999', '999', '111', 5],
158166
['-9', '1024', '123'],
159-
['9', '-1024', '127', 5],
160167
['3', '1024', '-149'],
161168
['2', '12', '2', 5],
162169
['3', '0', '13'],
163170
['-3', '0', '13', 4],
164171
];
172+
173+
if (version_compare(PHP_VERSION, '8.0.0') >= 0) {
174+
$a = array_merge($a, [['9', '-1024', '127', 5]]);
175+
}
176+
177+
return $a;
165178
}
166179

167180
/**

0 commit comments

Comments
 (0)