Laravel迁移数组类型(数据库列中的存储数组)

时间:2015-10-05 17:28:09

标签: php arrays laravel types laravel-5.1

我想在我的表中存储一个整数数组,但在 Documentation 中找不到任何支持数组的类型,任何建议。

迁移:

public function up()
{
    Schema::create('pickups', function (Blueprint $table) {
        $table->increment('id');
        $table->boolean('default');
        $table->integer('shifts');  <<--------- HERE I want to store an array of integers
        $table->integer('status_id');

        $table->timestamps();
    });
}

5 个答案:

答案 0 :(得分:43)

array数据类型不存在于所有数据库系统中,并且由于Laravel的Schema Builder与数据库无关,因此它不提供创建非公共数据类型列的方法。所以你有两个选择:

1。使用原始SQL语句添加列,类似下面我认为应该有效的语句。虽然我不确定查询生成器或Eloquent是否可以正确处理这些类型的列:

DB::statement('ALTER TABLE pickups ADD COLUMN shifts integer[]');

2。使用attribute casting使用Eloquent的可用解决方法。在您的迁移中,将列创建为json,如下所示:

public function up()
{
    Schema::create('pickups', function (Blueprint $table) {
        $table->increment('id');
        $table->boolean('default');
        $table->json('shifts');
        $table->integer('status_id');

        $table->timestamps();
    });
}

然后您可以设置Pickup模型(如果您还没有这样做)并使用$casts属性:

class Pickup extends Model
{
    protected $casts = [
        'shifts' => 'array'
    ];
}

这将让Eloquent知道,当它从数据库中获取数据时,必须将shifts列值转换为array。这仅模拟实际数组,因为在数据库级别,列的类型为TEXT,并且数组已序列化。但是,在对列值进行反序列化时,Eloquent会返回一个实际的整数数组,供您在代码中使用。以下是一个示例用例:

// Create a new Pickup entry
$pickup = App\Pickup::create([
    'default' => true,
    'shifts' => '[1, 5, 7]', // you can easily assign an actual integer array here
    'status_id' => 1
]);

假设上次检索条目时上面生成了id等于1的条目:

$pickup = App\Pickup::find(1);
dump($pickup->shifts);

上面代码中的dump()将输出一个实际的整数数组:

array:3 [▼
  0 => 1
  1 => 5
  2 => 7
]

答案 1 :(得分:2)

还有另一种更复杂的方法,但它允许使用架构构建器创建真正的本机数组。

PostgreSQL 示例。

  1. 注册新的 int_array 类型,该类型将通过扩展现有的 DB Schema Grammar 解析为 int[]
\DB::connection()->setSchemaGrammar(new class extends PostgresGrammar {
    protected function typeInt_array(\Illuminate\Support\Fluent $column)
    {
        return 'int[]';
    }
});

如果您只需要一次或将其放入 AppServiceProvider 以使其在整个项目中可用,您可以将此代码直接放入迁移中。

  1. 现在您可以在迁移中使用这种类型:
Schema::table('users', function (Blueprint $table) {
    $table->addColumn('int_array', 'group_ids')->nullable();
});

答案 2 :(得分:0)

我通常将数组作为逗号分隔的字符串存储在列中,并通过爆炸将其检索。

因此,在您存储的情况下,我会这样做:

$arraystring = implode(',',$array);

$pickups->shifts = $arraystring; //$pickups is an instance of your Pickups model.

//Then while retrieving I would just use;

$array = $pickups->shifts ? explode(',',$pickups-shifts) : []; 
/*just to make sure it is not an empty string 
else you will get an error on explode.*/

答案 3 :(得分:0)

简单,用json存储你的数组整数:

{{ $education->degree }} - {{ $education->fieldOfStudy }}

答案 4 :(得分:0)

你可以简单地添加:

protected $cast=['shifts'=>'array'];

在你的模型类中,它适用于 laravel 8。