如何在 laravel 迁移中添加随机字符串列

Posted

技术标签:

【中文标题】如何在 laravel 迁移中添加随机字符串列【英文标题】:How to add a random string column to laravel migration 【发布时间】:2018-03-19 20:01:59 【问题描述】:

我的 laravel 应用程序中有一个名为“threads”的表,我想在其中添加一个名为 key 的新列,其中包含长度为 5 的随机字符串。我在 CLL 上运行了 php artisan migrate:make add_key_to_threads 来创建迁移文件。在我生成的迁移文件中,我使用了 up 函数

Schema::table('threads', function($table)
            $table->str_random('key', 5);
        )

添加新列,之后我在 CLL 上运行 php artisan migrate。显然,方法 str_random() 不存在(在谷歌搜索时在资源中找到它),因为我不断收到错误“[BadMethodCallException] 方法 str_random 不存在”。 有人可以指导我正确地做到这一点。

【问题讨论】:

【参考方案1】:

只需使用$this 在迁移中使用您的随机字符串生成器。 例子:

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class Projects extends Migration


    public function up()
    
        Schema::create('example', function (Blueprint $table) 
            $table->bigIncrements('id');
            // use $this to access class function
            $table->string($this->randString(5));
        );

    

    // just a random string generator
    public function randString($length)
        $characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
        $charactersLength = strlen($characters);
        $randomString = '';
        for ($i = 0; $i < $length; $i++) 
            $randomString .= $characters[rand(0, $charactersLength - 1)];
        
        return $randomString;

    



【讨论】:

【参考方案2】:

Schema::table只是更新你的数据库表,不使用对应的SQL语句。在 SQL 中,没有列类型会自动用随机字符串填充您的表。因此列类型必须是string。 查看 Laravel 5.5 中退出的所有类型 https://laravel.com/docs/5.5/migrations#columns

$table->string('key', 5);

下一个问题是key 是否必须是唯一的,如果是,那么您可以附加 unique() 函数:

$table->string('key', 5)->unique();

如果您在第二步中已经有数据,那么您必须填写所有密钥。

您有两种选择来填充列中的随机数据,使用 PHP (Laravel) 或使用 SQL。使用 SQL,您必须编写一个函数,该函数可以根据您的 SQL Server 类型而有所不同,例如:Default random 10 character string value for SQL Server column

使用 Laravel Eloqent,您不必考虑您拥有什么 SQL Server。

$threads      = new Threads();
$threads->key = str_random(5);
$threads->save();

如果您使用了-&gt;unique() 函数,如果您的 APP 创建了两次密钥,这可能会引发异常。然后你必须捕获异常并再次尝试。

/* only if you need a unique Key */
$threads     = new Threads();

while (true)

    try
    
        $threads->key = str_random(5);
        $threads->save();
        //  We could save now we break out of the loop
        break;
    
    catch (Exception $e)
    
        //  Could not save, try it again
    

对于您现有的行,您可以按如下方式更改迁移:

public function up()

    Schema::table('threads', function (Blueprint $table)
    
        $table->string('key', 5);
    );

    $existing_threads = Threads::where('key', '')->get();

    foreach($existing_threads as $threads)
    
        $threads->key = str_random(5);
        $threads->save();                
    

模型Threads 必须在您进行迁移之前退出

【讨论】:

【参考方案3】:

给你:

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class AddRandomStringKeyToThreadsTable extends Migration

    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    
        Schema::table('threads', function (Blueprint $table) 
            $table->string('key');
        );

    

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    
        Schema::table('threads', function (Blueprint $table) 
            $table->dropColumn('key');
        );
    

更新

我已将$table-&gt;string('key')-&gt;default(str_random(5)); 更改为$table-&gt;string('key');

然后制作这条路线只是为了更新现有的行...这对我有用...也许您需要为您的表格修改它。但至少你会知道怎么做。

Route::get('/update-table', function () 
    $count = DB::table('threads')->count();

    while ($count > 1)
        DB::table('threads')
            ->where('id', '=', $count)
            ->update(['key' => str_random(5)]);
        $count--;
    

    return 'DB updated';
);

然后你需要为每个新线程创建一个随机字符串。

【讨论】:

这将自动为“线程”表中的所有现有行创建该“键”,您不必担心在其他地方创建它...(在控制器中的 store() 方法中例如)它将使用每个新线程自动创建 对不起,这将无法按预期工作...str_random(5) 将生成一个随机字符串,并在迁移期间将其设置为列的默认值。现在这是所有新行的相同的默认值... 您可以将它放在 Schema::table 之外 .... 并对其进行更新,以便它可以有所不同....然后对于新的创作,您将需要创建一个新的 str_random(5 ) 请记住,向现有表添加新键的迁移仅用于修复表中的现有行....对于新提交,您需要生成新的随机字符串 但是所有现有的键列都将具有相同的键,即使这个键是随机的,但是有 100 个旧行,键为 we45rgtjuz 不是一种获得方法。并且新列如果没有从 APP 获取密钥,将得到相同的字符串。【参考方案4】:

据我所知,这是可能的。在迁移中,您需要像这样创建普通的字符串列:

$table->string('key', 5);

然后在创建新模型时,您应该运行:

$model->key = str_random(5);

假设您在创建模型时使用 Eloquent,您可以使用以下语法:

$thread = new Thread();
// below are sample fields you normally save for this thread
$thread->field_1 = 'value1';
$thread->field_2 = 'value2';
// this is the random key you set
$thread->key = str_random(5);
// now you save thread in database
$thread->save();

【讨论】:

感谢您的帮助@Marcin Nabialek..请您解释一下在这种情况下创建新模型的过程吗?难道我不想在我的迁移文件中创建字符串后运行 php artisan migrate 吗? @banky 我已经更新了我的答案并在这里展示了如何创建模型。不,您创建正常迁移并将此密钥设置为字符串 inm 此迁移并运行它。稍后在创建任何模型时,您需要确保设置密钥。

以上是关于如何在 laravel 迁移中添加随机字符串列的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Scala 在 DataFrame 中添加新的可为空字符串列

如何将字符串列添加到python中的另一个字符串?

laravel 5.2 分页链接中添加随机字符

如何在 DataFrame 的字符串列中应用正则表达式替换?

如何从字符串列中提取数字?

如何在poedit中编辑原始字符串列?