【问题标题】:__autoload vs include family__autoload 与包含家庭
【发布时间】:2011-09-20 04:43:11
【问题描述】:

我今天发现了 __autoload 功能,在阅读了该功能的官方手册页后,我一点也不明白。

使用 __autoload() 和使用 require_once 有什么明显区别?

因为它看起来自动加载是执行所需包含的新时尚方式对我来说,使用 require_once 会好得多。因此,必须将 __autoload 定义到所有 php 文件中,这意味着将其代码写在那里,如果我将 ALL 我的 include/require_once/...etc 放入一个文件中,我们称之为 ma​​in_header .php 那么我只需要在我的网络应用程序文件中编写一行代码:

<?php require_once('main_header.php');  ?> 

我是不是哪里错了?

【问题讨论】:

    标签: php


    【解决方案1】:

    另一个注意事项:include 和 require 在单元测试时可能会变得很痛苦。

    我不知道我应该如何防止要求/包括任何东西。有test helpers,可以做一些有用的事情,例如防止退出或死亡,但它们仍然不能模拟包含或要求。

    Mockery library recommends 使用自动加载来模拟公共静态方法。

    【讨论】:

      【解决方案2】:

      我可以看到自动加载有两件事(不一定是__autoload;更喜欢更现代的spl_autoload_register):

      1. 您不需要显式包含这些类。当然,您可以像示例中一样创建main_header.php,但随后下一项就会生效。
      2. 如果您只打算使用 10 个类,则不必加载 100 个类。

      还值得指出的是,在反序列化尚未定义的类的对象时也会触发自动加载,这使事情变得更加实用。当然unserialize 中还有另一个钩子(配置设置unserialize_callback_func),所以从技术上讲不需要自动加载。不过肯定更好。

      【讨论】:

      • 谢谢乔恩,你的论点扼杀了它,我肯定会转向这种方法。
      【解决方案3】:

      所有答案都非常正确和充分。我只是想我应该加两分钱。

      首先,*_once 函数很慢。不要使用它们。

      其次,在我正在开发的应用程序中,我有很多相互依赖的类,而且我并不总是知道页面中需要哪些类。

      而不是创建一个 main.php 页面并包含很多的所有类;显然浪费资源和时间(包含和要求很昂贵),我使用自动加载在页面需要时包含这些文件。 因此,我所做的只是代码,类是自动添加的。

      这也改进了你的代码和目录结构,因为你遵循一个系统来命名你的类和文件。

      只是一个补充。在资源使用和速度方面(需求递减,速度递增):

      Require_once() ;包括一次();要求() ;包括()

      制作包括最好和最快的。

      【讨论】:

      • 谢谢!直到现在我才意识到 require_once 是如此昂贵,我认为它确实是 include_once 的一种更好的替代品。我肯定会通过转向自动加载系列来改变我的包含用法。也感谢您添加您的答案,尽管有其他很好的答案,您为他们增加了价值:)
      • 不,/谢谢/你。顺便说一句,当您使用自动加载时,您甚至不需要 *_once() 对,因为您的脚本不会两次查找同一个类。
      【解决方案4】:

      为工作选择合适的工具。自动加载用于加载尚未使用的未定义类的源代码。因此,您可以实例化目前还不需要文件的类。

      如果您使用类并且希望将文件放在一个中心位置,而不是在不同文件中的一个点,那么这很有意义。

      但是,如果您使用包含和要求来构建一个带有菜单和页脚的网站,那么这是没有意义的。自动加载对此不起作用:

      <html>
        <head><title>Reciepes collection - My Homepage</title></head>
        <body>
      <?php include('header.html'); ?>
      <h1>My Reciepes collection</h1>
      <p>Cooking is one of my favorite hobbies .... (</p>....)
      <?php include('footer.html'); ?>
        </body>
      </html>
      

      如果你使用 requires 来加载函数,你也不能使用 autoload。

      因此,仅因为自动加载在您看来其他人有些喜欢,并不意味着它符合您的需求。

      我个人将它用在我不想处理类需求以及希望能够从模块化目录和库结构中动态加载类的项目中。

      我只使用spl_autoload_register() 注册一个或多个自动加载实现。推荐在 PHP 中注册一个自动加载函数的方法,因为它允许有多个自动加载器。

      【讨论】:

      • 感谢您的广泛回答!
      【解决方案5】:

      Autoload 和 include 系列函数都有自己的位置。

      Autoload 用于延迟加载基于 OO 的脚本(即类和接口)中的模块,并在您使用 new 或静态调用尚未加载的类的方法时调用。这会触发自动加载以运行尝试加载(通常通过包含)相关类或接口的函数。这种方法的优点是类只在需要时才加载。任何没有被使用的类都不会被加载。

      自动加载不能用于加载不是类或接口的程序片段,对于那些您仍然需要包含系列的项目。

      至于必须为每个需要自动加载的脚本添加自动加载功能?在这种情况下,您将自动加载函数放在其自己的文件中,并将其包含在需要自动加载的脚本中。 :)

      【讨论】:

        【解决方案6】:

        我认为这取决于个人喜好。对我来说,自动加载是一种典型的 php 类型的东西 - 一个肮脏的“魔术引号” - 类似 hack,它的存在只是因为他们不费心坐下来编写一个干净的解决方案来解决问题 - 在这种情况下,一个足够的包装系统 + 一个可捕获的 ClassNotFound 异常。在我们解决这个问题之前,我会坚持使用include

        【讨论】:

          【解决方案7】:

          Autoloader 用于延迟初始化。它对 MVC 架构最有效,而不是对到处包含文件并在每个文件中定义数据库连接字符串的网站(这很糟糕)。

          将自动加载与 MVC 框架结合使用可以节省资源并为模块化带来很多好处。由于您不必在类中包含文件,因此您只需在当前所在的控制器中实例化您需要的类。

          基本上,这是一个面向对象的事情。如果您不使用对象方法来构建您的网站并且包含/要求对您有用,那么您不必担心。

          【讨论】:

          • 我确实经常使用 OOP(我的 webapps 现在是 90% OOP),那么我想这绝对适合我 :)。谢谢迈克尔 :)
          【解决方案8】:

          首先:使用spl_autoload_register() 而不是__autoload()

          当您尝试访问一个不存在的类时,会调用自动加载器。使用include(),您只需包含一个类。主要区别在于,使用自动加载器时,仅在确实需要/使用时才包含该类。

          通常您在一个文件中定义一个自动加载器,并在每个请求中包含这个。如果您使用引导程序(意思是:单个文件,它捕获每个请求并将其重定向到适当的目标),则只需要在那里定义自动加载器。所以它不需要在每个文件中定义它。

          【讨论】:

          • 我现在确实更好地理解了引导程序(虽然我不是很喜欢)和这个 __autoload 东西之间的联系。谢谢!
          猜你喜欢
          • 2011-11-03
          • 2012-12-13
          • 1970-01-01
          • 1970-01-01
          • 2016-03-28
          • 1970-01-01
          • 1970-01-01
          • 2016-12-26
          • 1970-01-01
          相关资源
          最近更新 更多