mpe*_*pen 18 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
});
}
Run Code Online (Sandbox Code Playgroud)
Mar*_*der 15
有一个新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
}
}
Run Code Online (Sandbox Code Playgroud)
然后调用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
});
}
Run Code Online (Sandbox Code Playgroud)
我不确定是否创建一个新的模式实例 DB::connection()->getSchemaBuilder();是最先进的,但它的工作原理.
您可以另外覆盖Schema外观并默认添加自定义蓝图.
我同样想以“自动”的方式解决这个问题,因此从 @WesleySmith 的答案中获得灵感来实现一个解决方案,Schema该解决方案涉及覆盖返回自定义Blueprint类的基础外观。
然而,从 Laravel 9 开始,该protected static function getFacadeAccessor()方法现在预计仅返回一个字符串,表示服务容器中的查找键。此更改记录在Laravel 9 升级指南中(搜索“getFacadeAccessor”),这里是对进行此更改的框架的相关提交。升级指南是这样说的:
getFacadeAccessor 方法必须始终返回容器绑定键。在 Laravel 的早期版本中,此方法可以返回一个对象实例;但是,此行为不再受支持。如果您编写了自己的外观,则应确保此方法返回容器绑定字符串。
对于SchemaFacade,此容器绑定键是字符串db.schema(如此处所示,尽管Laravel 文档的Facade 类参考中尚未记录它)。
因此,我的Schema类省去了自定义getFacadeAccessor方法并依赖父类返回密钥db.schema,并提供使用静态方法创建自定义模式生成器的逻辑customizedSchemaBuilder。
class Schema extends BaseSchema
{
/**
* Get a schema builder instance for a connection.
*
* @param string|null $name
*
* @return Builder
*/
public static function connection($name): Builder
{
return static::customizedSchemaBuilder($name);
}
/**
* Retrieves an instance of the schema `Builder` with a customized `Blueprint` class.
*
* @param string|null $name
*
* @return Builder
*/
public static function customizedSchemaBuilder(string|null $name = null): Builder
{
/** @var Builder $builder */
$builder = static::$app['db']->connection($name)->getSchemaBuilder();
$builder->blueprintResolver(static fn($table, $callback) => new CustomBlueprint($table, $callback));
return $builder;
}
}
Run Code Online (Sandbox Code Playgroud)
解析之前的自定义生成器的逻辑getFacadeAccessor应该包含在您的AppServiceProvider方法中register:
/**
* @return void
*/
public function register()
{
$this->app->bind('db.schema', fn() => Schema::customizedSchemaBuilder());
}
Run Code Online (Sandbox Code Playgroud)
您现在应该能够使用 Laravel 9 在迁移中使用自定义的Schema外观和类。Blueprint
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'));
}
}
Run Code Online (Sandbox Code Playgroud)
我创建了一个文件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;
}
}
Run Code Online (Sandbox Code Playgroud)
在里面config/app.php我更新了 Schema 的别名,如下所示:
'aliases' => [
'Schema' => App\Facades\Schema::class,
],
Run Code Online (Sandbox Code Playgroud)
现在,在我的迁移中,如下所示,当我调用 时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();
});
}
// ....
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3457 次 |
| 最近记录: |