我喜欢用PHP进行实验。我制作了自己的缩写MVC并且很开心。这一切都有效(分离显示和逻辑),并允许我创建主题来启动。使用KISS方法。所以请不要回答MVC / OOP。只是一个个人项目。
在下面的代码中,您可以看到我能够路由我的所有功能。但是我只注意到一件我不确定的奇怪事情。我的大多数页面都很小,由于简单,很少有参数。所以我做了一个更大的应用程序(游戏),当然需要参数,这是我可以说的错误:-)
当使用这种调用函数的方法时,它完美无缺,直到我发送一个参数。然后它给了我
函数validate()的参数太少,0传递
哪个不是真的。
所以,我理解为什么这不起作用,因为$ function是一个变量而不是一个实际的函数,所以它类似于说$ variable($ argument)是非法的。
所以只要没有参数,它就有效。
查看代码,您可以看到我想要完成的任务(如果可能),如何完成?如果有的话。编辑澄清
$view = 'default';
if (isset($url[0])) $view = $url[0];`code`
if (isset($url[1])) $function = $url[1];
if (isset($url[2])) $arg = $url[2];
if (isset($url[3])) $arg2 = $url[3]; // used for 2 arguments`
if(!empty($function) && function_exists($function)){
switch(true){
// add your case logic for your hight arg count down to here
case(!empty($arg) && !empty($arg2)) : $function($arg,$arg2); break; // BOTH arg not empty
case(!empty($arg) && empty($arg2)) : $function($arg); break; // FIRST arg only
case(empty($arg) && empty($arg2)) : $function(); break; // BOTH arg EMPTY
case(empty($arg) &&
empty($arg2) &&
isset($_POST)) :$function("hello world"); break; // BOTH arg EMPTY POST set
}
}
没有jquery,我更喜欢纯粹的js再次,这只是一个探索PHP的一些功能的个人项目。
你们中的任何人都可以帮助我玩得开心吗?谢谢!
特别感谢@Imaginaroom向我指出了正确的方向:
这是更新的代码:
if(isset($function) && function_exists($function)){
if(isset($_POST)) {
call_user_func($function, $_POST);
}else{
call_user_func_array($function, array($arg, $arg2));
}
再次感谢你们其他人。在我纠正这个问题之后,很多人都有类似的想法。伟大的思想!!
虽然它需要一些清理。这现在应该工作。而且,更重要的是,它允许我杀死大量冗余代码。
因此,根据我的观点,empty($function)
可以解决问题,如果它试图调用分配给变量$function
的callable,这就是它失败的原因(没有测试过)。
但是,function_exists仍然只接受字符串作为参数,它应该表示一个函数名称来检查它是否存在(显然)。因此,如果您的变量$function
是函数名称,那么您不能像$function($arg, $arg2)
那样使用它,而是需要查看call_user_func函数。另一方面,如果你将一个函数本身分配给变量$function
,那么你需要改变你的条件
if(!empty($function) && function_exists($function))
至
if(isset($function) && is_callable($function))
调用变量函数是callables的工作。尽管PHP / 7增强功能,它仍然是一个非常古老的功能。您可以使用:
另外(不确定你是否需要它)你可以使用func_get_args()获取函数接收的所有参数。
从错误消息“函数validate()的参数太少,0传递”似乎$function == 'validate'
和$arg
和$arg2
是空的。请注意,PHP函数empty()
也将数字0
和字符串"0"
视为空值。
您应该使用strlen()
来检查变量是否为空字符串。如果你使用从请求中获得的值设置$arg
和$arg2
,那么它们就是字符串(它们也可以是字符串数组)。
可能的代码重写可能是:
if (is_callable($f)) {
// Collect all the non-empty arguments in $arguments
$arguments = [];
// $arg[0] is the first character of the string stored in $arg
// when it is set (it exists) the string is not empty
if (isset($arg[0]) {
$arguments[] = $arg;
}
// More arguments
if (isset($arg2[0]) {
$arguments[] = $arg2;
}
// Call the function with arguments
call_user_func_array($f, $arguments);
}
阅读更多关于is_callable()
,isset()
和call_user_func_array()
的信息。
您可以使用带参数解包的闭包
$closureA = function ($a, $b) { return $a + $b; };
$closureB = function ($a) { return $a * 2; };
$closureC = function () { return 2; };
function run(Closure $closure, array $args = []) {
return $closure(...$args);
}
echo run($closureA, [1,2]);
echo run($closureB, [2]);
echo run($closureC);
输出:
342
这是运行带有不同参数的3个闭包的结果,即使没有参数也是如此。
可以使用key作为函数名将闭包设置为数组,然后可以使用array_key_exists轻松检查是否存在此类闭包,如果存在,则使用run()函数调用它
示例如下:
$closures = [];
$closures['add'] = function ($a, $b) { return $a + $b; };
$closures['multiplyby2'] = function ($a) { return $a * 2; };
$closures['return2'] = function () { return 2; };
function run(string $name, array $args = []){
global $closures;
return array_key_exists($name, $closures) ? $closures[$name](...$args) : "no closure for given name";
}
echo run('add', [1,2]);
echo run('multiplyby2', [2]);
echo run('return2');
echo run('blabla');
有很多方法可以实现这一目标
function test($arg1=FALSE,$arg2=FALSE){ // setting default value
// If you want to check if the values are numeric or something like that
// $arg1 = $arg1?is_numeric($arg1)?$arg1:FALSE:FALSE;
// $arg2 = $arg2?is_numeric($arg2)?$arg2:FALSE:FALSE;
$bothValid = ($arg1 && $arg2)?TRUE:FALSE;
// Then you can proceed the way you like
if($bothValid){
// code that uses both params
// return something;
}
if($arg1){
// code that uses argument 1
// return something;
}
if($arg2){
// code that uses argument 2
// return something;
}
}
或类似如下
function test($type,$arg1=FALSE,$arg2=FALSE){ // setting default value
// If you want to check if the values are numeric or something like that
// $arg1 = $arg1?is_numeric($arg1)?$arg1:FALSE:FALSE;
// $arg2 = $arg2?is_numeric($arg2)?$arg2:FALSE:FALSE;
$bothValid = ($arg1 && $arg2)?TRUE:FALSE;
switch ($type) {
case ($type == 'add' && $bothValid):
return $arg1 + $arg2;
break;
default:
return 'Your error message';
break;
}
}
您可以通过以下函数调用来检查它
test();
test(1,2);
test('sdfsdfsf','sdfsdf');
将您的功能移至课堂。然后你可以简化你的代码:
class myClass {
public function foo($arg = null, $arg2 = null) {}
public function test($function, $arg, $arg2) {
$args = array_filter([$arg, $arg2]);
if (method_exists([$this, $function])) {
if (empty($args) && !empty($_POST)) {
$function('Hello world');
} else {
call_user_func_array([$this, $function], array_filter($args));
}
}
}
}