奇特なブログ

「殊勝に値する行いや心掛け」を意味する、奇特な人になる為のブログです

traitに期待し過ぎ?(笑)

ピンと来て、出来てからにしようかと思ったんですが、まぁ良いかなと(笑)

「ログの出力をしたいけど、クラス毎にログの出力先を変えたい」という仕様があったとして、

↓のコード(PHP5.2というか、traitが無い状況の場合)を書いたんですが。

<?php

class log
{
  private $log_save_path;

  public function __construct($called_class_instance)
  {
    $this->set_log_save_path(get_class($called_class_instance));
  }

  public function set_log_save_path($called_class_name)
  {
    $this->log_save_path = '/tmp/' . $called_class_name;
  }

  public function write($log_message)
  {
    file_put_contents($this->log_save_path, $log_message . PHP_EOL, FILE_APPEND);
  }
}
<?php

require_once('log.php');
require_once('test_service.php');

class test_controller
{
  private $log;

  public function __construct()
  {
    $this->log = new log($this);
  }

  public function exec()
  {
    $this->log->write('controller1');

    $service = new test_service();
    $service->exec();

    $this->log->write('controller2');
  }
}

$test_controller = new test_controller();
$test_controller->exec();
<?php

require_once('log.php');

class test_service
{
  private $log;

  public function __construct()
  {
    $this->log = new log($this);
  }

  public function exec()
  {
    $this->log->write('service1');
  }
}

とする事で、test_controllerとtest_serviceで、保存先が別になると。
で、これをPHP7.2(trait有りバージョン)で書くと、

<?php

trait log
{
  // privateでも動くのは、ちょっとビックリ
  private function write($log_message)
  {
    // get_called_class()は、PHP5.3以上で使用可能なので、traitが使えれば絶対使える
    file_put_contents('/tmp/' . get_called_class(), $log_message . PHP_EOL, FILE_APPEND);
  }
}
<?php

require_once('log.php');
require_once('test_service.php');

class test_controller
{
  use log;

  public function exec()
  {
    $this->write('controller1');

    $service = new test_service();
    $service->exec();

    $this->write('controller2');
  }
}

$test_controller = new test_controller();
$test_controller->exec();
<?php

require_once('log.php');

class test_service
{
  use log;

  public function exec()
  {
    $this->write('service1');
  }
}

ということで、簡素化したかなとは思うものの、

それほどでも?とも思い、タイトルの事を思ったんですけどね(笑)

なんですが、以下を見てみた所。

PHPのトレイトを使うならおさえておきたい5つのこと

あぁ、「既に継承しているクラスで、継承元の親クラスに追加しない(それ以外のクラスでも使う処理なら、場所が不適切)で、更に機能を増やしたい時」に良さそうですね。

当初、ログやDBハンドルとか、色々な所で使うクラスをtraitにすれば良いのでは?と思っていたんですが、

さすがに今回は、処理が単純過ぎたから、本領発揮とはいかなかった様ですね(笑)

良い事例が見つかったら、改めてということで。

あと、本日のBGMは、中島みゆきの二艘の船 http://j-lyric.net/artist/a000701/l00f4b9.html でした(笑)