PHP 板


LINE

看板 PHP  RSS
> → wuwt4y: 这样说是没错,只是想说php自己一定会先扫过,他才知道有 > → wuwt4y: 哪些东西 觉得有需要把这几点讲清楚 - PHP 怎麽处理 autoload - PSR-0 / PSR-4 做了什麽 - composer 在干嘛 == PHP 本身怎麽处理 autoload == 基本上,PHP 这个大小姐什麽都没做,都是叫别人做。 PHP 没有自己实作 autoload 这件事 但是 PHP 允许(或说要求)开发者自己定义怎麽自动载入没看过的 PHP class `spl_autoload_register()` 的第一个参数是个 function(精确的说,callable) 当 PHP 看到没看过的 Class 的时候,就先会去呼叫那个 function,然後再检查是不是 Class 已经顺利载入了,如果没看过的 class 还是没看过,PHP 再喷出 fatal error (以前会用 __autoload(),不过那是过去的事了,忘了他吧) 例如这段程式 ``` spl_autoload_register(function($name){ echo "我没有真的载入 `{$name}` 呢啾咪 ^.<\n"; }); $a1 = new A; ``` 实际执行会看到 ``` 我没有真的载入 `A` 呢啾咪 ^.< PHP Fatal error: Uncaught Error: Class 'A' not found in /tmp/b.php:5 ``` 背後发生的事情大概是这样 - 首先透过 spl_autoload_register() 注册了一个 autoload function - PHP 看到了自己不认识的 Class A,呼叫事先注册的 autoload function - 这个 function 印出了一行嘲讽文字 - 然後什麽都没做,Class A 依然没被载入 - PHP 再检查一次是不是 Class A 已经载入,可以 new 他了 - PHP 发现 Class A 还是不存在,於是开骂:「找不到这个 Class 啦,你出老千」 另一个例子 ``` spl_autoload_register(function($name){ echo "PHP 说他找不到 class {$name}\n"; eval("Class {$name} extends stdClass{}"); eval("Class {$name}{$name} extends stdClass{}"); }); $a1 = new A; $a2 = new AA; $a3 = new A; ``` 只会印出一行 ``` PHP 说他找不到 class A ``` 背後的运作大概是这样 - 注册了 autoload function - 看到了不认识的 class A,呼叫 autoload function - 先印出「找不到 class A」字样 - 透过 eval 执行 `Class A extends stdClass{}` ,於是 class A 被定义了 - 透过 eval 执行 `Class AA extends stdClass{}` ,於是 class AA 被定义了 - PHP 现在认识 A 了,於是乖乖 new 了一个 A - PHP 已经认识 AA (载入A的时候一并把 AA 载入了),所以直接 new 了一个 AA - PHP 已经认识 A 了,所以又 new 了一个 A 要注意到 autoloading 机制本身跟 include 没有直接关系。 但实用上通常会把他们连在一起当成 combo 技来用。 例如,你可以注册一个这样子的 autoload function ``` spl_autoload_register(function($className){ include __DIR__ . "/lib/{$className}.php"; }); ``` 这样当你第一次用到某个 class 的时候 PHP 就会自动去 include lib 资料夹里面的同名档案 PHP 不会自动自发的去扫 lib 或 vendor 资料夹里面有什麽东西 他只是照着 autoloader 说的去做而已 可能有人会想「我没写过 autoload function 或 spl_autoload_register 耶?」 贴心小提示:你觉得 composer 做了什麽(笑 == PSR-0 / PSR-4 做了什麽 == PSR-0 / PSR-4 (或者说,所有的 PSR) 其实只是一种道德劝说。 PHP 没有自己支援这些功能,但是 PHP-FIG(可以想成 PHP 国是会议)呼吁大家 写 code 的时候要这麽写。 「如果你要写 autoloader 的话,你要把这些 class 的档案依照我讲的这样放喔」 大概是这种感觉。 虽然听起来有种出一张嘴的感觉,但 PSR 的建议大多很有价值,所以 很多人愿意照着他们的建议来做。 於是 PSR 就从道德劝说变成行规了。 概念上 PSR-0 跟 PSR-4 的 class loader 其实满单纯的,大概可以写成这样 ``` spl_autoload_register(function($className){ $path = findPsr4Path($className); // 依照 class name 判断档案应该在哪里 include $path; // include 那个档案 }); ``` 不过那个 `findPsr4Path()` 自己写起来有稍微麻烦一点... == composer 在干嘛 == 没人会想一直重写 PSR-0 / PSR-4 相容的 autoloader。 这种事当练习很有价值。但作为工作还满麻烦。 所幸 composer 除了「套件管理」以外还有个很重要的功能: 帮你写好符合 PSR-0 / PSR-4 规范的 autoloader 当执行 composer install 的时候,composer 会产生对应的 autoloader 而在执行 ``` include __DIR__ . '/vendor/autoload.php'; ``` 的时候,其实就是在载入 composer 产生出来的 autoloader。 当你安装了一堆套件,里面可能有成百上千个 class,全部载入是十分浪费资源的行为 所以 composer 的 autoloader 只有在某个 class 真的用到的时候,才会去 include 对应的 PHP 档案。 另外是 composer 的 autoloader 不会在载入 class 的时候去扫整个资料夹。 因为 PSR-0 / PSR-4 已经严格定义好 class 名称跟档案名称的对应关系,所以只要 检查对应的那一个档案是否存在就可以了。 不过如果如果你是跑 `composer install -o`, composer 会先扫过 vender 资料夹 里面所有的程式码,然後纪录在 class map (本身是个 array)里面,所以 install 的时间会变长,带来的好处是 autoloader 实际载入 class 的时候,只要检查 class map 里面的档案名称就可以了,每个载入的 class 都能少戳一次硬碟。 有兴趣的人可以观察一下 - vendor/composer/autoload_classmap.php 这个档案在带 -o 跟没有带 -o 的时候的内容变化 -- 顶天立地:爱孩子就要支持萝莉控 http://goo.gl/Bha7e --



※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 114.27.93.85
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/PHP/M.1517062696.A.F70.html ※ 编辑: GALINE (114.27.93.85), 01/27/2018 22:19:49
1F:推 tkdmaf: 我有问题!为什麽php是小姐? 01/27 22:55
小姐比较可爱,如果是个少爷我会想把他头扭下来... ※ 编辑: GALINE (114.27.93.85), 01/27/2018 23:24:44
2F:推 comicat: 推 详细 01/28 01:29
3F:推 wuwt4y: 非常详细,感谢。 01/28 01:42
4F:推 ksks5222: php觉得是妹妹比较好 01/28 01:42
5F:推 Kenqr: 推 01/28 03:57
6F:推 fezexp9987: 推推 01/28 09:19
7F:推 tkdmaf: 可是人家php明明是一只大象………(疑?) 01/28 11:31
8F:→ GALINE: https://i.imgur.com/OcqjqZR.jpg 是耳朵很大的朋友呢 01/28 11:55
9F:→ MOONRAKER: 大象就对 01/28 17:44
10F:推 tkdmaf: 这样也行………I 服了 you 01/28 19:07
11F:推 onininon: 实用推 01/28 22:03
12F:推 shvanta: 好文推 01/29 09:54
13F:推 newton2009: 好想按赞呀 01/29 18:50
14F:推 duke00184: 解说超详细的 01/29 22:39
15F:推 MangoTW: 精辟推 01/30 02:24
16F:推 bakedgrass: 推文的动物朋友让我喷笑 01/30 02:41
17F:推 ddtsatan: 推 01/30 08:34
18F:推 mcmj5566: 推 01/30 09:24
19F:推 TFnight: 推~ 01/31 14:43
20F:推 locklose: 好文推 02/02 18:09
21F:推 nfsong: 推 02/11 01:06
22F:推 lolikung: 感谢大大无私分享 02/16 20:00







like.gif 您可能会有兴趣的文章
icon.png[问题/行为] 猫晚上进房间会不会有憋尿问题
icon.pngRe: [闲聊] 选了错误的女孩成为魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一张
icon.png[心得] EMS高领长版毛衣.墨小楼MC1002
icon.png[分享] 丹龙隔热纸GE55+33+22
icon.png[问题] 清洗洗衣机
icon.png[寻物] 窗台下的空间
icon.png[闲聊] 双极の女神1 木魔爵
icon.png[售车] 新竹 1997 march 1297cc 白色 四门
icon.png[讨论] 能从照片感受到摄影者心情吗
icon.png[狂贺] 贺贺贺贺 贺!岛村卯月!总选举NO.1
icon.png[难过] 羡慕白皮肤的女生
icon.png阅读文章
icon.png[黑特]
icon.png[问题] SBK S1安装於安全帽位置
icon.png[分享] 旧woo100绝版开箱!!
icon.pngRe: [无言] 关於小包卫生纸
icon.png[开箱] E5-2683V3 RX480Strix 快睿C1 简单测试
icon.png[心得] 苍の海贼龙 地狱 执行者16PT
icon.png[售车] 1999年Virage iO 1.8EXi
icon.png[心得] 挑战33 LV10 狮子座pt solo
icon.png[闲聊] 手把手教你不被桶之新手主购教学
icon.png[分享] Civic Type R 量产版官方照无预警流出
icon.png[售车] Golf 4 2.0 银色 自排
icon.png[出售] Graco提篮汽座(有底座)2000元诚可议
icon.png[问题] 请问补牙材质掉了还能再补吗?(台中半年内
icon.png[问题] 44th 单曲 生写竟然都给重复的啊啊!
icon.png[心得] 华南红卡/icash 核卡
icon.png[问题] 拔牙矫正这样正常吗
icon.png[赠送] 老莫高业 初业 102年版
icon.png[情报] 三大行动支付 本季掀战火
icon.png[宝宝] 博客来Amos水蜡笔5/1特价五折
icon.pngRe: [心得] 新鲜人一些面试分享
icon.png[心得] 苍の海贼龙 地狱 麒麟25PT
icon.pngRe: [闲聊] (君の名は。雷慎入) 君名二创漫画翻译
icon.pngRe: [闲聊] OGN中场影片:失踪人口局 (英文字幕)
icon.png[问题] 台湾大哥大4G讯号差
icon.png[出售] [全国]全新千寻侘草LED灯, 水草

请输入看板名称,例如:BuyTogether站内搜寻

TOP