Compare commits

...

2 Commits

Author SHA1 Message Date
Clemens Schwaighofer
b8c0aff975 Update phive phars with correct version and update scripts to use both
new "-c" switch for all checking scripts to swtich to the composer version from the phive installed version

NOTE: phpstan plugins only work in the composer version.

Default is the phive version
2026-01-06 18:15:50 +09:00
Clemens Schwaighofer
c5fed66237 PHP 8.5 fixes and updates
All tested with PHP 8.4 and PHP 8.3 too

Major changes:
- cube root Math (cbrt) now throws InvalidArgumentException if NAN is returned instead of returning NAN
- Byte convert from string to int will throw errors if value is too large (\LengthException)
- new flag for returning string type but for this bcmath must be installed (\RuntimeException if no bcmath)
- Updated curl class and remove close handler as not needed and deprecated as of PHP 8.5
- Curl phpunit tests: convert string to JSON convert flow for return content check (to avoid per PHP version check)
- image close handler for ImageMagick removed as not needed and deprecated as of PHP 8.5
- updated all check calls too use phive tools if possible (except phpunit) and all scripts can have dynamic php version set
2026-01-06 15:55:47 +09:00
15 changed files with 537 additions and 162 deletions

View File

@@ -26,8 +26,8 @@
use Phan\Config; use Phan\Config;
return [ return [
// "target_php_version" => "8.2", // "target_php_version" => "8.3",
"minimum_target_php_version" => "8.2", "minimum_target_php_version" => "8.3",
// turn color on (-C) // turn color on (-C)
"color_issue_messages_if_supported" => true, "color_issue_messages_if_supported" => true,
// If true, missing properties will be created when // If true, missing properties will be created when

View File

@@ -1,12 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<phive xmlns="https://phar.io/phive"> <phive xmlns="https://phar.io/phive">
<phar name="phpunit" version="^10.3.5" installed="10.5.46" location="./tools/phpunit" copy="false"/> <phar name="phpunit" version="~9.6" installed="9.6.31" location="./tools/phpunit" copy="false"/>
<phar name="phpcbf" version="^3.7.2" installed="3.13.0" location="./tools/phpcbf" copy="false"/> <phar name="phpcbf" version="4" installed="4.0.1" location="./tools/phpcbf" copy="false"/>
<phar name="phpcs" version="^3.10.3" installed="3.13.0" location="./tools/phpcs" copy="false"/> <phar name="phpcs" version="4" installed="4.0.1" location="./tools/phpcs" copy="false"/>
<phar name="phpstan" version="^2.0" installed="2.1.17" location="./tools/phpstan" copy="false"/> <phar name="phpstan" version="^2.0" installed="2.1.33" location="./tools/phpstan" copy="false"/>
<phar name="phan" version="^5.4.3" installed="5.4.3" location="./tools/phan" copy="false"/> <phar name="phan" version="^5.4.3" installed="5.5.2" location="./tools/phan" copy="false"/>
<phar name="psalm" version="^5.15.0" installed="5.24.0" location="./tools/psalm" copy="false"/> <phar name="psalm" version="^5.26.1" installed="5.26.1" location="./tools/psalm" copy="false"/>
<phar name="phpdox" version="^0.12.0" installed="0.12.0" location="./tools/phpdox" copy="false"/> <phar name="phpdox" version="^0.12.0" installed="0.12.0" location="./tools/phpdox" copy="false"/>
<phar name="phpdocumentor" version="^3.4.2" installed="3.4.3" location="./tools/phpDocumentor" copy="false"/> <phar name="phpdocumentor" version="^3.4.2" installed="3.9.1" location="./tools/phpDocumentor" copy="false"/>
<phar name="php-cs-fixer" version="^3.34.1" installed="3.57.2" location="./tools/php-cs-fixer" copy="false"/> <phar name="php-cs-fixer" version="^3.34.1" installed="3.92.4" location="./tools/php-cs-fixer" copy="false"/>
</phive> </phive>

View File

@@ -1,6 +1,100 @@
base=$(pwd)"/"; #!/bin/env bash
function error() {
if [ -t 1 ]; then echo "[MAK] ERROR: $*" >&2; fi; exit 0;
}
usage() {
cat <<EOF
Usage: $(basename "${BASH_SOURCE[0]}") [-h] [-p VERSION]
Runs phan static analyzer.
If -p is not set, the default intalled PHP is used.
Available options:
-h, --help Print this help and exit
-p, --php VERSION Chose PHP version in the form of "N.N", if not found will exit
-c, --composer Use composer version and not the default phives bundle
EOF
exit
}
BASE_PATH=$(pwd)"/";
PHP_BIN_PATH=$(which php);
if [ -z "${PHP_BIN_PATH}" ]; then
echo "Cannot find php binary";
exit;
fi;
DEFAULT_PHP_VERSION=$(${PHP_BIN_PATH} -r "echo PHP_MAJOR_VERSION.'.'.PHP_MINOR_VERSION;");
if [ -z "${DEFAULT_PHP_VERSION}" ]; then
echo "Cannot set default PHP version";
exit;
fi;
php_version="";
no_php_version=0;
use_composer=0;
while [ -n "${1-}" ]; do
case "${1}" in
-p | --php)
php_version="${2-}";
shift
;;
-c | --composer)
use_composer=1;
shift
;;
-h | --help)
usage
;;
# invalid option
-?*)
error "[!] Unknown option: '$1'."
;;
esac
shift;
done;
if [ -z "${php_version}" ]; then
php_version="${DEFAULT_PHP_VERSION}";
no_php_version=1;
fi;
php_bin="${PHP_BIN_PATH}${php_version}";
echo "Use PHP Version: ${php_version}";
if [ "${use_composer}" -eq 1 ]; then
echo "Use composer installed phan";
else
echo "Use phan installed via phives";
fi;
if [ ! -f "${php_bin}" ]; then
echo "Set php ${php_bin} does not exist";
exit;
fi;
# must be run in ${base} # must be run in ${base}
cd $base || exit; cd "$BASE_PATH" || exit;
#PHAN_DISABLE_XDEBUG_WARN=1;${base}tools/phan --progress-bar -C --analyze-twice export PHAN_DISABLE_XDEBUG_WARN=1;
PHAN_DISABLE_XDEBUG_WARN=1;${base}vendor/bin/phan --progress-bar -C --analyze-twice PHAN_CALL=(
"${php_bin}"
);
if [ "${use_composer}" -eq 1 ]; then
PHAN_CALL+=("${BASE_PATH}vendor/bin/phan");
else
PHAN_CALL+=("${BASE_PATH}tools/phan");
fi;
PHAN_CALL+=(
"--progress-bar"
"-C"
"--analyze-twice"
)
"${PHAN_CALL[@]}";
if [ "${no_php_version}" -eq 0 ]; then
echo "*** CALLED WITH PHP ${php_bin} ***";
${php_bin} --version;
else
echo "Default PHP used: $(php --version)";
fi;
cd ~ || exit; cd ~ || exit;
# __END__

View File

@@ -1,5 +1,92 @@
base=$(pwd)"/"; #!/bin/env bash
# must be run in ${base}
cd $base || exit; function error() {
${base}tools/phpstan; if [ -t 1 ]; then echo "[MAK] ERROR: $*" >&2; fi; exit 0;
}
usage() {
cat <<EOF
Usage: $(basename "${BASH_SOURCE[0]}") [-h] [-p VERSION]
Runs phan static analyzer.
If -p is not set, the default intalled PHP is used.
Available options:
-h, --help Print this help and exit
-p, --php VERSION Chose PHP version in the form of "N.N", if not found will exit
-c, --composer Use composer version and not the default phives bundle
EOF
exit
}
BASE_PATH=$(pwd)"/";
PHP_BIN_PATH=$(which php);
if [ -z "${PHP_BIN_PATH}" ]; then
echo "Cannot find php binary";
exit;
fi;
DEFAULT_PHP_VERSION=$(${PHP_BIN_PATH} -r "echo PHP_MAJOR_VERSION.'.'.PHP_MINOR_VERSION;");
if [ -z "${DEFAULT_PHP_VERSION}" ]; then
echo "Cannot set default PHP version";
exit;
fi;
php_version="";
no_php_version=0;
use_composer=0;
while [ -n "${1-}" ]; do
case "${1}" in
-p | --php)
php_version="${2-}";
shift
;;
-c | --composer)
use_composer=1;
shift
;;
-h | --help)
usage
;;
# invalid option
-?*)
error "[!] Unknown option: '$1'."
;;
esac
shift;
done;
if [ -z "${php_version}" ]; then
php_version="${DEFAULT_PHP_VERSION}";
no_php_version=1;
fi;
php_bin="${PHP_BIN_PATH}${php_version}";
echo "Use PHP Version: ${php_version}";
if [ "${use_composer}" -eq 1 ]; then
echo "Use composer installed phan";
else
echo "Use phan installed via phives";
fi;
if [ ! -f "${php_bin}" ]; then
echo "Set php ${php_bin} does not exist";
exit;
fi;
BASE_PATH=$(pwd)"/";
cd "$BASE_PATH" || exit;
PHPSTAN_CALL=(
"${php_bin}"
);
if [ "${use_composer}" -eq 1 ]; then
PHPSTAN_CALL+=("${BASE_PATH}vendor/bin/phpstan");
else
PHPSTAN_CALL+=("${BASE_PATH}tools/phpstan");
fi;
"${PHPSTAN_CALL[@]}";
if [ "${no_php_version}" -eq 0 ]; then
echo "*** CALLED WITH PHP ${php_bin} ***";
${php_bin} --version;
else
echo "Default PHP used: $(php --version)";
fi;
cd ~ || exit; cd ~ || exit;

View File

@@ -15,8 +15,9 @@ If -p is not set, the default intalled PHP is used.
Available options: Available options:
-h, --help Print this help and exit -h, --help Print this help and exit
-t, --testdox Enable testdox output for phpunit -t, --testdox Enable testdox output for PHPunit
-v, --verbose Enable verbose output for PHPunit -v, --verbose Enable verbose output for PHPunit
-c, --composer Use composer version and not the default phives bundle
-p, --php VERSION Chose PHP version in the form of "N.N", if not found will exit -p, --php VERSION Chose PHP version in the form of "N.N", if not found will exit
EOF EOF
exit exit
@@ -45,6 +46,7 @@ opt_testdox="";
opt_verbose=""; opt_verbose="";
php_version=""; php_version="";
no_php_version=0; no_php_version=0;
use_composer=0;
while [ -n "${1-}" ]; do while [ -n "${1-}" ]; do
case "${1}" in case "${1}" in
-t | --testdox) -t | --testdox)
@@ -53,6 +55,10 @@ while [ -n "${1-}" ]; do
-v | --verbose) -v | --verbose)
opt_verbose="--verbose"; opt_verbose="--verbose";
;; ;;
-c | --composer)
use_composer=1;
shift
;;
-p | --php) -p | --php)
php_version="${2-}"; php_version="${2-}";
shift shift
@@ -74,21 +80,38 @@ if [ -z "${php_version}" ]; then
fi; fi;
php_bin="${PHP_BIN_PATH}${php_version}"; php_bin="${PHP_BIN_PATH}${php_version}";
echo "Use PHP Version: ${php_version}"; echo "Use PHP Version: ${php_version}";
if [ "${use_composer}" -eq 1 ]; then
echo "Use composer installed phan";
else
echo "Use phan installed via phives";
fi;
if [ ! -f "${php_bin}" ]; then if [ ! -f "${php_bin}" ]; then
echo "Set php ${php_bin} does not exist"; echo "Set php ${php_bin} does not exist";
exit; exit;
fi; fi;
php_bin="${php_bin} ";
# Note 4dev/tests/bootstrap.php has to be set as bootstrap file in phpunit.xml # Note 4dev/tests/bootstrap.php has to be set as bootstrap file in phpunit.xml
phpunit_call="${php_bin}${BASE_PATH}vendor/bin/phpunit ${opt_testdox} ${opt_verbose} -c ${PHPUNIT_CONFIG} ${BASE_PATH}4dev/tests/"; PHPUNIT_CALL=(
"${php_bin}"
${phpunit_call}; );
if [ "${use_composer}" -eq 1 ]; then
PHPUNIT_CALL+=("${BASE_PATH}vendor/bin/phpunit");
else
PHPUNIT_CALL+=("${BASE_PATH}tools/phpunit");
fi;
PHPUNIT_CALL+=(
"${opt_testdox}"
"${opt_verbose}"
"-c" "${PHPUNIT_CONFIG}"
"${BASE_PATH}4dev/tests/"
);
"${PHPUNIT_CALL[@]}" || exit;
echo -e "\nPHPUnit Config: ${PHPUNIT_CONFIG}"; echo -e "\nPHPUnit Config: ${PHPUNIT_CONFIG}";
if [ "${no_php_version}" -eq 0 ]; then if [ "${no_php_version}" -eq 0 ]; then
echo "CALLED WITH PHP: ${php_bin}$(${php_bin} --version)"; echo "*** CALLED WITH PHP ${php_bin} ***";
${php_bin} --version;
else else
echo "Default PHP used: $(php --version)"; echo "Default PHP used: $(php --version)";
fi; fi;

View File

@@ -123,47 +123,6 @@ final class CoreLibsConvertByteTest extends TestCase
]; ];
} }
/**
* Undocumented function
*
* @return array
*/
public function byteStringProvider(): array
{
return [
'negative number' => [
0 => '-117.42 MB',
1 => -123123794,
2 => -117420000,
],
'megabyte' => [
0 => '242.98 MB',
1 => 254782996,
2 => 242980000
],
'megabyte si' => [
0 => '254.78 MiB',
1 => 267156193,
2 => 254780000
],
'petabyte' => [
0 => '1 EiB',
1 => 1152921504606846976,
2 => 1000000000000000000,
],
'max int' => [
0 => '8 EB',
1 => -9223372036854775807 - 1,
2 => 8000000000000000000,
],
'exabyte, overflow' => [
0 => '867.36EB',
1 => 3873816255479021568,
2 => 363028535651074048,
]
];
}
/** /**
* Undocumented function * Undocumented function
* *
@@ -180,7 +139,7 @@ final class CoreLibsConvertByteTest extends TestCase
* @return void * @return void
*/ */
public function testHumanReadableByteFormat( public function testHumanReadableByteFormat(
$input, string|int|float $input,
string $expected, string $expected,
string $expected_si, string $expected_si,
string $expected_no_space, string $expected_no_space,
@@ -217,6 +176,73 @@ final class CoreLibsConvertByteTest extends TestCase
); );
} }
/**
* Undocumented function
*
* @return array
*/
public function byteStringProvider(): array
{
return [
'negative number' => [
0 => '-117.42 MB',
1 => -123123794,
2 => -117420000,
3 => "-123123793",
4 => "-117420000",
5 => null,
],
'megabyte' => [
0 => '242.98 MB',
1 => 254782996,
2 => 242980000,
3 => "254782996",
4 => "242980000",
5 => null,
],
'megabyte si' => [
0 => '254.78 MiB',
1 => 267156193,
2 => 254780000,
3 => "267156193",
4 => "254780000",
5 => null,
],
'petabyte' => [
0 => '1 EiB',
1 => 1152921504606846976,
2 => 1000000000000000000,
3 => "1152921504606846976",
4 => "1000000000000000000",
5 => null,
],
'max int' => [
0 => '8 EB',
1 => 0,
2 => 0,
3 => "9223372036854775808",
4 => "8000000000000000000",
5 => \LengthException::class,
],
'exabyte, overflow' => [
0 => '867.36EB',
1 => 0,
2 => 0,
3 => "999997996235794808832",
4 => "867360000000000000000",
5 => \LengthException::class,
],
'huge exabyte, overflow' => [
0 => '1000EB',
1 => 0,
2 => 0,
3 => "1152921504606846976000",
4 => "1000000000000000000000",
5 => \LengthException::class,
],
];
}
/** /**
* Undocumented function * Undocumented function
* *
@@ -227,10 +253,22 @@ final class CoreLibsConvertByteTest extends TestCase
* @param string|int|float $input * @param string|int|float $input
* @param string|int|float $expected * @param string|int|float $expected
* @param string|int|float $expected_si * @param string|int|float $expected_si
* @param string|int|float $expected_string
* @param string|int|float $expected_string_si
* @param ?string $exception
* @return void * @return void
*/ */
public function testStringByteFormat($input, $expected, $expected_si): void public function testStringByteFormat(
{ string|int|float $input,
string|int|float $expected,
string|int|float $expected_si,
string|int|float $expected_string,
string|int|float $expected_string_si,
?string $exception
): void {
if ($exception !== null) {
$this->expectException($exception);
}
$this->assertEquals( $this->assertEquals(
$expected, $expected,
\CoreLibs\Convert\Byte::stringByteFormat($input) \CoreLibs\Convert\Byte::stringByteFormat($input)
@@ -239,6 +277,17 @@ final class CoreLibsConvertByteTest extends TestCase
$expected_si, $expected_si,
\CoreLibs\Convert\Byte::stringByteFormat($input, \CoreLibs\Convert\Byte::BYTE_FORMAT_SI) \CoreLibs\Convert\Byte::stringByteFormat($input, \CoreLibs\Convert\Byte::BYTE_FORMAT_SI)
); );
$this->assertEquals(
$expected_string,
\CoreLibs\Convert\Byte::stringByteFormat($input, \CoreLibs\Convert\Byte::RETURN_AS_STRING)
);
$this->assertEquals(
$expected_string_si,
\CoreLibs\Convert\Byte::stringByteFormat(
$input,
\CoreLibs\Convert\Byte::BYTE_FORMAT_SI | \CoreLibs\Convert\Byte::RETURN_AS_STRING
)
);
} }
/** /**

View File

@@ -122,9 +122,9 @@ final class CoreLibsConvertMathTest extends TestCase
public function providerCbrt(): array public function providerCbrt(): array
{ {
return [ return [
'cube root of 2' => [2, 1.25992, 5], 'cube root of 2' => [2, 1.25992, 5, null],
'cube root of 3' => [3, 1.44225, 5], 'cube root of 3' => [3, 1.44225, 5, null],
'cube root of -1' => [-1, 'NAN', 0], 'cube root of -1' => [-1, 'NAN', 0, \InvalidArgumentException::class],
]; ];
} }
@@ -138,10 +138,14 @@ final class CoreLibsConvertMathTest extends TestCase
* @param float|int $number * @param float|int $number
* @param float $expected * @param float $expected
* @param int $round_to * @param int $round_to
* @param ?string $exception
* @return void * @return void
*/ */
public function testCbrt(float|int $number, float|string $expected, int $round_to): void public function testCbrt(float|int $number, float|string $expected, int $round_to, ?string $exception): void
{ {
if ($exception !== null) {
$this->expectException($exception);
}
$this->assertEquals( $this->assertEquals(
$expected, $expected,
round(\CoreLibs\Convert\Math::cbrt($number), $round_to) round(\CoreLibs\Convert\Math::cbrt($number), $round_to)

View File

@@ -59,8 +59,6 @@ final class CoreLibsUrlRequestsCurlTest extends TestCase
continue; continue;
} }
$this->url_basic = $url; $this->url_basic = $url;
// split out the last / part for url set test
curl_close($handle);
// print "Open: $url\n"; // print "Open: $url\n";
break; break;
} }
@@ -969,76 +967,77 @@ final class CoreLibsUrlRequestsCurlTest extends TestCase
"query" => ["foo-get" => "bar"] "query" => ["foo-get" => "bar"]
]); ]);
$this->assertEquals("200", $response["code"], "multi call: get response code not matching"); $this->assertEquals("200", $response["code"], "multi call: get response code not matching");
if (PHP_VERSION_ID >= 80400) { $request_expected = json_decode(
$this->assertEquals( <<<JSON
'{"HEADERS":{"HTTP_HOST":"soba.egplusww.jp",' {
. '"HTTP_USER_AGENT":"CoreLibsUrlRequestCurl\/1","HTTP_FIRST_CALL":"get",' "HEADERS":{
. '"HTTP_ACCEPT":"*\/*"},"REQUEST_TYPE":"GET","PARAMS":{"foo-get":"bar"},"BODY":null}', "HTTP_USER_AGENT":"CoreLibsUrlRequestCurl\/1",
$response['content'], "HTTP_FIRST_CALL":"get","HTTP_ACCEPT":"*\/*",
'multi call: get content not matching' "HTTP_HOST":"soba.egplusww.jp"
); },
} else { "REQUEST_TYPE":"GET",
$this->assertEquals( "PARAMS":{"foo-get":"bar"},"BODY":null
'{"HEADERS":{"HTTP_USER_AGENT":"CoreLibsUrlRequestCurl\/1",' }
. '"HTTP_FIRST_CALL":"get","HTTP_ACCEPT":"*\/*",' JSON,
. '"HTTP_HOST":"soba.egplusww.jp"},' true
. '"REQUEST_TYPE":"GET",' );
. '"PARAMS":{"foo-get":"bar"},"BODY":null}', $this->assertEquals(
$response['content'], $request_expected,
'multi call: get content not matching' json_decode($response['content'], true),
); 'multi call: get content not matching'
} );
// post // post
$response = $curl->post($this->url_basic, [ $response = $curl->post($this->url_basic, [
"headers" => ["second-call" => "post"], "headers" => ["second-call" => "post"],
"body" => ["foo-post" => "baz"] "body" => ["foo-post" => "baz"]
]); ]);
$this->assertEquals("200", $response["code"], "multi call: post response code not matching"); $this->assertEquals("200", $response["code"], "multi call: post response code not matching");
if (PHP_VERSION_ID >= 80400) { $request_expected = json_decode(
$this->assertEquals( <<<JSON
'{"HEADERS":{"HTTP_HOST":"soba.egplusww.jp",' {
. '"HTTP_USER_AGENT":"CoreLibsUrlRequestCurl\/1",' "HEADERS":{
. '"HTTP_SECOND_CALL":"post","HTTP_ACCEPT":"*\/*"},' "HTTP_HOST":"soba.egplusww.jp",
. '"REQUEST_TYPE":"POST","PARAMS":[],"BODY":{"foo-post":"baz"}}', "HTTP_USER_AGENT":"CoreLibsUrlRequestCurl\/1",
$response['content'], "HTTP_SECOND_CALL":"post",
'multi call: post content not matching' "HTTP_ACCEPT":"*\/*"
); },
} else { "REQUEST_TYPE":"POST",
$this->assertEquals( "PARAMS":[],
'{"HEADERS":{"HTTP_USER_AGENT":"CoreLibsUrlRequestCurl\/1",' "BODY":{"foo-post":"baz"}
. '"HTTP_SECOND_CALL":"post","HTTP_ACCEPT":"*\/*",' }
. '"HTTP_HOST":"soba.egplusww.jp"},' JSON,
. '"REQUEST_TYPE":"POST",' true
. '"PARAMS":[],"BODY":{"foo-post":"baz"}}', );
$response['content'], $this->assertEquals(
'multi call: post content not matching' $request_expected,
); json_decode($response['content'], true),
} 'multi call: post content not matching'
);
// delete // delete
$response = $curl->delete($this->url_basic, [ $response = $curl->delete($this->url_basic, [
"headers" => ["third-call" => "delete"], "headers" => ["third-call" => "delete"],
]); ]);
$this->assertEquals("200", $response["code"], "multi call: delete response code not matching"); $this->assertEquals("200", $response["code"], "multi call: delete response code not matching");
if (PHP_VERSION_ID >= 80400) { $request_expected = json_decode(
$this->assertEquals( <<<JSON
'{"HEADERS":{"HTTP_HOST":"soba.egplusww.jp",' {
. '"HTTP_USER_AGENT":"CoreLibsUrlRequestCurl\/1",' "HEADERS":{
. '"HTTP_THIRD_CALL":"delete","HTTP_ACCEPT":"*\/*"},' "HTTP_HOST":"soba.egplusww.jp",
. '"REQUEST_TYPE":"DELETE","PARAMS":[],"BODY":[]}', "HTTP_USER_AGENT":"CoreLibsUrlRequestCurl\/1",
$response['content'], "HTTP_THIRD_CALL":"delete","HTTP_ACCEPT":"*\/*"
'multi call: delete content not matching' },
); "REQUEST_TYPE":"DELETE",
} else { "PARAMS":[],
$this->assertEquals( "BODY":[]
'{"HEADERS":{"HTTP_USER_AGENT":"CoreLibsUrlRequestCurl\/1",' }
. '"HTTP_THIRD_CALL":"delete","HTTP_ACCEPT":"*\/*",' JSON,
. '"HTTP_HOST":"soba.egplusww.jp"},' true
. '"REQUEST_TYPE":"DELETE",' );
. '"PARAMS":[],"BODY":[]}', $this->assertEquals(
$response['content'], $request_expected,
'multi call: delete content not matching' json_decode($response['content'], true),
); 'multi call: delete content not matching'
} );
} }
// MARK: auth header set via config // MARK: auth header set via config

View File

@@ -74,9 +74,21 @@ foreach ($bytes as $byte) {
print '<div style="width: 35%; text-align: right; padding-right: 2px;">'; print '<div style="width: 35%; text-align: right; padding-right: 2px;">';
print "(" . number_format($byte) . "/" . $byte . ") bytes :"; print "(" . number_format($byte) . "/" . $byte . ") bytes :";
$_bytes = Byte::humanReadableByteFormat($byte); $_bytes = Byte::humanReadableByteFormat($byte);
print '</div><div style="width: 10%;">' . $_bytes; print '</div>';
print '</div><div style="width: 10%;">'; print '<div style="width: 10%;">' . $_bytes . '</div>';
print Byte::stringByteFormat($_bytes); print '<div style="width: 40%;">';
try {
print Byte::stringByteFormat($_bytes);
} catch (\LengthException $e) {
print "LengthException 1: " . $e->getMessage();
try {
print "<br>S: " . Byte::stringByteFormat($_bytes, Byte::RETURN_AS_STRING);
} catch (\LengthException $e) {
print "LengthException 2: " . $e->getMessage();
} catch (\RuntimeException $e) {
print "RuntimeException 1: " . $e->getMessage();
}
}
print "</div>"; print "</div>";
// //
print "</div>"; print "</div>";
@@ -87,13 +99,85 @@ foreach ($bytes as $byte) {
print "bytes [si]:"; print "bytes [si]:";
$_bytes = Byte::humanReadableByteFormat($byte, Byte::BYTE_FORMAT_SI); $_bytes = Byte::humanReadableByteFormat($byte, Byte::BYTE_FORMAT_SI);
print '</div><div style="width: 10%;">' . $_bytes; print '</div><div style="width: 10%;">' . $_bytes;
print '</div><div style="width: 10%;">'; print '</div><div style="width: 40%;">';
print Byte::stringByteFormat($_bytes); try {
print Byte::stringByteFormat($_bytes);
} catch (\LengthException $e) {
print "LengthException A: " . $e->getMessage();
try {
print "<br>Ssi: " . Byte::stringByteFormat($_bytes, Byte::RETURN_AS_STRING | Byte::BYTE_FORMAT_SI);
} catch (\LengthException $e) {
print "LengthException B: " . $e->getMessage();
} catch (\RuntimeException $e) {
print "RuntimeException A: " . $e->getMessage();
}
}
print "</div>"; print "</div>";
// //
print "</div>"; print "</div>";
} }
$string_bytes = [
'-117.42 MB',
'242.98 MB',
'254.78 MiB',
'1 EiB',
'8 EB',
'867.36EB',
'1000EB',
'10000EB',
];
print "<b>BYTE STRING TO BYTES TESTS</b><br>";
foreach ($string_bytes as $string) {
print '<div style="display: flex; border-bottom: 1px dashed gray;">';
//
print '<div style="width: 35%; text-align: right; padding-right: 2px;">';
print "string byte ($string) to bytes :";
try {
$_bytes = Byte::stringByteFormat($string);
} catch (\LengthException $e) {
print "<br>LengthException A: " . $e->getMessage();
$_bytes = 0;
}
try {
$_bytes_string = Byte::stringByteFormat($string, Byte::RETURN_AS_STRING);
} catch (\LengthException $e) {
print "<br>LengthException B: " . $e->getMessage();
$_bytes_string = '';
} catch (\RuntimeException $e) {
print "<br>RuntimeException: " . $e->getMessage();
$_bytes_string = '';
}
try {
$_bytes_si = Byte::stringByteFormat($string, Byte::BYTE_FORMAT_SI);
} catch (\LengthException $e) {
print "<br>LengthException A: " . $e->getMessage();
$_bytes_si = 0;
}
try {
$_bytes_string_si = Byte::stringByteFormat($string, Byte::RETURN_AS_STRING | Byte::BYTE_FORMAT_SI);
} catch (\LengthException $e) {
print "<br>LengthException B: " . $e->getMessage();
$_bytes_string_si = '';
} catch (\RuntimeException $e) {
print "<br>RuntimeException: " . $e->getMessage();
$_bytes_string_si = '';
}
print '</div>';
print '<div style="width: 20%;">'
. "F:" . number_format((int)$_bytes)
. '<br>B: ' . $_bytes
. '<br>S: ' . $_bytes_string
. "<br>Fsi:" . number_format((int)$_bytes_si)
. '<br>Bsi: ' . $_bytes_si
. '<br>Ssi: ' . $_bytes_string_si;
print '</div>';
print '<div style="width: 10%;">';
print "B: " . Byte::humanReadableByteFormat($_bytes) . "<br>";
print "Bsi: " . Byte::humanReadableByteFormat($_bytes_si, Byte::BYTE_FORMAT_SI);
print "</div>";
print "</div>";
}
print "</body></html>"; print "</body></html>";
// __END__ // __END__

View File

@@ -114,7 +114,7 @@ class Encoding
(($char != $r_char && (!self::$mb_error_char || (($char != $r_char && (!self::$mb_error_char ||
in_array(self::$mb_error_char, ['none', 'long', 'entity']))) || in_array(self::$mb_error_char, ['none', 'long', 'entity']))) ||
($char != $r_char && $r_char == self::$mb_error_char && self::$mb_error_char)) && ($char != $r_char && $r_char == self::$mb_error_char && self::$mb_error_char)) &&
ord($char) != 194 ord($char[0]) != 194
) { ) {
$failed[] = $char; $failed[] = $char;
} }

View File

@@ -14,6 +14,7 @@ class Byte
public const BYTE_FORMAT_NOSPACE = 1; public const BYTE_FORMAT_NOSPACE = 1;
public const BYTE_FORMAT_ADJUST = 2; public const BYTE_FORMAT_ADJUST = 2;
public const BYTE_FORMAT_SI = 4; public const BYTE_FORMAT_SI = 4;
public const RETURN_AS_STRING = 8;
/** /**
* This function replaces the old byteStringFormat * This function replaces the old byteStringFormat
@@ -119,7 +120,9 @@ class Byte
* @param int $flags bitwise flag with use space turned on * @param int $flags bitwise flag with use space turned on
* BYTE_FORMAT_SI: use 1000 instead of 1024 * BYTE_FORMAT_SI: use 1000 instead of 1024
* @return string|int|float converted value or original value * @return string|int|float converted value or original value
* @throws \InvalidArgumentException 1: no valid flag set * @throws \InvalidArgumentException no valid flag set
* @throws \LengthException number too large to convert to int
* @throws \RuntimeException BCMath extension not loaded if flag is set to string
*/ */
public static function stringByteFormat(string|int|float $number, int $flags = 0): string|int|float public static function stringByteFormat(string|int|float $number, int $flags = 0): string|int|float
{ {
@@ -129,7 +132,12 @@ class Byte
} else { } else {
$si = false; $si = false;
} }
if ($flags != 0 && $flags != 4) { if ($flags & self::RETURN_AS_STRING) {
$return_as_string = true;
} else {
$return_as_string = false;
}
if ($flags != 0 && $flags != 4 && $flags != 8 && $flags != 12) {
throw new \InvalidArgumentException("Invalid flags parameter: $flags", 1); throw new \InvalidArgumentException("Invalid flags parameter: $flags", 1);
} }
// matches in regex // matches in regex
@@ -142,6 +150,10 @@ class Byte
strtolower((string)$number), strtolower((string)$number),
$matches $matches
); );
$number_negative = false;
if (!empty($matches[1])) {
$number_negative = true;
}
if (isset($matches[2]) && isset($matches[3])) { if (isset($matches[2]) && isset($matches[3])) {
// remove all non valid characters from the number // remove all non valid characters from the number
$number = preg_replace('/[^0-9\.]/', '', $matches[2]); $number = preg_replace('/[^0-9\.]/', '', $matches[2]);
@@ -152,12 +164,48 @@ class Byte
if ($unit) { if ($unit) {
$number = $number * pow($si ? 1000 : 1024, stripos($valid_units_, $unit[0]) ?: 0); $number = $number * pow($si ? 1000 : 1024, stripos($valid_units_, $unit[0]) ?: 0);
} }
// if the number is too large, we cannot convert to int directly
if ($number <= PHP_INT_MIN || $number >= PHP_INT_MAX) {
// if we do not want to convert to string
if (!$return_as_string) {
throw new \LengthException(
'Number too large be converted to int: ' . (string)$number
);
}
// for string, check if bcmath is loaded, if not this will not work
if (!extension_loaded('bcmath')) {
throw new \RuntimeException(
'Number too large be converted to int and BCMath extension not loaded: ' . (string)$number
);
}
}
// string return
if ($return_as_string) {
// return as string to avoid overflow
// $number = (string)round($number);
$number = bcmul(number_format(
$number,
12,
'.',
''
), "1");
if ($number_negative) {
$number = '-' . $number;
}
return $number;
}
// convert to INT to avoid +E output // convert to INT to avoid +E output
$number = (int)round($number); $number = (int)round($number);
// if negative input, keep nnegative // if negative input, keep nnegative
if (!empty($matches[1])) { if ($number_negative) {
$number *= -1; $number *= -1;
} }
// check if number is negative but should be, this is Lenght overflow
if (!$number_negative && $number < 0) {
throw new \LengthException(
'Number too large be converted to int: ' . (string)$number
);
}
} }
// if not matching return as is // if not matching return as is
return $number; return $number;

View File

@@ -62,10 +62,15 @@ class Math
* *
* @param float $number Number to cubic root * @param float $number Number to cubic root
* @return float Calculated value * @return float Calculated value
* @throws \InvalidArgumentException if $number is negative
*/ */
public static function cbrt(float|int $number): float public static function cbrt(float|int $number): float
{ {
return pow((float)$number, 1.0 / 3); $value = pow((float)$number, 1.0 / 3);
if (is_nan($value)) {
throw new \InvalidArgumentException('cube root from this number is not supported: ' . $number);
}
return $value;
} }
/** /**

View File

@@ -291,7 +291,7 @@ class ErrorMessage
*/ */
public function getLastErrorMsg(): array public function getLastErrorMsg(): array
{ {
return $this->error_str[array_key_last($this->error_str)] ?? [ return $this->error_str[array_key_last($this->error_str) ?? -1] ?? [
'level' => '', 'level' => '',
'str' => '', 'str' => '',
'id' => '', 'id' => '',

View File

@@ -365,9 +365,6 @@ class Image
imagepng($thumb, $thumbnail_write_path . $thumbnail); imagepng($thumb, $thumbnail_write_path . $thumbnail);
break; break;
} }
// free up resources (in case we are called in a loop)
imagedestroy($source);
imagedestroy($thumb);
} else { } else {
throw new \RuntimeException( throw new \RuntimeException(
'Invalid source image file. Only JPEG/PNG are allowed: ' . $filename, 'Invalid source image file. Only JPEG/PNG are allowed: ' . $filename,
@@ -543,8 +540,6 @@ class Image
imagepng($img, $filename); imagepng($img, $filename);
break; break;
} }
// clean up image if we have an image
imagedestroy($img);
} }
} }

View File

@@ -614,8 +614,6 @@ class Curl implements Interface\RequestsInterface
// print "CURLINFO_HEADER_OUT: <pre>" . curl_getinfo($handle, CURLINFO_HEADER_OUT) . "</pre>"; // print "CURLINFO_HEADER_OUT: <pre>" . curl_getinfo($handle, CURLINFO_HEADER_OUT) . "</pre>";
// get response code and bail on not authorized // get response code and bail on not authorized
$http_response = $this->handleCurlResponse($handle, $http_result, $options['http_errors']); $http_response = $this->handleCurlResponse($handle, $http_result, $options['http_errors']);
// close handler
$this->handleCurlClose($handle);
// return response and result // return response and result
return [ return [
'code' => (string)$http_response, 'code' => (string)$http_response,
@@ -838,17 +836,6 @@ class Curl implements Interface\RequestsInterface
); );
} }
/**
* close the current curl handle
*
* @param \CurlHandle $handle
* @return void
*/
private function handleCurlClose(\CurlHandle $handle): void
{
curl_close($handle);
}
// ********************************************************************* // *********************************************************************
// MARK: PUBLIC METHODS // MARK: PUBLIC METHODS
// ********************************************************************* // *********************************************************************