0

Question:

How do I check if a function is being passed as a parameter?

Especially if the function being passed is returning a string etc?

IE in the example below I don't want to htmlentities the function html being passed as a parameter, but I do want to htmlentities anything else. Also assuming there could be more than a single parameter that needs to take a function later.

Example:

function html($tag,$content)
{

if(!is_callable($content)){$var=htmlentities($var, ENT_NOQUOTES, "UTF-8");}

return "<".$tag.">".$content."</".$tag.">";

}


echo html(html('Example','Example'),'Example');

This example does not seem to work for me. I still get htmlentitied content when its a function.

Community
  • 1
  • 1
Event_Horizon
  • 708
  • 1
  • 11
  • 30
  • 4
    You're not passing a function to `foo()`, you're passing the return value from the inner `foo()` function to the outer `foo()`, which is a string. – nickb Jul 27 '12 at 15:19
  • Even so, is there a way to check that a function is returning a value? Some way to detect function input? @nickb – Event_Horizon Jul 27 '12 at 15:20
  • Possible duplicate of: http://stackoverflow.com/questions/2835627/php-is-function-to-determine-if-a-variable-is-a-function The second answer should solve your problem – nybbler Jul 27 '12 at 15:22
  • @nybbler - `foo()` never receives a function as its input. – nickb Jul 27 '12 at 15:24
  • @nickb - You're right. Seems like an explanation of the order this code will be executed in might be in order – nybbler Jul 27 '12 at 15:25

3 Answers3

2

While you cannot detect if a string being passed to a function is the result of another function, you can pass something that is not a string, but behaves like a string.

While I don't really recommend this, and the side-effects could be plentiful, here is a possible solution.

A helper class that pretends to be a string, but it's a class.

class sillyString
{
    private $string = '';

    public function __construct($string)
    {
        $this->string = $string;
    }

    public function __toString()
    {
        return $this->string;
    }
}

Your function. I've jiggled it around a bit, but it checks the type of the content.

function html($content, $tag)
{
    if (!is_object($content)) {
        $content = htmlentities($content, ENT_NOQUOTES, "UTF-8");
    }

    return new sillyString("<".$tag.">".$content."</".$tag.">");
}

Call your function as before.

print html(html('content','tag1'),'tag2');

So the function can now tell that you haven't passed a string, but you can still use it exactly like a string inside the function.

Leigh
  • 12,859
  • 3
  • 39
  • 60
1

From what I can tell in your example, the best way to achieve what you're looking for is a third parameter, $escape_var:

function foo( $var, $var2, $escape_var = true)
{
    if( $escape_var === true)
        $var = htmlentities( $var, ENT_NOQUOTES, "UTF-8");

    return $var." ".$var2;
}

echo foo(foo('<Example>','<Example>'),'<Example>', false);
nickb
  • 59,313
  • 13
  • 108
  • 143
  • This seems like the best way out of current answers but what if I end up adding more parameters that need to accept functions returning strings etc? I'd need a true/false for each one. – Event_Horizon Jul 27 '12 at 15:36
0

No, you can not check that, you are not passing a function, just past the return value of the function.

Instead, you could do the below for your needs.

function foo() {
  $vars = func_get_args();
  foreach ($vars as &$var) {
    $var = htmlentities($var, ENT_NOQUOTES, "UTF-8");
  }
  return implode(" ", $vars);
}

// usage
foo('<Example>', '<Example>', '<Example>');
xdazz
  • 158,678
  • 38
  • 247
  • 274