# Laravel 9.x DB 連線測試 多資料庫關聯 Login 模擬註冊 2022-01-04 ###### tags: `Laravel` `Nginx` `Composer` `Web server` `Front end` `後端心得` --- Laravel 有些後台頁面 demo 時 會用指令的方式來模擬註冊, 並新建一筆註冊資料在 table 上 ## Laravel 支援多資料庫關聯~ 要在 `.env` `database.php` 以及 Models 底下的 `Admin/User.php` `migrations/2023_01_04_xxxxxx_admin_test`, 以及 commands 做操作 **Models 以及 migrations 需要用指令操作: ``` php artisan make:model Admin/User php artisan make:migration admin_test ``` ---- ## 1. 在 .env 檔案進行複製貼上 例如原本的 DB 相關連接設定: ``` # xxx_admin 後台多資料庫關聯 - 環境設定 DB_CONNECTION2=mysql -> 設定資料庫是 mysql DB_HOST2=192.168.66.xx -> 設定虛擬機或其他位址 DB_PORT2=330x DB_DATABASE2=xxx_admin -> 設定 admin 的 DB 名稱 DB_USERNAME2=xxxx -> 設定帳號 DB_PASSWORD2=xxxx -> 密碼 ``` 把它再複製一份寫在下面: ![](https://i.imgur.com/BNkQVXA.png) --- ## 2. 在 database.php 設定 這邊 laravel 會很細心地把常見的資料庫類型給預設寫在這, 例如 sqlite, mysql, pgsql 這邊以 mysql 作範例: 原本的預設值 ↓ ``` 'mysql' => [ 'driver' => 'mysql', 'url' => env('DATABASE_URL'), 'host' => env('DB_HOST', '127.0.0.1'), 'port' => env('DB_PORT', '3306'), 'database' => env('DB_DATABASE', 'forge'), 'username' => env('DB_USERNAME', 'forge'), 'password' => env('DB_PASSWORD', ''), 'unix_socket' => env('DB_SOCKET', ''), 'charset' => 'utf8mb4', 'collation' => 'utf8mb4_unicode_ci', 'prefix' => '', 'prefix_indexes' => true, 'strict' => true, 'engine' => null, 'options' => extension_loaded('pdo_mysql') ? array_filter([ PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'), ]) : [], ], ``` 把它複製一份寫上來: 第二個資料庫的設定 ↓ ``` // xxx_admin 後台多資料庫關聯 // env('xxx') 相關的名稱不要跟第一個資料庫一樣, 例如 env('DATABASE_URL2') 'mysql2' => [ 'driver' => 'mysql', 'url' => env('DATABASE_URL2'), // 設定資料庫位址, 偷懶的話可以寫URL2 'host' => env('DB_HOST2', '127.0.0.1'), 'port' => env('DB_PORT2', '3306'), 'database' => env('DB_DATABASE2', 'forge'), // 設定資料庫2 'username' => env('DB_USERNAME2', 'forge'), // 設定 admin 使用者 'password' => env('DB_PASSWORD2', ''), // 設定 admin 密碼 'unix_socket' => env('DB_SOCKET', ''), 'charset' => 'utf8mb4', 'collation' => 'utf8mb4_unicode_ci', 'prefix' => '', 'prefix_indexes' => true, 'strict' => true, 'engine' => null, 'options' => extension_loaded('pdo_mysql') ? array_filter([ PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'), ]) : [], ], ``` ---- ## 3. 在 Model 底下建一個 Admin/User namespace 的話記得照著路徑走, 例如 `Models\Admin\User.php` 的話 ``` namespace App\Models\Admin; ``` 物件導向的 class 也要照著規範寫: ``` class User extends Model { use HasFactory; protected $connection = 'mysql2'; protected $table = 'admin_test'; -> 根據 table 的名稱 protected $guarded = ['id']; -> 避免 id 被隨意輸入 protected $fillable = ['admin_test']; -> 代表這個 table 是可以被寫入的, 其他還有 email, password 等可以寫在這 // protected $fillable = ['name','password','created_at','updated_at']; } } ``` --- ## 4. 在 migrations 中設定 table 遷移對應的方式 migrations 在 Laravel 中是一種資料庫的版本控制, 可以讓 team 快速修改和共享資料庫結構 一個 migrations 中的 class 會包含 `up()` 和 `down()` 兩種方法 可以在 up(中這樣寫): ``` Schema::connection('mysql2')->create('admin_test', function (Blueprint $table) { $table->bigIncrements('id'); $table->string('name', 32); $table->string('email', 64)->unique(); $table->timestamp('email_verified_at')->nullable(); $table->string('password')->unique(); $table->timestamps(); $table->smallInteger('role_id'); // $table->timestamp('admin_test')->nullable(); }); ``` down() 中: ``` Schema::connection('mysql2')->drop('admin_test'); ``` 分別對應資料庫的架構 --- ## 5. 建一個 Commands 在 Commands 底下用指令造一個 CreateAdmin.php: ``` php artisan make:command CreateAdmin ``` 路徑記得引入 ``` use App\Models\Admin\User; ``` 指令的建構寫法: ``` class CreateAdmin extends Command { /** * The name and signature of the console command. * * @var string */ protected $signature = 'admin:create'; /** * The console command description. * * @var string */ protected $description = 'Command description'; /** * Execute the console command. * * @return int */ public function handle() { // $email = $this->ask('請輸入email'); // while (User::where('email', $email)->exists()) { // $this->info('email已存在'); // $email = $this->ask('請輸入email'); // } // $password = $this->ask('請輸入密碼'); // User::create([ // 'email' => $email, // 'password' => Hash::make($password), // 'name' => 'admin' . now()->format('YmdHis'), // 'role_id' => 1 // ]); // $this->info('新增成功'); // 測試用指令, 輸入 php artisan admin:create 會直接在 DB 新建資料 User::create([ 'admin_test' => now() ]); return true; } } ``` ## 6. 錯誤排除 `Add [admin_test] to fillable property to allow mass assignment on [App\Models\Admin\Login]` → 檢查 Models 底下的 Login 有沒有出現多個 class Login 的狀況, 記得不要復用 ` Class "App\Models\Admin\User" not found` → 使用通靈的方式(x)去找這個 class 為啥不存在 使用指令 `php artisan migrate` 後出現: ``` SQLSTATE[HY000] [1045] Access denied for user 'root'@'192.168.66.xx' (using password: YES) (SQL: create table `admin_test` (`id` bigint unsigned not null auto_increment primary key, `created_at` timestamp null, `updated_at` timestamp null, `admin_test` timestamp null) default character set utf8mb4 collate 'utf8mb4_unicode_ci') ``` → 去找 .env 和 database.php 有沒有設定錯誤, 或是跟某份資料庫共用到 ==沒事千萬不要用`php artisan migrate:reset`== 這指令會還原所有遷移, 如果用 `migrate:refresh` 會還原遷移再執行 migrate 參考: [Laravel資料庫遷移(migration)](https://ithelp.ithome.com.tw/articles/10220189) ---