Upgrade to Pro — share decks privately, control downloads, hide ads and more …

phpconJapan2023 わたし、Composerが気になります!

kero kero
October 08, 2023
740

phpconJapan2023 わたし、Composerが気になります!

kero kero

October 08, 2023
Tweet

Transcript

  1. 22卒 自称青魔道士系エンジニア 
 (株)インフィニットループ 
 kerokero ・北海道の 札幌 生まれ、札幌 育ち
 ・水産→数学(非情報系)→2022年4月にIL入社

      ・最近の趣味は 絵を描く ことと ストリートファイター6 です
 ・担当領域は サーバーサイドのアプリ・インフラ実装(PHP, AWSなど) です 

  2. ・パッケージって何ですか?
 ・公式の処理系である php-src に機能が詰まってると考えてよさ そう
 
   ・変数や定数、関数、for文やif文など
 
 
 ・php-src

    にない機能も使いたい
 
   ・ユニットテストや静的解析、便利なフレームワークなど
 ↑ これがパッケージということ
  3. ・パッケージって何ですか?
 ≡
 ・モジュール は関数、変数などのコードの基本単位
 
 ・パッケージ はモジュールの集合体
 
 ・ライブラリ はモジュール、パッケージの集合体


    ライブラリ 
 パッケージ A
 パッケージ B
 モジュール
 ← 大まかなイメージ ※言語や人によって流儀が違う可能性がある
  4. ・パッケージって何ですか?
 ・なので、composer が管理している パッケージ というのは、広義の意味ではモジュール・ パッケージ・ライブラリのどれかであると考えてよさそう 
 
 ・composer が管理している

    パッケージ は php-src の外部から仕入れてくるものと考え てよさそう
 
   ・phpunit や guzzle , Laravel など
 
 ・ざっくりと パッケージは 外部からインストール するものと考えてよさそう
 
 

  5. ・パッケージって何ですか?
 ・なので、composer が管理している パッケージ というのは、広義の意味ではモジュール・ パッケージ・ライブラリのどれかであると考えてよさそう 
 
 ・composer が管理している

    パッケージ は php-src の外部から仕入れてくるものと考え てよさそう
 
   ・phpunit や guzzle , Laravel など
 
 ・ざっくりと パッケージは 外部からインストール するものと考えてよさそう
 
        ↑ よっしゃー、とりあえず phpunit をインストールしてみるぜ  > 
 猫

  6. ・パッケージって何ですか?
 ・PHPUnit
 PHPUnit に必要なすべての 依存ファイル をひとつのファイル にまとめた PHP アーカイブ (PHAR)

    を配布します
 
 
 あるいは、Composer を使って PHPUnit やその 依存ファイ ル をダウンロードしてインストールすることもできます。

  7. ・パッケージって何ですか?
 ・PHPUnit
 PHPUnit に必要なすべての 依存ファイル をひとつのファイル にまとめた PHP アーカイブ (PHAR)

    を配布します
 
 
 あるいは、Composer を使って PHPUnit やその 依存ファイ ル をダウンロードしてインストールすることもできます。
 依存ファイル
  8. ・依存って何ですか?
 ・PHPUnit
 PHPUnit に必要なすべての 依存ファイル をひとつのファイル にまとめた PHP アーカイブ (PHAR)

    を配布します
 
 
 あるいは、Composer を使って PHPUnit やその 依存ファイ ル をダウンロードしてインストールすることもできます。
 ちょっとスライドを戻って…… 
 ↑↑ こっちの話

  9. ・依存って何ですか?
 ・ひとまず前提知識として
 
   ・composer 自身も1つの パッケージ であることは分かる
 
     ・php-src に含まれている機能ではないということ


    
   ・composer をインストールしてくる必要がある
     
     ・とりあえずdockerコンテナでcomposer環境を試す

  10. ・依存って何ですか?
 ・ひとまず前提知識として
 
   ・composer 自身も1つの パッケージ であることは分かる
 
     ・php-src に含まれている機能ではないということ


    
   ・composer をインストールしてくる必要がある
     
     ・とりあえずdockerコンテナでcomposer環境を試す
 頭の中に思い浮かべてみよう >
  11. ・依存って何ですか?
 ・composer を実行できる環境を用意
 . ├ Dockerfile ├ docker-compose.yml └ composer.json

    # New! { "require-dev": { "phpunit/phpunit": "*" } } ・phpunit について書かれている......?
 tree
 composer.json

  12. ・依存って何ですか?
 ・composer を実行できる環境を用意
 . ├ Dockerfile ├ docker-compose.yml └ composer.json

    # New! { "require-dev": { "phpunit/phpunit": "*" } } ・phpunit について書かれている......?
 tree
 composer.json
 ・この composer.json というものは、Composer がインストールしてくる対象を決定している「何 らかの定義」が書かれているファイルとして存在しています

  13. ・依存って何ですか?
 ・composer を実行できる環境を用意
 . ├ Dockerfile ├ docker-compose.yml └ composer.json

    # New! { "require-dev": { "phpunit/phpunit": "*" } } ・phpunit について書かれている......?
 tree
 composer.json
 ・この composer.json というものは、Composer がインストールしてくる対象を決定している「何 らかの定義」が書かれているファイルとして存在しています
 
 
 ・ここに欲しいパッケージとそのバージョンを指定してあげるとよさそう

  14. ・依存って何ですか?
 ・composer を実行できる環境を用意
 . ├ Dockerfile ├ docker-compose.yml └ composer.json

    # New! { "require-dev": { "phpunit/phpunit": "*" } } ・phpunit について書かれている......?
 tree
 composer.json
 ・この composer.json というものは、Composer がインストールしてくる対象を決定している「何 らかの定義」が書かれているファイルとして存在しています
 
 
 ・ここに欲しいパッケージとそのバージョンを指定してあげるとよさそう
 
 
 ・jsonの中身は、インストールするパッケージ : バージョン という書式
 "phpunit/phpunit": "*"
  15. ・依存って何ですか?
 . ├ Dockerfile ├ docker-compose.yml └ composer.json # New!

    ・composer を実行できる環境を用意
 tree
 ・インストール対象を指定できたので、この状態でインストールを実行するとパッケー ジを取得できそうな気がしますよね?
 

  16. ・依存って何ですか?
 . ├ Dockerfile ├ docker-compose.yml └ composer.json # New!

    ・composer を実行できる環境を用意
 tree
 ・インストール対象を指定できたので、この状態でインストールを実行するとパッケー ジを取得できそうな気がしますよね?
 
 
 ・というわけで、この状態でdockerコンテナの中で composer install を実行
 

  17. ・依存って何ですか?
 . ├ Dockerfile ├ docker-compose.yml ├ composer.json ├ composer.lock

    # New! └ vendor # New! ├ bin ├ composer ├ myclabs ├ nikic ├ phar-io ├ phpunit ├ sebastian └ theseer ・すると、左記のような構成に変化します 

  18. ・依存って何ですか?
 . ├ Dockerfile ├ docker-compose.yml ├ composer.json ├ composer.lock

    # New! └ vendor # New! ├ bin ├ composer ├ myclabs ├ nikic ├ phar-io ├ phpunit ├ sebastian └ theseer ・すると、左記のような構成に変化します 
 
 ・composer install によって次の2つが増えた 
 
   ・composer.lock
 
   ・vendor ディレクトリ 

  19. ・依存って何ですか?
 . ├ Dockerfile ├ docker-compose.yml ├ composer.json ├ composer.lock

    # New! └ vendor # New! ├ bin ├ composer ├ myclabs ├ nikic ├ phar-io ├ phpunit ├ sebastian └ theseer ・すると、左記のような構成に変化します。 
 
 ・composer install によって次の2つが増えた 
 
   ・composer.lock
 
   ・vendor ディレクトリ 
 
 ・vendor の中に phpunit がある‼
 これ

  20. ・依存って何ですか?
 . ├ Dockerfile ├ docker-compose.yml ├ composer.json ├ composer.lock

    # New! └ vendor # New! ├ bin ├ composer  ├ myclabs <- ? ├ nikic <- ? ├ phar-io <- ? ├ phpunit ├ sebastian <- ? └ theseer <- ? ・すると、左記のような構成に変化します。 
 
 ・composer install によって次の2つが増えた 
 
   ・composer.lock
 
   ・vendor ディレクトリ 
 
 ・vendor の中に phpunit がある‼
 
 ・とはいえ、他にもなんか色々ある
 これ

  21. ・依存って何ですか?
 └ vendor └ phpunit ├ php-code-coverage ├ php-file-iterator ├

    php-invoker ├ php-text-template ├ php-timer └ phpunit   ・vendor/phpunit を見てみると…… 

  22. ・依存って何ですか?
 └ vendor └ phpunit ├ php-code-coverage ├ php-file-iterator ├

    php-invoker ├ php-text-template ├ php-timer └ phpunit   ・vendor/phpunit を見てみると…… 
 
 ・さらに phpunit があった
 これ

  23. ・依存って何ですか?
 └ vendor └ phpunit └ phpunit ├ schema ├

    src ├ .phpstorm.meta.php ├ ChangeLog-10.1.md ├ composer.json ├ LICENCE ├ phpunit ├ phpunit.xsd ├ README.md └ SECURITY.md ・vendor/phpunit を見てみると…… 
 
 ・さらに phpunit があった
 
 ・というわけで中を見てみると……

  24. ・依存って何ですか?
 └ vendor └ phpunit └ phpunit ├ schema ├

    src ├ .phpstorm.meta.php ├ ChangeLog-10.1.md ├ composer.json ├ LICENCE ├ phpunit ├ phpunit.xsd ├ README.md └ SECURITY.md ・vendor/phpunit を見てみると…… 
 
 ・さらに phpunit があった
 
 ・というわけで中を見てみると……
 
 ・ここにも composer.json があった
 これ

  25. ・依存って何ですか?
 "require": { "php": ">=8.1", "ext-dom": "*", "ext-json": "*", "ext-libxml":

    "*", "ext-mbstring": "*", "ext-xml": "*", "ext-xmlwriter": "*", "myclabs/deep-copy": "^1.10.1", "phar-io/manifest": "^2.0.3", "phar-io/version": "^3.0.2", "phpunit/php-code-coverage": "^10.1.1", "phpunit/php-file-iterator": "^4.0", "phpunit/php-invoker": "^4.0", "phpunit/php-text-template": "^3.0", "phpunit/php-timer": "^6.0", "sebastian/cli-parser": "^2.0", "sebastian/code-unit": "^2.0", "sebastian/comparator": "^5.0", "sebastian/diff": "^5.0", "sebastian/environment": "^6.0", "sebastian/exporter": "^5.0", "sebastian/global-state": "^6.0", "sebastian/object-enumerator": "^5.0", "sebastian/recursion-context": "^5.0", "sebastian/type": "^4.0", "sebastian/version": "^4.0" }, ・vendor/phpunit/phpunit/composer.json

  26. ・依存って何ですか?
 "require": { "php": ">=8.1", "ext-dom": "*", "ext-json": "*", "ext-libxml":

    "*", "ext-mbstring": "*", "ext-xml": "*", "ext-xmlwriter": "*", "myclabs/deep-copy": "^1.10.1", "phar-io/manifest": "^2.0.3", "phar-io/version": "^3.0.2", "phpunit/php-code-coverage": "^10.1.1", "phpunit/php-file-iterator": "^4.0", "phpunit/php-invoker": "^4.0", "phpunit/php-text-template": "^3.0", "phpunit/php-timer": "^6.0", "sebastian/cli-parser": "^2.0", "sebastian/code-unit": "^2.0", "sebastian/comparator": "^5.0", "sebastian/diff": "^5.0", "sebastian/environment": "^6.0", "sebastian/exporter": "^5.0", "sebastian/global-state": "^6.0", "sebastian/object-enumerator": "^5.0", "sebastian/recursion-context": "^5.0", "sebastian/type": "^4.0", "sebastian/version": "^4.0" }, ・vendor/phpunit/phpunit/composer.json
 
 ・myclubs, phar-io, sebastian がある
 
   ・これらは vendor に入ってた

  27. ・依存って何ですか?
 "require": { "php": ">=8.1", "ext-dom": "*", "ext-json": "*", "ext-libxml":

    "*", "ext-mbstring": "*", "ext-xml": "*", "ext-xmlwriter": "*", "myclabs/deep-copy": "^1.10.1", "phar-io/manifest": "^2.0.3", "phar-io/version": "^3.0.2", "phpunit/php-code-coverage": "^10.1.1", "phpunit/php-file-iterator": "^4.0", "phpunit/php-invoker": "^4.0", "phpunit/php-text-template": "^3.0", "phpunit/php-timer": "^6.0", "sebastian/cli-parser": "^2.0", "sebastian/code-unit": "^2.0", "sebastian/comparator": "^5.0", "sebastian/diff": "^5.0", "sebastian/environment": "^6.0", "sebastian/exporter": "^5.0", "sebastian/global-state": "^6.0", "sebastian/object-enumerator": "^5.0", "sebastian/recursion-context": "^5.0", "sebastian/type": "^4.0", "sebastian/version": "^4.0" }, ・vendor/phpunit/phpunit/composer.json
 
 ・myclubs, phar-io, sebastian がある
 
   ・これらは vendor に入ってた
 
 ・確かに入ってる……

  28. ・依存って何ですか?
 ここまでの流れを整理すると
 
 ・composer を実行できる環境を用意した 
 
 ・composer.json にインストールするものを定義 (phpunit)

    
 
 ・composer install すると、composer.lock と vendor ディレクトリができた 
 
 ・vendor の中には phpunit を含むいくつかのパッケージが入ってた 
 
 

  29. ・依存って何ですか?
 ここまでの流れを整理すると
 
 ・composer を実行できる環境を用意した 
 
 ・composer.json にインストールするものを定義 (phpunit)

    
 
 ・composer install すると、composer.lock と vendor ディレクトリができた 
 
 ・vendor の中には phpunit を含むいくつかのパッケージが入ってた 
 
 ・phpunit の中には更に別の composer.json が入ってた 
 
 

  30. ・依存って何ですか?
 ここまでの流れを整理すると
 
 ・composer を実行できる環境を用意した 
 
 ・composer.json にインストールするものを定義 (phpunit)

    
 
 ・composer install すると、composer.lock と vendor ディレクトリができた 
 
 ・vendor の中には phpunit を含むいくつかのパッケージが入ってた 
 
 ・phpunit の中には更に別の composer.json が入ってた 
 
 ・その中には vendor に入ってた phpunit 以外のパッケージが指定されていた 
 
   ・myclubs, phar-io, sebastian があった
 

  31. ・依存って何ですか?
 ここまでの流れを整理すると
 
 ・composer を実行できる環境を用意した 
 
 ・composer.json にインストールするものを定義 (phpunit)

    
 
 ・composer install すると、composer.lock と vendor ディレクトリができた 
 
 ・vendor の中には phpunit を含むいくつかのパッケージが入ってた 
 
 ・phpunit の中には更に別の composer.json が入ってた 
 
 ・その中には vendor に入ってた phpunit 以外のパッケージが指定されていた 
 
   ・myclubs, phar-io, sebastian があった
 
 ここに注目 >
  32. ・依存って何ですか?
 つまり、
 
  composer.json で指定したパッケージの中で、
 
  別の composer.json が更に他のパッケージを指定していた 


    
 ということ
 phpunit を使うためには、 myclubs, phar-io, sebastian が必要で、これらを使うためには……  > → composer install を実行すると、composer.json で定義されたパッケー ジが再帰的にインストールされていくということ 

  33. ・依存って何ですか?
 すごく雑に説明すると……
 
 ・composer.json に A を追加
 
         ↓
 


    ・A の中の composer.json には B がある 
 
         ↓
 
 ・B の中の composer.json には C がある 

  34. ・依存って何ですか?
 すごく雑に説明すると……
 
 ・composer.json に A を追加
 
         ↓
 


    ・A の中の composer.json には B がある 
 
         ↓
 
 ・B の中の composer.json には C がある  →  vendor に C を追加  

  35. ・依存って何ですか?
 すごく雑に説明すると……
 
 ・composer.json に A を追加 
 
         ↓

    
 
 ・A の中の composer.json には B がある     vendor に B を追加 
 
         ↓                   ↑ 
 
 ・B の中の composer.json には C がある  →  vendor に C を追加  

  36. ・依存って何ですか?
 すごく雑に説明すると……
 
 ・composer.json に A を追加 vendor に A

    を追加 
 
         ↓ ↑ 
 
 ・A の中の composer.json には B がある     vendor に B を追加 
 
         ↓                   ↑ 
 
 ・B の中の composer.json には C がある  →  vendor に C を追加  

  37. ・依存って何ですか?
 すごく雑に説明すると…… vendor の中に A, B, C が用意される!
 
 ・composer.json

    に A を追加 vendor に A を追加 
 
         ↓ ↑ 
 
 ・A の中の composer.json には B がある     vendor に B を追加 
 
         ↓                   ↑ 
 
 ・B の中の composer.json には C がある  →  vendor に C を追加  
 だいたいこんなイメージ >
  38. ・依存って何ですか?
 ここで、冒頭の依存とは何かという話に戻ると……
 
 ・Aを使うにはBが必要で、Bを使うにはCが必要な時 
 
   ・A ← B ←

    C という依存関係が存在する 
 
 ・Aを composer.json で指定するだけで、↑の依存関係を自動で解決しつつインストールし てくれるのが composer ということ

  39. ・依存って何ですか?
 ここで、冒頭の依存とは何かという話に戻ると……
 
 ・Aを使うにはBが必要で、Bを使うにはCが必要な時 
 
   ・A ← B ←

    C という依存関係が存在する 
 
 ・Aを composer.json で指定するだけで、↑の依存関係を自動で解決しつつインストールし てくれるのが composer ということ
 でもさぁ、
 composer 使えるように設定する方が面倒くさくない?

  40. ・依存って何ですか?
 ここで、冒頭の依存とは何かという話に戻ると……
 
 ・Aを使うにはBが必要で、Bを使うにはCが必要な時 
 
   ・A ← B ←

    C という依存関係が存在する 
 
 ・Aを composer.json で指定するだけで、↑の依存関係を自動で解決しつつインストールし てくれるのが composer ということ
 でもさぁ、
 composer 使えるように設定する方が面倒くさくない?
 ↑  別の例を考えてみよう
  41. ・依存って何ですか?
 ・AがBとEに依存する
 
 ・BはCとFに依存する
 
 ・CはDとEとGに依存する
 
 ・DはFとHに依存する
 
 ・Eは特に他のパッケージに依存しない

    
 
 ・FはIに依存する
 
 ・JはEに依存する
 ・それぞれのパッケージは 指定されたバージョン の範囲で定 義されている ・依存するパッケージが 該当のバージョンで動く かどうかは要 別途確認 ・なるべく新しいかつ安定しているバージョンのものを使いた い ・あっ、D のバージョンはちょっと古いやつでよろしく ......  >

  42. ・依存って何ですか?
 ・AがBとEに依存する
 
 ・BはCとFに依存する
 
 ・CはDとEとGに依存する
 
 ・DはFとHに依存する
 
 ・Eは特に他のパッケージに依存しない

    
 
 ・FはIに依存する
 
 ・JはEに依存する
 ・それぞれのパッケージは 指定されたバージョン の範囲で定 義されている ・依存するパッケージが 該当のバージョンで動く かどうかは要 別途確認 ・なるべく新しいかつ安定しているバージョンのものを使いた い ・D のバージョンはちょっと古いやつで ・それぞれのパッケージは 指定されたバージョン の範囲で定 義されている ・依存するパッケージが 該当のバージョンで動く かどうかは要 別途確認 ・なるべく新しいかつ安定しているバージョンのものを使いた い ・あっ、D のバージョンはちょっと古いやつでよろしく
  43. ・管理ツールって何ですか?
 ここまでの流れを整理すると
 
 ・composer を実行できる環境を用意した 
 
 ・composer.json にインストールするものを定義 (phpunit)

    
 
 ・composer install すると、composer.lock と vendor ディレクトリができた 
 
 ・vendor の中には phpunit を含むいくつかのパッケージが入ってた 
 
 ・phpunit の中には更に別の composer.json が入ってた 
 
 ・その中には vendor に入ってた phpunit 以外のパッケージが指定されていた 
 
   ・myclubs, phar-io, sebastian があった
 
 少し前のスライドに戻ってみると……

  44. ・管理ツールって何ですか?
 ここまでの流れを整理すると
 
 ・composer を実行できる環境を用意した 
 
 ・composer.json にインストールするものを定義 (phpunit)

    
 
 ・composer install すると、composer.lock と vendor ディレクトリができた
 
 ・vendor の中には phpunit を含むいくつかのパッケージが入ってた 
 
 ・phpunit の中には更に別の composer.json が入ってた 
 
 ・その中には vendor に入ってた phpunit 以外のパッケージが指定されていた 
 
   ・myclubs, phar-io, sebastian があった
 
 少し前のスライドに戻ってみると……
 ↑ これについて特に言及されていなかった…… 

  45. ・管理ツールって何ですか?
 composer.lock の中を見てみると以下のようなことが書いてある 
 
 "_readme": [ "This file locks

    the dependencies of your project to a known state", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ],
  46. ・管理ツールって何ですか?
 composer.lock の中を見てみると以下のようなことが書いてある 
 
 "_readme": [ "This file locks

    the dependencies of your project to a known state", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], 「このファイルは、プロジェクトの 依存関係を既知の状態にロック します、このファイルは自動生成されます」 

  47. ・管理ツールって何ですか?
 依存関係を既知の状態にロック しますとは......
 
 「このファイルが存在する状態で composer install を実行すると composer.json ではなくcomposer.lock

    の方を参照してパッケージをインストールしてくる」ということ
 というわけで、実験してみる
 Better Than Nothing ...... >
  48. ・管理ツールって何ですか?
 実際に、composer.json を以下の様に変更して再度 composer install を実行してみましょう
 { "require-dev": { "phpunit/phpunit":

    "*", "guzzlehttp/guzzle": "^6.3" } } 
 
 すると、これまでの流れだとおそらく guzzleとguzzleの依存パッケージ に関するディレクトリが vendor直下に追加されることが予想できます 

  49. ・管理ツールって何ですか?
 実際に、composer.json を以下の様に変更して再度 composer install を実行してみましょう
 { "require-dev": { "phpunit/phpunit":

    "*", "guzzlehttp/guzzle": "^6.3" } } 
 
 すると、これまでの流れだとおそらく guzzleとguzzleの依存パッケージ に関するディレクトリが vendor直下に追加されることが予想できます 
 phpunit の時と同じはず >
  50. ・管理ツールって何ですか?
 しかし、実際に続行してみると以下のようなエラー文が出て失敗します。
 
 Installing dependencies from lock file (including require-dev)

    Verifying lock file contents can be installed on current platform. Warning: The lock file is not up to date with the latest changes in composer.json. You may be getting outdated dependencies. It is recommended that you run `composer update` or `composer update <package name>`. - Required (in require-dev) package "guzzlehttp/guzzle" is not present in the lock file.
  51. ・管理ツールって何ですか?
 しかし、実際に続行してみると以下のようなエラー文が出て失敗します。
 
 Installing dependencies from lock file (including require-dev)

    Verifying lock file contents can be installed on current platform. Warning: The lock file is not up to date with the latest changes in composer.json. You may be getting outdated dependencies. It is recommended that you run `composer update` or `composer update <package name>`. - Required (in require-dev) package "guzzlehttp/guzzle" is not present in the lock file. 「composer.json と composer.lock で定義されている内容が違うぞ」 

  52. ・管理ツールって何ですか?
 しかし、実際に続行してみると以下のようなエラー文が出て失敗します。
 
 Installing dependencies from lock file (including require-dev)

    Verifying lock file contents can be installed on current platform. Warning: The lock file is not up to date with the latest changes in composer.json. You may be getting outdated dependencies. It is recommended that you run `composer update` or `composer update <package name>`. - Required (in require-dev) package "guzzlehttp/guzzle" is not present in the lock file. 「composer.json と composer.lock で定義されている内容が違うぞ」 
 これが、プロジェクトの依存関係を既知の状態にロックしている状態というわけです。

  53. ・管理ツールって何ですか?
 しかし、実際に続行してみると以下のようなエラー文が出て失敗します。
 
 Installing dependencies from lock file (including require-dev)

    Verifying lock file contents can be installed on current platform. Warning: The lock file is not up to date with the latest changes in composer.json. You may be getting outdated dependencies. It is recommended that you run `composer update` or `composer update <package name>`. - Required (in require-dev) package "guzzlehttp/guzzle" is not present in the lock file. 「composer.json と composer.lock で定義されている内容が違うぞ」 
 これが、プロジェクトの依存関係を既知の状態にロックしている状態というわけです。
 つまり、composer.lockファイルというのは
 「現在のvendorの中身を正確に定義して固定しているもの」という理解ができます。

  54. ・管理ツールって何ですか?
 しかし、実際に続行してみると以下のようなエラー文が出て失敗します。
 
 Installing dependencies from lock file (including require-dev)

    Verifying lock file contents can be installed on current platform. Warning: The lock file is not up to date with the latest changes in composer.json. You may be getting outdated dependencies. It is recommended that you run `composer update` or `composer update <package name>`. - Required (in require-dev) package "guzzlehttp/guzzle" is not present in the lock file. 「composer.json と composer.lock で定義されている内容が違うぞ」 
 これが、プロジェクトの依存関係を既知の状態にロックしている状態というわけです。
 つまり、composer.lockファイルというのは
 「現在のvendorの中身を正確に定義して固定しているもの」という理解ができます。
 composer installを実行した後で、lockファイルやvendorの中身を弄ったりしない限りはvendorの 中身はlockファイルに描かれているもので保証されているというわけです。

  55. ・管理ツールって何ですか?
 Installing dependencies from lock file (including require-dev) Verifying lock

    file contents can be installed on current platform. Warning: The lock file is not up to date with the latest changes in composer.json. You may be getting outdated dependencies. It is recommended that you run `composer update` or `composer update <package name>`. - Required (in require-dev) package "guzzlehttp/guzzle" is not present in the lock file. というわけでここに書かれている通り、
 composer updateを実行してcomposer.lockの内容を上書きしてみましょう。
 

  56. ・管理ツールって何ですか?
 . └ vendor ├ bin ├ composer ├ guzzlehttp

    ├ myclabs ├ nikic ├ phar-io ├ phpunit ├ psr ├ ralouphie ├ sebastian ├ sumfony └ theseer ・すると、左記のような構成に変化します 
 

  57. ・管理ツールって何ですか?
 . └ vendor ├ bin ├ composer ├ guzzlehttp

    <- New! ├ myclabs ├ nikic ├ phar-io ├ phpunit ├ psr <- New! ├ ralouphie <- New! ├ sebastian ├ sumfony <- New! └ theseer ・すると、左記のような構成に変化します 
 
 ・たしかに、guzzlehttpと依存パッケージがいくつか追 加されている

  58. ・管理ツールって何ですか?
 . └ vendor ├ bin ├ composer ├ guzzlehttp

    <- New! ├ myclabs ├ nikic ├ phar-io ├ phpunit ├ psr <- New! ├ ralouphie <- New! ├ sebastian ├ sumfony <- New! └ theseer ・すると、左記のような構成に変化します 
 
 ・たしかに、guzzlehttpと依存パッケージがいくつか追 加されている
 
 ・この状態でvendorディレクトリを削除し、 
 composer install を行ってみると 同じ状況が再現され ることも確認

  59. ・管理ツールって何ですか?
 なので、composer.json, composer.lock の役割についてまとめると以下の様になります 
 
 ・初回の composer install では

    .json を参照
 
 ・二回目以降は .lock を参照
 
 上記に関しては嬉しいこととしては次のような点があります

  60. ・管理ツールって何ですか?
 なので、composer.json, composer.lock の役割についてまとめると以下の様になります 
 
 ・初回の composer install では

    .json を参照
 
 ・二回目以降は .lock を参照
 
 上記に関しては嬉しいこととしては次のような点があります
 
 ・チーム開発などでパッケージの依存関係に関する情報を共有したい場合
 
 ・誰かが用意した composer.lock を git等で管理し、各自の環境で composer install することにより共通の開発環境を手軽に用意可能

  61. ・まだ何かあるような気がします! ~ require ~
 とはいえ、追加でパッケージが欲しい時に、composer.jsonに必要なパッケージを書き込んで composer updateするという 手順を取りたくないとき もあると思います
 
 それはどんなときかというと、


    
 「追加パッケージに関係のないパッケージのバージョンを動かしたくない」
 
 等の場合が一例としてあります
 
 
 そこで使うコマンドが、 composer require <パッケージ名> 

  62. ・まだ何かあるような気がします! ~ require ~
 試しに、
 composer require monolog/monolog 
 を実行すると、composer.json に

    monolog に関する定義が追加されていることが確認できます 
 
 
 { "require-dev": { "phpunit/phpunit": "*", "guzzlehttp/guzzle": "^6.3" }, "require": { "monolog/monolog": "^3.3" } }
  63. ・まだ何かあるような気がします! ~ require ~
 { "require-dev": { "phpunit/phpunit": "*", "guzzlehttp/guzzle": "^6.3"

    }, "require": { "monolog/monolog": "^3.3" } } ・ここで “require” となっているのは、本番環境で必 要とされるパッケージ群を定義している 
 
 
 ・” require-dev “ と書いてある方は開発環境で必要 となるパッケージの定義 

  64. ・まだ何かあるような気がします! ~ require ~
 { "require-dev": { "phpunit/phpunit": "*", "guzzlehttp/guzzle": "^6.3"

    }, "require": { "monolog/monolog": "^3.3" } } ・ここで “require” となっているのは、 本番環境で必 要とされるパッケージ群を定義している 
 
 
 ・” require-dev “ と書いてある方は 開発環境で必要 となるパッケージの定義 
 ・devの方には composer require --dev <パッケージ名> としてあげることで追加できる 
 
 ・この状態で何も指定せずにcomposer installを実行すると、requireもrequire-devも どちらもインストールされる 
 
 ・composer install --no-dev とすると、require-devの記載分を除く 本番環境用だけをインストールする 

  65. ・まだ何かあるような気がします! ~ プロジェクトとパッケージ ~
 具体例として下に書いてあるcomposer.jsonを例に考えてみよう 
 
 すると、これはphpunit, guzzle, monologが入ったパッケージを定義しているのと同じであることが分かる 


    
 とはいえ、この例ではプロジェクトと呼ぶにはなんかちょっと足りてない感じがする 
 
 
 
 { "require-dev": { "phpunit/phpunit": "*", "guzzlehttp/guzzle": "^6.3" }, "require": { "monolog/monolog": "^3.3" } }
  66. ・まだ何かあるような気がします! ~ プロジェクトとパッケージ ~
 ・この例では、プロジェクト名が kerokero/hello-composer であり、ベンダー名が kerokero、
 パッケージ名が hello-composer ということになります。


    
 ・作ったライブラリはPackagistなどのレポジトリに登録することができ、誰でも簡単に使うことができるようになる
 
 ・なので、これまでcomposer installでインストールしていたパッケージは、このような形で誰かが作ったものであるとい うことを知っておくと良いかも
 
 
 
 "name": "kerokero/hello-composer", 
  67. ・まだ何かあるような気がします! ~ プロジェクトとパッケージ ~
 ・また、composerには プラットフォームパッケージ という概念もある
 
 ・これはシステムにインストールされる仮想的なパッケージのことであり、 
 具体的にはphpやcurlなどがあり

    "php" : "^5.5 || ^7.0", などという形で指定することができる 
 
 ・これらは別途誰かが作ったパッケージというよりは、 仮想的にcomposerでインストールできるようにパッケージ 化しているものと考えてよさそう
 
 
 
 
 { "require": { "php": ">=5.3" } }
  68. ・pharについて
 少しスライドを戻ってみましょう
 PHPUnit に必要なすべての 依存ファイル をひとつのファイル にまとめた PHP アーカイブ (PHAR)

    を配布します
 
 
 あるいは、Composer を使って PHPUnit やその 依存ファイ ル をダウンロードしてインストールすることもできます。

  69. ・pharについて
 ・この説明を見る限り......
 
 
 ・pharは依存パッケージをまとめて配布するためのものであると考えてよさそう
 
 
 ・つまり、zipやtarの様に複数のPHPファイルを1つにまとめられると考えてよさそ う
 


    
 ・.pharファイルというのは上記の通り、PHPUnitなどのパッケージを
 まとめてアーカイブ化した現物を提供するための定義であると考えられる
 
 

  70. ・pharについて
 ・しかし、composer.jsonやlockを使ってinstallできる状態で、いったいphar を使う意味とは何なのでしょうか?
 
 
 ・例えば、pharでまとめなかったとしても 
 composer require --dev

    <パッケージ名> 
 で開発時にのみ使う依存パッケージをインストールできます
 
 
 ・これは便利だし、直感的にも何をしているかわかりやすい
 のでこれでよさそうな気がしますよね。
 
 よね >
  71. ・pharについて
 ・多くのプロジェクトはツール単体で開発されているわけではなく、
 ツール自体も他のパッケージに依存しているということはこれまでの話からも理解で きていると思います
 
 
 ・例えば……
 コードフォーマッタである PHP-CS-Fixer は多くの

    Symfony コンポーネントに依存し ているので、何かの事情で古いバージョンに依存しているパッケージがインストール できない場合などがあります
 
 ・ツールを含めた依存パッケージを全て同時にバージョン管理する必要があるため、ライブラリの 依存関係がrequire-devのみで解決することができずにプロダクトで使われているパッケージ全体に 問題が波及してしまう
 
 つらい >
  72. ・オートロードについて
 ・ここまでが パッケージ管理ツール としての Composer の役割でした
 
 ・そして実は、もうひとつの Composer の役割として

    autoloader という役割がありま す。
 
 なので、ここからはオートロードとPSRについて話します。
 
 
 
 
 

  73. ・オートロードについて
 ・オートロードしない場合の流れは、 実際には次のようになります
 
 
 
 
 
 
 


    
 
 
 
 <?php class A{ public $name = ""; public function __construct() { $this->name = "kerokero"; } public function Hello() { echo $this->name."\n"; } } <?php require_once __DIR__.'/../classes/A.php'; class B extends A{ public $email = ""; public function Send() { echo "Send mail to ".$this->email."\n"; } } <?php require_once __DIR__.'/classes/B.php'; $b = new B(); $b->Hello(); $b->Send(); A.php B.php main.php
  74. ・オートロードについて ~ PSR ~ 
 ・PHPにも推奨されるコード規約というものがある 
 
 ・しかし、PHPの公式が出しているものというわけではなく、PHPのフレームワーク等の開発者有 志のグループであるPHP-FIGによって策定されているコーディング規約 があります
 


      ・それがPSR(PHP Standarrd Recommendations) 
 
   ・多くのPHPライブラリはこの考え方に則って作られている 
 
 ・そして、Composerも類を洩れずこれに従っている。 
 実際、Composerは名前空間に関する規約であるPSR-4 に従っています。
 
 name space >
  75. ・オートロードについて ~ 名前空間 ~ 
 ・ここでは名前空間については深く触れずに、簡単に説明しようと思います 
 
 ・例えば、main.php で itemShop.php から

    getItem関数 を呼ぶとします
 
 
 ・おそらく、
 require_once("itemShop.php); 
  として main.php 内で getItem関数 を呼ぶことで解決できます 
 
 
 
 
 
  まあね >
  76. ・オートロードについて ~ 名前空間 ~ 
 ・では、main.php で treasureBox.php から getItem 関数も呼びたくなったとしましょう ・この時、関数名が同じなので衝突してしまい実行できません。

      ・二重定義のエラーが出てしまいます ・そこで、この現象を回避するために 名前空間というものを用意します 
 
 
 
 

  77. ・オートロードについて ~ 名前空間 ~ 
 ・では、main.php で treasureBox.php から getItem 関数も呼びたくなったとしましょう ・この時、関数名が同じなので衝突してしまい実行できません。

      ・二重定義のエラーが出てしまいます ・そこで、この現象を回避するために 名前空間というものを用意します 
 ・それぞれに ItemShop と TreasureBox という名前空間を与えると、それぞれの関数は 
 ItemShop/getItem、TreasureBox/getItem と異なる塊にすることができます。 
 
 

  78. ・オートロードについて ~ PSR-4 ~ 
 ・というわけで、名前空間の利用価値が分かったので、名前空間を定義した状態で クラスをオートロードでき るようにしてあげたいですね
 
 
 
 ・Composerの場合はPSR-4に準拠しているので、PSR-4の中の一文を見てみます

    
 
 
 
 
 
 
 
 
 The terminating class name corresponds to a file name ending in .php. The file name MUST match the case of the terminating class name. 「クラス名は .php で終わるファイル名に対応します。ファイル名は、クラス名の大文字小文字と一 致しなければなりません (MUST)」

  79. ・オートロードについて ~ composerのオートロード ~ 
 ・なので、このことからも composerのオートロード がやっていることは
 
 「クラスが入ってるファイルのパスを名前空間に紐づけているだけ」
 
 ということがなんとなく分かったと思います


    
 
 ・この autoload_static.php の $classmap の中を見ると、確かにこれだけの量のクラスをいちいち require する必要があると考えれば、オートロードが便利だということもなんとなく分かると思います
 
 
 
 
 
 

  80. ・Slim Framework の場合
 ・これまでの説明で、composer とそれに採用されている autoload が便利なことはなんとなく分か ります
 
 


    ・とはいえ、いまいちまだピンときていない部分もあるので、実際に Slim Frameworkのコードを見て みることで実感してみます
 
 
 ・最初の方で使っていた composer.json に Slim Framework を追加します。
 composer require slim/slim で require に追加し、composer update を行い composer.lock にSlim Framework を入れます
 
 
 
 

  81. ・Slim Framework の場合
 ・これまでの説明で、composer とそれに採用されている autoload が便利なことはなんとなく分か ります
 
 


    ・とはいえ、いまいちまだピンときていない部分もあるので、実際に Slim Frameworkのコードを見て みることで実感してみます
 
 
 ・最初の方で使っていた composer.json に Slim Framework を追加します。
 composer require slim/slim で require に追加し、composer update を行い composer.lock にSlim Framework を入れます
 
 
 ・同様にして composer require slim/psr7 も入れます。
 そして、composer install を実行すると確かに vendor ディレクトリの中に slim が誕生していることが確 認できます (画像割愛)

  82. ・Slim Framework の場合
 ・この状態で以下の様に html/index.php を用意してみます
 
 
 
 


    
 
 
 
 
 
 
 
 
 ・アクセスしてみると、たしかにslimを使って書かれ た情報が返却されます
 
 ・コードを見ると /../vendor/autoload.php をrequireしてい ることが分かります
 
 ・composer でオートロードされたクラスを、use Slim\Factory\AppFactory; のようにして呼び出している ということになります

  83. ・Slim Framework の場合
 ・この状態で以下の様に html/index.php を用意してみます
 
 
 
 


    
 
 
 
 
 
 
 
 
 ・アクセスしてみると、たしかにslimを使って書かれ た情報が返却されます
 
 ・コードを見ると /../vendor/autoload.php をrequireしてい ることが分かります
 
 ・composer でオートロードされたクラスを、use Slim\Factory\AppFactory; のようにして呼び出している ということになります
 おお! >