扩展蓝图类?

2022-08-30 17:47:34

我想重写在类中找到的函数。我该怎么做?timestamps()Blueprint

例如,

public function up() {
    Schema::create('users', function (Blueprint $table) {
        $table->increments('id');
        $table->string('username')->unique();
        $table->string('password');
        $table->string('email');
        $table->string('name');
        $table->timestamps(); // <-- I want this to call my method instead of the one found in the base Blueprint class
    });
}

答案 1

有一个新函数,它接受一个回调函数,然后返回实例。blueprintResolverBlueprint

因此,请像这样创建自定义蓝图类:

class CustomBlueprint extends Illuminate\Database\Schema\Blueprint{

    public function timestamps() {
        //Your custom timestamp code. Any output is not shown on the console so don't expect anything
    }
}

然后调用返回实例的函数。blueprintResolverCustomBlueprint

public function up()
{
    $schema = DB::connection()->getSchemaBuilder();

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

    $schema->create('users', function($table) {
        //Call your custom functions
    });
}

我不确定创建一个新的架构实例是否是最先进的,但它是有效的。DB::connection()->getSchemaBuilder();

默认情况下,您还可以覆盖外观并添加自定义蓝图。Schema


答案 2

Marcel Gwerder的答案是救命稻草。就像一些用户在那里评论的那样,我想知道这是否可以更自动地完成。我的目标同样是覆盖该方法。经过一些修补,这就是我最终为我工作的东西:timestamps

我在以下位置创建了一个文件:app/Classes/Database/Blueprint.php

<?php

namespace App\Classes\Database;


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

class Blueprint extends BaseBlueprint
{
    /**
     * Add automatic creation and update timestamps to the table.
     *
     * @param  int  $precision
     */
    public function timestamps($precision = 0): void
    {
        $this->timestamp('created_at', $precision)->default(DB::raw('CURRENT_TIMESTAMP'));
        $this->timestamp('updated_at', $precision)->default(DB::raw('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'));
    }
}

我在app/Facades/Schema.php

<?php

namespace App\Facades;

use App\Classes\Database\Blueprint;
use Illuminate\Database\Schema\Builder;
use Illuminate\Support\Facades\Schema as BaseSchema;

class Schema extends BaseSchema
{
    /**
     * Get a schema builder instance for a connection.
     *
     * @param  string|null  $name
     * @return Builder
     */
    public static function connection($name): Builder
    {
        /** @var \Illuminate\Database\Schema\Builder $builder */
        $builder = static::$app['db']->connection($name)->getSchemaBuilder();
        $builder->blueprintResolver(static function($table, $callback) {
            return new Blueprint($table, $callback);
        });
        return $builder;
    }

    /**
     * Get a schema builder instance for the default connection.
     *
     * @return Builder
     */
    protected static function getFacadeAccessor(): Builder
    {
        /** @var \Illuminate\Database\Schema\Builder $builder */
        $builder = static::$app['db']->connection()->getSchemaBuilder();
        $builder->blueprintResolver(static function($table, $callback) {
            return new Blueprint($table, $callback);
        });
        return $builder;
    }
}

在内部,我更新了架构的别名,如下所示:config/app.php

'aliases' => [
    'Schema' => App\Facades\Schema::class,
],

现在,在我的迁移中,如下所示,当我调用时,它会调用我的覆盖方法。timestamps()

<?php

use App\Classes\Database\Blueprint;
use \Illuminate\Database\Migrations\Migration;

class TimestampTest extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     * @throws \Throwable
     */
    public function up(): void
    {
        Schema::connection('mysql')->create('some_table', static function (Blueprint $table) {
            $table->string('some_column')->nullable();
            $table->timestamps();
        });

    }

    // ....
}

推荐