---
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 %}
---
```