php – laravel – 將已存在的資料庫匯出 migration 與 seed

匯出 Migration

首先安裝這個套件,先匯出 DB Schema 到 migration

composer require --dev "xethron/migrations-generator"

Laravel 5.5 以後的版本,下載好後就不需安裝任何的 Providers。使用方法如:

// 所有資料表
php artisan migrate:generate

// 指定資料表
php artisan migrate:generate table1,table2,table3,table4,table5

// 所有資料表但排除某些表,可加參數
--ignore="table3,table4,table5"

// 檢視所有可選用的參數
php artisan help migrate:generate

不過資料表欄位的型態,若是 Enum 的時候,目前版本 v2.0.2 會出錯,請修改 src/Xethron/MigrationsGenerator/Generators/FieldGenerator.php

protected function setEnum(array $fields, $table)
{
    foreach ($this->getEnum($table) as $column) {
        $column_name = isset($column->column_name)
            ? $column->column_name
            : $column->COLUMN_NAME;

        $column_type = isset($column->column_type)
            ? $column->column_type
            : $column->COLUMN_TYPE;

        $fields[$column_name]['type'] = 'enum';
        $fields[$column_name]['args'] = str_replace('enum(', 'array(', $column_type);
    }
    return $fields;
}

主要是 MySQL 8 返回的欄位名稱是大寫, MariaDB 返回的是小寫,需要稍作修改就可以了。我提出了合併請求,不過我看目前開發者合併停滯在 2017 年,因為這個功能僅單次使用,我也就不再 fork 了,手改一下就好。

匯出 Seed

接著產出 seed,就下載這個套件

composer require orangehill/iseed

一樣 Laravel 5.4 以後不需要做任何安裝設定。比較麻煩的是要個別指定匯出的資料表名稱,使用方法如

// 匯出所需資料
php artisan iseed my_table
php artisan iseed my_table,another_table

// 產出的 seeder class 名稱加入前綴
php artisan iseed my_table --classnamesuffix=Customizations

// 強制覆蓋已存在的 seed
php artisan iseed users --force

Mysql – mysqldump 備份還原指令

參考網友文章

備份

把 hostname 位置在 127.0.0.1 的資料庫 testdb ,匯出到 dump.sql

mysqldump -h 127.0.0.1 -u root -p testdb > dump.sql

還原

將 dump.sql 匯入到資料庫 testdb

mysql -u root -p testdb < dump.sql

php – Laravel – 解決 env() 取出的值為 null

因為 Laravel 會製作快取,所以我們要清空

php artisan config:clear

測試看看

php artisan tinker
env('DB_DATABASE')

這樣就可以正常顯示了

 

php – Laravel – 自訂 404 回傳 JSON

Laravel 5.7 預設會回傳 404 的 view。如果我們製作 API 希望回傳的是 JSON 格式的 404,那麼參考以下修改。

app\Exceptions\Handler.php

public function render($request, Exception $exception)
{
    if ($this->isHttpException($exception))
    {
        if ($exception->getStatusCode() == 404)
        {
            return response(json_encode(['error' => 'Not found.']), 404)
                ->header('Content-Type', 'application/json');
        }
    }
    return parent::render($request, $exception);
}

參考

 

php – Laravel – 透過 Gmail 發送 E-mail 信件

參考官方章節

.env 設定檔

關於使用 Gmail 的設定,可以注意這篇我提到的:在 PHP 中使用 Gmail SMTP 無法驗證的方法。透過這篇步驟,我們理當能取得下方 SMTP 的各個資訊包含密碼,我們填入吧!

MAIL_DRIVER=smtp
MAIL_HOST=smtp.gmail.com
MAIL_PORT=587
MAIL_USERNAME=帳號
MAIL_PASSWORD=密碼
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS=fdjkgh580@gmail.com
MAIL_FROM_NAME=fdjkgh580

要使用全域的 “from” (寄件者地址) 或 “reply_to” (回覆的地址),在 config/mail.php 中能發現是透過 .env 來寫入我們的 mail 設定檔,例如

'driver' => env('MAIL_DRIVER', 'smtp'),
'host' => env('MAIL_HOST', 'smtp.mailgun.org'),
'port' => env('MAIL_PORT', 587),
'username' => env('MAIL_USERNAME'),
'password' => env('MAIL_PASSWORD'),
......

Mailables

準備一個”能夠發送郵件” (Mailables) 的類別,例如產生 app\Mail\Warning.php

php artisan make:mail Warning
<?php
namespace App\Mail;

use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;

class Warning extends Mailable
{
    use Queueable, SerializesModels;

    public $params;

    // 讓外部可以將參數指定進來
    public function __construct($params)
    {
        $this->params = $params;
    }

    public function build()
    {
        // 透過 with 把參數指定給 view
        return $this->subject("警告訊息")
            ->view('emails.warning')
            ->with([
                'params' => $this->params,
            ]);
    }
}

View

而信件內容模板的變數 $params 我們會由 Controller 傳入。我們建立 /views/emails/warning.blade.php

<p>
    {{ $params['say'] }}
</p>

Router

routes/web.php

Route::get('/warning', 'WarningController@send');

Controller 寄出郵件

php artisan make:controller WarningController
<?php
namespace App\Http\Controllers;

use Illuminate\Http\Request;
// 記得使用 use
use Illuminate\Support\Facades\Mail;
use App\Mail\Warning;

class WarningController extends Controller
{
    public function send()
    {
        // 收件者務必使用 collect 指定二維陣列,每個項目務必包含 "name", "email"
        $to = collect([
            ['name' => 'Jason', 'email' => 'fdjkgh580@gmail.com']
        ]);

        // 提供給模板的參數
        $params = [
            'say' => '您好,這是一段測試訊息的內容'
        ];

        // 若要直接檢視模板
        // echo (new Warning($data))->render();die;

        Mail::to($to)->send(new Warning($params));
    }
}

這樣就能成功透過 Gmail 發送郵件囉!附帶要提的是,以上這種方法是 Laravel 比較後期的官方建議寫法,不然依照我們過去經驗例如使用過 PHPMailer ,我們可能會寫在一起,例如

Mail::send('emails.welcome', $data, function($message)
{
    $message->from('us@example.com', 'Laravel');

    $message->to('foo@example.com')->cc('bar@example.com');

    $message->attach($pathToFile);
});

雖然也可以送信,不過透過 “Mailable” 的方式,可以把整個網站的發送指派行為,全部集中在路徑app\Mail 底下;剩下在控制器中的行為也只有「用哪個 Mailable 寄給誰」。

好處就是方便維護。當我們的發送郵件行為一旦增量,例如有些要發送註冊通知信、修改密碼信、訂單成立、到貨通知、系統錯誤通知、等等非常多,要維護也只需要查看路徑 app\Mail 底下的 “Mailable” 就能很快知道有那些送件行為,省去到各個 Controller, Services, Libraries 查找的時間。