1. 程式人生 > >手把手帶你建立一個 Laravel CRUD 程式碼生成器

手把手帶你建立一個 Laravel CRUD 程式碼生成器

file

讓我們來看看如何在 Laravel 中建立自己的 CRUD 生成器,來提升我們的工作效率。

通常情況下,一旦決定使用控制器提供的架構方案,你需要一個生成器,以便將來不會被重寫。

你可以從 這裡 獲取到原始碼。


第 1 步 --- 建立專案

建立一個新的 Laravel 專案:

composer create-project laravel/laravel Contest

第 2 步--- 啟動

將你的 Laravel 應用程式連線到資料庫並啟動伺服器。

第 3 步--- 使用命令生成

下面我們開始研究 CRUD 生成器的命令。

建立一個 CRUD 生成器命令:

php artisan make:
command CrudGenerator

如果你執行:

php artisan

你應該有一個新的命令可用:

command:name         Command description

當然,該命令還沒有設定,這就是為什麼你看到一個預設的名稱和說明。

在我們處理命令之前,如果你願意,我們需要一些存根或藍圖。


第 4 步---stub 模板

複製下面的程式碼到 resources/stubs 目錄。

stubs 目錄預設是不存在的,所以請確認你首先建立了它。並且,請用後面的名字命名這些檔案:Controller.stubModel.stubRequest.stub

正如你在下面所看到的,這些 stub 模板檔案裡有一些佔位符,我們稍後會用真實資料來替換它們。

Controller.stub

<?php

namespace App\Http\Controllers;

use App\Http\Requests\{{modelName}}Request;
use App\{{modelName}};

class {{modelName}}Controller extends Controller
{
    public function index()
    {
        ${{modelNamePluralLowerCase}} = {
{modelName}}::latest()->get(); return response()->json(${{modelNamePluralLowerCase}}); } public function store({{modelName}}Request $request) { ${{modelNameSingularLowerCase}} = {{modelName}}::create($request->all()); return response()->json(${{modelNameSingularLowerCase}}, 201); } public function show($id) { ${{modelNameSingularLowerCase}} = {{modelName}}::findOrFail($id); return response()->json(${{modelNameSingularLowerCase}}); } public function update({{modelName}}Request $request, $id) { ${{modelNameSingularLowerCase}} = {{modelName}}::findOrFail($id); ${{modelNameSingularLowerCase}}->update($request->all()); return response()->json(${{modelNameSingularLowerCase}}, 200); } public function destroy($id) { {{modelName}}::destroy($id); return response()->json(null, 204); } }

Model.stub

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class {{modelName}} extends Model
{
    protected $guarded = ['id'];
}

Request.stub

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class {{modelName}}Request extends FormRequest
{
    public function authorize()
    {
        return true;
    }

    public function rules()
    {
        return [];
    }
}

你的 resources 目錄看起來應該像下面這樣:

file


第 5 步 --- 實現程式碼生成器

現在讓我們來實現第 3 步所建立的控制檯命令。

app/Console/Commands 資料夾找到 CrudGenerator.php

修改命令標誌和描述,如下:

protected $signature = 'crud:generator
    {name : Class (singular) for example User}';

protected $description = 'Create CRUD operations';

描述要簡潔、明瞭。

至於命令標誌,可以根據個人喜好命名,就是後面我們要呼叫的 artisan 命令,如下:

php artisan crud:generator Car

接下來建立一個方法用來獲取樁程式碼。

protected function getStub($type)
{
    return file_get_contents(resource_path("stubs/$type.stub"));
}

getStub 方法只是簡單的返回我們需要的樁程式碼內容。


下面,我們來看看怎樣使用 resources/stubs 資料夾下的 stub 模板來建立模型。

protected function model($name)
{
    $modelTemplate = str_replace(
        ['{{modelName}}'],
        [$name],
        $this->getStub('Model')
    );

    file_put_contents(app_path("/{$name}.php"), $modelTemplate);
}

從程式碼可以看到,model方法需要一個 name 引數,它由我們在 artisan 命令裡傳入。

看看 $modelTemplate 屬性。我們使用 str_replace 函式把 Model.stub檔案裡的佔位符替換為我們期望的值。

基本上,在Model.stub檔案裡,我們用$name替換了{{modelName}}。請記住,在我們的例子中,$name的值是 Car。

你可以開啟Model.stub檔案檢查一下,所有的{{modelName}}都被替換為了 Car。

file_put_contents函式再次使用了$name建立了一個新檔案,因此它被命名為Car.php。並且,我們給這個檔案傳入內容,這些內容是從$modelTemplate屬性獲取的。$modelTemplate屬性值是Model.stub檔案的內容,只是所有的佔位符均被替換了。

同樣的事情還發生在controllerrequest方法裡。因此,我將這兩個方法的內容貼上在這裡。

protected function controller($name)
{
    $controllerTemplate = str_replace(
        [
            '{{modelName}}',
            '{{modelNamePluralLowerCase}}',
            '{{modelNameSingularLowerCase}}'
        ],
        [
            $name,
            strtolower(str_plural($name)),
            strtolower($name)
        ],
        $this->getStub('Controller')
    );

    file_put_contents(app_path("/Http/Controllers/{$name}Controller.php"), $controllerTemplate);
}
protected function request($name)
{
    $requestTemplate = str_replace(
        ['{{modelName}}'],
        [$name],
        $this->getStub('Request')
    );

    if(!file_exists($path = app_path('/Http/Requests')))
        mkdir($path, 0777, true);

    file_put_contents(app_path("/Http/Requests/{$name}Request.php"), $requestTemplate);
}

好極了,現在我們來看受保護方法handle


在 handle() 方法裡,我們只需要呼叫剛剛定義好的那些方法。

public function handle()
{
    $name = $this->argument('name');

    $this->controller($name);
    $this->model($name);
    $this->request($name);

    File::append(base_path('routes/api.php'), 'Route::resource(\'' . str_plural(strtolower($name)) . "', '{$name}Controller');");
}

很顯然,我們需要獲得使用者使用命令傳遞過來的引數值,在這個例子中這個引數值將永遠都是 Car ,接下來呼叫上面幾段裡面的解釋過的三個函式,最後在 rotues/api.php 檔案中追加一個資源路由。


第 6 步 --- 執行控制檯命令

現在讓我們去嘗試執行一下我們已經寫好的控制檯命令。

開啟一個終端控制檯並在終端輸入如下命令:

php artisan crud:generator Car

現在,你應該可以得到三個可用的檔案,一個是 app/ 資料夾下 Model 層的 Car.php ,第二個是 app/Http/Controllers 資料夾下 Controller 層的 CarController.php ,第三個是 app/Http/Requests 資料夾的 CarRequest.php 檔案。

你可以看到,這個控制檯命令建立不了表的遷移檔案。由於這篇文章要發到 Medium 上,我們要讓它更簡單易懂,所以,接下來我們利用 Laravel 框架已經封裝好的控制檯命令去快速建立 cars 的表的遷移檔案。

php artisan make:migration create_cars_table --create=cars

修改 app/database/migrations 的 cars 的表格遷移檔案裡的 up 方法為下面的內容:

public function up()
{
    Schema::create('cars', function (Blueprint $table) {
        $table->increments('id');
        $table->string('model');
        $table->integer('year');
        $table->timestamps();
    });
}

接下來執行以下命令來應用遷移:

php artisan migrate

第 7 步 --測試用控制檯命令生成的 CRUD

在這個步驟中,我將會使用 postman 工具來進行測試。

儲存

file

顯示

file

顯示指定資料

file

更新

file

刪除

file

總結

在你的專案中,你現在已經擁有了一個 CRUD 程式碼生成器。假如你看不慣 resources/stubs 資料夾下的檔案,你可以點進去,然後修改這些檔案。

一般來說, 你只需要通過一個簡潔的控制檯命令來建立一些簡單的 CRUD 程式碼,而不用花費 10 到 15 分鐘甚至更多的時間去建立它。很酷的一件事情,是不是?

因為這篇文章已經收到了很多好評,所以我這陣子打算把這個 CRUD 程式碼生成器改寫成一個完整的 PHP 包!:blush:

敬請期待 & 快樂編碼!