自动加载函数最佳实践

3
在使用PHP的面向对象编程范式与__autoload()函数的项目中,对于管理独立函数,以下哪项被认为是最佳实践:
(示例为简洁起见而简化)
tl;dr:如何常规处理独立函数加载:
1. 伪自动加载(例如通过__callStatic魔术方法) 2. 抽象帮助类分组静态方法 3. 另一种选择
另请注意,我发布了一个相关问题,涉及Option 1的参数/引用问题,可以在此处找到:__callStatic(),call_user_func_array(),references和PHP 5.3.1index.php中给出。
function __autoload($class){
    require $class . '.class.php';
}

选项1:一个抽象的Core类(或Library,或其他名称),可以“自动加载”函数:
## Core.class.php
abstract class Core{
    public static function __callStatic($function, $arguments){
        if(!function_exists($function)){
            require $function . '.function.php';
        }
        return call_user_func_array($function, $arguments);
    }
}

## SayHello.function.php
function sayHello(){
    echo 'Hello';
}

## SayGoodbye.function.php
function sayGoodbye(){
    echo 'Goodbye';
}

## index.php
Core::sayHello();   // Hello
Core::sayGoodbye(); // Goodbye

选项2:将相关功能分组到抽象的“helper”类中,以静态方式调用:
## SayStuff.class.php
abstract class SayStuff{
    public static function sayHello(){
        echo 'Hello';
    }
    public static function sayGoodbye(){
        echo 'Goodbye';
    }
}

## index.php
SayStuff::sayHello();   // Hello
SayStuff::sayGoodbye(); // Goodbye
2个回答

4

我在这里没有看到一个明确的问题,但由于标题包含“最佳实践”,我最近发现了一条建议:

使用PHP的SPL自动加载函数似乎比__autoload()更可取(David博客上有很好的例子)。

引用链接的博客文章:

使用SPL版本的最大好处(目前我能看到的)是:

  • 可以使用/注册多个函数 - 函数链接在一起,按顺序使用,直到一个函数加载类文件。此外,也可以即时取消注册函数。
  • 可以实现一些不错的错误处理(见示例3),尽管有些人可能会用try/catch实现,这可能不符合你的编码风格。
  • 如果愿意,可以使用不同的扩展名(即不是.php或.php.inc或.inc)通过spl_autoload_extensions()来实现。
  • 确保“我的”自动加载类不被覆盖!如果稍后运行__autoload(),我的spl_autoload_register()函数将不会被替换。

1
除此之外,使用符合PSR-0标准的自动加载器可能是一个不错的主意。更多信息请参见http://groups.google.com/group/php-standards/web/psr-0-final-proposal。 - mfonda
1
感谢Frosty Z的建议;我非常赞赏SPL自动加载相较于非SPL自动加载的优点。在未来的项目中,我一定会开始使用它,取代提供核心的__autoload功能。我会在我的问题中添加一个tl;dr的小结。 - Dan Lugg

1

我不会使用“选项1”,主要是因为它使用了call_user_func*,这比直接调用函数要慢。

如果你只需要一些不太相关的辅助函数,那么我可能会包含一个helpers.php文件,其中列出了所有不封装在静态类中的辅助函数。因为在这种情况下,封装并不能真正实现任何目的。大多数情况下,辅助函数将用于每个请求,所以在每个请求中包含此文件不会造成任何损害...


感谢rATRIJS;我也在考虑这个方向,递归函数可能会成为瓶颈。随着时间的推移,我编写了许多基本上扩展了PHP核心功能的函数,虽然有些函数可能会在某个项目中使用,但有些则不会。由于某些函数的普遍性,将它们分成逻辑组(类)是困难的,但这仍然是我正在考虑的选项。每次都将它们全部加载作为一个巨大的库并不是最优选择(我认为),因为当我完成整合我的库时,它的大小将变得非常庞大。 - Dan Lugg
我注意到“选项1”的另一个问题是,带有按引用传递的参数的函数当然无法正常工作。我忘记了这个警告。 - Dan Lugg

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