Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
18
Help us understand the problem. What is going on with this article?
@YusukeHigaki

Symfonyのconsoleコンポーネントを使ってCLIコマンドを作成する

More than 5 years have passed since last update.

Httpで出力させているものをCLIでみたいとの要望があったので対応した。色々躓いた点があったのでメモ。

CLI対応の流れ

  1. symfony/consoleコンポーネントをインストール
  2. Commandファイルを作成
  3. composerのautoloaderにCommandファイルの名前空間を指定し読み込まれるようにする
  4. 実行ファイル(app/console)を作成
  5. 実行

詳細

1. symfony/consoleコンポーネントをインストール

composer.json
{
    "require":{
        "symfony/http-foundation":"2.1.x-dev",  
        "pimple/pimple": "1.0.0",
        "guzzlehttp/guzzle": "~5.0",
        "symfony/console": "2.4.*" ←追加
    }
}

その後composerを実行。

$ composer install
//もしくは下記で実行してもok。下記はautoloadだけを更新するのでよりスマート。
$ composer dumpautoload

ちゃんとコンポーネントがインストールされているかチェック。

$ vendor/symfony/console

これでok。つぎにこれらコンポーネントが自動読み込みされるようにbootstrap.phpに追加。composerに追加されたコンポーネントはすべてvendor/autoload.phpを読み込むことで自動読み込みされる。

bootstrap.php
require 'vendor/autoload.php'; //←追加
require 'config.php';
require 'model.php';
require 'controller.php';
require 'service/apiService.php';

2. Commandファイルを作成

つぎにCommandファイルを作成する。

$ mkdir Command
$ vim Command/AnalizeCommand.php

コマンドファイルの接尾語はxxxCommand.phpである必要があるので注意。

AnalizeCommand.php
namespace Command;

use Command\CommandWrapper;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Formatter\OutputFormatterStyle;

class AnalizeCommand extends CommandWrapper
{
    protected function configure()
    {
        $this
            ->setName('traintrack:analize')
            ->setDescription('Analize location infomation')
        ;
    }
    protected function execute(Inputinterface $input, OutputInterface $output)
    {
        $muchData = $this->container['model.allData'];
        foreach($muchData as $data):
            $text = 'id:'.$data['id'].' user_id:'.$data['user_id'];
            $output->writeln('<info>'.$text.'</info>');
        endforeach;
    }
}

execute時にcontainerを使いたかったのでCommand\CommandWrapperクラスをつくりそれを継承する形で実装した。

CommandWrapper.php
namespace Command;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

abstract class CommandWrapper extends Command
{
    protected $container;
    public function __construct($container)
    {
        $this->container = $container;
        parent::__construct(null);
    }
}

ここらへんはSymfony2のクックブックを参照のこと。
コンソール/コマンドラインツールとしてのコマンドの作成方法

3. composerのautoloaderにCommandファイルの名前空間を指定し読み込まれるようにする

Commandファイル中で名前空間を利用しているので、これを認識させる必要がある。ここでもcomposerの自動読み込みを使う。

composer.json
{
    "require":{
        "symfony/http-foundation":"2.1.x-dev",  
        "pimple/pimple": "1.0.0",
        "guzzlehttp/guzzle": "~5.0",
        "symfony/console": "2.4.*"
    },
    "autoload":{
        "classmap":["Command/"] ←追加
    }
}

autoloaderへの追加の仕方は、名前空間の指定、クラスマップの指定、ファイル自体の指定などができる。そちらに関してはこちらのブログを参照。

composer.jsonに登録したらアップデートしてやる。

$ composer dumpautoload

実際に登録されたかどうかを確認するには下記をみてみる。

vendor/composer/autoload_classmap.php
// autoload_classmap.php @generated by Composer

$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);

return array(
    'Command\\AnalizeCommand' => $baseDir . '/Command/AnalizeCommand.php', //←登録済
    'Command\\CommandWrapper' => $baseDir . '/Command/CommandWrapper.php', //←登録済
);

これでok。

4. 実行ファイル(app/console)を作成

最後に実行ファイルを作成する。

$ mkdir app
$ vim app/console
conosole
#!/usr/bin/env php
<?php
set_time_limit(0);

require dirname(__FILE__).'/../bootstrap.php';

use Symfony\Component\Console\Application;
use Command\AnalizeCommand;

$app = new Application();
$app->add(new AnalizeCommand($container));
$app->run();

ここでは触れていないが、bootstrap.phpで読み込んでいるconfig.phpでPimpleオブジェクトの$containerを生成している。

ここでいくつか注意点がある。

  • bootstrapの読み込み:dirname(FILE)は参照元のファイル(console)からの相対パスを表す。これがないと実行元のファイルからの相対パスになってしまい、bootstrapがfile not foundとなってしまう。

  • app/consoleに実行権限を与える:chmod +x app/consoleをしてやる必要あり。

  • shebang(シバン)をつけてやる必要がある:一行目の #!/usr/bin/env php のことをシバンという。シェルなどのインタプリタを起動するためのもの。

5. 実行

$ app/console traintrack:analize

これできちんと実行できればok。実行場所はappと同じディレクトリであること。

18
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
YusukeHigaki
株式会社ニコリーで代表をしております。起業当初は自分でも開発をしていたのですが、最近はCTO以下、自分より遥かに優秀なメンバーにバトンタッチし、もっぱら企画や営業周りを統括しています。自分で書いていた経験もあり、エンジニアという職種に対するリスペクトは絶大です。

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
18
Help us understand the problem. What is going on with this article?