Help us understand the problem. What is going on with this article?

cakephp3 ビジネスロジックを書くためにServiceクラスを作る

More than 1 year has passed since last update.

ビジネスロジック書くところ無い

cakephpでは、Helper,Component,ShellHelper,Cellなどもろもろロジックを使いまわすための機構がありますが、バッチなどを動かすShellと、ウェブ上で動かすcontroller等のソースで、ロジックを共有したいのに既存のものだとロジックを置く場所がないです。

参考

みんな困ってます。

ということで、Serviceクラスを作ってみました

正直DDDはよく分かってません。

cakephp3では適当なディレクトリとnamespaceを勝手に作れる

Cakephp3はsrc/Controllerなどのディレクトリがありますが、srcの下にディレクトリを掘って、適切なnamespaceを設定してあげると、その配下においたクラスは、自由に他の場所でも使えるようになります。(psr-4のおかげですが

tree.log
cake-app
├── bin
├── config
├── logs
├── plugins
├── src
│   ├── Console
│   ├── Controller
│   ├── Model
│   ├── 省略....
│   ├── Service // ここに適当にディレクトリを作る
│   └── View
├── tmp
├── vendor
└── webroot
    ├── css
    ├── img
    └── js

Serviceディレクトリを作成、classのphpを起き、クラスのnamespaceをApp\Serviceに

src/Service/EnqueteFileService.php
<?php
namespace App\Service;
class EnqueteFileService {

    public function imageFileExist($file_path) {
        return file_exist($file_path);
    }
}

とすると、

SellやControllerやModelやHelperやCellやEntity、Tableなどいろんなところで、use句で読み込んであげて、このように使えます。

use App\Service\EnqueteFileService;

// snip

$service = new EnqueteFileService();
$service->imageFileExist($file_path);

一生懸命componentに実装したのにShellでつかえねーし、一生懸命componentに実装したのにHelperにcomponentってまじどうやって渡すの…。また同じこと書くのかよコレ!!!またTableクラスに書くの…。このロジックEntityに書いてもいい…??って陳謝しながら許しを請うになったらご利用ください。

AppServiceクラスを作ってみました。

それなりに使えそうな、AppServiceクラスを作ってみました。

App/Service/AppService.php
<?php
namespace App\Service;

use Cake\Datasource\ModelAwareTrait;
use Cake\ORM\Locator\LocatorAwareTrait;
use Cake\Log\LogTrait;

class AppService {

    use LocatorAwareTrait;
    use LogTrait;
    use ModelAwareTrait;

    public $name = null;
    public $plugin = null;

    public function __construct($name = null)
    {
        if ($name !== null) {
            $this->name = $name;
        }

        if ($this->name === null) {
            list(, $name) = namespaceSplit(get_class($this));
            $this->name = substr($name, 0, -10);
        }
        $this->initialize();
    }

    public function initialize() {

    }

    /**
     * Magic accessor for model autoloading.
     *
     * @param string $name Property name
     * @return bool|object The model instance or false
     */
    public function __get($name)
    {
        return $this->loadModel($name);
    }
}

これを基底クラスにするとTableクラスのロードとかがControllerとおんなじ感じで簡単にできます。phpdocの@propertyのおかげだけど

App/Service/EnqueteFileService.php
<?php
namespace App\Service;

/**
 * @property \App\Model\Table\EnqueteTable $Enquete
 * @property \App\Model\Table\EnqueteImageTable $EnqueteImage
 */
class EnqueteFileService extends AppService{

    public function deleteRemainImages($id) {
        $_enquetes = $this->Enquete->get($id, [
            'contain' => ['EnqueteImage']
        ]);
        foreach($_enquetes as $_enquete) {
            if(file_exist($_enquete->enquete_image->file_path)){
                unlink($_enquete->enquete_image->file_path);
            }

        }
    }
}

これが、コントローラーでもshellでもhelperでもcomponentでも呼び出せます。

Why do not you register as a user and use Qiita more conveniently?
  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
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  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