【问题标题】:Is it possible to evaluate an expression before being used as a function name?是否可以在用作函数名之前评估表达式?
【发布时间】:2017-05-24 08:35:00
【问题描述】:

我遇到了一个有简单解决方案的问题...

$this->controller = new "controllers\\" . $namespace . $controller($this->relativePath);

我想做类似上面的事情,但它不起作用,因为似乎在评估连接字符串的值之后 $controller($this->relativePath) 被评估。

解决方案是这样的......

$x = "controllers\\" . $namespace . $controller
$this->controller = new $x($this->relativePath);

但是拥有一个一次性变量让我很生气。有其他选择吗?

【问题讨论】:

  • 没试过,我个人对使用一次性变量没有问题;但是像$this->controller = new {"controllers\\" . $namespace . $controller}($this->relativePath); 这样的大括号包装呢?
  • 这两种大括号都不起作用。

标签: php class variables object dynamic


【解决方案1】:

您可以告诉 PHP 引擎评估字符串并使用eval() 执行它...大多数解释型语言都有这样的功能。不过我必须警告你,如果你的代码不是绝对正确的,这可能是非常危险的,因为 PHP 引擎无法确定你正在评估的是正确的 PHP 代码。因此,当您使用它时,您将失去引擎提供的一些安全性。但是,如果您知道自己在做什么,这不应该阻止您使用它;就是为了这个目的。

$this->controller = eval("new controllers\\" . $namespace . $controller($this->relativePath));

如果评估顺序错误...用括号表达您的意图;它们的优先级最高。

Eval Documentation

我的个人推荐

使用Strategy Design Pattern

【讨论】:

  • 我大部分时间都没有提到过,只要有一点聪明,你通常可以避免使用eval。您尝试实现的设计模式称为Strategy。它很常见,我建议使用更惯用的方法。
【解决方案2】:

如果您绝对不想使用第二个变量,您可以改用反射:

<?php
function createObject($name, $params = null) {
    if($params == null) {
        return (new ReflectionClass($name))->newInstance();
    } else {
        return (new ReflectionClass($name))->newInstanceArgs($params);
    }
}


$instance = createObject("your"."classname", ["parameters"]);

可以测试它如何在性能方面与eval 保持一致,但由于这只能实例化对象(与可以任意执行代码的 eval 相比),这可以提供安全性益处。 您还可以扩展该功能以将其限制为某些命名空间等。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-05-16
    • 1970-01-01
    • 2010-09-09
    • 2017-05-05
    • 2017-11-24
    • 2019-08-05
    • 2013-10-23
    相关资源
    最近更新 更多