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;
}
7条答案
按热度按时间disbfnqx1#
您可以创建自己的自动化功能。要做到这一点,请使用一个包含所有保留字的数组。Check out for more information
epfja78i2#
in_array()
是一个糟糕的解决方案,as this iterates over every single element within the array, takingO(n)
time,,而使用查找散列可以在O(1)
时间内完成。为了清楚起见,下面的解决方案使用[php.net上的四个列表:][2]
Full Working Demo Online的
字符串
ep6jt1vc3#
从http://www.php.net/manual/en/reserved.keywords.php借用的阵列
您可以很容易地修改它,使其适用于预定义的常量数组。
字符串
您还可以通过替换以下内容与表单一起实现此功能:
型
与
型
即:
型
在窗体中使用这两个数组集的不同版本。
它可以代表一些抛光,但它的伎俩
型
e4yzc0pl4#
你可以的正如你在链接中提到的,我们有一个这个名字的列表,那么为什么只是以这种方式检查呢?:
字符串
r8xiu3jd5#
我写了这个函数
isRW(string $string) NULL|false|string
试试。如果输入不是单词,则返回NULL
;如果输入不是保留的,则返回布尔值false
;如果输入是保留的,则返回string
(PHP词法标记名)。字符串
一些测试输出:
型
abithluo6#
根据您的用例,在php中检查保留字可能比简单地在列表中查找值要复杂一些。
有两件事需要考虑:
相同的保留字在代码中可能会有不同的行为,具体取决于此,让我们以
array
关键字为例。又如,
namespace
__halt_compiler
一起使用是两个排除项之一,即使在8.0版中也不能在命名空间中使用正如您所看到的,有许多细微差别,这取决于不同版本中的许多变化。
我也有同样的需求,为此创建了一个库。它可以用在复杂的用例中,检查一个保留字是否可以用在特定php版本的特定地方。请看一下,也许它能解决你的问题。
https://github.com/sspat/reserved-words
kxxlusnw7#
已经有一个公认的答案了,但我同意@HoldOffHunger的观点,即性能是一个具有如此大的值列表的问题。
但是,而不是作出大量的编辑,以解决问题的答案,这是我的版本。它将区分大小写的关键字与传递参数的小写版本进行比较。
感谢@HoldOffHunger提供初始结构。
字符串
工作代码:https://onlinephp.io/c/51226