سؤال

Is there some function for checking whether a word is reserved in PHP or I can use it myself? I can check it manually: just use it and see the error or warning, but I need to automate this check. Is there any way to do this?

هل كانت مفيدة؟

المحلول 2

Array borrowed from http://www.php.net/manual/en/reserved.keywords.php

You could easily modify it to work for the predefined constants array.

This works.

<?php
$keywords = array('__halt_compiler', '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', 'for', 'foreach', 'function', 'global', 'goto', 'if', 'implements', 'include', 'include_once', 'instanceof', 'insteadof', 'interface', 'isset', 'list', 'namespace', 'new', 'or', 'print', 'private', 'protected', 'public', 'require', 'require_once', 'return', 'static', 'switch', 'throw', 'trait', 'try', 'unset', 'use', 'var', 'while', 'xor');

$predefined_constants = array('__CLASS__', '__DIR__', '__FILE__', '__FUNCTION__', '__LINE__', '__METHOD__', '__NAMESPACE__', '__TRAIT__');

$checkWord='break'; // <- the word to check for.
if (in_array($checkWord, $keywords)) {
    echo "Found.";
}

else {
echo "Not found.";
}

?>

You could also implement this in conjunction with a form by replacing:

$checkWord='break';

with

$checkWord=$_POST['checkWord'];

I.e.:

<?php

if(isset($_POST['submit'])){
$keywords = array('__halt_compiler', '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', 'for', 'foreach', 'function', 'global', 'goto', 'if', 'implements', 'include', 'include_once', 'instanceof', 'insteadof', 'interface', 'isset', 'list', 'namespace', 'new', 'or', 'print', 'private', 'protected', 'public', 'require', 'require_once', 'return', 'static', 'switch', 'throw', 'trait', 'try', 'unset', 'use', 'var', 'while', 'xor');

$predefined_constants = array('__CLASS__', '__DIR__', '__FILE__', '__FUNCTION__', '__LINE__', '__METHOD__', '__NAMESPACE__', '__TRAIT__');
$checkWord=$_POST['checkWord'];

if (in_array($checkWord, $keywords)) {
    echo "FOUND!!";
}

else {
echo "Not found.";
   }

}

?>

<form method="post" action="">

Enter word to check: 
<input type="text" name="checkWord">

<br>
<input type="submit" name="submit" value="Check for reserved word">
</form>

A different version using both arrays set inside a form.

It could stand for some polishing up, but it does the trick

<?php

if(isset($_POST['submit'])){
$keywords = array('__halt_compiler', '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', 'for', 'foreach', 'function', 'global', 'goto', 'if', 'implements', 'include', 'include_once', 'instanceof', 'insteadof', 'interface', 'isset', 'list', 'namespace', 'new', 'or', 'print', 'private', 'protected', 'public', 'require', 'require_once', 'return', 'static', 'switch', 'throw', 'trait', 'try', 'unset', 'use', 'var', 'while', 'xor');

$predefined_constants = array('__CLASS__', '__DIR__', '__FILE__', '__FUNCTION__', '__LINE__', '__METHOD__', '__NAMESPACE__', '__TRAIT__');

$checkWord=$_POST['checkWord'];

$checkconstant=$_POST['checkconstant'];

if (in_array($checkWord, $keywords)) {
    echo "<b>Reserved word FOUND!!</b>";
    echo "\n";
}

else {
echo "Reserved word not found or none entered.";
   }

if (in_array($checkconstant, $predefined_constants)) {
    echo "<b>Constant word FOUND!!</b>";
    echo "\n";
}

else {
echo "Constant not found or none entered.";
   }

}

?>

<form method="post" action="">

Enter reserved word to check: 
<input type="text" name="checkWord">

Enter constant word to check: 
<input type="text" name="checkconstant">

<br><br>
<input type="submit" name="submit" value="Check for reserved words">
<input type="reset" value="Reset" name="reset">
</form>

نصائح أخرى

you can build your own automated function. To do that use an array that hold all the reserved word.Check out for more information

Yes, you can. As you mentioned in link, we have a list of this names, so why just check in this way?:

   $keywords = array('__halt_compiler', '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', 'for', 'foreach', 'function', 'global', 'goto', 'if', 'implements', 'include', 'include_once', 'instanceof', 'insteadof', 'interface', 'isset', 'list', 'namespace', 'new', 'or', 'print', 'private', 'protected', 'public', 'require', 'require_once', 'return', 'static', 'switch', 'throw', 'trait', 'try', 'unset', 'use', 'var', 'while', 'xor');

 var_dump(in_array('__halt_compiler',$keywords)); 

I wrote this function isRW(string $string) NULL|false|string try it.. it will return NULL if the input is not a word, and will return a boolean false if the input is not reserved, and a string (PHP lexical token name) if the input is reserved..

function isRW($str){
    if(!preg_match("/^\w{1,20}/", $str)) return null; $rsv=false;
    $uc  = ['true','false','parent','self']; //uncheckable list
    $tk  = token_get_all('<?php '.(boolval($str)? $str:'x')); $tknm=token_name($tk[1][0]); 
    $cst = get_defined_constants(true); unset($cst['user']); global $phpcst; 
    $phpcst = !isset($phpcst)? array_merge(...array_column($cst, null)): $phpcst;

    if($tknm!='T_STRING'
    or in_array($str, $uc)  //if it's uncheckable 
    or @settype($str, $str) //if it's a type like int,NULL,object..
    or preg_match("/__\w/", $str) //PHP reserved all methods prefixed by "__" for future use
    or array_key_exists($str, $phpcst) //if it's a PHP const
    or (function_exists($str) and (new \ReflectionFunction($str))->isInternal())
    or (class_exists($str)    and (new \ReflectionClass($str))->isInternal())) $rsv=true;

    return $rsv? $tknm: $rsv;
}

some test outputs :

isRW('}');                  //return null
isRW('foobar');             //return boolean false
isRW('void');               //return boolean false
isRW('isInternal');         //return boolean false
isRW('_call');              //return boolean false
isRW('__call');             //return string T_STRING
isRW('__halt_compiler');    //return string T_HALT_COMPILER
isRW('private');            //return string T_PRIVATE
isRW('__DIR__');            //return string T_DIR
isRW('global');             //return string T_GLOBAL
isRW('E_ERROR');            //return string T_STRING
isRW('DATE_ISO8601');       //return string T_STRING
isRW('PHP_SAPI');           //return string T_STRING
isRW('namespace');          //return string T_NAMESPACE
isRW('function');           //return string T_FUNCTION
isRW('ReflectionClass');    //return string T_STRING
isRW('abstract');           //return string T_ABSTRACT
isRW('self');               //return string T_STRING
isRW('array');              //return string T_ARRAY
isRW('is_array');           //return string T_STRING
isRW('callable');           //return string T_CALLABLE
isRW('isset');              //return string T_ISSET
isRW('and');                //return string T_LOGICAL_AND
isRW('echo');               //return string T_ECHO

in_array() is a bad solution, as this iterates over every single element within the array, taking O(n) time, whereas using a lookup hash can be done in O(1) time.

To be clear, the solution below uses [the four lists on php.net:][2]

  • List of Keywords — 71 Keywords
  • Predefined Classes — 18 Keywords
  • Predefined Constants — 57 Keywords
  • List of other reserved words &mdash 13 Keywords

Full Working Demo Online

    class PHPReservedWords {
        public function isWordReserved($args) {
            $word = $args['word'];
            
            if($this->GetPHPReservedWordsHash()[$word]) {
                return TRUE;
            }
            
            return FALSE;
        }
        
        public function GetPHPReservedWordsHash() {
            if($this->word_hash) {
                return $this->word_hash;
            }
            
            $hash = [];
            
            foreach($this->GetPHPReservedWords() as $word) {
                $hash[$word] = TRUE;
            }
            
            return $this->word_hash = $hash;
        }
        public function GetPHPReservedWords() {
            return [
                        # Primary Source: https://www.php.net/manual/en/reserved.php
                        # ----------------------------------------------------------
                        
                    # List 1 of 4: https://www.php.net/manual/en/reserved.keywords.php
                    # ----------------------------------------------------------------
            
                '__halt_compiler',
                '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',           # (as of PHP 7.4)
                'for',
                'foreach',
                'function',
                'global',
                'goto',
                'if',
                'implements',
                'include',
                'include_once',
                'instanceof',
                'insteadof',
                'interface',
                'isset',
                'list',
                'match',        # (as of PHP 8.0)
                'namespace',
                'new',
                'or',
                'print',
                'private',
                'protected',
                'public',
                'readonly',     # (as of PHP 8.1.0)
                'require',
                'require_once',
                'return',
                'static',
                'switch',
                'throw',
                'trait',
                'try',
                'unset()',
                'use',
                'var',
                'while',
                'xor',
                'yield',
                'yield from',
                        
                    # List 2 of 4: https://www.php.net/manual/en/reserved.classes.php
                    # ---------------------------------------------------------------
                
                'Directory',
                'stdClass',
                '__PHP_Incomplete_Class',
                'Exception',
                'ErrorException',
                'php_user_filter',
                'Closure',
                'Generator',
                'ArithmeticError',
                'AssertionError',
                'DivisionByZeroError',
                'Error',
                'Throwable',
                'ParseError',
                'TypeError',
                'self',
                'static',
                'parent',
                        
                    # List 3 of 4: https://www.php.net/manual/en/reserved.constants.php
                    # ---------------------------------------------------------------
                    
                'PHP_VERSION',
                'PHP_MAJOR_VERSION',
                'PHP_MINOR_VERSION',
                'PHP_RELEASE_VERSION',
                'PHP_VERSION_ID',
                'PHP_EXTRA_VERSION',
                'PHP_ZTS',
                'PHP_DEBUG',
                'PHP_MAXPATHLEN',
                'PHP_OS',
                'PHP_OS_FAMILY',
                'PHP_SAPI',
                'PHP_EOL',
                'PHP_INT_MAX',
                'PHP_INT_MIN',
                'PHP_INT_SIZE',
                'PHP_FLOAT_DIG',
                'PHP_FLOAT_EPSILON',
                'PHP_FLOAT_MIN',
                'PHP_FLOAT_MAX',
                'DEFAULT_INCLUDE_PATH',
                'PEAR_INSTALL_DIR',
                'PEAR_EXTENSION_DIR',
                'PHP_EXTENSION_DIR',
                'PHP_PREFIX',
                'PHP_BINDIR',
                'PHP_BINARY',
                'PHP_MANDIR',
                'PHP_LIBDIR',
                'PHP_DATADIR',
                'PHP_SYSCONFDIR',
                'PHP_LOCALSTATEDIR',
                'PHP_CONFIG_FILE_PATH',
                'PHP_CONFIG_FILE_SCAN_DIR',
                'PHP_SHLIB_SUFFIX',
                'PHP_FD_SETSIZE',
                'E_ERROR',
                'E_WARNING',
                'E_PARSE',
                'E_NOTICE',
                'E_CORE_ERROR',
                'E_CORE_WARNING',
                'E_COMPILE_ERROR',
                'E_COMPILE_WARNING',
                'E_USER_ERROR',
                'E_USER_WARNING',
                'E_USER_NOTICE',
                'E_RECOVERABLE_ERROR',
                'E_DEPRECATED',
                'E_USER_DEPRECATED',
                'E_ALL',
                'E_STRICT',
                'true',
                'false',
                'null',
                'PHP_WINDOWS_EVENT_CTRL_C',
                'PHP_WINDOWS_EVENT_CTRL_BREAK',
                        
                    # List 4 of 4: https://www.php.net/manual/en/reserved.other-reserved-words.php
                    # ---------------------------------------------------------------
                    
                'int',
                'float',
                'bool',
                'string',
                'true',
                'false',
                'null',
                'void',         # (as of PHP 7.1)
                'iterable',     # (as of PHP 7.1)
                'object',       # (as of PHP 7.2)
                'resource',
                'mixed',
                'numeric',
            ];
        }
    }
    
    $reserved_words = new PHPReservedWords();
    print($reserved_words->isWordReserved(['word'=>'new']));

Depending on your use case, checking for reserved words in php can be a bit more tricky than simply looking up the values in a list.

There are two things that should be taken into account:

  • PHP version where you want to use the reserved word
  • Where you want to use it - function/namespace/constant/class/method name

The same reserved word can have different behavior in your code depending on this, let's take the array keyword for example.

  • It can't be used as a constant name from version 4.0 up to version 7.0, but can be used starting from 7.0
  • It can't be used as part of a namespace from version 4.0 up to version 8.0, but can be used starting from 8.0
  • It can't be used as a class name starting from version 4.0
  • It can't be used as a function name starting from version 4.0
  • It can't be used as a method name from version 4.0 up to version 7.0, but can be used starting from 7.0

Another example, namespace

  • It can't be used as a constant name from version 5.3 up to version 7.0, but can be used starting from 7.0
  • It can't be used as part of a namespace from version 5.3, and with __halt_compiler is one of the two exclusions that cannot be used in namespaces even in version 8.0
  • It can't be used as a class name starting from version 5.3
  • It can't be used as a function name starting from version 5.3
  • It can't be used as a method name from version 5.3 up to version 7.0, but can be used starting from 7.0

As you see, there are many nuances, that depend on a lot of changes in different versions.

I had the same needs and created a library for that purpose. It can be used in complex use-cases to check whether a reserved word can be used in specific places for specific php versions. Please take a look, maybe it can solve your problem.

https://github.com/sspat/reserved-words

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top