クイック エンジニアリングブログ

株式会社クイック Web事業企画開発本部のエンジニアリングチームが運営する技術ブログです。

【PHP再入門】ComposerのAutoload機能を今更使ってみた

こんにちは。最近、PHPの魅力を再発見している五所です。

PHPの魅力

自分は、つい最近まで

PHP? 時代はRubyだ!全てがオブジェクトであるRubyこそが美しい!」

PHPオブジェクト指向なんて後付けだ、オープンクラスで自由に拡張できるRubyこそが至高!」

という痛いエンジニアだったのですが、ここ最近PHPも悪くないなと穏やかな目線を持っております。

ざっと再発見したところですと、

  • Composerによるパッケージ管理が便利。RubyのBundler、Pythonのpipに相当するが、それ以外のこともできる。
  • オブジェクトの継承関係が分かりやすい。selfthisparentキーワードが面倒だが分かりやすい。Rubyだと見失うことがある。
  • 関数の引数に型が指定できる。function (MyClass $my_class_instance)ができる。
  • PsyShという素晴らしいREPLがある。RubyのPry、PythonのIPythonに相当。

REPL: コマンドラインから1行ずつコマンドを実行できるツール。 スクリプトの実行を止めて、インタラクティブデバッグできる機能が付いていることが多い。これ超便利。

で、最近は以前に作ったものをモダンPHPっぽくしています。 その一環でGoogle AdwordsAPIクライアントをComposerのAutoload機能を使って書き直したので、メモ代わりに書いておきます。

Composerとは

PHPPHPによるPHPのためのパッケージ管理ツールです。

下記のような手順で使います。

  • アプリケーションが依存しているライブラリをcomposer.jsonというテキストファイルに記述
  • Composerはcomposer.jsonを読み込んで、必要なライブラリをインストール
  • composer.jsonをGitなどで管理し、ライブラリの追加などで依存関係に変化があれば適宜バージョンを更新

これによって何が嬉しいかというと

  • 「うまく動かないのは、あのライブラリが無いからだった」というトラブルが無い
  • アプリケーションのインストールがコマンド一つで終わる
  • 全世界のライブラリをコマンド一発でインストールできる
  • ライブラリはバージョン管理の対象に入らないので、GitやSVNのレポジトリのサイズが小さくなる

パッケージ管理はもともとRubyのBundlerがありましたが、Composerはそれに触発されたようです。

ライブラリを自動で読み込むAutoload機能や、インストール先の指定などの機能が搭載されています。

(これらはBundlerにもあるかもしれませんが・・・)

前提

Google Adwords APIを使った広告レポートの自動ダウンロードについては、前に記事に書きました。

もし広告の効率化の記事をお探しの方がいれば、こちらをぜひご覧下さい。

aimstogeek.hatenablog.com

また、自分の環境は以下です。

ComposerはPHP5.3以上でないと動作しません。

変更点

最終的に作りたいプログラムは上記の記事と同じなので、Composer導入にあたり行ったことのみ書きます。

Composerのインストール

まず、適当な空のディレクトリに移動して下さい。

Composerのインストールは死ぬほど簡単で、コマンドラインから一発です。

curl -sS https://getcomposer.org/installer | php

これで、カレントディレクトリにcomposer.pharというファイルができると思います。

依存関係の定義

インストールできたところで、composer.jsonを記述して、依存ライブラリを書いていきます。

{
    "require": {
        "googleads/googleads-php-lib": "^10.0"
    },
    "autoload": {
        "classmap": [
            "vendor/googleads/googleads-php-lib/src/Google/Api/Ads/AdWords/Util/v201603"
        ]
    }
}

一応解説

  • Google Adwordsのライブラリをrequireするよう指定。ベンダー名/ライブラリ名という形式。GitHubから取ってくる。
  • classmapは、対象ディレクトリにある全てのPHPファイルを自動読み込みするという意味らしい

依存パッケージのインストール

php composer.phar install

めっちゃ時間かかります。これ何とかならないでしょうか・・・。

終わると、vendorというディレクトリができていると思います。Composerで入れたライブラリは全てここに入っています。

もしGitでバージョン管理している場合は、.gitignorevendorを加えておきましょう。

寄り道

急いでいる方は、ここを飛ばして下さい。

Composerが何をやっているのか、ちょっとだけ覗いてみます。

インストール直後のディレクトリはこうなっているはず

[k-gosho@kgosho-ubuntu] % ls
composer.json  composer.lock  composer.phar  vendor

vendor/の中身を見てみます。 インストールしたファイルなどが格納されています。

[k-gosho@kgosho-ubuntu] % ls vendor
autoload.php  composer  googleads

vendor/autoload.phpを見てみます。 vendor/composer/autoload_real.phpを読み込むだけのようです。

また、ランダムな値で初期化しています。一意性を保証するためでしょうか。

[k-gosho@kgosho-ubuntu] % cat vendor/autoload.php
<?php

// autoload.php @generated by Composer

require_once __DIR__ . '/composer' . '/autoload_real.php';

return ComposerAutoloaderInit3ebbbd8623d57243578d079335b97187::getLoader();

vendor/googleads/googleads-php-lib/src/Google/Api/Ads/AdWords/Util/v201603/の中身を見てみます。 この中にあるPHPファイルが全て読み込まれるようです。

[k-gosho@kgosho-ubuntu] % ls vendor/googleads/googleads-php-lib/src/Google/Api/Ads/AdWords/Util/v201603
BatchJobClasses.php        BatchJobUtils.php  ReportUtilsDelegate.php
BatchJobUtilsDelegate.php  ReportClasses.php  ReportUtils.php

Autoload機能を利用する

Composerをプログラムから利用する方法も死ぬほど簡単です。

vendor/autoload.phpをrequireするだけです。

ついでなので、前回の記事で作ったプログラムを書き直してみます。

<?php

--- require_once dirname(__FILE__) . '/googleads-php-lib/examples/AdWords/v201509/init.php';
+++ require __DIR__.'/vendor/autoload.php';

$user = new AdWordsUser();
$user->SetClientCustomerId('カスタマーID');

// Build AWQL.
$fields      = 'Date,CampaignName,Impressions,Clicks,Cost,ConvertedClicks,AveragePosition';
$report_type = 'CAMPAIGN_PREFORMANCE_REPORT';
$first_date  = '20160301';
$last_date   = '20160331';

$report_query = sprintf(
    "SELECT %s  FROM %s WHERE CampaignStatus IN [ 'ENABLED','PAUSED' ]  DURING  %d,%d",
    $fields , $report_type , $first_date , $last_date
);
    
// Set additional options.
 $options = array(
    'version' => ADWORDS_VERSION,
    'skipReportHeader'  => true,
    'skipColumnHeader'  => true,
    'skipReportSummary' => true,
    'includeZeroImpressions' => false,
);
    
// Download report.
ReportUtils::DownloadReportWithAwql( $report_query ,  'report.csv', $user, 'CSV', $options );

ってまあ、変わったのは1行だけなんですが、Composerを導入することでライブラリの管理を考えなくて良いので楽ですね。

まとめ

ここには書いていませんが、このプログラムのデプロイにはLaravel製のEnvoyというツールを使っています。

これもComposerから一発でインストールでき、設定もシンプルでなかなかいい感じです。良かったらどうぞ。

https://laravel.com/docs/5.0/envoy

こんな感じで、気軽にパッケージを追加できるのもいいですね。

より良いPHPライフを過ごしていきましょう!

また、弊社では「いまさらPHP?いやこれからもPHPやろ!」と意気込んでいるPHPerを募集しておりますので、良かったらご覧ください。

https://www.green-japan.com/job/40769