如何在 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();
如果您使用了->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->string('key')->default(str_random(5));
更改为$table->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 个旧行,键为 we45r
或 gtjuz
不是一种获得方法。并且新列如果没有从 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 中添加新的可为空字符串列