Webからは実行できないモジュールを作成する | Tips

Sabelの上に作成されたアプリケーションは、sabel.php を実行することによってコマンドラインからでも実行できます。
$ php sabel.php "myController/myAction"
コマンドラインから実行される場合でも、Webからのアクセス時と全く同じように実装できるのは良いことです。しかし、バッチ処理など専用のロジックが、Webからでも呼び出せてしまうのは問題かもしれません。

例えば下記のようなルーティング設定を行っていたとします。
config/Map.php

<?php

class Config_Map extends Sabel_Map_Configurator
{
  public function configure()
  {
    $this->route("cli")
          ->uri("cli/:controller/:action")
          ->module("cli");
    
    $this->route("default")
          ->uri(":controller/:action")
          ->module("index")
          ->defaults(array(
            ":controller" => "index",
            ":action"     => "index",
          ));
  }
}
コマンドラインから cliモジュール の fooコントローラ の barアクション を実行するには、下記のコマンドを実行します。
$ php sabel.php "cli/foo/bar"
しかしブラウザで http://www.example.com/cli/foo/bar にアクセスすれば、このロジック(アクション)は実行されてしまいます。この問題を解決する手段はいくつもありますが、いくつかの例をここで示します。
1. 基底クラスを作成し、そのクラスのinitializeメソッドで判断する。
app/cli/controllers/Base.php

<?php

class Cli_Controllers_Base extends Sabel_Controller_Page
{
  public function initialize()
  {
    if (!is_cli()) {
      $this->response->getStatus()->setCode(Sabel_Response::BAD_REQUEST);
    }
  }
}
この場合、cliモジュール内の全てのコントローラは Cli_Controllers_Base を継承する必要があり、また、各コントローラに initializeメソッド を作成した場合は親の initializeメソッド を必ず呼び出す必要があります。
app/cli/controllers/MyController.php

<?php

class Cli_Controllers_MyController extends Cli_Controllers_Base
{
  public function initialize()
  {
    parent::initialize();
  }
}
2. コマンドラインからの実行の時のみ、それ用のルーティング設定を行う。
config/Map.php

<?php

class Config_Map extends Sabel_Map_Configurator
{
  public function configure()
  {
    if (is_cli()) {
      $this->route("cli")
            ->uri("cli/:controller/:action")
            ->module("cli");
    }
    
    $this->route("default")
          ->uri(":controller/:action")
          ->module("index")
          ->defaults(array(
            ":controller" => "index",
            ":action"     => "index",
          ));
  }
}
3. Initializerプロセッサ内で処理する。
lib/processor/Initializer.php

<?php

class Processor_Initializer extends Sabel_Bus_Processor
{
  public function execute(Sabel_Bus $bus)
  {
    $destination = $bus->get("destination");
    if ($destination->getModule() === "cli" && !is_cli()) {
      $bus->get("response")->getStatus()->setCode(Sabel_Response::BAD_REQUEST);
    }
    
    ...
  }
}

関連項目