我正在开发一个可通过Web访问的API,并且一直试图找出将$ _POST / $ _GET变量指定为函数参数的最整洁,最有效的方法。我知道变量不能用作参数默认值,因此目标是DRY(不要重复自己);在应用程序和外部接口中都可以使用API函数。
背景
1)目前,API函数被组织成具有公共静态方法的类。当发出远程请求时,(安全地)确定所请求的类和方法,如果类+方法组合有效,则使用call_user_func("$class::$method")
调用它。
2)最终调用class::method()
的代码故意愚蠢 - 它不知道或不关心函数所需的参数。由于无法使用缺少的参数调用函数,因此API中的所有函数都必须没有参数,或者没有默认参数。我认为这里最干净的事情是使用默认值null
定义所需的参数,并让函数在内部处理$ _POST变量的赋值:
public static function complete($id = null, $offset = 0, $limit = 50){ ... }
3)在内部,API方法返回常规PHP变量,然后外部接口使用json_encode()
对此值进行编码。
我现在的工作原理是什么:
我最初尝试了一些怪物,每个功能需要10个或更多的额外行,但我已将其削减为可重复使用的功能。我看了一下extract()
,但它不够精确或不够安全。
function assign($postIndex, &$target, $require = true){
// Any code assigned parameter overrides remote values
if($target != null && $require == true)
return;
// Force parameter requirement if specified
if($require && !isset($_POST[$postIndex]))
throw new MissingParameterException();
// Assign to referenced variable if it's set
if(isset($_POST[$postIndex]))
$target = $_POST[$postIndex];
}
使用如:
public static function delete($id = null){
assign('id', $id);
...
}
请注意我知道潜在的注入漏洞;无论原点如何,所有API函数都会清除其参数。我也知道其他人使用这种方法为API编写函数可能会假设参数是安全的,但是由于必须显式调用assign()
,我认为这有点无效(如果函数重命名则更多{{} 1}}) - 它基本上与写assign_raw_post_var_to_param()
一样明确。
问题......
有没有更好的方法将$ _POST / $ _GET变量分配给函数参数,这些参数允许通过外部接口和代码透明地调用函数?如果是这样你会如何实现呢?
答案 0 :(得分:1)
我认为你需要call_user_func_array
。使用它你可以指定一个参数数组,这样你就可以保留简单的方法签名。
如果你不知道参数的顺序并且需要计算出运行时间,你可以使用reflections来完成。
按OP编辑:
反思是一个很好的解决方案。例如:
class TestClass {
public static function some_method($name, $email, $bannana){
}
}
$reflection = new ReflectionMethod('TestClass', 'some_method');
$params = $reflection->getParameters();
$params
现在看起来像这样:
Array
(
[0] => ReflectionParameter Object
(
[name] => name
)
[1] => ReflectionParameter Object
(
[name] => email
)
[2] => ReflectionParameter Object
(
[name] => bannana
)
)