使用字符串调用PHP语言构造


Calling PHP language constructs using a string

我想缓冲一些内容。获取内容的方式取决于它,这就是为什么我在缓冲区函数中添加了一个类型参数来定义是包含还是回显源。

PHP

<?php
function bufferContent($source, $type = 'include') {
  ob_start();
  $type($source);
  return ob_get_clean();
}
echo bufferContent('<html>test</html>', 'echo');
?>

输出

Fatal error: Call to undefined function echo() in #### on line 5

为什么?难道不可能用字符串变量调用标准的PHP函数,比如echo((或include((吗?

编辑:稍微更改了问题,使其更适合答案。

echo不是函数:它是一种语言构造,因此不能以这种方式调用。

您可以定义一个函数,该函数本身将调用echo,并在调用bufferContent:时使用您的函数

function my_echo($str) {
    echo $str;
}
echo bufferContent('<html>test</html>', 'my_echo');


A参考文献,引用echo:的手册页面

注意:因为这是一个语言构造而不是函数,所以不能使用变量调用功能

您不能从字符串变量中调用echo、include、require_eonce、isset、empty,因为它们的行为与正常函数不同。你可以使用

include "file.php";

include("file.php");

您可以制作一个包装器函数,并调用它们,例如:

function wrap_echo($str) { echo($str); };

并进行

$f = "wrap_echo";
$f("sth");

会因此受到指责,但在您的情况下,懒惰的解决方法是:

eval(" $type('$source); ");

这适用于正常的函数和语言结构。尽管您确实应该在特殊情况下使用开关,并在其他情况下保持正常的变量函数调用。

function buffer_content($source, $type = 'echo') {
    if(!is_string($type)){
        trigger_error('$type must be a string.', E_USER_WARNING);
        return false;
    }
    if(is_object($source) and method_exists($source, '__toString')){
        $source = strval($source);
    }elseif(is_scalar($source)){
        $source = strval($source);
    }elseif(!is_string($source)){
        trigger_error('$source must be a string as non-scalars do not echo nicely.', E_USER_WARNING);
        return false;
    }
    ob_start();
    switch(strtolower($type)){
        case 'include': include $source; break;
        case 'include_once': include_once $source; break;
        case 'require': require $source; break;
        case 'require_once': require_once $source; break;
        case 'echo': echo $source; break;
        default: trigger_error("'$type '{$type}' is not supported.", E_USER_WARNING); break;
    }
    return ob_get_clean();
}

^你需要即兴发挥一下这就是你做你需要做的事情的方式!但有更好、更高效/通用的方法可以做到这一点。

不能将echo作为函数调用,因为它实际上不是一个函数,而是PHP中的一种语言构造。

为了有效地调用echo,您可以创建一个包装方法,例如:

function call_echo($str){
  echo $str;
}

关于通过字符串调用函数的主题,我将使用call_user_func

mixed call_user_func ( callback $function [, mixed $parameter [, mixed $... ]] )

所以在你的情况下是

call_user_func($type, $source);

我会选择call_user_func而不是变量函数,因为它可读性更强,不易混淆。如果我正在阅读您的代码,如果您调用call_user_func

,我会立即看到您在做什么