Php function as function's parameter

355

In my php project I have some functions that in some cases I want to call under try-catch block, and in some cases not under try-catch block. And now I want to write a function that gets some function as parameter, calls it and return false in case of exception.

Approximately code like this and with support of different numbers of parameters for 'someFunction'.

function tryTo($someFunctionName) {
    try {
        return someFunctionName();
    } catch (Exception $error) {
        return false;
    }

How to organize that?

749

Answer

Solution:

You need to define your original functions as Closures so they are represented by variables and can be passed as function arguments.

Here is example code:

function myFunc ($arg) {
    echo "called myFunc with '$arg' as argument";
}

// create a Closure for it
$myFunc = function ($arg) { myFunc($arg); };

function tryTo($someFunctionName, $arg) {
    try {
        return $someFunctionName($arg);
    } catch (Exception $error) {
        return false;
    }
}

// call tryTo passing the Closure and the argument
echo tryTo($myFunc, "test");

As of PHP 5.6 you can also use the spread operator which makes it a piece of cake to support multiple arguments. That way onetryIt function can host for functions with different numbers of parameters:

function tryTo($someFunctionName, ...$args) {
    try {
        return $someFunctionName(...$args);
    } catch (Exception $error) {
        return false;
    }
}
152

Answer

Solution:

PHP allows you to call a number of things as if they were functions - this includes:

  • function names as strings (for instance"myFunc")
  • arrays containing a function name as the first element and an array of arguments as the second element (for instance["myFunc", ["arg1", "arg2"]])
  • arrays containing an object as the first element and an array of arguments as the second element (for instance[new MyClass(), ["arg1", "arg2"]])
  • instances of classes implementing the__invoke() magic method
  • Closures/anonymous functions

All of these can be denoted by thecallable typehint. As such, implementing your function as such:

tryTo(callable $callable) {
    try {
        $callable();
    catch(\Exception $ex) {
        return false;
    }
}

would allow you to usetryTo() for anything PHP considers callable, and enforce that whatever you pass can be used to call a function.

So the following will work:

tryTo('myFunc'); // Equivalent to myFunc();
tryTo('MyClass::myFunc'); // Equivalent to MyClass::myFunc();
tryTo(['myFunc', ['myArg', 'myOtherArg']]; // Equivalent to myFunc('myArg', 'myOtherArg');
tryTo([new MyClass(), 'myFunc']); // Equivalent to (new MyClass())->myFunc();
tryTo(function() { echo 'test'; }); // executes whatever closure you pass

You can see here for more information.

That said, I'm seriously questioning the use case for a function like that - generally, exceptions shouldn't happen unless something is wrong, and using a function like that opens you up to silent failures. At the very least, you should log the exception that occurred so you can see that something went wrong, but in my opinion you should handle specific exceptions wherever they're relevant. That, however, is an entirely different discussion altogether and does nothing to answer your question.

889

Answer

Solution:

<?php 
function tryTo($someFunctionName) {
  try {
    return $someFunctionName();
} catch (Exception $error) {
    return false;
}

// call tryTo function by passing function name
tryTo(functionName);
?>

People are also looking for solutions to the problem: php - Comparing datetime objects. The right way

Source

Didn't find the answer?

Our community is visited by hundreds of web development professionals every day. Ask your question and get a quick answer for free.

Ask a Question

Write quick answer

Do you know the answer to this question? Write a quick response to it. With your help, we will make our community stronger.

Similar questions

Find the answer in similar questions on our website.