PHP使用带参数的function_exists()

问题描述 投票:2回答:6

我喜欢用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));
        }

再次感谢你们其他人。在我纠正这个问题之后,很多人都有类似的想法。伟大的思想!!

虽然它需要一些清理。这现在应该工作。而且,更重要的是,它允许我杀死大量冗余代码。

php
6个回答
0
投票

因此,根据我的观点,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))

0
投票

调用变量函数是callables的工作。尽管PHP / 7增强功能,它仍然是一个非常古老的功能。您可以使用:

另外(不确定你是否需要它)你可以使用func_get_args()获取函数接收的所有参数。


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);
}

阅读更多关于is_callable()isset()call_user_func_array()的信息。


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个闭包的结果,即使没有参数也是如此。

Working fiddle

可以使用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');

Working fiddle


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');

-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));
            }
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.