247 lines
3.8 KiB
PHP
247 lines
3.8 KiB
PHP
<?php
|
||
|
||
namespace core;
|
||
|
||
/**
|
||
* Requires utils.php to be loaded before
|
||
*/
|
||
|
||
/**
|
||
* Autoloading function
|
||
*
|
||
* @param \string $class_name Name of the class (with namespace)
|
||
*
|
||
* @throws \Exception
|
||
*/
|
||
function load_class(string $class_name) : void
|
||
{
|
||
$path = 'class' . \DIRECTORY_SEPARATOR . # WARNING: hard-coded path
|
||
\str_replace('\\', \DIRECTORY_SEPARATOR, $class_name) .
|
||
'.class.php';
|
||
|
||
if (\is_file($path))
|
||
{
|
||
require_once($path);
|
||
}
|
||
else
|
||
{
|
||
throw new \Exception(\core\substitute(
|
||
'the class {class} cannot be found in the path {path}',
|
||
array('class' => $class_name, 'path' => $path),
|
||
));
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Check if the given string is a class name
|
||
*
|
||
* Use definition here: https://www.php.net/manual/en/language.oop5.basic.php
|
||
* I don't use regex because they don't seems to work well
|
||
*
|
||
* @param \string $value
|
||
*
|
||
* @return \bool
|
||
*/
|
||
function is_class_name(string $value) : bool
|
||
{
|
||
$parts = \explode('\\', $value);
|
||
foreach ($parts as $part)
|
||
{
|
||
if (\in_array(
|
||
$part,
|
||
array(
|
||
'__halt_compiler', # defined here: https://www.php.net/manual/en/reserved.keywords.php
|
||
'abstract',
|
||
'and',
|
||
'array',
|
||
'as',
|
||
'break',
|
||
'callable',
|
||
'case',
|
||
'catch',
|
||
'class',
|
||
'clone',
|
||
'const',
|
||
'continue',
|
||
'declare',
|
||
'default',
|
||
'die',
|
||
'do',
|
||
'echo',
|
||
'else',
|
||
'elseif',
|
||
'empty',
|
||
'enddeclare',
|
||
'endfor',
|
||
'endforeach',
|
||
'endif',
|
||
'endswitch',
|
||
'endwhile',
|
||
'eval',
|
||
'exit',
|
||
'extends',
|
||
'final',
|
||
'finally',
|
||
'fn',
|
||
'for',
|
||
'foreach',
|
||
'function',
|
||
'global',
|
||
'goto',
|
||
'if',
|
||
'implements',
|
||
'include',
|
||
'include_once',
|
||
'instanceof',
|
||
'insteadof',
|
||
'interface',
|
||
'isset',
|
||
'list',
|
||
'match',
|
||
'namespace',
|
||
'new',
|
||
'or',
|
||
'print',
|
||
'private',
|
||
'protected',
|
||
'public',
|
||
'readonly',
|
||
'require',
|
||
'require_once',
|
||
'return',
|
||
'static',
|
||
'switch',
|
||
'throw',
|
||
'trait',
|
||
'try',
|
||
'unset',
|
||
'use',
|
||
'var',
|
||
'while',
|
||
'xor',
|
||
'yield',
|
||
'yield from', # contains a space so will not work even if not here, but still here because why not
|
||
'__CLASS__',
|
||
'__DIR__',
|
||
'__FILE__',
|
||
'__FUNCTION__',
|
||
'__LINE__',
|
||
'__METHOD__',
|
||
'__NAMESPACE__',
|
||
'__TRAIT__',
|
||
'Directory', # defined here: https://www.php.net/manual/en/reserved.classes.php
|
||
'stdClass',
|
||
'__PHP_incomplete_Class',
|
||
'Exception',
|
||
'ErrorException',
|
||
'php_user_filter',
|
||
'Closure',
|
||
'Generator',
|
||
'ArithmeticError',
|
||
'AssertionError',
|
||
'DivisionByZeroError',
|
||
'Error',
|
||
'Throwable',
|
||
'ParseError',
|
||
'TypeError',
|
||
'self',
|
||
'parent',
|
||
'int', # defined here: https://www.php.net/manual/en/reserved.other-reserved-words.php
|
||
'float',
|
||
'bool',
|
||
'string',
|
||
'true',
|
||
'false',
|
||
'null',
|
||
'void',
|
||
'iterable',
|
||
'object',
|
||
'mixed',
|
||
'never',
|
||
),
|
||
))
|
||
{
|
||
return False;
|
||
}
|
||
if (\in_array($part[0], array(
|
||
'1', '2', '3', '4', '5', '6', '7', '8', '9',
|
||
)))
|
||
{
|
||
return False;
|
||
}
|
||
foreach (\str_split($part) as $char)
|
||
{
|
||
if (\in_array(
|
||
$char,
|
||
array(
|
||
'$', # misc
|
||
'#',
|
||
'@',
|
||
',',
|
||
'.',
|
||
':',
|
||
';',
|
||
'`', # string
|
||
'\'',
|
||
'"',
|
||
'&', # operator
|
||
'|',
|
||
'+',
|
||
'-',
|
||
'*',
|
||
'.',
|
||
'/',
|
||
'%',
|
||
'^',
|
||
'=',
|
||
'~',
|
||
'?',
|
||
'!',
|
||
'{', # delimiter
|
||
'(',
|
||
'[',
|
||
']',
|
||
')',
|
||
'}',
|
||
' ', # whitespace
|
||
' |