diff --git a/src/EmailHelper.php b/src/EmailHelper.php index 9d80587..45d1a8c 100644 --- a/src/EmailHelper.php +++ b/src/EmailHelper.php @@ -24,23 +24,23 @@ class EmailHelper * * Проверка валидности email адреса. * - * @param string $sString + * @param string|null $string * * @return bool */ - public static function isEmailValid(?string $sString = ''): bool + public static function isEmailValid(?string $string = ''): bool { - if ('' === $sString || \is_null($sString)) { + if (null === $string || '' === $string) { return false; } // According to the FQDN add a dot to the end of the string and check if the domain has an mx record - if (\function_exists('filter_var') && \filter_var($sString, FILTER_VALIDATE_EMAIL) && \checkdnsrr(\ltrim(\stristr($sString, '@'), '@') . '.', 'MX')) { + if (\function_exists('filter_var') && \filter_var($string, FILTER_VALIDATE_EMAIL) && \checkdnsrr(\ltrim(\stristr($string, '@'), '@') . '.', 'MX')) { return true; } // Сheck using a regular expression if the filter_var() function does not exist - if (\preg_match('/^[a-zA-Z0-9.!#$%&\'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/sD', $sString) && \preg_match('/@.+\./', $sString) && \checkdnsrr(\ltrim(\stristr($sString, '@'), '@') . '.', 'MX')) { + if (\preg_match('/^[a-zA-Z0-9.!#$%&\'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/sD', $string) && \preg_match('/@.+\./', $string) && \checkdnsrr(\ltrim(\stristr($string, '@'), '@') . '.', 'MX')) { return true; } diff --git a/src/FileHelper.php b/src/FileHelper.php index 644fa1b..546fb42 100644 --- a/src/FileHelper.php +++ b/src/FileHelper.php @@ -22,14 +22,14 @@ class FileHelper * Gets name of the filename only (without dot and extension). * If the file name contains several dots (file.name.ext) - return all parts before the last dot. * - * @param string $sFilename + * @param string|null $sFilename * @param string $default * * @return string */ public static function getFileNameOnly(?string $sFilename = '', string $default = ''): string { - if ('' === $sFilename || \is_null($sFilename)) { + if (null === $sFilename || '' === $sFilename) { return $default; } @@ -41,14 +41,14 @@ public static function getFileNameOnly(?string $sFilename = '', string $default /** * Gets filename extension only (without dot and name) * - * @param string $sFilename + * @param string|null $sFilename * @param string $default * * @return string */ public static function getFileExtOnly(?string $sFilename = '', string $default = ''): string { - if ('' === $sFilename || \is_null($sFilename)) { + if (null === $sFilename || '' === $sFilename) { return $default; } @@ -56,4 +56,32 @@ public static function getFileExtOnly(?string $sFilename = '', string $default = return $sParsed ? $sParsed : $default; } + + /** + * Converts file size in bytes into human readable file size. + * + * Конвертация размера файла в удобный для чтения формат. + * + * @param mixed|null $bytes + * @param int $decimals + * + * @return string human readable file size (2.87 MB) + * + * @author evgenij at kostanay dot kz + * + * @edit Leonid Sheikman + */ + public static function getHumanFileSize(?mixed $bytes, int $decimals = 2): string + { + if (null === $bytes) { + return '0'; + } + + $factor = \floor((\strlen((string) $bytes) - 1) / 3); + if ($factor > 0) { + $sz = 'KMGT'; + } + + return \sprintf("%.{$decimals}f", (float) $bytes / \pow(1024, $factor)) . ' ' . @$sz[$factor - 1] . 'B'; + } } diff --git a/src/PhoneHelper.php b/src/PhoneHelper.php index 5541a4f..b598073 100644 --- a/src/PhoneHelper.php +++ b/src/PhoneHelper.php @@ -57,7 +57,7 @@ public static function formatRussianMobilePhoneNumber(?string $phoneNumber): ?st * Функция принимает телефонный номер в произвольном формате и возвращает телефонный * номер в формате +7xxxxxxxxxx или false, если входной номер телефона не проходит проверку валидности. * - * @param string $sString + * @param string|null $string * * @return bool|string * @@ -65,25 +65,25 @@ public static function formatRussianMobilePhoneNumber(?string $phoneNumber): ?st * * @edit Leonid Sheikman (leonid74) */ - public static function getValidRusPhone(?string $sString = '') + public static function getValidRusPhone(?string $string = '') { - if ('' === $sString || \is_null($sString)) { + if (null === $string || '' === $string) { return false; } - $sString = \preg_replace('#[^0-9+]+#uis', '', \trim((string) $sString)); + $string = \preg_replace('#[^0-9+]+#uis', '', \trim((string) $string)); - if (!\preg_match('#^(?:\\+?7|8|)(.*?)$#uis', $sString, $aTmp)) { + if (!\preg_match('#^(?:\\+?7|8|)(.*?)$#uis', $string, $aTmp)) { return false; } - $sString = '+7' . \preg_replace('#[^0-9]+#uis', '', $aTmp[1]); + $string = '+7' . \preg_replace('#[^0-9]+#uis', '', $aTmp[1]); - if (!\preg_match('#^\\+7[0-9]{10}$#uis', $sString, $aTmp)) { + if (!\preg_match('#^\\+7[0-9]{10}$#uis', $string, $aTmp)) { return false; } - return $sString; + return $string; } /** @@ -91,20 +91,20 @@ public static function getValidRusPhone(?string $sString = '') * * Проверка номера телефона на существование через sms.ru * - * @param string $sString + * @param string $string * @param string $apiToken * @param string $apiSmsId API Key to SMS.RU * * @return stdClass() */ - public static function isPhoneExist(string $sString, string $apiToken) + public static function isPhoneExist(string $string, string $apiToken) { $oResult = new \stdClass(); - $oResult->phone = $sString; + $oResult->phone = $string; $oResult->phone_exists = 'unknown'; $oResult->is_error = false; - if (empty($sString)) { + if (empty($string)) { $oResult->phone_exists = false; return $oResult; @@ -115,7 +115,7 @@ public static function isPhoneExist(string $sString, string $apiToken) $i = 1; do { $json = \json_decode( - \file_get_contents("https://sms.ru/sms/cost?api_id={$apiToken}&to={$sString}&msg=" . \urlencode('Test' . \microtime(true)) . '&json=1') + \file_get_contents("https://sms.ru/sms/cost?api_id={$apiToken}&to={$string}&msg=" . \urlencode('Test' . \microtime(true)) . '&json=1') ); if ((\json_last_error() === JSON_ERROR_NONE) && $json) { diff --git a/src/StringHelper.php b/src/StringHelper.php index b40ae34..ffe9472 100644 --- a/src/StringHelper.php +++ b/src/StringHelper.php @@ -114,7 +114,7 @@ public static function mb_substr_replace(string $string, string $replacement, in // @codingStandardsIgnoreLine public static function mb_strlen(?string $string = ''): int { - if ('' === $string || \is_null($string)) { + if (null === $string || '' === $string) { return 0; } @@ -124,10 +124,10 @@ public static function mb_strlen(?string $string = ''): int } // @codingStandardsIgnoreLine - public static function mb_strtolower(?string $string = '', ?string $sDefault = ''): string + public static function mb_strtolower(?string $string = '', ?string $default = ''): string { - if ('' === $string || \is_null($string)) { - return $sDefault; + if (null === $string || '' === $string) { + return $default; } return \function_exists('mb_strtolower') @@ -136,10 +136,10 @@ public static function mb_strtolower(?string $string = '', ?string $sDefault = ' } // @codingStandardsIgnoreLine - public static function mb_strtoupper(?string $string = '', ?string $sDefault = ''): string + public static function mb_strtoupper(?string $string = '', ?string $default = ''): string { - if ('' === $string || \is_null($string)) { - return $sDefault; + if (null === $string || '' === $string) { + return $default; } return \function_exists('mb_strtoupper') @@ -148,20 +148,20 @@ public static function mb_strtoupper(?string $string = '', ?string $sDefault = ' } // @codingStandardsIgnoreLine - public static function mb_ucfirst(?string $string = '', ?string $sDefault = ''): string + public static function mb_ucfirst(?string $string = '', ?string $default = ''): string { - if ('' === $string || \is_null($string)) { - return $sDefault; + if (null === $string || '' === $string) { + return $default; } return self::mb_strtoupper(self::mb_substr($string, 0, 1)) . self::mb_substr($string, 1); } // @codingStandardsIgnoreLine - public static function mb_convert_case(?string $string = '', ?string $sDefault = ''): string + public static function mb_convert_case(?string $string = '', ?string $default = ''): string { - if ('' === $string || \is_null($string)) { - return $sDefault; + if (null === $string || '' === $string) { + return $default; } return \function_exists('mb_convert_case') @@ -170,50 +170,50 @@ public static function mb_convert_case(?string $string = '', ?string $sDefault = } // @codingStandardsIgnoreLine - public static function htmlspecialchars(?string $string = '', ?string $sDefault = ''): string + public static function htmlspecialchars(?string $string = '', ?string $default = ''): string { - if ('' === $string || \is_null($string)) { - return $sDefault; + if (null === $string || '' === $string) { + return $default; } return \htmlspecialchars($string, ENT_COMPAT | ENT_SUBSTITUTE | ENT_HTML5, static::$defaultEncoding); } // @codingStandardsIgnoreLine - public static function htmlspecialchars_decode(?string $string = '', ?string $sDefault = ''): string + public static function htmlspecialchars_decode(?string $string = '', ?string $default = ''): string { - if ('' === $string || \is_null($string)) { - return $sDefault; + if (null === $string || '' === $string) { + return $default; } return \htmlspecialchars_decode($string, ENT_COMPAT | ENT_HTML5); } // @codingStandardsIgnoreLine - public static function htmlentities(?string $string = '', ?string $sDefault = ''): string + public static function htmlentities(?string $string = '', ?string $default = ''): string { - if ('' === $string || \is_null($string)) { - return $sDefault; + if (null === $string || '' === $string) { + return $default; } return \htmlentities($string, ENT_COMPAT | ENT_SUBSTITUTE | ENT_HTML5, static::$defaultEncoding); } // @codingStandardsIgnoreLine - public static function html_entity_decode(?string $string = '', ?string $sDefault = ''): string + public static function html_entity_decode(?string $string = '', ?string $default = ''): string { - if ('' === $string || \is_null($string)) { - return $sDefault; + if (null === $string || '' === $string) { + return $default; } return \html_entity_decode($string, ENT_COMPAT | ENT_HTML5, static::$defaultEncoding); } // @codingStandardsIgnoreLine - public static function utf8_urldecode(?string $string = '', ?string $sDefault = ''): string + public static function utf8_urldecode(?string $string = '', ?string $default = ''): string { - if ('' === $string || \is_null($string)) { - return $sDefault; + if (null === $string || '' === $string) { + return $default; } $string = \preg_replace('/%u([0-9a-f]{3,4})/i', '&#x\\1;', \urldecode($string)); @@ -226,18 +226,18 @@ public static function utf8_urldecode(?string $string = '', ?string $sDefault = * * Добавление BOM в начало строки * - * @param string $sString - * @param string $sDefault + * @param string $string + * @param string $default * * @return string */ - public static function addBOM(?string $sString = '', ?string $sDefault = ''): string + public static function addBOM(?string $string = '', ?string $default = ''): string { - if ('' === $sString || \is_null($sString)) { - return $sDefault; + if (null === $string || '' === $string) { + return $default; } - return \chr(0xEF) . \chr(0xBB) . \chr(0xBF) . $sString; + return \chr(0xEF) . \chr(0xBB) . \chr(0xBF) . $string; } /** @@ -245,18 +245,18 @@ public static function addBOM(?string $sString = '', ?string $sDefault = ''): st * * Удаление BOM из начала строки * - * @param string $sString - * @param string $sDefault + * @param string $string + * @param string $default * * @return string */ - public static function removeBOM(?string $sString = '', ?string $sDefault = ''): string + public static function removeBOM(?string $string = '', ?string $default = ''): string { - if ('' === $sString || \is_null($sString)) { - return $sDefault; + if (null === $string || '' === $string) { + return $default; } - return 0 === \strncasecmp(\pack('CCC', 0xEF, 0xBB, 0xBF), $sString, 3) ? \mb_substr($sString, 3) : $sString; + return 0 === \strncasecmp(\pack('CCC', 0xEF, 0xBB, 0xBF), $string, 3) ? \mb_substr($string, 3) : $string; } /** @@ -264,18 +264,18 @@ public static function removeBOM(?string $sString = '', ?string $sDefault = ''): * * Замена
на \n. * - * @param string $sString - * @param string $sDefault + * @param string $string + * @param string $default * * @return string */ - public static function br2nl(?string $sString = '', ?string $sDefault = ''): string + public static function br2nl(?string $string = '', ?string $default = ''): string { - if ('' === $sString || \is_null($sString)) { - return $sDefault; + if (null === $string || '' === $string) { + return $default; } - return \preg_replace('/\/i', "\n", $sString); + return \preg_replace('/\/i', "\n", $string); } /** @@ -286,24 +286,24 @@ public static function br2nl(?string $sString = '', ?string $sDefault = ''): str * StringHelper::truncateString('Lorem ipsum inum', 10); // returns 'Lorem i...' * StringHelper::truncateString('Lorem ipsum inum', 15, '>>>'); // returns 'Lorem ipsum >>>' * - * @param string $sString + * @param string $string * @param int $iLength (defaults to 100) * @param string $sSuffix (optional, defaults to '...') - * @param string $sDefault + * @param string $default * * @return string */ - public static function truncateString(?string $sString = '', ?int $iLength = 100, ?string $sSuffix = '...', ?string $sDefault = ''): string + public static function truncateString(?string $string = '', ?int $iLength = 100, ?string $sSuffix = '...', ?string $default = ''): string { - if ('' === $sString || \is_null($sString)) { - return $sDefault; + if (null === $string || '' === $string) { + return $default; } - if ($iLength <= 0 || \mb_strlen($sString) <= $iLength) { - return $sString; + if ($iLength <= 0 || \mb_strlen($string) <= $iLength) { + return $string; } - return \mb_substr($sString, 0, $iLength - \mb_strlen($sSuffix)) . $sSuffix; + return \mb_substr($string, 0, $iLength - \mb_strlen($sSuffix)) . $sSuffix; } /** @@ -385,24 +385,24 @@ public static function hidingData($data = null, array $aDataToHide = []): string * * Проверка, закодирована ли строка в формате Base64 * - * @param ?string $sString + * @param ?string $string * @param array $enc * @param string $data * * @return bool */ - public static function isBase64Encoded(?string $sString = '', ?array $enc = ['UTF-8', 'ASCII']): bool + public static function isBase64Encoded(?string $string = '', ?array $enc = ['UTF-8', 'ASCII']): bool { - if ('' === $sString || \is_null($sString)) { + if (null === $string || '' === $string) { return false; } try { - if (!\preg_match('/^[a-zA-Z0-9\/\r\n+]*={0,2}$/', $sString)) { + if (!\preg_match('/^[a-zA-Z0-9\/\r\n+]*={0,2}$/', $string)) { return false; } - $sDecoded = \base64_decode($sString, true); + $sDecoded = \base64_decode($string, true); if (false === $sDecoded) { return false; } @@ -422,18 +422,18 @@ public static function isBase64Encoded(?string $sString = '', ?array $enc = ['UT * * Возвращает транслитерированную строку (исходно содержащую символы á é ò и т.п.), содержащую только латинские символы * - * @param string $sString - * @param string $sDefault + * @param string $string + * @param string $default * * @return string */ - public static function toLatinString(?string $sString = '', ?string $sDefault = ''): string + public static function toLatinString(?string $string = '', ?string $default = ''): string { - if ('' === $sString || \is_null($sString)) { - return $sDefault; + if (null === $string || '' === $string) { + return $default; } - return \transliterator_transliterate('Any-Latin; Latin-ASCII; [\u0180-\u7fff] remove', $sString); + return \transliterator_transliterate('Any-Latin; Latin-ASCII; [\u0180-\u7fff] remove', $string); } /** @@ -447,22 +447,22 @@ public static function toLatinString(?string $sString = '', ?string $sDefault = * - двойные пробелы заменяются на один * - удаляются пробелы в начале и конце строки * - * @param string $sString - * @param string $sDefault + * @param string $string + * @param string $default * * @return string */ - public static function minClean(?string $sString = '', ?string $sDefault = ''): string + public static function minClean(?string $string = '', ?string $default = ''): string { - if ('' === $sString || \is_null($sString)) { - return $sDefault; + if (null === $string || '' === $string) { + return $default; } - $sString = \str_ireplace(["\0", '\\a', '\\b', "\v", "\e", "\f", "\t", "\r", "\n"], ' ', $sString); - $sString = \preg_replace('/[\s]{2,}/', ' ', $sString); - $sString = \trim($sString); + $string = \str_ireplace(["\0", '\\a', '\\b', "\v", "\e", "\f", "\t", "\r", "\n"], ' ', $string); + $string = \preg_replace('/[\s]{2,}/', ' ', $string); + $string = \trim($string); - return (0 == \mb_strlen($sString, static::$defaultEncoding)) ? $sDefault : $sString; + return (0 == \mb_strlen($string, static::$defaultEncoding)) ? $default : $string; } /** @@ -600,30 +600,30 @@ public static function replaceStringInFile(string $filename, string $searchStrin * the string is trimmed up to the previous word. If no spaces are found within * the limit, or if the first word exceeds the limit, an empty string is returned. * - * @param string|null $sString the input string to be trimmed + * @param string|null $string the input string to be trimmed * @param int $maxLength the maximum allowed length of the output string - * @param string $sDefault default value + * @param string $default default value * * @return string the trimmed string with preserved last word integrity up to maxLength */ - public static function trimStringToLastWord(?string $sString = '', int $maxLength = 0, string $sDefault = ''): string + public static function trimStringToLastWord(?string $string = '', int $maxLength = 0, string $default = ''): string { - if ('' === $sString || null === $sString || 0 == $maxLength) { - return $sDefault; + if (null === $string || '' === $string || 0 == $maxLength) { + return $default; } - $sString = \trim($sString); + $string = \trim($string); // Return the original string if it is within maxLength. - if (static::mb_strlen($sString) <= $maxLength) { - return $sString; + if (static::mb_strlen($string) <= $maxLength) { + return $string; } // Trim the string to maxLength first to see if we're cutting through a word. - $trimmedString = static::mb_substr($sString, 0, $maxLength); + $trimmedString = static::mb_substr($string, 0, $maxLength); // Check if we are on a space or just passed one; if so, we can return early. - if ($sString[$maxLength] == ' ' || $sString[$maxLength - 1] == ' ') { + if ($string[$maxLength] == ' ' || $string[$maxLength - 1] == ' ') { return \rtrim($trimmedString); } @@ -632,13 +632,43 @@ public static function trimStringToLastWord(?string $sString = '', int $maxLengt // If there's no space at all, return an empty string as we cannot preserve any word. if ($lastSpacePosition === false) { - return $sDefault; + return $default; } // Return substring up to the last found space position. return static::mb_substr($trimmedString, 0, $lastSpacePosition); } + /** + * Split string with full name (LFS) into 3 parts, remove multiple spaces. + * + * Разбиваем строку с ФИО на 3 части, удаляем множественные пробелы. + * + * @param string|null $string string with full name + * + * @return array + * + * @author Leonid Sheikman + */ + public function splitFullname(?string $string = ''): array + { + if (null === $string || '' === $string) { + return []; + } + + $dataRaw = \explode(' ', \trim(\preg_replace('/[\s]{2,}/', ' ', $string))); + $data = [ + 'lastname' => $dataRaw[0] ?? '', + 'firstname' => $dataRaw[1] ?? '', + 'secondname' => $dataRaw[2] ?? '', + ]; + $data['fullname_lfs'] = $data['lastname'] . ($data['firstname'] ? ' ' . $data['firstname'] : '') . ($data['secondname'] ? ' ' . $data['secondname'] : ''); + $data['fullname_lf'] = $data['lastname'] . ($data['firstname'] ? ' ' . $data['firstname'] : ''); + $data['fullname_fl'] = $data['firstname'] . ($data['lastname'] ? ' ' . $data['lastname'] : ''); + + return $data; + } + /** * Escapes HTML special characters in a string by replacing predefined entities (for Telegram purposes). * diff --git a/src/UrlHelper.php b/src/UrlHelper.php index 93febcb..1b9c3f9 100644 --- a/src/UrlHelper.php +++ b/src/UrlHelper.php @@ -24,13 +24,13 @@ class UrlHelper * UrlHelper::addTrailingSlash('https://aaa.bbb.ccc'); // returns 'https://aaa.bbb.ccc/' * UrlHelper::addTrailingSlash('https://aaa.bbb.ccc/'); // returns 'https://aaa.bbb.ccc/' * - * @param string $sUrl + * @param string|null $sUrl * * @return string */ public static function addTrailingSlash(?string $sUrl = ''): string { - if ('' === $sUrl || \is_null($sUrl)) { + if (null === $sUrl || '' === $sUrl) { return '/'; } @@ -42,13 +42,13 @@ public static function addTrailingSlash(?string $sUrl = ''): string * * UrlHelper::removeTrailingSlash('https://aaa.bbb.ccc/'); // returns 'https://aaa.bbb.ccc' * - * @param string $sUrl + * @param string|null $sUrl * * @return string */ public static function removeTrailingSlash(?string $sUrl = ''): string { - if ('' === $sUrl || \is_null($sUrl)) { + if (null === $sUrl || '' === $sUrl) { return ''; } @@ -61,13 +61,13 @@ public static function removeTrailingSlash(?string $sUrl = ''): string * UrlHelper::prependSlash('aaa/bbb/ccc'); // returns '/aaa/bbb/ccc' * UrlHelper::prependSlash('/aaa/bbb/ccc'); // returns '/aaa/bbb/ccc' * - * @param string $sUrl + * @param string|null $sUrl * * @return string */ public static function prependSlash(?string $sUrl = ''): string { - if ('' === $sUrl || \is_null($sUrl)) { + if (null === $sUrl || '' === $sUrl) { return '/'; } @@ -79,13 +79,13 @@ public static function prependSlash(?string $sUrl = ''): string * * UrlHelper::getHostOnly('https://aaa.bbb.ccc:9090/path?arg=value#anchor'); // returns 'aaa.bbb.ccc' * - * @param string $sUrl + * @param string|null $sUrl * * @return string */ public static function getHostOnly(?string $sUrl = ''): string { - if ('' === $sUrl || \is_null($sUrl)) { + if (null === $sUrl || '' === $sUrl) { return ''; } @@ -99,13 +99,13 @@ public static function getHostOnly(?string $sUrl = ''): string * * UrlHelper::getHostWithScheme('https://aaa.bbb.ccc:9090/path?arg=value#anchor'); // returns 'https://aaa.bbb.ccc' * - * @param string $sUrl + * @param string|null $sUrl * * @return string */ public static function getHostWithScheme(?string $sUrl = ''): string { - if ('' === $sUrl || \is_null($sUrl)) { + if (null === $sUrl || '' === $sUrl) { return ''; } @@ -119,13 +119,13 @@ public static function getHostWithScheme(?string $sUrl = ''): string * * UrlHelper::getHostWithSchemeAndPath('https://aaa.bbb.ccc:9090/path?arg=value#anchor'); // returns 'https://aaa.bbb.ccc/path' * - * @param string $sUrl + * @param string|null $sUrl * * @return string */ public static function getHostWithSchemeAndPath(?string $sUrl = ''): string { - if ('' === $sUrl || \is_null($sUrl)) { + if (null === $sUrl || '' === $sUrl) { return ''; } @@ -133,4 +133,36 @@ public static function getHostWithSchemeAndPath(?string $sUrl = ''): string return $aParsedUrl['scheme'] . '://' . ($aParsedUrl['host'] ? $aParsedUrl['host'] . $aParsedUrl['path'] : \array_shift(\explode('/', $aParsedUrl['path'], 2))); } + + /** + * base64 variant encoding with replace characters (=+/) in result string + * + * @param string|null $sUrl string to encode + * + * @return string encoded base64url string + */ + public static function base64EncodeUrl(?string $sUrl = ''): string + { + if (null === $sUrl || '' === $sUrl) { + return ''; + } + + return \str_replace(['+', '/', '='], ['-', '_', ''], \base64_encode($sUrl)); + } + + /** + * base64 variant decoding with replace characters (-_) in result string + * + * @param string|null $sUrl string to decode + * + * @return string decoded base64url string + */ + public static function base64DecodeUrl(?string $sUrl = ''): string + { + if (null === $sUrl || '' === $sUrl) { + return ''; + } + + return \base64_decode(\str_replace(['-', '_'], ['+', '/'], $sUrl)); + } }