类中的 require_once()

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

我发现,如果我在一个类方法中声明的函数与一个外部函数同名,就会出现错误:

function a(){
  ...
}

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

}

这个可以正常工作:
function a(){
  ...
}

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

我可以使用require_once或类似的方法将一组函数作为该类的静态方法包含吗?

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


3
在我看来,永远不应该在一个函数内部声明另一个函数的定义。很可能有更好的方法来实现你想要的目标。你为什么要这样做呢? - dqhendricks
我不需要在函数内部声明一个函数,那只是我的愚蠢示例,因为require_once()显然只能在类函数内部使用 :) 我想以某种方式从不同的文件中包含一组静态方法到这个类中。它们将在不同的文件中,因为它们太多了 :) - Alex
你可以将函数放在脚本顶部的 include 中,或者更好的方法是将函数放入类中,然后创建一个类自动加载器,这样你就可以透明地按需加载所需的类。 - dqhendricks
http://www.spotlesswebdesign.com/blog.php?id=13 - dqhendricks
@dqhendricks:在面向对象编程的上下文中,当然是完全不同的问题,在函数式编程上下文中则又是另外一个问题。而且由于PHP现在已经支持闭包和lambda表达式,所以这个问题也不再那么奇怪了。 - Peter Host
4个回答

3

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

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

在类定义中调用require_once语句是不可能的。PHP语法不允许这样做。类定义是特殊的作用域/语言结构,仅允许在立即解析级别内进行函数或变量声明。因此,PHP不允许这样做(类及其方法必须一次性声明,不能组装),并且没有真正好的或可取的解决方案可以满足您的需求。


嗯,我们几周前讨论过一件非常相似的事情。但是我找不到它了... - mario

1
假设不定义第二个“a”方法是不可接受的,您需要将它移到init方法之外。
听起来您的require_once调用是问题所在(绝对不应在类内部调用)。您能发布一个完整的示例,包括不起作用的require_once调用吗?

1
回答这个问题:你应该先使用function_exists检查函数a是否已经被实现了。
class foo{
  public function init(){
    if(!function_exists('a')):
    function a(){  // <- will only be declared when it doesn't already exist
        ...    
    }
    endif;
    ...
  }

}

然而,将此视为非常糟糕的编码实践。很快就会变得一团糟,因为您不知道确切发生了什么以及将使用哪个函数。我建议您最好使用子类并require_once适当的子类。


1
如果你的类结构允许,你可以将类分成几个不同的类,它们是继承链的一部分:
class foo1 {
    public static function a() {}
}
class foo extends foo1 {
    public static function b() {}
}

或者,如果您愿意承受性能损失,也可以使用__callStatic()。 (需要PHP 5.3;但是如果您只需要非静态方法,则__call从5.0可用。)Smarty 3就是这样做的。

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 据说 将包括 traits,这是一种更直接的将外部代码包含到类中的方式:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接