- 投稿日:2020-06-27T23:52:10+09:00
Laravel MySQL DBのカラム名を途中で変更する
目的
- Laravelにて新規作成後のDBのカラム名の変更方法をまとめる
実施環境
- ハードウェア環境
項目 情報 OS macOS Catalina(10.15.5) ハードウェア MacBook Pro (13-inch, 2020, Four Thunderbolt 3 ports) プロセッサ 2 GHz クアッドコアIntel Core i5 メモリ 32 GB 3733 MHz LPDDR4 グラフィックス Intel Iris Plus Graphics 1536 MB
- ソフトウェア環境
項目 情報 備考 PHP バージョン 7.4.3 Homwbrewを用いて導入 Laravel バージョン 7.0.8 commposerを用いてこちらの方法で導入→Mac Laravelの環境構築を行う MySQLバージョン 8.0.19 for osx10.13 on x86_64 Homwbrewを用いてこちらの方法で導入→Mac HomebrewでMySQLをインストールする 前提情報
- MySQLを使用しているが確認箇所以外はそのほかのRDSでも作業内容は変わらない。
- カラム名を変更するとLaravelアプリで自分で実装したデータ取得処理を変更しないといけない場合があるので注視する。
- すでに存在するカラムの名前を変更する際の方法を記載する。
- 本方法と応用するとカラムタイプなどの変更可能となる。
- 公式ドキュメントに記載されている内容を元に自分なりにまとめてみる。
概要
- ライブラリのインストール
- マイグレーションファイルの作成と記載
- マイグレート
- 確認
詳細
ライブラリのインストール
アプリ名ディレクトリで下記コマンドを実行してライブラリをインストールする。
$ composer require doctrine/dbalマイグレーションファイルの作成と記載
アプリ名ディレクトリで下記コマンドを実行してマイグレーションファイルを作成する。
$ php artisan make:migration rename_変更する前のカラム名_to_変更した後のカラム名_on_所属テーブル名_table --table=所属テーブル名アプリ名ディレクトリで下記コマンドを実行してマイグレーションファイルを開く。
$ vi database/migrations/YYYY_MM_DD_XXXXXX_rename_変更する前のカラム名_to_変更した後のカラム名_on_所属テーブル名_table.phpマイグレーションファイルを下記の様に修正する。(
public function up()
にはマイグレーションにより実行したい処理(今回だとカラムのリネーム)処理を記載する。public function down()
にはロールバックで実行したい(カラムのリネームを直す)処理)database/migrations/YYYY_MM_DD_XXXXXX_rename_変更する前のカラム名_to_変更した後のカラム名_on_所属テーブル名_table.php<?php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; class Rename変更する前のカラム名To変更した後のカラム名Onテーブル名Table extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::table('テーブル名', function (Blueprint $table) { //下記を追記する $table->renameColumn('変更する前のカラム名', '変更した後のカラム名'); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::table('テーブル名', function (Blueprint $table) { //下記を追記する $table->renameColumn('変更した後のカラム名', '変更する前のカラム名'); }); } }マイグレート
アプリ名ディレクトリで下記コマンドを実行してマイグレートを実行する。
$ php artisan migrate確認
下記コマンドを実行してMySQLにターミナルからログインする。(MySQLのパスワードを忘れてしまった方はこちら→Mac ローカル環境の MySQL 8.0 のrootパスワードを忘れた時のリセット方法)
$ mysql -u root -p下記を実行してカラム名が変更されたことを確認する。
mysql> show columns from DB名.テーブル名;参考文献
- 投稿日:2020-06-27T18:26:24+09:00
【Laravel】グローバルスコープを用いてコード量を減らす
はじめに
実装していてモデルのクエリに制約で何度も同じ実装することはありませんか。
そんな時はグローバルスコープというLaravelの機能のグローバルスコープを使って1回の実装で済むようにするのも1つの方法かなと思います。グローバルスコープとは
グローバルスコープにより、指定したモデルの全クエリに対して、制約を付け加えることができます。Laravel自身のソフトデリート機能は、「削除されていない」モデルをデータベースから取得するためにグローバルスコープを使用しています。独自のグローバルスコープを書くことにより、特定のモデルのクエリに制約を確実に、簡単に、便利に指定できます。
グローバルスコープを1回の実装すれば特定のモデルのクエリに制約ができ、かなり便利です。
グローバルスコープの実装
Illuminate\Database\Eloquent\Scope
配下に適当なファイルを作成します。walkingMinutes.php<?php namespace App\Scopes; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Scope; class walkingMinutesScope implements Scope { /** * Eloquentクエリビルダへ適用するスコープ * * @param \Illuminate\Database\Eloquent\Builder $builder * @param \Illuminate\Database\Eloquent\Model $model * @return void */ public function setGlobalScope(Builder $builder, Model $model) { static::addGlobalScope('walking_minute', function (Builder $builder) { $builder->orderByRaw('walking_minute' ASC NULLS LAST); }); } }こんな感じに実装するとどこでもwalking_minutes(徒歩時間)が短い順に表示できるようになります。
おわりに
いかがでしたでしょうか。
うまく実装して無駄な実装を減らしていきましょう。
- 投稿日:2020-06-27T16:46:01+09:00
【PHP】DateIntervalクラスで、あさってが「1日差」になっちゃった!?
環境
CentOS 7.6
PHP 7.1.20現象
PHPの DateInterval クラス は、
今日が 2020/01/01 とすると、2020/01/03 との日数差が
なぜか「1」で返る場合があります(2が欲しいのに。)$date1 = new DateTime(); //今日 $date2 = new DateTime('2020-01-03'); //あさって $diff = $date1->diff( $date2 ); echo $diff->days; // 1原因
今日の
$date1 = new DateTime();
に現在時刻が含まれているからです。
その分、日数差が2日に届かず、1日となっているようです。例えば 現在時刻をクリアすれば、期待する「2」が得られます。
$date1 = new DateTime(); $date1->setTime(0,0,0); //時刻クリア $date2 = new DateTime('2020-01-03'); $diff = $date1->diff( $date2 ); echo $diff->days; // 2余談ですが、DateTime::diff のマニュアルには、
英語コメントに同様の記述がありました。参考
- 投稿日:2020-06-27T16:27:52+09:00
Laravel開発用のDockerイメージできたのでシェアします。
これからLaravelを使って開発とかしていく予定だったので、すぐにスタートできるようにDockerでイメージ作りました。
同じ環境で開発してる方など、よかったら持ってってください。https://hub.docker.com/r/ryuki0529/webserver
大まかなイメージ環境
- OS:CentOS 7.8
- サーバー:Apache 2.4.6
- PHP 7.4.7
- PHPMyAdmin 5.0.2
- Composer 1.10.7
- Laravel Installer 3.1.0
- Git 2.9.5
- データベース:mysql Ver 15.1 Distrib 10.4.13-MariaDB
注意点
docker run
でコンテナ作るときに、--privileged
と起動時のコマンドで/sbin/init
を指定しないとsystemctl
コマンド周りが使えないので注意です。これで3時間ほどハマってしまいました。詳しくは下記の記事で説明されてます。
CentOS7のコンテナでsystemctlを使うための方法ということで、最終的にコマンドは以下になります。
docker run -itd -p 80:80 --privileged webserver:1.0.2 /sbin/init docker exec -it webserver /bin/bash
- 投稿日:2020-06-27T13:43:22+09:00
Eccube で OutOfMemoryException が出た時にやってみたこと
$qb = $em->getRepository('Eccube\Entity\Order')->createQueryBuilder('o'); $qb // query builder に関する処理 ... ; $query = $qb->getQuery(); $result = $query->getResult(); foreach($result as $Order) { // Order に対する処理 }こうすると巨大なOrder オブジェクトに対して一度に処理することになりOutOfMemoryException が発生した。
ので、
$qb = $em->getRepository('Eccube\Entity\Order')->createQueryBuilder('o'); $qb // query builder に関する処理 ... ; $query = $qb->getQuery(); $iterableResult = $query->iterate(); foreach($iterableResult as $count => list($Order)) { // list() でアンラップ // Order に対する処理 if (++$count % 1000 === 0) { $em->clear(); // 1000回トラバースする毎にEntityManagerのオブジェクトを開放 } }\$query->getResult() で結果セット全体を一度に持ってきていたところを、$query->iterate() で一つずつ処理するようにし、1000回処理するごとにメモリーを開放するようにしました。
これでOutOfMemoryException が起きなくなりました。
iterate で持ってきた result は array でラップされているとのことで、list() でアンラップすればgetResult() のときの \$Order と同じように扱えます(\$Order->getId() とかが使える)。
- 投稿日:2020-06-27T11:15:41+09:00
【SQL】3つのテーブルのリレーション方法
はじめに
こんにちは、takumi(@takumidiary)です。
タイトルの通り今回は3つのテーブルのリレーションをします。WEBサービスを開発している過程で3つのテーブルをリレーションしないといけない場面があったので調べながら実装しました。意外と簡単です。
環境
OS :
mac Catalina vaersion10.15.5
ディベロッパーツール :MAMP version 5.7
目次
1. テーブルの準備
2. リレーションする
2-1. 方法1〜外部結合
2-2. 方法2〜内部結合
3. おわりに1. テーブルの準備
以下の3つのテーブルを準備します。
phpMyAdmin使いました。
- userテーブル
- areaテーブル
- itemテーブル
userテーブル
id name area_id 1 浦島 1 2 桃 4 3 猿 3 4 雉子 3 5 犬 2 areaテーブル
id name 1 竜宮城 2 犬小屋 3 動物園 4 家 5 北海道 itemテーブル
id name user_id 1 刀 2 2 黍団子 2 3 宝 1 4 羽根 4 5 ドッグフード 5 2. リレーションする
2つの方法でリレーションしていきます。
2-1. 方法1〜外部結合
sql文
SELECT * FROM user LEFT JOIN item ON user.id=item.user_id LEFT JOIN area ON user.area_id=area.id;このsql文をphpMyAdminのsqlタブに入力して実行します。
実行結果
2-2. 方法2〜内部結合
sql文
SELECT * FROM user INNER JOIN item ON user.id=item.user_id INNER JOIN area ON user.area_id=area.id実行結果
3. おわりに
今回は簡単のため、'WEHERE'句などは使っていないので条件を追加したりして自分で試してみましょう。
間違いなどありましたら、ご指摘お願いします。
- 投稿日:2020-06-27T10:46:19+09:00
foreach と type="radio" の共存の仕方
foreach (PHP)
<?php $fruits = ["ぶどう", "みかん", "もも"]; foreach ($fruits as $value) { echo $value; } ?>こう表示される
ぶどうみかんもも
type="radio" (HTML)
<input type="radio">ガッチャンコする
<?php $fruits = ["ぶどう", "みかん", "もも"]; foreach ($fruits as $value) { ?> <input type="radio"> <?php echo $value; } ?>こんな感じで表示される
●ぶどう●みかん●もも
思ったこと
ベースをHTMLにして書いてるからPHPとして埋め込んで書くところをちゃんと指定して区別してやってあげないとね!って感じ