扩展蓝图类?

时间:2014-03-16 23:44:37

标签: php laravel laravel-4

我想覆盖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
    });
}

3 个答案:

答案 0 :(得分:13)

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

因此,像这样创建自定义Blueprint类:

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

然后调用您返回blueprintResolver实例的CustomBlueprint函数。

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外观并默认添加自定义蓝图。

答案 1 :(得分:3)

只是为Marcel Gwerder的答案添加几点(已经很棒了):


(编辑2016-03-06)
最近有一个GitHub问题:#12539

答案 2 :(得分:1)

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内部,我更新了Schema的别名,如下所示:

'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();
        });

    }

    // ....
}