【发布时间】:2011-04-27 09:15:56
【问题描述】:
PHP 的__autoload() (documentation) 对我来说非常有趣。以下是它的工作原理:
- 你尝试使用一个类,比如
new Toast_Mitten()(footnote1) - 该类尚未加载到内存中。 PHP 缩回拳头,用一个错误来敲你。
- 它暂停了。 “等等,”它说。 “定义了一个
__autoload()函数。”它运行它。 - 在该函数中,您以某种方式将字符串
Toast_Mitten映射到classes/toast_mitten.php并告诉它需要该文件。确实如此。 - 现在该类在内存中,您的程序继续运行。
内存优势:您只加载您需要的类。简洁的好处:您可以停止在任何地方包含这么多文件,而只需包含您的自动加载器。
如果
,事情会变得特别有趣1) 您的__autoload() 有一种从类名中自动确定文件路径和名称的方法。例如,也许您所有的课程都在classes/ 中,而Toast_Mitten 将在classes/toast_mitten.php 中。或者,也许您将类命名为 Animal_Mammal_Weasel,它将在 classes/animal/mammal/animal_mammal_weasel.php 中。
2) 您使用工厂方法来获取您的类的实例。
$Mitten = Mitten::factory('toast');
Mitten::factory 方法可以对自己说:“让我们看看,我是否有一个名为 Toast_Mitten() 的子类?如果有,我将返回它;如果没有,我将返回我自己的一个通用实例- 一个标准手套。哦,看!__autoload() 告诉我有一个特殊的 toast 类。好的,这是一个实例!"
因此,您可以开始在整个代码中使用通用手套,当您需要为 toast 提供特殊行为的那一天到来时,您只需创建该类并 bam! - 您的代码正在使用它。
我的问题有两个:
- (事实)其他语言有类似的结构吗?我看到了Ruby has an autoload,但您似乎必须在给定的脚本中指定您希望在哪些类上使用它。
- (意见) 这也太神奇了吧?如果您最喜欢的语言没有做到这一点,您会认为“嘿,漂亮,我们应该有那个”或“我很高兴语言 X 不是那么马虎?”
1 我向非英语母语人士道歉。这是一个小笑话。据我所知,没有“烤面包手套”这样的东西。如果有,那将是拿起热吐司的手套。也许您在自己的国家/地区有敬酒手套?
【问题讨论】:
-
喜欢使用它,尤其是在与经验不足的开发人员一起工作时......“为什么它有效,包含/要求在哪里”等。
-
@Hannes - “它让新手开发者感到困惑”难道不是不喜欢它的原因吗?
-
在找到关于小玩笑的评论之前,我已经仔细阅读了您对自动加载的描述。在那之前,我一直在阅读 Toast_Kitten 而不是 Toast_Mitten……在我脑海中留下了不同的形象。就我个人而言,我发现自动加载非常有用,尤其是在需要内存的应用程序中,但是如果你有多个第三方库,每个库都使用自己的自动加载器(开发人员并不总是记得在这个案例,然后抱怨库不起作用)请参阅 Gordon 的解决方案评论
-
@Nathan Long 我们在挑战中成长,我认为自己是一个卑鄙的宫城先生,不开玩笑,这是一个很棒的概念,但如果你不熟悉它也会让你很困惑.此外,如果您在这里应用自己的逻辑,应该尝试以一种有意义的方式使用它......例如
class Category_Package_Subpackage_Class=>category/package/subpackage/class.php -
@Hannes - 是的,当我第一次看到它时确实让我感到困惑,但幸运的是有一个像你展示的逻辑模式,所以一旦解释了,就很好了。
标签: php ruby language-agnostic language-features autoload