もくじ
usersテーブルにカラムを追加する
カラムを追加・変更するにはdoctrine/dbalが必要なのでインストール
$ docker-compose exec php-fpm composer require doctrine/dbal
カラム追加用のmigrationファイルを作成します。
$ docker-compose exec php-fpm php artisan make:migration add_comment_website_to_users_table --table=users
–table=<テーブル名>で指定します。
comment, websiteカラムを追加しました。commentやwebsiteで検索をかけることはないのでprofileテーブルを作ってなどして正規化はしない。
$ vi $APP_PATH//database/migrations/2019_08_11_100511_add_comment_website_to_users_table.php <?php use Illuminate\Support\Facades\Schema; use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class AddCommentWebsiteToUsersTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::table('users', function (Blueprint $table) { + $table->string('comment')->nullable(); + $table->string('website')->nullable(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::table('users', function (Blueprint $table) { // }); } }
反映させます。
$ docker-compose exec php-fpm php artisan migrate Migrating: 2019_08_11_100511_add_comment_website_to_users_table Migrated: 2019_08_11_100511_add_comment_website_to_users_table
シード用のデータを削除しておく。
comment, websiteカラムを追加したシーディングファイルにアップデートする。
$ vi $APP_PATH/database/seeds/UsersTableSeeder.php <?php use Carbon\Carbon; // 日付クラス use Illuminate\Database\Seeder; use Illuminate\Support\Facades\DB; class UsersTableSeeder extends Seeder { /** * Run the database seeds. * * @return void */ public function run() { DB::table('users')->insert([ 'id' => 1, 'name' => '優', 'email' => 'yuu@example.net', 'password' => bcrypt('pass'), + 'comment' => 'いつも頑張っています。', + 'website' => 'https://www.yuulinux.tokyo/', 'created_at' => Carbon::now(), 'updated_at' => Carbon::now(), ]); ・・・ } }
反映させます。
$ docker-compose exec php-fpm php artisan db:seed --class=UsersTableSeeder
SNS機能関係のテーブルとモデルを作る
modelとテーブルは同時に作ることも出来る
docker-compose exec php-fpm php artisan make:model Models/Following --migration docker-compose exec php-fpm php artisan make:model Models/Followed --migration docker-compose exec php-fpm php artisan make:model Models/Tweet --migration docker-compose exec php-fpm php artisan make:model Models/Tweet_picture --migration docker-compose exec php-fpm php artisan make:model Models/Tweet_nice --migration docker-compose exec php-fpm php artisan make:model Models/Tweet_comment --migration
Laravelノウハウ
基本クラスのエイリアス
$ cat $HOME/yomuyo/config/app.php ・・・ 'aliases' => [ 'App' => Illuminate\Support\Facades\App::class, 'Arr' => Illuminate\Support\Arr::class, 'Artisan' => Illuminate\Support\Facades\Artisan::class, ・・・
Composerのクラスの場所
$ cat $HOME/yomuyo/vendor/composer/autoload_classmap.php <?php // autoload_classmap.php @generated by Composer $vendorDir = dirname(dirname(__FILE__)); $baseDir = dirname($vendorDir); return array( 'App\\Console\\Kernel' => $baseDir . '/app/Console/Kernel.php', 'App\\Exceptions\\Handler' => $baseDir . '/app/Exceptions/Handler.php', 'App\\Http\\Controllers\\Auth\\ForgotPasswordController' => $baseDir . '/app/Http/Controllers/Auth/ForgotPasswordController.php', 'App\\Http\\Controllers\\Auth\\LoginController' => $baseDir . '/app/Http/Controllers/Auth/LoginController.php', 'App\\Http\\Controllers\\Auth\\RegisterController' => $baseDir . '/app/Http/Controllers/Auth/RegisterController.php', 'App\\Http\\Controllers\\Auth\\ResetPasswordController' => $baseDir . '/app/Http/Controllers/Auth/ResetPasswordController.php', 'App\\Http\\Controllers\\Auth\\VerificationController' => $baseDir . '/app/Http/Controllers/Auth/VerificationController.php', 'App\\Http\\Controllers\\BookController' => $baseDir . '/app/Http/Controllers/BookController.php', 'App\\Http\\Controllers\\Controller' => $baseDir . '/app/Http/Controllers/Controller.php', ・・・
ルーティングが有効になっているかの確認
$ docker-compose exec php-fpm php artisan route:list
{{ asset(‘パス’) }}
<img src="{{ asset('/images/19212klzds_TP_V.jpg') }}">
publicフォルダからパスで読んでくれる。
名前空間を追加したら、クラスが見つからない?
- composer.jsonに追加する。
- 名前空間を変更した場合は、『composer dump-autoload』を行う
$ docker-compose exec php-fpm composer dump-autoload
CSRF記述の変更 “419 Page Expired”
Laravel5.6以上から記述が「@csrf」になった。
{{ csrf_field() }} ↓変更 @csrf
{{ csrf_field() }}でも記述エラーにならないが、CSRF機能が動いていない罠がある。
@csrfを使おう!
composer updateとcomposer install
原則は「$ docker-compose exec php-fpm composer install」を利用する。
- そうしないと共同開発しているときにパッケージでバージョンの違いが出てします。
- composer updateはパッケージのバージョンを上げたい時のみ利用する
アップデートして正常動作したら、composer.lockはpushする
composer installしたライブラリの利用
→
サービスプロバイダにライブラリのサービスプロバイダ用クラスを登録して呼び出す。
例として
composerでsocialiteをインストールした。これをサービスプロバイダに登録する
$ view $APP_PATH/vendor/laravel/socialite/src/SocialiteServiceProvider.php <?php namespace Laravel\Socialite; use Illuminate\Support\ServiceProvider; use Laravel\Socialite\Contracts\Factory; class SocialiteServiceProvider extends ServiceProvider {
classであるSocialiteServiceProviderは、
Laravel\Socialite\SocialiteServiceProviderというパスであることがわかります。
- config/app.phpのprovidersにライブラリのクラスを登録する
- config/app.phpのaliasesにエイリアスを登録する
- ライブラリの呼び出し
・use <登録したエイリアス名>
・クラスの中でエイリアス名::利用したいライブラリの関数()
config/app.php
'providers' => [ // Other service providers... Laravel\Socialite\SocialiteServiceProvider::class, ],
config/app.phpのprovidersに「Laravel\Socialite\SocialiteServiceProvider::class」で登録します。
'aliases' => [ ・・・ 'Socialite' => Laravel\Socialite\Facades\Socialite::class, //←●追加 ],
aliasesにも登録します。
コントローラで利用する
Http/Controllers/Auth/SocialController.php
$ vi $APP_PATH/app/Http/Controllers/SocialController.php <?php namespace App\Http\Controllers\Auth; use App\Http\Controllers\Controller; use Socialite; class SocialController extends Controller { /** * Redirect the user to the GitHub authentication page. * * @return Response */ public function viewLogin() { return view('auth.login'); } /** * Redirect the user to the GitHub authentication page. * * @return Response */ public function redirectToFacebookProvider() { return Socialite::driver('facebook')->redirect(); } /** * Obtain the user information from GitHub. * * @return Response */ public function handleFacebookProviderCallback() { try{ $user = Socialite::driver('facebook')->user(); if($user){ dd($user); // OAuth Two Providers $token = $user->token; $refreshToken = $user->refreshToken; // not always provided $expiresIn = $user->expiresIn; // All Providers $user->getId(); $user->getNickname(); $user->getName(); $user->getEmail(); $user->getAvatar(); } }catch(Exception $e){ return redirect("/"); } // $user->token; } }
use Socialite;でエイリアスで登録している名前で呼び出す。
クラスの中で
エイリアス名::利用したい関数()で利用できる。
Illuminate関連の標準ライブラリの場所
$ ls $APP_PATH/vendor/laravel/framework/src/Illuminate/ Auth Cache Container Database Filesystem Http Notifications Queue Session Validation Broadcasting Config Contracts Encryption Foundation Log Pagination Redis Support View Bus Console Cookie Events Hashing Mail Pipeline Routing Translation
確認出来る。
使いたい時は
$ cat $APP_PATH/vendor/laravel/framework/src/Illuminate/Http/Request.php <?php namespace Illuminate\Http; use Closure; use ArrayAccess; use RuntimeException; use Illuminate\Support\Arr; use Illuminate\Support\Str; use Illuminate\Support\Traits\Macroable; use Illuminate\Contracts\Support\Arrayable; use Symfony\Component\HttpFoundation\ParameterBag; use Symfony\Component\HttpFoundation\Request as SymfonyRequest; class Request extends SymfonyRequest implements Arrayable, ArrayAccess {
名前空間とクラスを確認して、
useで利用できる。
use Illuminate\Http\Request;
外部キーのエラーでmigrateに失敗する
- 子テーブルのカラムを親キーのカラムと型を合わせる
- 親テーブルのファイルの日時を古く、子テーブルの日時を新しくする
親が先に生成されないと、親を参照している子テーブルは作れない。
DI
- クラスの中で別のクラスをnewしない。
- コンストラクタやセッターで別クラスを、依存性を注入する
ファサード
- サービスコンテナ(クラス)を作成
- サービスプロバイダを作成しサービスを1のサービスコンテナを登録
- ファサードを作成し名前を付ける
- $ composer dump autoload
- config/app.phpパスを通す
メリット
- 一連の機能をまとめてコントローラの肥大化を抑える
- メンテナンス性の向上
- 単純にインスタンス化するよりメモリを食わない
デメリット
- クラスの依存関係がわかりにくくなる
→DIで対応できる
@see
- 【Laravel】ファサードの仕組み ? 実装を読んで理解する
- 【Laravel】ファーサードとは
- Laravel ファサードを利用しないメリット
- Laravelファサードの作り方からその構造まで徹底解説入門
マジックメソッド
- https://public-constructor.com/php-how-to-use-magic-method/
- https://public-constructor.com/laravel-what-is-facade/
Dockerの削除
すべてのコンテナの停止、コンテナ削除、イメージ削除
docker stop $(docker ps -q) docker rm $(docker ps -q -a) docker rmi $(docker images -q)
GitHub
HEADに戻す
$ sudo git reset --hard HEAD
branch開発
●developブランチ
developブランチの作成 $ git branch develop developブランチに移動 $ git checkout develop ・・・作業する ローカルにコミット $ git add . $ git commit -m "Done!" Githubにpush! $ git push origin develop
●masterブランチ
masterブランチに移動する $ git checkout master developブランチの作業をmasterブランチにマージする $ git merge develop
ローカルのdevelopブランチを削除
$ git branch -d develop
通常はこれでOK
消せない場合は下記で
$ git branch -D develop
※git merge developでのエラー
$ git merge develop Updating 917d991..ab4ca75 error: Your local changes to the following files would be overwritten by merge: schemaspy/diagrams/summary/relationships.real.compact.dot ・・・ schemaspy/tables/users.html Please commit your changes or stash them before you merge.
masterにコミットして
$ git add . $ git commit -m "schemaspy" $ git merge develop
リモートリポジトリmasterブランチにpushする
$ git push origin master
ひやりはっと戻す
ローカルリポジトリをある地点まで戻したい
$ git checkout <ハッシュ値>
ローカルリポジトリをある地点まで戻し、リモートリポジトリも戻す※劇薬
$ git checkout <ハッシュ値> $ git reset --hard <ハッシュ値> $ git push -f origin HEAD^:master
コミットをまとめる
$ git log --graph --oneline * 653a6fc (HEAD -> master, origin/master) SNSログイン修正4 * e2bcc40 SNSログイン修正3 * bd23f32 SNSログイン修正2 * 5e84824 SNSログイン修正1 * 972790b いったんコミット
$ git rebase -i 6787c39 pick 9767b45 自分が既に押しているいいねは赤く表示する #22 r3 -pick 6787c39 自分が既に押しているいいねは赤く表示する #22 -pick 0e94891 自分が既に押しているいいねは赤く表示する #22 r5 -pick 3b5e121 r6 -pick 919d4f1 いいね対応 + s 6787c39 自分が既に押しているいいねは赤く表示する #22 + s 0e94891 自分が既に押しているいいねは赤く表示する #22 r5 + s 3b5e121 r6 + s 919d4f1 いいね対応
1つ以上pickを残してまとめたいコミットをsに変える
これで何事もなければ、
$ git push -f origin master
リモートリポジトリにpushして完了
※エラーが出た場合
error: cannot 'squash' without a previous commit You can fix this with 'git rebase --edit-todo' and then run 'git rebase --continue'. Or you can abort the rebase with 'git rebase --abort'.
git rebase –continueでコンフリクトしたファイルが見れるので修正する。VS Codeだとここらへんの修正が楽。
それからgit add -AしてリモートにpushでOK
$ git add -A $ git push -f origin master
なんか操作してミスしてりとかだったらrebaseの作業を破棄することで戻れる
$ git rebase --abort
issue機能
issue#<番号>でイッシュー用のブランチを作成し作業する
$ git branch issue#1 $ git checkout issue#1
commitする時にissue番号を入れるとリンクが作成される。
$ git add . $ git commit -m "Done! Review.phpのgetList() 全件取得時のキャッシュ機能が抜けている #1" $ git push origin issue#1
issueでcommit番号のハッシュ値を張ることで、リンクが出来る。
masterにも反映させる
masterブランチに移動 $ git checkout master masterにissue#1をマージ $ git merge issue#1 masterのリモートリポジトリ(GitHub)にもpushする $ git push origin master
issue#1ブランチの削除
$ git branch -D issue#1
課題点
ポートフォリオとして作るのが第一目的なので最後に回す。
- Google Books APIの作者データの配列が不安定で、出力に作者名を持たせるのを断念。
→Amazon PA APIか楽天APIに切り替える。 - ログイン認証
メール認証の追加、ソーシャルログイン認証を洗練させる。
※非機能部分なので見えにくいので後回し。
@see
デプロイ
Laravel
- Laravelでウェブアプリケーションをつくるときのベストプラクティスを探る (6) イベント&ジョブ編
- Laravel5.3 自作class使用方法
- Laravel の .env の値は config() 経由で使う。
- Amazonアフィリエイトのリンクをツールなしで作成する方法
- 多言語化
- Laravel使用時に困った点と対処方法
- LTSV FAQ – LTSV って何? どういうところが良いの?
- Laravel 5 Pagination with array
- コレクション 5.5 Laravel
- 【5.5対応】Laravel の Collection を使い倒してみたくなった 〜 サンプルコード 115 連発 1/3
- Laravelのmiddleware authを理解したい
- 素のPHPでも最低限.envとmonologくらいは使う際の手順,オレオレClassもautoloadできるようにしておく
- migrationの操作(データ型の変更)
- 【Laravel 5.7対応】掲示板を作成するチュートリアル
- LaravelでRoute::resourceを使うときに気をつけること
- 危険!Laravelで「config:cache」を使う時の注意点
ログイン
ルーティング
オブジェクト指向
Eloquant
- 【Laravel:Eloquentクラス】fillableとguardedの指定はどちらかだけでいい
- LaravelでインサートしたデータのID値を確認する
- Laravel・データベースからデータ取得する全実例
- Laravelのクエリビルダ記法まとめ(QueryBuilder/DB Facade)
- 【Laravel】1対多のテーブルリレーション・hasMany/belongsToとは?
- Laravel5 QueryBuilderでgroupByが動かない時の対応方法
- LaravelクエリビルダーのDB::rawで変数の値をバインドしようしたら詰まった
- ちょっと複雑なSQLをEloquentに落とし込むためのメモ
- laravel-eloquent-select-case
データベース設計
- DB論理設計のノウハウ
- なぜTwitterは低遅延のままスケールできたのか。秒間120万つぶやきを処理、Twitterシステムの“今”
- 【初心者向け】丁寧すぎるRails『アソシエーション』チュートリアル【幾ら何でも】【完璧にわかる】
- SNSをつくるときのテーブル設計
- 1日に100万レコード増える場合のテーブル設計
SNSテーブル設計例
- https://github.com/yoosuf/Messenger
- reverse engineering through Facebook business entities
- Database Answers
- Social Network Friends Relationship Database Design
- Design a friends table for a social networking site
- 【MySQL入門】データベースの概要
ロック, デッドロック
- デッドロックおじさん戦記
・同一テーブルのレコードのインスタンス同士がやり取りする時は、ソートしてから更新する。
ユーザ同士でコメントするシステムなので気を付けたい。
・ギャップロック撲滅。空のレコードに対してクエリを行わない。
・トランザクションは短く - SQLテクニック(行ロック:FOR UPDATE)
- 【MySQL】InnoDBの select for update のロックの動作を確認する
>主キー、ユニークキーで select ~ for update しないと、テーブル全体でロックになったり、ある程度の範囲でロックがかかったりする。 - MySQL(InnoDB)でのDeadLock調査
Session
テストコード
メール認証
テストコード
オブジェクトキャッシュ, Redis
PHP
- Web業界で働くためのPHP入門
- 関数リファレンス
- PHPで配列の要素を削除する:unset, array_splice, array_shift, array_pop
- PHPで配列に安全にアクセスしたいだけだが
- PHP で二次元配列を特定の値でソートする
- [PHP] usort 関数を使って 2 次元配列をソートする
JSON
Bootstrap
Ajax
その他
- セキュリティを重視した開発手法ベストプラクティス
- 伸びないプログラマに見られる4つの傾向
- 本当にあった怖いプログラム(クソコード事例集)
- チームラボオンラインスキルアップ課題
- いいねボタンジェネレータ
- Web制作で使えそうなアイコンフォント