我喜欢尝试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));
}
再次感谢您。在我纠正此问题之后,似乎很多人都有类似的想法。好主意!
它需要一些清理。现在可以正常工作了。而且,更重要的是,它使我能够杀死很多冗余代码。
答案 0 :(得分:0)
调用变量函数是callables的工作。尽管有PHP / 7的增强功能,它还是一个相当老的功能。您可以使用:
另外(不确定是否需要在这里),您可以使用func_get_args()获取函数接收的所有参数。
答案 1 :(得分:0)
因此,我认为,empty($function)
如果尝试调用分配给变量$function
的可调用对象,可能会解决该问题,这就是失败的原因(没有对其进行测试)。
但是,function_exists仍然只接受字符串作为参数,该字符串应表示一个函数名称以检查其是否存在(显然)。因此,如果变量$function
是函数的名称,则不能像$function($arg, $arg2)
那样使用它,而是需要研究call_user_func函数。
另一方面,如果您将函数本身分配给变量$function
,则需要将条件从更改为
if(!empty($function) && function_exists($function))
到
if(isset($function) && is_callable($function))
答案 2 :(得分:0)
从错误消息“函数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);
}
答案 3 :(得分:0)
您可以将闭包与参数解压缩一起使用
$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个具有不同参数的闭包的结果,即使其中的1个没有args。
可以将闭包设置为以键作为函数名称的数组,然后使用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');
答案 4 :(得分:0)
有很多方法可以实现这一目标
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');
答案 5 :(得分:-2)
将您的函数移至类。然后,您可以简化代码:
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));
}
}
}
}