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/m.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燈, 水草

請輸入看板名稱,例如:Gossiping站內搜尋

TOP