PHP 板


LINE

看板 PHP  RSS
嗨,大家好。 小弟耳聞composer這個套件管理工具很久了,一直覺得很困難而沒有弄懂它。 最近終於掌握了它一些,也理解了它的創造理念。 分享這個理解的過程,希望對正要入門composer的朋友有幫助。 有寫錯的地方希望各位不吝指正。 感恩<( _ _ )> 網頁好讀版 http://blog.turn.tw/?p=1039 ------------------------------------------------------- 相信有在用PHP的朋友近年來常聽到composer這個套件管理工具。 它到底是做什麼用的?又是為了解決什麼問題而存在呢? 要瞭解這個,得先從歷史開始說起…。 PHP最早讀取套件的方法 初學PHP時,最早會面對的問題之一就是require與include差別何在? require_once與include_once又是什麼? 弄懂這些問題之後,如果不使用framework,直接開發,便常出現類似這樣的code: // whatever.php // 這檔案需要用到幾個類別 require 'xxx_class.php'; require 'yyy_class.php'; require 'zzz_class.php'; // ... 然後在其他檔案會出現: // another.php // 這檔案需要用到幾個類別 require 'yyy_class.php'; require 'zzz_class.php'; // ... 這樣的結果,會產生至少兩個問題: 1. 許多檔案用到同樣幾個class,於是在不同地方都需要載入一次。 2. 當類別多了起來,會顯得很亂、忘記載入時還會出現error。 那麼,不如試試一種懶惰的作法? 寫一個php,負責載入所有類別: // load_everything.php require 'xxx_class.php'; require 'yyy_class.php'; require 'zzz_class.php'; require 'aaa_class.php'; require 'bbb_class.php'; require 'ccc_class.php'; 然後在其他檔案都載入這支檔案即可: require 'load_everything.php' 結果新問題又來了:當類別很多的時候,隨便一個web page都會載入一堆code, 吃爆記憶體,怎麼辦呢? __autoload 為了解決這個問題,PHP 5開始提供__autoload這種俗稱「magic method」的函式。 當你要使用的類別PHP找不到時,它會將類別名稱當成字串丟進這個函式,在PHP噴error投 降之前,做最後的嘗試: // autoload.php function __autoload($classname) { if ($classname === 'xxx.php'){ $filename = "./". $classname .".php"; include_once($filename); } else if ($classname === 'yyy.php'){ $filename = "./other_library/". $classname .".php"; include_once($filename); } else if ($classname === 'zzz.php'){ $filename = "./my_library/". $classname .".php"; include_once($filename); } // blah } 也因為PHP這種「投降前最後一次嘗試」的行為,有時會讓沒注意到的人困惑「奇怪我的 code怎麼跑得動?我根本沒有require啊..」,所以被稱為「magic method」。 如此一來,問題似乎解決了? 可惜還是有小缺點..,就是這個__autoload函式內容會變得很巨大。 以上面的例子來說,一下會去根目錄找、一下會去other_library資料夾、 一下會去my_library資料夾尋找。在整理檔案的時候,顯得有些混亂。 spl_autoload_register 於是PHP從5.1.2開始,多提供了一個函式。 可以多寫幾個autoload函式,然後註冊起來,效果跟直接使用__autoload相同。 現在可以針對不同用途的類別,分批autoload了。 spl_autoload_register('my_library_loader'); spl_autoload_register('other_library_loader'); spl_autoload_register('basic_loader'); function my_library_loader($classname) { $filename = "./my_library/". $classname .".php"; include_once($filename); } function other_library_loader($classname) { $filename = "./other_library/". $classname .".php"; include_once($filename); } function basic_loader($classname) { $filename = "./". $classname .".php"; include_once($filename); } 每個loader內容可以做很多變化。可以多寫判斷式讓它更智慧、可以進行字串處理…。 自動載入類別的問題終於解決了…。 但是光上面的code也有15行,而且在每個project一定都會寫類似的東西。有沒有辦法自動 產生這15行呢? 我的願望很簡單,我告訴你,反正我有my_library資料夾跟other_library資料夾,你自己 進去看到什麼類別就全部載入好不好…? 阿不對,全部載入剛又說效能不好,那你進去看到什麼就全部想辦法用 spl_autoload_register記起來好不好…? 我懶得打15行了,我只想打這幾個字: $please_autoload = array( 'my_library', 'other_library'); 可不可以發明一個工具,去吃$please_autoload這個變數,然後自己想辦法載入一切啊…? ㄟ等等,我連php程式碼都懶得打了,在web領域JSON格式更簡潔。允許我這樣打,好嗎? { "autoload": [ "my_library", "other_library" ] } 然後誰來個工具幫我產生一大串autoload相關的php程式碼吧…,可以嗎? 可以。 Composer登場 首先,裝好composer(本文不介紹如何安裝。) 再來,建立一個composer.json檔,裡面輸入這些: { "autoload": { "classmap": [ "my_library", "other_library" ] } } 比原本希望的多打了一些字,不過差不多。 再來,在terminal輸入 composer install 執行成功之後,你會看到一個vendor資料夾,內含一個autoload.php。 沒錯,跟你夢想的一樣。你只要載入這個檔案: require 'vendor/autoload.php'; 你需要的所有類別,都會在適當的時候、以適當的方式自動載入。 php再也不會噴error說你「類別尚未定義」了! 這vendor資料夾裡面的一切,都只是php code而已,並沒有特別神奇的地方。只要去看 autoload.php的原始碼,就能知道composer到底寫了哪些php code給你。 ㄟ等等,我寫的類別都放在my_library裡面了,other_library都是網路上copy下來的現成 類別。我想要用Google API的Client類別、Doctrine資料庫管理抽象層類別、還有 guzzlehttp的發送request類別。 我連去下載這些檔案、然後丟進這個資料夾都懶得做了,我根本不想手動建立 other_library這個資料夾。composer真那麼神…不如連下載都幫我自動下載?可以嗎? 可以。 查詢一下那幾個套件在「https://packagist.org/」的名稱、還有你需要的版本號。 把剛剛的composer.json改成這樣: { "require": { "google/apiclient": "1.0.*@beta", "guzzlehttp/guzzle": "~4.0", "doctrine/dbal": "~2.4" }, "autoload": { "classmap": [ "my_library" ] } } 然後’composer install’指令除了自動載入你的類別之外、 還會自動下載你需要的類別、然後自動載入它們。 一樣require ‘vendor/autoload.php’就可以了。 composer實在是太棒了。 --



※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 36.229.213.31
※ 文章網址: http://webptt.com/m.aspx?n=bbs/PHP/M.1416476586.A.C3E.html
1F:推 crossdunk: 推 11/20 17:45
2F:推 onininon: 有看有推 11/20 17:56
3F:推 rickysu: 推 11/20 18:04
4F:推 lucky1lk: 不錯 11/20 18:48
5F:推 KawasumiMai: 目前還停留在require一個all_require的階段XDD 11/20 19:08
6F:推 martin77: 推, 說明得很棒 11/20 23:38
7F:推 ga013077: 推 11/21 07:22
8F:推 alex0914: 有懂有推 11/21 22:48
9F:推 xdraculax: 推 雖然我懶得安裝寧可自己寫@@ 11/22 00:48
10F:推 aoeeoak: 有看有懂,很喜歡這種風格的教學文 11/22 02:03
11F:推 windwofswold: 下完composer指令後可以去泡茶 12/01 01:58
12F:推 ottokang: Composer好用,給推 12/08 09:50
13F:→ Laravel: 推 12/09 16:14
14F:→ serinasky: 推 02/23 02:17
15F:推 theren: 有懂有推 09/19 12:05







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

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

TOP