扩展 Laravel 5.5/5.6 蓝图

Posted

技术标签:

【中文标题】扩展 Laravel 5.5/5.6 蓝图【英文标题】:Extending Laravel 5.5/5.6 Blueprint 【发布时间】:2018-08-13 06:46:24 【问题描述】:

如何使用自定义方法 $table->myMethod() 扩展 Laravel 5.5/5.6 MySQL 蓝图,例如预建方法 $table->timestamps( );?

我用 SQLlite 试过一个例子:Extending Blueprint for SQLite in Laravel 5

但我无法让它工作。我正在开发自己的包(使用包开发最佳实践)并希望从那里包含蓝图扩展。

我的开发包有 Laravel 扩展文件夹“Extension”: ./packages/vendorname/packagename/src/Extension/

有文件:

1) ./packages/vendorname/packagename/src/Extension/Blueprint.php

<?php

namespace Vendorname\Packagename\Extension;

use Illuminate\Database\Schema\Blueprint as ParentBlueprint;
use Illuminate\Support\Facades\DB;

class Blueprint extends ParentBlueprint


     public function myMethod()
     
          $this->text('custom_column')->default('Some value');
          $this->text('custom_column2')->default('Some value2');
     

2) ./packages/vendorname/packagename/src/Extension/MySqlConnection.php

<?php

namespace Vendorname\Packagename\Extension;

use Vendorname\Packagename\Extension\Blueprint;
use Illuminate\Database\mysqlConnection as ParentMySqlConnection;
use Illuminate\Database\Schema\MySqlBuilder;

class MySqlConnection extends ParentMySqlConnection


     public function getSchemaBuilder()
     
          if (is_null($this->schemaGrammar)) 
               $this->useDefaultSchemaGrammar();
          

          $builder = new MySqlBuilder($this);
          $builder->blueprintResolver(function ($table, $callback) 
               return new Blueprint($table, $callback);
          );

          return $builder;
     

我的包裹有服务提供商: ./packages/vendorname/packagename/src/VendornamePackagenameServiceProvider.phpregister() 方法:

public function register()
      if ($this->app->config->get('vendorname-packagename') === null) 
          $this->app->config->set('vendorname-packagename', require __DIR__.'/../config/vendorname-packagename');
     

     $this->app->bind('db.connection.mysql', Vendorname\Packagename\Extension\MySqlConnection::class);

我的包也有迁移文件: ./packages/vanilla/vanilla-admin/src/migrations/2018_02_07_213437_create_logs_table.php

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
//use Vendorname\Packagename\Extension\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateLogsTable extends Migration


    public function up()
    
        Schema::create('logs', function (Blueprint $table) 
            $table->increments('id');
            $table->text('package');
            $table->longText('log');
            $table->myMethod();
            $table->timestamps();
        );
    

    public function down()
    
        Schema::dropIfExists('logs');
    

如何使用标准“使用 Illuminate\Database\Schema\Blueprint;”在迁移中,因为我不想使用“use Vendorname\Packagename\Extension\Blueprint;”。

我在运行迁移“php artisan migrate:refresh”时也遇到了错误:

Type error: Argument 1 passed to CreateLogsTable::closure() must be a
  n instance of Vanilla\VanillaAdmin\Extension\Blueprint, instance of Ill
  uminate\Database\Schema\Blueprint given, called in /Users/raido/.compos
  er/vendor/bin/laravel-packages/vendor/laravel/framework/src/Illuminate/
  Database/Schema/Builder.php on line 164

请帮我找到解决办法。我在互联网上搜索并测试了一整天,我无法让它工作:(

【问题讨论】:

使用 dc.connector.sqlite 代替 db.connection.sqlite 请更新,我遇到同样的问题 【参考方案1】:

我在搜索相同问题时发现了这一点。我正在使用 Laravel 5.8 并这样做。

    创建自定义蓝图类
namespace App\Database\Schema;

class Blueprint extends \Illuminate\Database\Schema\Blueprint

    public function datetimeCreatedAt($precision = 0)
    
        return $this->dateTime('created_at', $precision);
    


    创建 MySqlConnection 类或您需要的任何东西
namespace App\Database;

class MySqlConnection extends \Illuminate\Database\MySqlConnection

    public function getSchemaBuilder()
    
        $builder = parent::getSchemaBuilder();
        $builder->blueprintResolver(function ($table, $callback) 
            return new \App\Database\Schema\Blueprint($table, $callback);
        );

        return $builder;
    

    更改 AppServiceProvider
namespace App\Providers;

use App\Database\MySqlConnection;
use Illuminate\Database\Connection;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider

    public function register()
    
        Connection::resolverFor('mysql', function ($connection, $database, $prefix, $config) 
            return new MySqlConnection($connection, $database, $prefix, $config);
        );
    

【讨论】:

这是迄今为止 2019 年最好的答案。感谢您的贡献【参考方案2】:

使用 Laravel 5.5,扩展蓝图的最佳方式是在您的 AppServiceProvider 引导方法中注册 macros,如下所示:

Blueprint::macro('yourmethod', function ()   
    // your method here
);

【讨论】:

【参考方案3】:

我遇到了同样的问题,我通过创建一个新的 CustomBlueprint 类解决了这个问题。我为此写了一个单独的博客。只要去那里,你就会找到你的答案。 这里我只是举一个迁移文件的例子,它具有 commonFields() 方法来在模型中添加公共字段

    $schema = DB::connection()->getSchemaBuilder();

    $schema->blueprintResolver(function ($table, $callback) 
        return new CustomBlueprint($table, $callback);
    );

    $schema->create('roles', function (CustomBlueprint $table) 
        $table->bigIncrements('id');
        $table->string('name')->unique();
        $table->commonFields();
    );

我创建了具有该方法的 CustomBlueprint 类。

<?php
namespace App\common;
use Illuminate\Database\Schema\Blueprint;
class CustomBlueprint extends Blueprint

    public function commonFields()
    
        $this->timestamp('created_at')->nullable();;
        $this->unsignedBigInteger('created_by')->nullable();
        $this->timestamp('updated_at')->nullable();;
        $this->unsignedBigInteger('updated_by')->nullable();
        $this->timestamp('deleted_at')->nullable();;
        $this->unsignedBigInteger('deleted_by')->nullable();
        $this->boolean('is_deleted')->default(0);
    

链接:custom-blueprint-in-laravel-mode

【讨论】:

我也必须测试一下 ;)【参考方案4】:

只需在迁移中使用它:

public function up()

    $schema = \DB::getSchemaBuilder();

    $schema->blueprintResolver(function($table, $callback) 
        return new YourBlueprint($table, $callback);
    );

    $schema->create('table_name', function (YourBlueprint $table) 
    ...

【讨论】:

以上是关于扩展 Laravel 5.5/5.6 蓝图的主要内容,如果未能解决你的问题,请参考以下文章

Laravel kalnoy/nestedset

Mysql:5.5-5.6:Components & Plugins

Laravel 5 - 文件上传

Laravel 路由问题:自动重定向到根文件夹

Laravel 5 教程 - 文件上传

MySQL 4.1/5.0/5.1/5.5/5.6各版本的主要区别