昨天看到一个项目,特别好奇的看了一眼,顿觉世界人民还是智慧满天下的。
大家可能都知道,php 是弱类型的,那么就意味着有各种可能性,bug 能在代码中游离,不顾一切。
好了,段子说完了,我们开始说正题。
如果要做到参数检查,无非两点
- 语言本身支持
- 写校验
对于第一点可以选择 hacklang,不缀述了。本文围绕第二点,可能看到这儿你会觉得我偏你感情,校验谁不会,但客官先别急。
我以前也是如同你这般,检验参数谁不会的态度走了这么久…但当我看到昨天那个项目的时候,有必要写一篇出来。
昨天看到的项目的校验是这么写的
<?php
function foo($a, $b) {
Argument::i()
->test(1, 'string')
->test(2, 'number');
}
而通常我们写是这么写的
<?php
function foo($a, $b) {
if (!is_string($a) || !is_numeric($b)) {
throw new ArgumentInvalidException('xxx');
}
}
摔桌子……
一个是完全有规律有节奏的校验,一个是没有共性 case by case 的校验。
最近也是对数据的校验产生了浓厚的兴趣,原因无他,因为没有一个能把这个事情干漂亮的。
看到这儿,大家可能也想知道是如何做的?
在整个 PHP 体系里面,奇技淫巧数不胜数,当然从侧面讲是“高级特性”。要想做到上面写到的这块代码描述的情况,也不是什么难事儿。咋们可以幻想一下,实现此类功能,应该如何做;
- 首先得获取到调用参数的运行时变量值
- 然后给定规则校验这个值是否 OK
可以看到,就如第一段代码描述的,感觉只有设定规则,并没有去获取函数参数值。这块就让我百思不得姐了;
<?php
function foo() {
var_dump(debug_backtrace());
}
foo(1, 2, 'test');
其输出
array(1) {
[0]=>
array(4) {
["file"]=>
string(31) "/Users/shouding/Downloads/t.php"
["line"]=>
int(8)
["function"]=>
string(3) "foo"
["args"]=>
array(3) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
string(4) "test"
}
}
}
居然用了 debug_backtrace
函数,虽然这样能拿到参数,但我想性能损耗也是比较大的。
可能你会突然说,我操,原来用来这个东西,但其实我们很少用到这些,因为某公司还处在 PHP 5.2 的水平上。
但,文法确实很赞,给了我一些思路。
如果协助以编译工具,或者稍微写代码的时候允许繁琐一点,就能比较完美的实现函数参数类型校验了。
<?php
function foo($a, $b) {
Argument::i(func_get_args())
->test(1, 'string')
->test(2, 'number');
}
文法、性能上都有所考虑了。
我还没说完,等我晚上更。