【问题标题】:How to add a random string column to laravel migration如何在 laravel 迁移中添加随机字符串列
【发布时间】: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 不存在”。 有人可以指导我正确地做到这一点。

【问题讨论】:

    标签: php laravel laravel-5 laravel-migrations


    【解决方案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 此迁移并运行它。稍后在创建任何模型时,您需要确保设置密钥。
        猜你喜欢
        • 1970-01-01
        • 2021-09-04
        • 2011-09-16
        • 1970-01-01
        • 1970-01-01
        • 2016-03-29
        • 2016-12-26
        • 2023-03-12
        • 2022-07-20
        相关资源
        最近更新 更多