【问题标题】:require_once() in a class类中的 require_once()
【发布时间】:2011-08-25 17:15:34
【问题描述】:

我注意到,如果我在与外部函数同名的类方法中声明一个函数,我会收到错误:

function a(){
  ...
}

class foo{
  public function init(){
    function a(){  // <- error
    ...    
    }
    ...
  }

}

但是这会起作用:

function a(){
  ...
}

class foo{
  public static function a(){
    ...
  }
}

我可以使用 require_once 或类似的东西包含一组充当此类静态方法的函数吗?

require_once('file.php');class foo{ 之后不起作用...

【问题讨论】:

  • 恕我直言,永远不应该有需要在另一个函数中声明函数定义的时候。很有可能,有更好的方法来完成你想要完成的事情。你为什么要这样做?
  • 我不需要在函数内部声明函数,这只是我的愚蠢示例,因为 require_once() 显然只能在类函数内部工作:) 我想以某种方式包含一组来自不同文件的此类的静态方法。它们将位于不同的文件中,因为它们太多了:)
  • 您可以将函数放在脚本顶部的包含中,或者更好的是,将您的函数放入类中,然后创建一个类自动加载器,这样您就可以只透明地加载您的类随意需要。
  • @dqhendricks :在 OOP 上下文中确定的事情,在 FunctionalOP 中完全不同的问题。由于 PHP 现在有闭包和 lambda,所以问题不再那么奇怪了。

标签: php class function require


【解决方案1】:

PHP 允许在其他函数中嵌套函数声明,但它实际上没有嵌套函数。它们总是在全局范围内结束。因此,您在 init 方法中定义的 a() 与已经定义的 function a() 发生冲突。

static function a() 与类命名空间相关联,即使它的行为类似于函数,而不是方法。

不可能在类定义中调用require_once 语句。 PHP 语法不允许这样做。类定义是特殊的范围/语言结构,只允许在直接解析级别内声明函数或变量。 - 所以 PHP 不允许这样做(类和它们的方法必须立即声明,而不是组装),对于你想要的,没有真正好的或可取的解决方法。

【讨论】:

  • 嗯,几周前我们进行了非常相似的讨论。但我再也找不到它了..
【解决方案2】:

如果您的类结构允许,您可以将类拆分为几个不同的类,它们是继承链的一部分:

class foo1 {
    public static function a() {}
}
class foo extends foo1 {
    public static function b() {}
}

或者,如果您愿意承受性能损失,也可以使用__callStatic()。 (需要 PHP 5.3;但如果您只需要非静态方法,则 __call 可从 5.0 开始。)Smarty 3 执行此 IIRC。

class foo {
    private static $parts = array('A', 'B');
    public static __callStatic($name, $arguments) {
        foreach (self::$parts as $part) {
            if (method_exists($part, $name)) {
                return call_user_func_array(array($part, $name), $arguments);
            }
        }
        throw new Exception();
    }
}
class A {
    public static function a() {}
}
class B {
    public static function b() {}
}

PHP 5.4 将 supposedly 包含特征,这是在类中包含外部代码的更直接的方式:

class foo {
    use A, B;
}
trait A {
    public static function a() {}
}
trait B {
    public static function b() {}
}

【讨论】:

    【解决方案3】:

    回答问题:首先检查a函数是否已经使用function_exists实现了:

    class foo{
      public function init(){
        if(!function_exists('a')):
        function a(){  // <- will only be declared when it doesn't already exist
            ...    
        }
        endif;
        ...
      }
    
    }
    

    但是,认为这是一种非常糟糕的编码习惯。如果您不知道到底发生了什么以及将使用什么功能,它很快就会变得一团糟。我会说你最好使用子类和require_once 适当的子类。

    【讨论】:

      【解决方案4】:

      假设不定义第二个“a”方法是不可接受的,您需要将它移到 init 方法之外。

      听起来你的 require_once 调用是问题所在(绝对不应该在类内调用)。您能否发布一个完整的示例,包括您的 require_once 调用,但该调用不起作用?

      【讨论】:

        猜你喜欢
        • 2012-02-25
        • 2011-02-08
        • 2012-06-27
        • 2019-04-26
        • 2013-09-10
        • 1970-01-01
        • 2023-03-14
        • 2011-09-15
        • 2013-03-27
        相关资源
        最近更新 更多