自动加载器的功能

Sho*_*hoe 55 php class function autoloader

上周我学会了通过编写__autoload()函数将类包含在项目中.然后我了解到使用自动加载器不仅是一种技术,也是一种模式.

现在我在我的项目中使用自动加载器,我发现它非常有用.我想知道是否可以用功能做同样的事情.忘记在其中包含正确的PHP文件可能非常有用.

那么,是否可以创建一个功能自动加载器?

irc*_*ell 61

函数没有函数自动加载器.你有四个现实的解决方案:

  1. 将所有函数包装到命名空间类中(适合上下文).所以假设你有一个叫做的函数string_get_letters.您可以将其添加到称为StringFunctions静态函数的类中.所以不要打电话string_get_letters(),而是打电话StringFunctions::get_letters().然后你会__autoload那些命名空间的类.

  2. 预加载所有功能.由于您正在使用类,因此您不应该使用那么多函数,因此只需预加载它们即可.

  3. 在使用之前加载函数.在每个文件中,require_once将在该文件中使用的函数文件.

  4. 首先不要使用功能.如果你正在开发OOP代码(无论如何你似乎都是这样),根本不需要函数.您需要一个功能(或多个)的所有东西,您可以以OO方式构建并避免需要功能.

就个人而言,根据您的确切需求以及代码库的质量和大小,我建议使用1,2或4 ...

  • +1,但不是你通过松散功能可能做的一切自然转换为OOP设置.如果您只想要一个规范化路径格式的实用程序方法,或以特定方式操作数组,该怎么办?不要试图将一切都变成OO风格:) (56认同)
  • @ircmaxell"如果它足够通用将它添加到实用程序类中"这样的实用程序类只是一堆杂项,否则将被编写为独立函数.这样做的唯一原因是因为PHP无法自动加载功能.关于它没有任何关于它的事情. (7认同)
  • @ircmaxell呃,是的,但是"这不是关于鞋子的问题,而是关于设计." 似乎暗示有一些特定的_design_理由将实用程序函数移动到实用程序类中,此外它意味着PHP可以自动加载它们. (5认同)
  • +1实际上,使用静态方法(如StringUtils`,`WebHelpers`,`CollectionUtils`等)收集类中的常用函数是一个很好的设计模式.所以我选择选项1或4. (4认同)
  • @Alix:这不是一个函数,它是一个方法,它对类起作用.它不启用延迟加载,而是调用不存在的方法.@Will:这不是鞋子.如果您需要以特定方式设计数组,那么要么在需要它的类上使其成为受保护/私有成员方法,要么如果它足够通用,则将其添加到实用程序类.它不是关于鞋子的,而是关于设计.当然,你可以使用不可维护的代码进行鞋拔,但如果你设计得当,你将获得两个世界的好处.但混合松散的范式几乎从来都不好...... (4认同)

ivo*_*oba 34

如果您在项目中使用Composer,则可以将文件指令添加到自动加载部分.

这实际上会在自动加载器中生成require_once,但感觉就像真正的自动加载,因为你不必处理它.
虽然它不是懒惰的装载.

Assetic获取的示例:

"autoload": {
        "psr-0": { "Assetic": "src/" },
        "files": [ "src/functions.php" ]
    }
Run Code Online (Sandbox Code Playgroud)

  • 在 guzzlehttp\psr7: ` "autoload": { "psr-4": { "GuzzleHttp\\Psr7\\": "src/" }, "files": ["src/functions_include.php"] } ` 中发现。 ..似乎是合法的! (2认同)

Ali*_*xel 15

我读了一段关于一个丑陋的黑客,它发现了致命错误并试图包含并执行缺失的函数,但我绝对不会走那条路.

你最接近的是__call() 魔术方法,它是一种__autoload()方法,而不是函数.它可能足以满足您的需求; 如果你有能力打电话给一个班级,并分别要求每个不同的功能.从PHP 5.3.0开始,你也有__callStatic().

使用示例__callStatic():

class Test
{
    public function __callStatic($m, $args)
    {
        if (function_exists($m) !== true)
        {
            if (is_file('./path/to/functions/' . $m . '.php') !== true)
            {
                return false;
            }

            require('./path/to/functions/' . $m . '.php');
        }

        return call_user_func_array($m, $args);
    }
}

Test::functionToLoad(1, 2, 3);
Run Code Online (Sandbox Code Playgroud)

这将调用functionToLoad()./path/to/functions/functionToLoad.php中定义的函数.

  • @ircmaxell:跟你的行`__autoload()`也不是自动加载器,如果它找不到指定的类只是一个后备... (2认同)
  • 这是有效的,除非它没有.返回引用(*通常与*一样)会失败.还有其他一些警告; 我会尝试挖掘自己的问题,我想我有一个关于此的问题. (2认同)

mar*_*rio 8

好吧,像往常一样,有一个PECL扩展:

(来自:http://phk.tekwire.net/joomla/support/doc/automap.htm)

它应该自动加载函数以及类.然而,这对当前的PHP解释器不起作用.

(另一种选择btw,是生成加载和运行命名空间对应项的存根函数.)

话虽如此.自动加载并不是普遍认为的好习惯.它导致阶级等级和对象幸福感过度分裂.PHP具有自动加载的真正原因是因为包含和依赖管理系统不成熟.