扩展 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.php 与 register() 方法:
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 蓝图的主要内容,如果未能解决你的问题,请参考以下文章