目标
最初的问题是关于验证未知数据类型的值并丢弃所有值,除了那些只包含数字的值。似乎只有两种方法可以达到这个预期的结果。
如果目标是快速失败,则需要检查无效值然后失败,而不是检查有效值并将所有代码包装在一个if
块中。
问题中的选项 1
if (preg_match('/\D/', $company_id)) exit('Invalid parameter');
regex
如果匹配非数字,则使用失败。缺点:正则表达式引擎有开销
问题中的选项 2
if (!ctype_digit((string) $company_id)) exit('Invalid parameter');
如果为 FALSE,则使用ctype_digit
失败。缺点:必须将值转换为字符串,这是一个(小)额外步骤
您必须将值转换为字符串,因为ctype_digit
需要一个字符串,而 PHP 不会为您将参数转换为字符串。如果你将一个整数传递给ctype_digit
,你会得到意想不到的结果。
这是记录在案的行为。例如:
ctype_digit('42'); // true
ctype_digit(42); // false (ASCII 42 is the * character)
选项 1 和 2 之间的区别
由于正则表达式引擎的开销,选项二可能是最好的选择。但是,担心这两个选项之间的差异可能属于过早优化类别。
注意:上述两个选项之间也存在功能差异。第一个选项将NULL
空字符串视为有效值,第二个选项不考虑(从 PHP 5.1.0 开始)。这可能会使一种方法比另一种方法更受欢迎。要使regex
选项功能与ctype_digit
版本相同,请改用它。
if (!preg_match('/^\d+$/', $company_id)) exit('Invalid parameter');
注意:上面的'start of string'^
和'end of string'$
锚点regex
非常重要。否则,abc123def
将被视为有效。
其他选项
这里和其他问题中还提出了其他方法,这些方法无法实现既定目标,但我认为重要的是要提及它们并解释它们为什么不起作用,因为它可能对其他人有帮助。
is_numeric
允许指数部分、浮点数和十六进制值
is_int
'1'
如果被认为是有效的,则检查对验证没有用的数据类型而不是值。表单输入始终是一个字符串。如果您不确定值的来源,则无法确定数据类型。
filter_var
withFILTER_VALIDATE_INT
允许负整数和值,例如1.0
. 无论数据类型如何,这似乎都是实际验证整数的最佳函数。但是如果你只想要数字就行不通了。注意:重要的是要检查FALSE
身份,而不仅仅是真/假是否0
被视为有效值。