---
# System prepended metadata

title: Laravel 9.x DB 連線測試 多資料庫關聯 Login 模擬註冊 2022-01-04
tags: [Front end, Web server, 後端心得, Nginx, Composer, Laravel]

---

# 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)   

---