Slide 1

Slide 1 text

Composer ⼊入⾨門與應⽤用

Slide 2

Slide 2 text

Jace Ju ⼤大澤⽉⽊木⼩小鐵 KKBOX Senior Developer @jaceju

Slide 3

Slide 3 text

使⽤用情境

Slide 4

Slide 4 text

曾經有⼀一個開發團隊 A-Team

Slide 5

Slide 5 text

他們⽤用 PHP 開發了⼀一個新專案 A-Team Project

Slide 6

Slide 6 text

Log xdebug Xml Project 這個專案⽤用到了⼀一些 PHP 套件

Slide 7

Slide 7 text

專案開發中,加了⼀一位新⼈人 Newbie A-Team

Slide 8

Slide 8 text

他拿到了專案的原始碼 Source Code Newbie

Slide 9

Slide 9 text

花了很多時間還是沒辦法讓專案執⾏行 Source Code localhost

Slide 10

Slide 10 text

因為他不知道⾃自⼰己還有套件沒安裝 Project Log xdebug Xml

Slide 11

Slide 11 text

這浪費掉很多⼯工作時數

Slide 12

Slide 12 text

Project 所以我們需要知道專案⽤用了哪些套件 Log xdebug Xml

Slide 13

Slide 13 text

Project 套件管理就是幫我們做好這件事 Package Manager Log xdebug Xml

Slide 14

Slide 14 text

有哪些套件管理系統?

Slide 15

Slide 15 text

常⾒見語⾔言的套件管理系統 Node.js Ruby PHP

Slide 16

Slide 16 text

常⾒見語⾔言的套件管理系統 Node.js Ruby PHP npm

Slide 17

Slide 17 text

常⾒見語⾔言的套件管理系統 Node.js Ruby PHP npm gem

Slide 18

Slide 18 text

常⾒見語⾔言的套件管理系統 Node.js Ruby PHP npm gem ??

Slide 19

Slide 19 text

PHP 的套件管理系統

Slide 20

Slide 20 text

PHP 的套件管理系統 PEAR

Slide 21

Slide 21 text

PHP 的套件管理系統 PEAR Pyrus (PEAR2)

Slide 22

Slide 22 text

PHP 的套件管理系統 PEAR Pyrus (PEAR2) Composer

Slide 23

Slide 23 text

為什麼不⽤用 PEAR / Pyrus •套件管理是針對整個系統⽽而⾮非專案 •沒辦法檢查執⾏行環境 •套件審核機制複雜 •設定檔編寫複雜  (XML) •必須使⽤用官⽅方的套件庫或⾃自⾏行架設 •不潮了

Slide 24

Slide 24 text

為什麼要⽤用 Composer •仿  npm  /  gem  的套件相依管理 •針對專案的套件做管理 •可以檢查執⾏行環境 •設定檔編寫簡單  (JSON) •⽀支援⽤用常⾒見的版本控制系統做為 套件下載來源  (SVN  /  GIT)

Slide 25

Slide 25 text

套件相依觀念

Slide 26

Slide 26 text

套件如何組織?

Slide 27

Slide 27 text

套件如何組織? root   package root-package 就是我們的專案

Slide 28

Slide 28 text

套件如何組織? root   package package  1 package  2 package  3 我們的專案相依了三個套件

Slide 29

Slide 29 text

套件如何組織? root   package package  1 package  2 package  3 package  5 package  4 package  6 package 2 則⼜又相依其他套件

Slide 30

Slide 30 text

套件如何組織? root   package package  1 package  2 package  3 package  5 package  4 package  6 在 root package 操作就好 Composer 會協助我們處理剩下的相依問題

Slide 31

Slide 31 text

• composer  的  package  基本上可分為   • application  :應⽤用程式 • library  :函式庫 • application  通常是  root-­‐package • application  通常相依多個  libraries • library  也有可能相依多個  libraries ⼩小提醒

Slide 32

Slide 32 text

安裝 Composer

Slide 33

Slide 33 text

*nix 環境安裝 $ curl -sS https://getcomposer.org/installer | php 下載官⽅方的安裝指令,並透過 PHP 安裝 通常會安裝在專案根⺫⽬目錄下, 安裝好的檔案為 composer.phar

Slide 34

Slide 34 text

*nix 環境安裝 $ curl -sS https://getcomposer.org/installer | php $ php composer.phar 在專案根⺫⽬目錄下,透過 php 來執⾏行 composer.phar

Slide 35

Slide 35 text

*nix 環境安裝 $ curl -sS https://getcomposer.org/installer | php $ php composer.phar $ sudo mv composer.phar /user/local/bin/composer 如果希望讓所有⼈人都可以使⽤用 composer 就將 composer.phar 搬到共⽤用執⾏行⺫⽬目錄, 例如 /usr/local/bin

Slide 36

Slide 36 text

*nix 環境安裝 $ curl -sS https://getcomposer.org/installer | php $ php composer.phar $ sudo mv composer.phar /user/local/bin/composer $ composer 這樣就可以直接執⾏行 composer 若不能執⾏行,則要以 chmod 加⼊入可執⾏行權限

Slide 37

Slide 37 text

Windows 環境安裝 Composer-Setup.exe https://getcomposer.org/Composer-Setup.exe 下載回來執⾏行,⼀一直點下⼀一步就可以

Slide 38

Slide 38 text

Composer 有什麼功能 $ composer list 顯⽰示有哪些指令和選項可⽤用

Slide 39

Slide 39 text

Composer 有什麼功能 $ composer list $ composer help 顯⽰示指令的詳細⽤用法

Slide 40

Slide 40 text

將 Composer 套⽤用到 PHP 專案上

Slide 41

Slide 41 text

初始化 $ cd /path/to/project $ composer init • name • description • authors • minimum-­‐stability • license • require • require-­‐dev

Slide 42

Slide 42 text

name • 格式:  "vendor/package-­‐name" • vendor  :開發者  (公司)  名稱 • package-­‐name  :套件名稱 http://getcomposer.org/doc/04-schema.md#name

Slide 43

Slide 43 text

description • 簡短的套件描述 • 儘量在⼀一⾏行內結束 • ⼀一定要輸⼊入 http://getcomposer.org/doc/04-schema.md#description

Slide 44

Slide 44 text

authors • 格式:  "Name  " • 可以有多個  author  (需⼿手動加⼊入) • 預設抓取  ~/.gitconfig  的設定 http://getcomposer.org/doc/04-schema.md#authors

Slide 45

Slide 45 text

minimum-stability • ⽤用來過濾相依套件穩定度的設定 • 只能⽤用在  root-­‐package • 可設定的值:   (由最穩定到最不穩定的順序)   • stable  (預設) • RC • beta • alpha • dev • 相依的套件之穩定度不可低於設定值 http://getcomposer.org/doc/04-schema.md#minimum-stability

Slide 46

Slide 46 text

license • 指定套件的授權 • 可參考  SPDX  的  identifier  來設定 • Apache-­‐2.0 • BSD-­‐2-­‐Clause • MIT • ... • 私有專案可⽤用  proprietary http://spdx.org/licenses/ http://getcomposer.org/doc/04-schema.md#minimum-stability

Slide 47

Slide 47 text

require • 格式:  "vendor/package-­‐name":  "version" • 指定專案⼀一定要安裝的套件或平台環境 • 如果現存的套件版本不符合  version  條件的話, 就不會安裝任何套件 http://getcomposer.org/doc/04-schema.md#require

Slide 48

Slide 48 text

require-dev • 格式同  require • 主要指定開發⽤用的套件 • 只能⽤用在  root-­‐package http://getcomposer.org/doc/04-schema.md#require-dev

Slide 49

Slide 49 text

{        "name":  "jaceju/first-­‐app",        "description":  "My  First  Application",        "require":  {                "psr/log":  "*"        },        "require-­‐dev":  {                "phpunit/phpunit":  ">=  3.7.0"        },        "license":  "MIT",        "authors":  [                {                        "name":  "Jace  Ju",                        "email":  "[email protected]"                }        ],        "minimum-­‐stability":  "dev" } composer.json

Slide 50

Slide 50 text

• 所有  package  都需要  composer.json • composer.json  的部份屬性只有在   root-­‐package  才有作⽤用 ⼩小提醒

Slide 51

Slide 51 text

套件版本

Slide 52

Slide 52 text

套件版本的規則 http://getcomposer.org/doc/01-basic-usage.md#package-versions • 數字版本以  semantic  versioning  ⽅方式指定 • 版本號寫法分為: • Exact  version  :明確指定版本,例如  "1.0.1" • Range  :指定版本範圍,可⽤用   ">",  ">=",  "<",  "<="  及  "!="  ,以  ","  分隔 例如  ">=  1.0.1"  或  ">=  1.0,  <  2.0" • Wildcard  :萬⽤用字元,例如  "1.0.*"  , 等同於  ">=  1.0,  <  1.1" • Next  Significant  Release  :下⼀一個重要版本; 即版本號倒數第⼆二位數字加  1  ,例如: "~1.2"  ,等同於  ">=  1.2,  <  2.0"  ; "~1.3.1"  ,等同於  ">=  1.3.1,  <  1.4.0"

Slide 53

Slide 53 text

其他規則 http://getcomposer.org/doc/04-schema.md#package-links • 在版本號後⾯面加上  @  ,⾮非必要; 例如:  "1.0.*@beta"  或  "@dev" • 分⽀支表⽰示法:  -­‐  ; 例如:  "dev-­‐master" • 版號表⽰示法:  #  ; 例如:"dev-­‐master#2eb0c..."   或  "1.0.x-­‐dev#abc123"

Slide 54

Slide 54 text

安裝與更新

Slide 55

Slide 55 text

$ composer install Loading  composer  repositories  with  package  information Installing  dependencies  (including  require-­‐dev)    -­‐  Installing  psr/log  (dev-­‐master  fe0936e)        Cloning  fe0936ee26643249e916849d48e3a51d5f5e278b    -­‐  Installing  sebastian/diff  (dev-­‐master  1e09170)        Cloning  1e091702a5a38e6b4c1ba9ca816e3dd343df2e2d  (中略)    -­‐  Installing  phpunit/phpunit  (dev-­‐master  900b501)        Cloning  900b501d8bd3e80da58dc6ff3cc9b01393149717 phpunit/phpunit-­‐mock-­‐objects  suggests  installing  ext-­‐soap  (*) phpunit/phpunit  suggests  installing  phpunit/php-­‐invoker  (>=1.1.0) Writing  lock  file Generating  autoload  files

Slide 56

Slide 56 text

vendor 資料夾 • 套件預設會安裝在  vendor  資料夾 • ⾃自動載⼊入的載⼊入器與快取檔放在 vendor/composer  下

Slide 57

Slide 57 text

全新安裝 (專案負責⼈人) composer.json 第⼀一次全新安裝會參考 composer.json

Slide 58

Slide 58 text

全新安裝 (專案負責⼈人) composer.json Download  list 接下來就會去官⽅方套件庫下載清單

Slide 59

Slide 59 text

全新安裝 (專案負責⼈人) composer.json Download  list Download  package 找到符合版本設定的套件並下載

Slide 60

Slide 60 text

全新安裝 (專案負責⼈人) composer.json Generate composer.lock Download  list Download  package 產⽣生 composer.lock 並記住每個套件在此次安裝時的版本, 這樣⼀一來就不⽤用再從清單裡找符合的版本

Slide 61

Slide 61 text

全新安裝 (專案負責⼈人) composer.json Generate composer.lock Download  list Download  package Generate autoloading  files 將所有相依套件的⾃自動載⼊入設定 加到快取檔案中

Slide 62

Slide 62 text

再次安裝 (其他成員安裝) composer.lock 直接找 composer.lock 記錄的版本

Slide 63

Slide 63 text

再次安裝 (其他成員安裝) composer.lock Download  package 然後從快取或來源中取得套件檔案

Slide 64

Slide 64 text

Generate autoloading  files 再次安裝 (其他成員安裝) composer.lock Download  package 將所有相依套件的⾃自動載⼊入設定 加到快取檔案中

Slide 65

Slide 65 text

$ composer update Loading  composer  repositories  with  package  information Updating  dependencies  (including  require-­‐dev) Generating  autoload  files 類似第⼀一次 install 的動作,但會找符合條件且較新的版本

Slide 66

Slide 66 text

⼩小提醒 • 只有專案負責⼈人才做第⼀一次  install   及之後的  update  (會更動  composer.lock  ) • 其他成員⼀一律使⽤用  install • 第⼀一次  install  及之後的  update  會將所有 相依套件的資訊編寫到  composer.lock  上, 並固定套件版本 • -­‐-­‐prefer-­‐source  :從版本控制下載 • -­‐-­‐prefer-­‐dist  :下載壓縮檔

Slide 67

Slide 67 text

• root-­‐package  的  composer.json  及   composer.lock  要放到版本控制系統 裡,這麼⼀一來其他成員可以直接使⽤用 • library  的  composer.lock  則不要放 到版本控制系統中 • vendor  資料夾不要放到版本控制系統, 應該⽤用  composer  install  安裝 版本控制

Slide 68

Slide 68 text

官⽅方套件庫

Slide 69

Slide 69 text

• 記錄常⾒見的  Open  Source  library  資訊 • 預設  composer  搜尋套件的地⽅方 • 不須審核,⼈人⼈人都可以註冊⾃自⼰己的套件 • 不是實際存放套件內容的地⽅方 packagist.org

Slide 70

Slide 70 text

運作⽅方式 composer Packagist Packages  list Package  content source

Slide 71

Slide 71 text

運作⽅方式 composer Packagist Packages  list Package  content source composer 向 packagist 搜尋套件

Slide 72

Slide 72 text

運作⽅方式 composer Packagist Packages  list Package  content source packagist 回傳套件清單

Slide 73

Slide 73 text

運作⽅方式 composer Packagist Packages  list Package  content source composer 依照套件清單找到來源

Slide 74

Slide 74 text

運作⽅方式 composer Packagist Packages  list Package  content source composer 從來源取回套件內容

Slide 75

Slide 75 text

增加相依套件

Slide 76

Slide 76 text

$ composer require Search  for  a  package  []:  phpunit Found  15  packages  matching  phpunit      [0]  phpunit/phpunit      [1]  phpunit/phpunit-­‐mock-­‐objects      ....    [14]  ezzatron/phpunit-­‐extensions Enter  package  #  to  add,  or  the  complete  package  name   if  it  is  not  listed  []:  0 Enter  the  version  constraint  to  require  []:  >=  3.7.0 Search  for  a  package  []:

Slide 77

Slide 77 text

⼩小提醒 • -­‐-­‐dev  :安裝開發⽤用的套件 • -­‐-­‐no-­‐update  :不直接安裝套件 • composer  show  -­‐i   可以看⺫⽬目前安裝的套件

Slide 78

Slide 78 text

平台環境相依性

Slide 79

Slide 79 text

PHP 平台、 Extension 與系統函式庫 root   package PHP  5.3 ext-­‐xdebug 2.3.3 ext-­‐http 1.7.6 lib-­‐openssl 0.9.8

Slide 80

Slide 80 text

類型 • php  :  PHP  平台 • ext-­‐  :以  PECL  安裝之套件 • lib-­‐  :系統函式庫 • composer  show  -­‐-­‐platform  : 查看⺫⽬目前平台的套件 http://getcomposer.org/doc/02-libraries.md#platform-packages

Slide 81

Slide 81 text

composer.json 寫法 "require":  {        "php":  ">=  5.3",        "ext-­‐xdebug":  ">=  2.3.3",        "ext-­‐http":  ">=  "1.7.6",        "lib-­‐openssl":  ">=  0.9.8" } 需要⼿手動加⼊入

Slide 82

Slide 82 text

套件來源

Slide 83

Slide 83 text

來源類型 Composer VCS PEAR 在  packagist.org  管理的套件  (預設) 以  GIT  /  SVN  /  HG  管理的套件 以  PEAR  管理的套件 http://getcomposer.org/doc/05-repositories.md

Slide 84

Slide 84 text

VCS (GIT) 的 composer.json 寫法 {        "require":  {                "vendor/private-­‐repo":  "dev-­‐master"        },        "repositories":  [                {                        "type":  "vcs",                        "url":    "[email protected]:vendor/private-­‐repo.git"                }        ] } 針對私有的 git 專案採⽤用的寫法

Slide 85

Slide 85 text

• repositories  只作⽤用在  root-­‐package  上 • 所以就算在相依套件的  composer.json  有定義   repositories  ,也不會被  composer  取⽤用 • 必須在  root-­‐package  的  composer.json  中 定義所有的套件來源 ⼩小提醒 http://getcomposer.org/doc/05-repositories.md

Slide 86

Slide 86 text

⾃自動載⼊入

Slide 87

Slide 87 text

• 統⼀一⾃自動載⼊入的⽅方法 • 每個  Package  的⺫⽬目錄結構不⾒見得相同 • 讓  Package  ⾃自⾏行提供載⼊入⽅方式 為什麼 Composer 要提供⾃自動載⼊入?

Slide 88

Slide 88 text

載⼊入類型 PSR-­‐0 classmap files 符合 PSR-0 規範的類別檔案 對應類別名稱的檔案 ⾮非類別但需要⼀一開始就⾃自動載⼊入的檔案 http://getcomposer.org/doc/04-schema.md#autoload

Slide 89

Slide 89 text

composer.json 寫法 {        "autoload":  {                "psr-­‐0":  {                          "Monolog\\":  ["src/",  "lib/"],                        "Zend_":  "library/"                },                "classmap":  [  "classes/",  "Something.php"  ],                "files":  ["src/MyLibrary/functions.php"]        } }

Slide 90

Slide 90 text

loader 寫法 //  Composer  autoloading include  'vendor/autoload.php'; /*  @var  $loader  Composer\Autoload\ClassLoader  */ var_dump(new  Zend\Http\Client());

Slide 91

Slide 91 text

• autoload  採相對於  composer.json  的路徑 • 每個套件只需負責⾃自⼰己的  autoload • 在  root-­‐package  執⾏行: composer  dump-­‐autoload 就會把所有相依套件的  autoload  屬性 編譯到  vendor  ⺫⽬目錄裡的快取檔案 • 載⼊入  loader  之後就不⽤用⾃自⾏行引⽤用類別定義檔 • MVC  Framework  只要在  index.php   載⼊入  loader  即可 ⼩小提醒 http://getcomposer.org/doc/04-schema.md#autoload

Slide 92

Slide 92 text

PEAR-like Style 與 Namespace 並存

Slide 93

Slide 93 text

• Namespace  類別名稱格式:  Vendor\Package\Class • PEAR-­‐like  類別名稱格式:  Vendor_Package_Class • "Vendor\",  "Vendor\Package",   "Vendor_",  "Vendor_Package_"  統稱為  Prefix Namespace vs. PEAR-like

Slide 94

Slide 94 text

以 ZF1 與 ZF2 為例 /path/to/zf1/library/ /Zend/Http/Client.php vendor/zendframework/ zendframework/library/ Zend/Http/Client.php Composer ClassLoader ZF1:  Zend_Http_Client ZF2:  Zend\Http\Client Composer 提供的 ClassLoader ⽤用了 SPL 的⾃自動載⼊入功能 可以幫我們⾃自動載⼊入類別檔案

Slide 95

Slide 95 text

以 ZF1 與 ZF2 為例 /path/to/zf1/library/ /Zend/Http/Client.php vendor/zendframework/ zendframework/library/ Zend/Http/Client.php Composer ClassLoader 'Zend_'  =>  '/path/to/zf1/library' ZF1:  Zend_Http_Client ZF2:  Zend\Http\Client 告訴 ClassLoader ZF1 的類別要去哪裡找 新增 Prefix 的路徑對應

Slide 96

Slide 96 text

以 ZF1 與 ZF2 為例 /path/to/zf1/library/ /Zend/Http/Client.php vendor/zendframework/ zendframework/library/ Zend/Http/Client.php Composer ClassLoader 'Zend_'  =>  '/path/to/zf1/library' ZF1:  Zend_Http_Client ZF2:  Zend\Http\Client

Slide 97

Slide 97 text

以 ZF1 與 ZF2 為例 /path/to/zf1/library/ /Zend/Http/Client.php vendor/zendframework/ zendframework/library/ Zend/Http/Client.php Composer ClassLoader 'Zend_'  =>  '/path/to/zf1/library' ZF1:  Zend_Http_Client ZF2:  Zend\Http\Client

Slide 98

Slide 98 text

以 ZF1 與 ZF2 為例 /path/to/zf1/library/ /Zend/Http/Client.php vendor/zendframework/ zendframework/library/ Zend/Http/Client.php Composer ClassLoader 'Zend_'  =>  '/path/to/zf1/library' ZF1:  Zend_Http_Client ZF2:  Zend\Http\Client PEAR-like 使⽤用 Prefix 定義

Slide 99

Slide 99 text

以 ZF1 與 ZF2 為例 ZF1:  Zend_Http_Client ZF2:  Zend\Http\Client /path/to/zf1/library/ /Zend/Http/Client.php vendor/zendframework/ zendframework/library/ Zend/Http/Client.php Composer ClassLoader 'Zend_'  =>  '/path/to/zf1/library'

Slide 100

Slide 100 text

以 ZF1 與 ZF2 為例 ZF1:  Zend_Http_Client ZF2:  Zend\Http\Client /path/to/zf1/library/ /Zend/Http/Client.php vendor/zendframework/ zendframework/library/ Zend/Http/Client.php Composer ClassLoader 'Zend_'  =>  '/path/to/zf1/library'

Slide 101

Slide 101 text

以 ZF1 與 ZF2 為例 ZF1:  Zend_Http_Client ZF2:  Zend\Http\Client /path/to/zf1/library/ /Zend/Http/Client.php vendor/zendframework/ zendframework/library/ Zend/Http/Client.php Composer ClassLoader 'Zend_'  =>  '/path/to/zf1/library' Namespace 則使⽤用預設 vendor 路徑

Slide 102

Slide 102 text

並存的 loader 寫法 //  定義  ZF1  的  library  路徑 $zf1Path  =  getenv('ZF1_PATH'); if  (!$zf1Path)  {        $zf1Path  =  dirname(__DIR__)  .  '/zf1/library'; } //  ZF1  的路徑需要加到  include_path  給  Zend/Loader.php  ⽤用 $includePath  =  implode(PATH_SEPARATOR,  array(        $zf1Path, )); set_include_path($includePath); //  Composer  autoloading if  (file_exists('vendor/autoload.php'))  {        $loader  =  include  'vendor/autoload.php';        /*  @var  $loader  Composer\Autoload\ClassLoader  */        $loader-­‐>add('Zend_',  $zf1Path); } var_dump(new  Zend_Http_Client()); var_dump(new  Zend\Http\Client());

Slide 103

Slide 103 text

• 預設會以  vendor  下定義的  namespace   來抓取類別定義檔案 • 先試  Namespace  ,再試  PEAR-­‐like  style   • Prefix  有沒有底線不重要 例如  'Zend'  或  'Zend_'  是⼀一樣的;加上底線 主要是為了判斷它是不是  PEAR-­‐like ⼩小提醒

Slide 104

Slide 104 text

Framework Skeleton

Slide 105

Slide 105 text

• Skeleton  是⼀一個將⺫⽬目錄結構和檔案定義好的專案 • 部份  MVC  Framework  直接提供下載包 • 部份  MVC  Framework  ⽤用  generator  產⽣生 • 較新的  MVC  Framework  可透過  Composer  的   create-­‐project  指令來下載 為什麼需要 Skeleton ?

Slide 106

Slide 106 text

Laravel Skeleton $ composer create-project \ laravel/laravel \ --prefer-dist Laravel 直接使⽤用 packagist 上的套件定義 http://laravel.com/docs/installation

Slide 107

Slide 107 text

ZF2 Skeleton $ composer create-project \ --repository-url=\ "https://packages.zendframework.com" \ -s dev \ zendframework/skeleton-application \ path/to/install ZF2 使⽤用 Zend 官⽅方⾃自⼰己的套件系統 http://framework.zend.com/manual/2.2/en/user-guide/skeleton-application.html

Slide 108

Slide 108 text

• Skeleton  通常是⼀一個  root-­‐package • composer  create-­‐project  預設抓取   packagist.org  的套件 • 可以⽤用  satis  架設私⼈人的  package-­‐repository   重點說明 https://github.com/composer/satis

Slide 109

Slide 109 text

Q&A