--- title: Laravel 自訂義 Controller、Repository、Services tags: Templates, Talk description: View the slide with "Slide Mode". --- ## Laravel Artisan 自訂義 Controller、Repository、Services (1) >製作Tinn >參考:Google各位大大 --- ## 目標 節省複製貼上、手工建檔的的時間、維持一併的開發格式。 **1.製作 Controller、Services、Repository 指令與樣板** ```php= php artisan make:ctl --NameServices=youreServices, ``` ```php= php artiasn make:Services --NameRepository=yourRepository ``` ```php= php artisan make:Repositry --Tb=yourTableName ``` **2.製作一個整合的指令將三個樣板建立** ```php= php artisan make:all ``` --- ## Controller Command 位置範例: /app/console/Commands/ControllerCommand 位置範例: /app/console/Commands/Stubs/ctl.stub ```php= <?php /** * Created by PhpStorm. * User: 20181201 * Date: 2019/2/22 * Time: 下午 01:46 */ namespace App\Console\Commands; use Illuminate\Console\GeneratorCommand; use Symfony\Component\Console\Input\InputOption; class ControllerMakeCommand extends GeneratorCommand { /** * The console command name. * * @var string */ protected $name = 'make:ctl'; /** * The console command description. * * @var string */ protected $description = 'Create a new Custom Controller class'; /** * The type of class being generated. * * @var string */ protected $type = 'Controller'; /** * Get the stub file for the generator. * * @return string */ protected function getStub() { return __DIR__ . '/stubs/ctl.stub'; } /** * Get the default namespace for the class. * * @param string $rootNamespace * @return string */ protected function getDefaultNamespace($rootNamespace) { return $rootNamespace . '\Http\Controllers'; } /** * Replace the namespace for the given stub. * * @param string $stub * @param string $name * @return $this */ protected function replaceNamespace(&$stub, $name) { $name = explode('/', $this->getNameInput('name')); $funName = str_replace('Controller', '', $name[0]); //NameServices 為輸入時的值 //Tb 為小寫用 (變數使用) //Fn 為大寫用 (function 使用) $stub = str_replace( ['NameServices', 'Tb', 'Fn'], [$this->option('NameServices'), strtolower($funName), $funName], $stub ); return $this; } /** * Get the console command options. * * @return array */ protected function getOptions() { //陣列索引值對照 //0.要替換的名稱 //1.model 可填寫Null //2.詳細請看 http://blog.friparia.com/blog/2014/06/16/laravel-command-with-option-chs/ return [ ['NameServices', 'm', InputOption::VALUE_OPTIONAL, 'Injection Controller.'], ['Tb', 'r', InputOption::VALUE_OPTIONAL, 'Injection Controller.'], ]; } } ``` ## Controller stubs ```php= <?php namespace App\Http\Controllers; use App\Services\NameServicesServices; use Illuminate\Http\Request; class DummyClass extends Controller { protected $_Tb; public function __construct(NameServicesServices $NameServices) { $this->_Tb = $NameServices; } public function getFnList(Request $request) { try { $list = $this->_Tb->getTbList( $request->only([ 'page', 'pageSize', 'sort', 'sortName' ])); return successResponse($list['list'], $list['count']); } catch (\Exception $e) { return errorResponse($e->getCode(), $e); } } public function getFn($id) { try { $data = $this->_Tb->getTb($id); return successResponse($data); } catch (\Exception $e) { return errorResponse($e->getCode(), $e); } } public function createFn(Request $request) { try { $this->_Tb->createTb($request->only([''])); return successResponse(); } catch (\Exception $e) { return errorResponse($e->getCode(), $e); } } public function updateFn($id, Request $request) { try { $this->_Tb->updateTb($id, $request->only([''])); return successResponse(); } catch (\Exception $e) { return errorResponse($e->getCode(), $e); } } public function deleteFn($id) { try { $this->_Tb->deleteFn($id); return successResponse(); } catch (\Exception $e) { return errorResponse($e->getCode(), $e); } } } ``` --- ## Services Command ```php= <?php /** * Created by PhpStorm. * User: 20181201 * Date: 2019/2/22 * Time: 下午 01:46 */ namespace App\Console\Commands; use Illuminate\Console\GeneratorCommand; use Symfony\Component\Console\Input\InputOption; class ServicesMakeCommand extends GeneratorCommand { /** * The console command name. * * @var string */ protected $name = 'make:services'; /** * The console command description. * * @var string */ protected $description = 'Create a new services class'; /** * The type of class being generated. * * @var string */ protected $type = 'Services'; /** * Get the stub file for the generator. * * @return string */ protected function getStub() { return __DIR__ . '/stubs/services.stub'; } /** * Get the default namespace for the class. * * @param string $rootNamespace * @return string */ protected function getDefaultNamespace($rootNamespace) { return $rootNamespace . '\Services'; } /** * Replace the namespace for the given stub. * * @param string $stub * @param string $name * @return $this */ protected function replaceNamespace(&$stub, $name) { $name = explode('/', $this->getNameInput('name')); $funName = str_replace('Services', '', $name[0]); $stub = str_replace( ['NameRepository', 'Fn'], [$this->setModel(), $funName], $stub ); return $this; } /** * set Model * */ private function setModel() { if (!empty($this->option('repository'))) { return $this->option('repository') . "Repository"; } else { $name = explode('/', $this->getNameInput('name')); $new = str_replace('Services', '', $name[0]); // return str_replace('Services"', '', $new . "Repository"); return $new . "Repository"; } } /** * Get the console command options. * * @return array */ protected function getOptions() { return [ ['repository', 'm', InputOption::VALUE_OPTIONAL, 'Injection Services.'], ['Tb', 'r', InputOption::VALUE_OPTIONAL, 'Injection Services.'], ]; } } ``` ## Services stubs ```php= <?php namespace App\Services; use App\Repository\NameRepository; class DummyClass { protected $_Fn; public function __construct(NameRepository $model) { $this->_Fn = $model; } public function getFnList($request) { $request['page'] = $request['page'] ?? 1; $request['pageSize'] = $request['pageSize'] ?? 10; $list = $this->_Fn->getFnList($request); $rows = 100; return [ 'count' => $rows, 'list' => $list, ]; } public function getFn($id) { $isExists = $this->_Fn->checkFnExists($id); if($isExists === 0 ){ throw new \Exception('無法取得 找不到Id', 404); } $data = $this->_Fn->getFn($id); return $data; } public function createFn($request) { $insert = [ [ 'name' => 'A1', 'code' => 'A' ], [ 'name' => 'B1', 'code' => 'B' ], ]; $this->_Fn->createdFn($insert); } public function updateFn($id, $request) { $isExists = $this->_Fn->checkFnExists($id); if($isExists === 0 ){ throw new \Exception('無法更新 找不到Id', 404); } $update = [ 'name' => 'A1', 'code' => 'AA' ]; $this->_Fn->updateFn($id, $update); } public function deleteFn($id) { $isExists = $this->_Fn->checkFnExists($id); if($isExists === 0 ){ throw new \Exception('無法刪除 找不到Id', 404); } $this->_Fn->deleteFn($id); } } ``` ## Repository Command ```php= <?php /** * Created by PhpStorm. * User: 20181201 * Date: 2019/2/22 * Time: 下午 01:46 */ namespace App\Console\Commands; use Illuminate\Console\GeneratorCommand; use Symfony\Component\Console\Input\InputOption; class RepositoryMakeCommand extends GeneratorCommand { /** * The console command name. * * @var string */ protected $name = 'make:repository'; /** * The console command description. * * @var string */ protected $description = 'Create a new repository class'; /** * The type of class being generated. * * @var string */ protected $type = 'Repository'; /** * Get the stub file for the generator. * * @return string */ protected function getStub() { return __DIR__ . '/stubs/repository.stub'; } /** * Replace the namespace for the given stub. * * @param string $stub * @param string $name * @return $this */ protected function replaceNamespace(&$stub, $name) { $name = explode('/', $this->getNameInput('name')); $modelName = str_replace('Repository', '', $name[0]); $stub = str_replace( ['Tb', 'Fn'], [ $this->option('Tb'), $modelName ], $stub ); return $this; } /** * Get the default namespace for the class. * * @param string $rootNamespace * @return string */ protected function getDefaultNamespace($rootNamespace) { return $rootNamespace . '\Repository'; } /** * Get the console command options. * * @return array */ protected function getOptions() { return [ ['Tb', 'm', InputOption::VALUE_OPTIONAL, 'Injection model.'], ['Fn', 'r', InputOption::VALUE_OPTIONAL, 'Injection model.'] ]; } } ``` ## Repository stubs ```php= <?php namespace App\Repository; use DB; use Illuminate\Database\QueryException; class DummyClass { private $_table; private $_query; public function __construct() { $this->_table = 'Tb'; $this->_query = $this->prepareFnQuery(); } public function prepareFnQuery() { return DB::table($this->_table); } public function getFnList($request) { try { return $this->_query ->take($request['pageSize']) ->skip($request['page'] > 1 ? ($request['page'] - 1) * $request['pageSize'] : 0) ->get(); } catch (QueryException $e) { logger($e->getMessage(), $e->getTrace()); return false; } } public function getFn($id) { try { return $this->_query->where('id', $id)->first(); } catch (QueryException $e) { logger($e->getMessage(), $e->getTrace()); return false; } } public function updateFn($id, $request) { try { return $this->_query->where('id', $id)->update($request); } catch (QueryException $e) { logger($e->getMessage(), $e->getTrace()); return false; } } public function destroyFn($id) { try { return $this->_query->where('id', $id)->update(['isDeleted' => 1]); } catch (QueryException $e) { logger($e->getMessage(), $e->getTrace()); return false; } } public function checkFnExists($id) { try { return $this->_query->where('id', $id)->count(); } catch (QueryException $e) { logger($e->getMessage(), $e->getTrace()); return false; } } /* public function editFn($id) { try { return $this->_query->table->where('id', $id)->first(); } catch (QueryException $e) { logger($e->getMessage(), $e->getTrace()); return false; } } */ } ``` ## 整合三個樣板的指令 採問答與填寫方式輸入 ```php= <?php namespace App\Console\Commands; use Illuminate\Console\Command; use Artisan; class AllMakeCommand extends Command { /** * The name and signature of the console command. * * @var string */ protected $signature = 'make:all'; /** * The console command description. * * @var string */ protected $description = '[創建][Controller、Services、Repository]'; /** * Create a new command instance. * * @return void */ public function __construct() { parent::__construct(); } /** * Execute the console command. * * @return mixed */ public function handle() { $className = $this->ask('你要創建的Controller、Services、Repository名稱為?'); if ($className && preg_match('/^[A-Za-z0-9]+$/', $className)) { $controllerName = $className . 'Controller'; $servicesName = $className . 'Services'; $repositoryName = $className . 'Repository'; $tableName = $this->ask('請輸入 Table name'); if ($this->confirm('確認創建' . $controllerName . "、" . $servicesName . "、" . $repositoryName)) { Artisan::call('make:ctl', ['name' => $controllerName, '--NameServices' => $className]); $this->info(Artisan::output()); Artisan::call('make:services', ['name' => $servicesName, '--repository' => $className]); $this->info(Artisan::output()); Artisan::call('make:repository', ['name' => $repositoryName, '--Tb' => $tableName]); $this->info(Artisan::output()); } else { $this->error('沒事發生'); } } else { $this->error('您輸入的名稱不符合英數字'); } } } ``` ## 指令運行過程 <img src='https://i.imgur.com/AsAwS7U.gif'> ### Demo --- {%youtube 1LraAsP71ik %} --- ```