20210213のMySQLに関する記事は5件です。

Redash使う時に、知らなかったSQLの書き方を学びました

Redash使う時に、知らなかったSQLの書き方を学びました

概要

最近、redashでsqlを書く機会が多く、こんな書き方があったのかとsqlに関して勉強をしなおしているので、学んだことをここに書きます

目次

  1. Redashとは
  2. 月ごとにデータを表示させたい
  3. 週ごとにデータを表示させたい
  4. 日付指定をする方法
  5. having
  6. case when と or null
  7. データ連携

1. Redashとは

Redashは、SQLの分析結果をわかりやすく可視化し共有するオープンソースBIツールです。

簡単にいうなら、DBのデータやGoogleアナリティクスなどからデータを取得してきて、グラフなどに表示させてくれます
また、定期的に作成したクエリの実行や、slackへグラフの表示など色々と便利なツールです
https://redash.io/

2. 月ごとにデータを表示させたい

月ごとにユーザ数の推移を見たい時に使います

//月ごと
DATE_FORMAT(date,![スクリーンショット 2021-02-13 22.04.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/472696/21b04bae-6761-9cb0-170e-dbf57368b5e2.png)
 '%Y-%m')

//group by を使用して月ごとに分ける
group by DATE_FORMAT(date, '%Y-%m') 

3. 週ごとにデータを表示させたい

月ではなくて、もっと細かく週で見たい時に使えます

//週ごと
DATE_FORMAT(consultation_date, '%Y-%U weeks') 

//group by を使用して週ごとに分ける
group by week 

4. 日付指定をする方法

月でも週でもなくて、その時に欲しい値が欲しいから、指定してデータを取得したい場合に使えます

WHERE 
    date >= "{{start_date}}"
   AND date <= "{{end_date}}"

スクリーンショット 2021-02-13 22.05.00.png

5. having

havingはgroup byと一緒に使用します
staff_idでわけて、さらに合計金額が1万円以上に該当する値のみ表示させています

group by staff_id
having sum(money) >= 10000 

6. case whenor null

例えば男女それぞれの人数を出したい時に使えます

select
 case sex
        when 'man' then '男性'
        when 'woman' then '女性'
    end as '性別',
    count(sex) as '人数'
from members
where date >= "2021-02-01"
 group by 性別

スクリーンショット 2021-02-13 22.16.09.png

or null を使用しても人数は出すことができます

select
 count(sex = "man" or null) as 男性,
 count(sex = "woman" or null) as 女性
from members
where registration_date >= "2021-02-01"

スクリーンショット 2021-02-13 22.18.31.png

違い

case whenを使用した場合は、同じカラムに値が入っているのでpieチャートを作成することができるのですが、or nullでは、違うカラムに値を出しているのでpieチャートの作成をしてくれないです
スクリーンショット 2021-02-13 22.23.32.png

7. データ連携

このデータ連携はアナリティクスからデータを取得したい時にも活用できますし、1つのクエリでうまく取得ができない時や、gorup byで基準をそれぞれ分けたい時に2つのクエリを作って最終的には1つのグラフに表示させたい時などに活用できます

SELECT
    a.name,
    b.year
FROM query_111 a
LEFT JOIN query_112 b ON b.id = a.staff_id
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Attempt to read property on nullの解決

LaravelでAttempt to read property on nullが出た話

記事内容

本記事ではLaravelで自作の認証機能を実装していた際に、本題のエラーが出たので、その解決方法を書き下ろします。

開発環境

Laravel 8.22.1
PHP:8.0.1
MySQL:8.0.23
MacOS:11.1 ( Big Sur )

やろうとしていること

ビューで入力フォームと、データベースにcompaniesテーブルを作成し、
ユーザーから入力された値と、テーブルに格納されているデータ(カラム:company_id)と一致するものがあれば、ページを遷移させる。
一致するものがなければ、簡単なエラーメッセージを返すというもの。

テーブル

○○_create_companies_table.php
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateCompaniesTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('companies', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('company_id')->unique();
            $table->string('name');
            $table->timestamps();
        });
    }

今回の認証に利用したのはcompany_idカラムのみの簡単なもの。

Blade

login.blade.php(一部)
<div class="cpylogin-block">
  <form action="/company/login" method="post">
    <label for="company_id">会社/団体ID</label>
    <input type="text" name="company_id" value="{{ old('company_id') }}" placeholder="ID" required>
    <div class="btn-area">
      <button>ログイン</button>
    </div>
    {{ csrf_field() }}
  </form>

フォームの入力値も1つのみ。inputタグのname属性をcompany_idとする。
ちなみにloginブレードはコントローラの記述より、route/web.phpから呼び出しています。

Controller

LoginController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

use App\Models\Company;

class CpyLoginController extends Controller
{
    //
    public function index(Request $request)
    {
        return view('pages.cpylogin');
    }

    public function post(Request $request)
    {
        // Companyモデルからcompany_idで情報を検出→オブジェクト化
        $company = Company::where('company_id', $request->company_id)->first();
        $msg = ['msg' => '入力されたIDは存在しません'];

        if ($request->company_id === $company->company_id) {
            return redirect()->route('usrlogin');
        }
        else {
            return view('pages.cpylogin', $msg);
        }
    }
}

・LoginControllerのpostメソッドで認証機能が動くように記述。
Authを使っていない上に、よくあるuserモデルでのログイン機能ではないことをあらかじめ把握しておいてください。

・if文のところで、フォームのinputタグに入力された値がcompanyモデルのcompany_idカラムに保存されているデータと一致するものがあれば、usrloginビューを表示する。

実行

スクリーンショット 2021-02-13 19.04.55.png

Attempt to read property "company_id" on null とエラーになる。
日本語訳すると、「“company_id” プロパティをnullなのに読み込もうとしている。」の意味(少しズレてるかも)。

原因

エラーの原因はControllerの中の、companyモデルを呼び出す記述にありました。

LoginController.php
--- 省略 ---

    public function post(Request $request)
    {
        // Companyモデルからcompany_idで情報を検出→オブジェクト化
        $company = Company::where('company_id', $request->company_id)->first();

--- 省略 ---

    }

\$company変数の定義を間違えていました。
\$company変数を、\$request->company_idと、フォームで入力された値と紐付けるのではなく、
companyテーブルに存在する全てのデータをオブジェクト化したものにするべきでした。

解決策

ということで、\$company変数の定義を下記のように書き換えると解決しました。

LoginController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

use App\Models\Company;

class CpyLoginController extends Controller
{
    //
    public function index(Request $request)
    {
        return view('pages.cpylogin');
    }

    public function post(Request $request)
    {
        $validate_rule = $request->validate([
            'company_id' => ['required']
        ]);

        // Companyモデルからcompany_idで情報を検出→オブジェクト化
        $company = Company::all()->first();
        $msg = ['msg' => '入力されたIDは存在しません'];

        if ($request->company_id === $company->company_id) {
            return redirect()->route('usrlogin');
        }
        else {
            return view('pages.cpylogin', $msg);
        }
    }
}

\$company変数をCompanyモデルから全て取り出しオブジェクト化したデータと定義することで、うまくいきました。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

MySQLdbで文字コードエラー

こんなエラー

Traceback (most recent call last):
....
    cursor.execute(sql)
  File "/home/user/.local/lib/python3.6/site-packages/MySQLdb/cursors.py", line 188, in execute
    query = query.encode(db.encoding)
  File "/usr/lib/python3.6/encodings/cp1252.py", line 12, in encode
    return codecs.charmap_encode(input,errors,encoding_table)
UnicodeEncodeError: 'charmap' codec can't encode characters in position 486-487: character maps to <undefined>

対策
デフォルトでlatin-1を使うらしいので、接続時に明示的にエンコードコード方法を指定

conn = MySQLdb.connect(
    host=host,
    db=dbname,
    port=port,
    user=user,
    passwd=password,
    use_unicode=True,
★これ  charset="utf8mb4"
)

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

flaskにwebアプリをデプロイして躓いたこと

概要

いくつものエラーを解決して、ようやくflaskフレームワークによるWebアプリが完成しました。

内容はかなりシンプルかつジュニアレベルなもので
言ってしまえば単なるメモ帳のようなものです。
或いは自分しか存在しないtwitterのタイムラインといえば伝わりやすいでしょうか。
https://young-mesa-87008.herokuapp.com/

できること

・ユーザ登録
・メモの記録
・過去の記録を閲覧

実装してみた主な機能

パスワードはsalt・sha256関数によるパスワードのハッシュ化&認証
ログイン・ログアウトはsessionライブラリによるセッション管理を実装
herokuのDBアドオンによるClearDBサーバに対し、PyMysqlをドライバとして使用

開発で躓いたところ:cry:

その1:ログイン後、逐一セッションが切れる

ログインに成功して、ひとまず機能動作確認の為
ぐるぐるページ遷移したりガチャガチャ操作していると
突然 500 error が返されることがありました。

原因の究明

まず、heroku logs --tailでErrorの内容を見ると
デコレータによってsessionを確認した際、KeyErrorを起こしているようでした。

ERROR in app: Exception on /user/home [GET]
return super(SecureCookieSession, self).__getitem__(key)
KeyError: 'login'


そもそもの処理内容としましては
アプリ内で登録したユーザでログインを行った後、
メモを記載するページや過去の記録を閲覧するページに遷移できるのですが
その際、login_requiredデコレータで現在ログインしているユーザの情報をsessionから取得させるようにしていました。

app.py
# ログイン時に呼ばれる関数
@app.route('/login/try', methods=['POST'])
def login_try():
    name = request.form.get('name')
    pwd = request.form.get('pwd')
    result = check_user(name, str(pwd))
    if result:
        # ↓ ココで辞書型配列であるsessionに
        #   'login'をKey値としてnameを格納
        session['login'] = name

def login_required(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        # ↓ ココで問い合わせ
        if not is_login():
            return redirect('/login')
        return func(*args, **kwargs)
    return wrapper

# セッション管理
def is_login():
    # 辞書型配列のsessionから loginをキーに持つ値を返す。 
    return 'login' in session

調査として、flaskのsession絡みのコード記事
app.secret_keyに関する質問記事を読むと、
sessionの確立にはapp.secret_keyをsetする必要があり
またkey値はアプリケーション内で同一のものを使用する必要がありました。

そこで自身のコードを見直してみると..

app.py
# ランダム文字列生成
def randomname(n):
    randlst = [random.choice(string.ascii_letters + string.digits) for i in range(n)]
    return ''.join(randlst)

# Flaskインスタンスと暗号化キーの指定
app = Flask(__name__)
app.secret_key = randomname(16)

上記のようにapp.secret_keyの値を関数によって算出し、
使用していることが原因のようでした。
アプリケーションを再起動するたびに、新しいキーが与えられるため、以前のキーは無効になります。
つまり、最初に定義したキーが無効になり、新しいsecret key の下でsessionが定義されるので、当然参照したsessionのKeyは空となり、KeyErrorが発生していたようです。

修正対応としては、
①iniファイルに機密情報(16文字のstring)を記載しておく
②iniファイルを読み込むインタラクティブなモジュール(ini.py)を用意
③ini.pyをメインモジュール(app.py)にimportして流用する
といった対応にしました。

app.py
import secret

app.secret_key = secret.ini_key
ini.py
import configparser

ini = configparser.ConfigParser()
ini.read('config.ini', encoding='UTF-8')
ini_key = ini['secret_key']['sec_key']
config.ini
[secret_key]
sec_key = XXXXXXXXXXXXXXXX

その2:複数のクエリを実行したい時、Pymysqlのconnentionが確立しない

これはselectやinsertのクエリをウォーターフォールで実行するテストを行った時に出会いました。以下のpyを呼び出すと、ins_queryの実行タイミングで
raise err.Error("Already closed")が返されてしまいます。

mysql.py
    # select
    def query(stmt, *args):
        try:
            with conn.cursor() as cursor:
                cursor.execute(stmt, (args))
                data = cursor.fetchall()
        finally:
            conn.close()
            cursor.close()
            return data

    # insert
    def ins_query(stmt, *args):
        try:
            with conn.cursor() as cursor:
                cursor.execute(stmt, (args))
                data = cursor.fetchall()
        finally:
            conn.commit()
            conn.close()
            cursor.close()
            return True

原因の究明

こちらの記事を参考にしました。
1つ目のquery()実行後、conn.close()を行い、
2つ目のins_query()実行時には、cursorを定義して接続しようとしていますが
一度閉じた接続を再接続するにはself.connnection.ping() を投げてやる必要があるようです。
以下のように、cursorによるDB接続試行前に、conn.ping()を書くことで
修正に至りました。

class MySQL:

    # select
    def query(stmt, *args):
        try:
       # ↓ここ
            conn.ping()
            with conn.cursor() as cursor:
                cursor.execute(stmt, (args))
                data = cursor.fetchall()
        finally:
            conn.close()
            cursor.close()
            return data

    # insert
    def ins_query(stmt, *args):
        try:
       # ↓ここ
            conn.ping()
            with conn.cursor() as cursor:
                cursor.execute(stmt, (args))
                data = cursor.fetchall()
        finally:
            conn.commit()
            conn.close()
            cursor.close()
            return True

その3:記録を投稿した時刻と、閲覧した時に返される時刻が9時間ずれている

例えば
投稿した時間→ 2/13 0:50の場合
表示される時間→2/12 15:50
9時間前に投稿したことになっていました。

現在時刻は以下のように取得しています。

app.py
# 今日日付取得
def get_today():
    d = datetime.datetime.now()
    today = (d.strftime('%Y-%m-%d'))
    return today

# 現在時刻取得
def get_time():
    t = datetime.datetime.now()
    time = (t.strftime('%H:%M:%S'))
    return time

原因の究明

恐らくタイムゾーンの設定ではないかと、ClearDBの設定値を疑いましたが
DBの設定値を直接変えることはできず、heroku上で変更が可能だそうです。
herokuのタイムゾーン設定変更

heroku config:add TZ=Asia/Tokyo --app [app-name]

終わりに

現在の業務が忙しく(言い訳)、なかなか勉強する時間が取れず(言い訳)
昨年6月頃から始めた学習を滞らせていましたが
ようやくサーバに自作アプリをアップロードさせることが出来、
一つ達成感を得ることが出来ました。

ただ、実装した機能は初歩中の初歩ですし、
まだまだ改善の余地があると思います。
それに今後商用アプリを作成するならばもっとセキュアにする必要もありますね。
今後もpythonやフロントサイドのoutputとして開発を積み上げていきたいです。

次回はAPI連携や機械学習を取り入れたサービスを創ろうと思います。
また、PHPやvue.jsといった言語も取り入れて、より動的なアプリを作ってみたいです。
それと、他のRuby on Rails, Django, Lavarelといったフレームワークも挑戦してみたいと思います。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Laravel8.xのプロジェクトをXREAで無料公開する

概要

Laravel8+MySQLで作ったプロジェクトを無料でホスティングしたいなーと思って調べていたら、XREA(エクスリア)というレンタルサーバーを見つけました。無料プランながらシンプルで使いやすく、Laravelアプリの公開もかなり簡単にできたので、こちらに手順をまとめておきます。
Laravel以前にかなり基本的な部分から書いてありますので、わかる部分は適当に読み飛ばして使ってください。

前提

  • Laravel8系のプロジェクトができている
  • githubなどにソースコードが上がっている
  • (MacOS)

手順

1. バリュードメインのユーザー登録、XREAのアカウント作成

2. ドメインの購入(特にこだわりがなければ必要ありません)

3. XREAで各種設定
- 3.1 SSH接続の許可
- 3.2 DBの作成
- 3.3 サイト設定の変更 (ドメインを購入していない場合のみ)
- 3.4 ドメイン設定(ドメインを購入した場合のみ)
- 3.5 サイト設定(ドメインを購入した場合のみ)

4. SSHログイン
- 4.1 シェルをbashに変更
- 4.2 composerのセットアップ
- 4.3 node,npmのバージョンアップ

5. プロジェクトの設定
- 5.1 git cloneで持ってくる
- 5.2 composer、npm周り
- 5.3 .envの設定
- 5.4 マイグレーション等

6. シンボリックリンクの設定

変に詰まらなければ20分くらいで終わると思います。

1. バリュードメインのユーザー登録、XREAのアカウント作成

https://www.xrea.com/signup/

こちらにアクセスして手順通りにバリュードメインとXREAの登録をします。

  • バリュードメイン
    image.png

  • XREA
    test2.png

2021年2月現在、XREAに登録すると1年間無料で.shopのドメインがついてきます。次の2.ドメインの購入を行わない方は、ここで決めたアカウント名がそのままURLになります。
希望のサーバー選択はおそらく無料プランでは選べないようになっているので、そのまま登録してください。

2. ドメインの購入

希望のドメインがある方は、バリュードメインのドメイン登録から、希望のドメインの検索をして購入します。

https://www.value-domain.com/domain/search/
image.png

現在は.tokyoドメインが安く、(取られてなければ)初年度25円で取得できるみたいです。
支払いもクレジットカードからコンビニ決済まで対応しているので結構気軽に買えます。
image.png
購入後は登録者情報の入力など手順通りに進めてください。

3. XREAでの各種設定

XREA登録時にメールが届いているので確認します。
test.png
ログインに必要な情報が記載してあるので、これを使ってXREAにログインします。
https://cp.xrea.com/account/login/

XREAのパスワードはバリュードメインに自分で登録したものとは違うので注意してください。
また、XREAでは独自のパスワードが設定できないため、このパスワードはどこかにメモしておくといいと思います。
test.png
ログイン後の画面です。
test.png
※もし旧コントロールパネルが表示されている場合は、右上の新コンパネ切替をONにして新コントロールパネルに移行します。
image.png

3.1 SSH接続の許可

メニューのサイト設定からツール/セキュリティーを開き、下の方にあるSSH接続IP許可のボタンをクリックします。
これでSSH接続が可能になります。
image.png

3.2 DBの作成

メニューのデータベースから、データベースの新規作成をクリックします。
test.png
無料プランでは、XREAのユーザー名がそのままDB名になります。
パスワードは後ほど.envのDB情報に入力するので覚えておいてください。
 

3.3 サイト設定の変更 (ドメインを購入していない場合のみ)

ついてきた.shopのドメインを使う場合は、以下の設定をしてください。

メニューのサイト設定から、wwwのついている方のサイトについての設定を変更します。
test.png
PHPのバージョンが7.3以上でないとLaravel8は動かないため、バージョンを7.4にします。
test.png

3.4 ドメイン設定 (ドメインを購入した場合のみ)

購入したドメインを使う場合は以下の設定をしてください。

メニューのドメイン設定からドメイン設定の新規設定をクリックし、先ほど取得したドメインを設定します。
Frame 10.png

3.5 サイト設定 (ドメインを購入した場合のみ)

次にメニューのサイト設定から先ほど設定したドメインについて設定します。
ドメイン名に取得したドメイン、SSLは無料SSL、PHPは7.4を選んでください(Laravel8はPHP7.3以上が必要なため)。
test.png

4. SSHログイン

XREAの画面の右上に、ユーザー名とホスト名が表示されています。
test.png
コマンドラインで以下のように入力します。

$ ssh {user}@{host}

$ ssh hoge1234@s202.xrea.com

パスワードの入力を要求されるので、XREAのパスワード(先ほど送られてきたメールに記載してあるもの)をコピペで入力します。

[hoge1234@s202 ~]$

このように表示されればログイン成功です。

4.1 シェルをbashへ変更

デフォルトのシェルはrbashになっています。このままではcdなどのコマンドが使えないため、bashに変更します。

$ chsh
hoge1234 のシェルを変更します。
新しいシェル [/bin/rbash]: /bin/bash
パスワード:
シェルを変更しました。
$ exit
ログアウト
Connection to s202.xrea.com closed.

パスワードはSSHログイン時と同じです。
bashに変更したあと一度ログアウトして再度入ると変更が反映されており、cdなどのコマンドが使えるようになっています。

4.2 composerのセットアップ

Download Composerより、以下のコマンドを実行してください。
ただし、CLI版PHPを使うためコマンドがphp74cliとなっていることに注意してください。

また、2行目ではハッシュ値のチェックによりオリジナルファイルかどうかを確認していますが、このハッシュ値はcomposer-setup.phpの変更に伴って変わります。下記のハッシュがそのとき使えるとは限らないので、下記のコピペではなく上記のリンクから公式のコマンド(ハッシュ値)を持ってきて実行してください。

$ php74cli -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
$ php74cli -r "if (hash_file('sha384', 'composer-setup.php') === '756890a4488ce9024fc62c56153228907f1545c228516cbf63f885e036d37e9a59d27d63f46af1d4d07ee0f76181c7d3') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
$ php74cli composer-setup.php
$ php74cli -r "unlink('composer-setup.php');"

コマンドを実行し終えたらcomposerを叩いてみます。

$ php74cli -d register_argc_argv=1 ~/composer.phar --version
Composer version 2.0.9 2021-01-27 16:09:27

実行コマンドが長いのでエイリアスに登録しておきます。(パスの通し方がイマイチわかりませんでした…)
viで.bash_profileに以下を記載します。

.bash_profile
alias composer="php74cli -d register_argc_argv=1 ~/composer.phar"

反映します。

$ source ~/.bash_profile
$ composer --version
Composer version 2.0.9 2021-01-27 16:09:27

これでcomposerのセットアップは終わりです。

4.3 node,npmのバージョンアップ

node,npmも入っているもののかなり古いので、バージョンアップします。

$ node -v
v6.17.1

$ npm -v
3.10.10

node.js Downloads

現在のLatestはnode: 14.15.5,npm: 6.14.11だったので、とりあえずそれを持ってきます。

# curlで圧縮ファイルを取ってくる
$ curl -sSL -O https://nodejs.org/dist/v14.15.5/node-v14.15.5-linux-x64.tar.xz

# 解凍
$ tar xvf ./node-v14.15.5-linux-x64.tar.xz

# 圧縮ファイルの削除
$ rm node-v14.15.5-linux-x64.tar.xz

#ディレクトリを用意する
$ mkdir ~/.local/lib

# 移動する
$ mv ./node-v14.15.5-linux-x64 ~/.local/lib/

パスを通すために.bash_profileに以下を追記します。

.bash_profile
export PATH="${HOME}/.local/lib/node-v14.15.5-linux-x64/bin:${PATH}"

反映します。

$ source ~/.bash_profile
$ node -v
v14.15.5

$ npm -v
6.14.11

nodeとnpmのバージョンアップもできました。

5. プロジェクトの設定

5.1 git cloneで持ってくる

ホームディレクトリのpublic_html内には、XREAのサイト設定にあるサイトごとにディレクトリが用意されています。(ドメイン購入をした場合は、元からついている.shopのディレクトリに加えて購入したドメインのディレクトリがあると思います。)

$ cd ~/public_html/
$ ls
log  hoge1234.shop

XREAではデフォルトでgitが使えます。
使いたいドメインのディレクトリに入り、git cloneします。

$ cd hoge1234.shop
$ git clone https://github.com/hoge/fuga.git

5.2 composer, npm周り

ここはローカルでの作業とあまり変わりません。
cloneしたプロジェクトのディレクトリに入り、下記コマンドを実行します。

# composerのライブラリのインストール
$ composer install

# npmパッケージのインストール
$ npm install

# LaravelMixでアセットをコンパイル
$ npm run dev

5.3 .envの設定

.envをサーバーに合わせて設定していきます。

$ cp .env.example .env
$ vi .env

以下のように変更します。

.env
+ APP_NAME={appname} (自分で決めたappの名前)
+ APP_ENV=production
APP_KEY=
+ APP_DEBUG=false
+ APP_URL=https://{domain} (使うドメイン)

LOG_CHANNEL=stack
+ LOG_LEVEL=error

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
+ DB_DATABASE=hoge1234 (3.2 DBの作成 で決めたDB名、ユーザー名と同じ)
+ DB_USERNAME=hoge1234 (ユーザー名)
+ DB_PASSWORD={password} (3.2 DBの作成 で決めたパスワード)

5.4 migration等

こちらもローカルでの作業と変わりません。
ただし、artisanコマンドを使用する際はphp74cli artisanとなることに注意してください。

# keyの生成
$ php74cli artisan key:generate

# migration
$ php74cli artisan migrate

# seederがある場合
$ php74cli artisan db:seed

ローカルで動かす時と同じようにコマンドを叩いてください。

6. シンボリックリンクの設定

Laravelプロジェクトの準備はできたので、参照先の設定をします。
ここもついてくる.shopを使う方とドメインを購入した方とで少し違うので注意してください。

現在のディレクトリ構成は以下のようになっていると思います。

public_html
    |
    |-- {domain}
           |
           |-- {appname}
                   |
                   |-- app
                   |-- bootstrap
                   |-- config
                   |-- database
                   |-- ...
                   |-- ...
                   |-- public
                   |-- ...

.shopを使う場合、hoge1234.shopにアクセスするとwww.hoge1234.shopにリダイレクトされ、~/public_html/をルートとしてファイルを参照するようになっています。

~/public_html/を参照した際に、~/public_html/{domain}/{appname}/public/のファイルを代わりに参照するようにします。

$ ln -s ~/public_html/{domain}/{appname}/public/index.php ~/public_html/index.php
$ ln -s ~/public_html/{domain}/{appname}/public/.htaccess ~/public_html/.htaccess
$ ln -s ~/public_html/{domain}/{appname}/public/js ~/public_html/js
$ ln -s ~/public_html/{domain}/{appname}/public/css ~/public_html/css
$ ln -s ~/public_html/{domain}/{appname}/public/img ~/public_html/img
$ ln -s ~/public_html/{domain}/{appname}/public/mix-manifest.json ~/public_html/mix-manifest.json
$ ln -s ~/public_html/{domain}/{appname}/public/robots.txt ~/public_html/robots.txt
$ ln -s ~/public_html/{domain}/{appname}/public/favicon.ico  ~/public_html/favicon.ico

購入したドメインを使う場合、fuga1234.comにアクセスすると~/public_html/fuga1234.com/をルートとしてファイルを参照するようになっています。
~/public_html/fuga1234.com/を参照した際に、~/public_html/{domain}/{appname}/public/のファイルを代わりに参照するようにします。

$ ln -s ~/public_html/{domain}/{appname}/public/index.php ~/public_html/{domain}/index.php
$ ln -s ~/public_html/{domain}/{appname}/public/.htaccess ~/public_html/{domain}/.htaccess
$ ln -s ~/public_html/{domain}/{appname}/public/js ~/public_html/{domain}/js
$ ln -s ~/public_html/{domain}/{appname}/public/css ~/public_html/{domain}/css
$ ln -s ~/public_html/{domain}/{appname}/public/img ~/public_html/{domain}/img
$ ln -s ~/public_html/{domain}/{appname}/public/mix-manifest.json ~/public_html/{domain}/mix-manifest.json
$ ln -s ~/public_html/{domain}/{appname}/public/robots.txt ~/public_html/{domain}/robots.txt
$ ln -s ~/public_html/{domain}/{appname}/public/favicon.ico  ~/public_html/{domain}/favicon.ico

public内の各ファイルについてシンボリックリンクを貼っています。
他にもpublic内にfontsなど別のアセットがある場合はその分のシンボリックリンクも貼ります。

これでURLにアクセスしてみて、表示されていたら成功です。

.shopを使う場合、SSL設定ができないのでhttps://をつけると上手くいきません。

最後に

ここまで書きましたがやっぱりherokuの方が楽な気がし
XREAでLaravelプロジェクトを無料公開する手順を最初から最後まで書いている記事が見つからなかったため、いろいろ調べた勢いで書いてみました。
ところどころ知識が甘く曖昧な表現などがあると思いますが、「とりあえずなんでもいいからLaravelで作ったものを公開してみたい!」という方のお役に立てれば幸いです。

参考記事

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む