- 投稿日:2020-10-09T20:04:53+09:00
Laravel [マイグレーションの設定~テーブル作成〜カラム作成]
マイグレーション設定
モデルは artisan コマンドを使えば良いので php artisan とした後に、 make:model そして モデル名を今回は記事の Model なので Post としてあげましょう。
その後にバージョン管理するためのマイグレーションファイルも作りたいので、 php artisan make:model Post --migration のようなオプションを付けてあげましょう。
こうする事でPostモデルとマイグレーションフォルダができます。マイグレーションの記述
migration ファイルには up() と down() というメソッドがあるのですが、 up() がこのマイグレーションで行いたい処理、 down() はそれを巻き戻すための処理になります
カラムの追加
column の種類なんですが、 SQL でいうところの varchar は string で設定していくので string('title') 、そして body に関してはテキストで設定したいので text('body') としてあげれば OKです。
その後に、
php artisan migrate とするとdbにテーブルができます。
- 投稿日:2020-10-09T17:48:19+09:00
Laravel Sanctum(Laravel8)とNuxt.jsによるSPA認証
概要
業務でフロントを分離したくなってLaravelのAPI認証について調べてみると、Laravel7からSanctumの利用を推奨されていた。
Nuxtとの連携を調査したので作業ログも兼ねて記事として残します。Sanctumについて
APIトークンを発行するタイプと、SPA認証の2種類を提供するライブラリです。
ここではSPA認証を紹介します。
和訳ドキュメント完成品
最終的なコードを置いておきます。
https://github.com/nagi125/nuxt_laravel_auth_spa_sample
環境
docker-composeで構成し、nginxでRPしています。
- Host:Mac
- Docker
- nginx:1.19-alpine
- node:13.8-alpine (Nuxt2.14.x)
- php:7.4-fpm-alpine (Laravel8.x)
docker-composeは下記の通りです。
docker-compose.ymlversion: '3' services: nginx: container_name: nginx build: context: ./.docker/nginx dockerfile: Dockerfile ports: - 80:80 tty: true restart: always depends_on: - web web: container_name: web build: context: ./.docker/web dockerfile: Dockerfile environment: PORT: '3000' HOST: '0.0.0.0' expose: - 3000 volumes: - ./web:/app stdin_open: true tty: true restart: always depends_on: - api api: container_name: api build: context: ./.docker/api dockerfile: Dockerfile environment: LANG: 'ja_JP.UTF-8' TZ: 'Asia/Tokyo' LOG_CHANNEL: 'stderr' DB_CONNECTION: 'pgsql' DB_HOST: 'db' DB_PORT: '5432' DB_DATABASE: 'laravel_development' DB_USERNAME: 'docker' DB_PASSWORD: 'docker' SESSION_DOMAIN: 'localhost' SANCTUM_STATEFUL_DOMAINS: 'localhost' volumes: - ./api:/app expose: - 9000 tty: true restart: always depends_on: - db db: image: postgres:12 container_name: db environment: TZ: 'Asia/Tokyo' POSTGRES_USER: 'docker' POSTGRES_PASSWORD: 'docker' POSTGRES_DB: 'laravel_development' volumes: - db:/var/lib/postgresql/data ports: - 5432:5432 volumes: db:「nginx」「web」「api」コンテナの細かい構成については下記から確認してください。
https://github.com/nagi125/nuxt_laravel_auth_spa_sample/tree/main/.docker検証環境構築
完成品をCloneしていただいて、下記のコマンドで準備。
$ docker-compose upNuxt側
$ docker-compose exec web yarn install $ docker-compose exec web yarn devLaravel側
$ docker-compose exec api composer install $ docker-compose exec api cp .env.example .env $ docker-compose exec api php artisan key:generate $ docker-compose exec api php artisan migrate:refresh --seed以上で、Nuxt側・Laravel側の準備が完了です。
動作確認
http://localhost/login
メールアドレスとpasswordについてはLaravel側のseedで確認してください。
http://localhost/secret
にアクセスできれば認証成功です。認証設定について
認証設定について何をしたのか記載していきます。
Laravel側
Sanctumの準備
$ docker-compose exec api composer require laravel/sanctum $ docker-compose exec api php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"Sanctumの設定
KernelにClassを追加
api/app/Http/Kernel.php<?php namespace App\Http; use Illuminate\Foundation\Http\Kernel as HttpKernel; use Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful; // 追加 // ... protected $middlewareGroups = [ 'api' => [ EnsureFrontendRequestsAreStateful::class, // 追加 'throttle:api', \Illuminate\Routing\Middleware\SubstituteBindings::class, ], ];CORS設定
api/config/cors.php<?php return [ 'paths' => ['api/*'], // 変更 'allowed_methods' => ['*'], 'allowed_origins' => ['http://localhost:3000'], // 変更 'allowed_origins_patterns' => [], 'allowed_headers' => ['*'], 'exposed_headers' => [], 'max_age' => 0, 'supports_credentials' => true, // 変更 ];.envに環境変数をセットする
※サンプルコードではdocker-compose.ymlに環境変数をセットしています。SESSION_DOMAIN=localhost SANCTUM_STATEFUL_DOMAINS=localhostLoginControllerの準備
最低限の動作さえすればいい実装にしています。実際に使う場合はValidation含め作り込んでください。
api/app/Http/Controllers/Api/Auth/LoginController.php<?php namespace App\Http\Controllers\Api\Auth; use App\Http\Controllers\Controller; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; class LoginController extends Controller { /** * @Method POST * @param Request $request * @return \Illuminate\Http\JsonResponse */ public function login(Request $request): JsonResponse { $credentials = $request->validate([ 'email' => 'required|email', 'password' => 'required' ]); if (auth()->attempt($credentials)) { return response()->json(['message' => 'OK!'], 200); } return response()->json(['message' => 'ユーザーが見つかりません。'], 422); } }Routeの設定
認証用のRouteとUser情報取得用のRouteを設定します。
※ Laravel8からControllerの指定の仕方が変わったので注意してください。api/routes/api.php<?php use Illuminate\Http\Request; use Illuminate\Support\Facades\Route; use App\Http\Controllers\Api\Auth\LoginController; Route::prefix('auth')->group(function() { Route::post('/login', [LoginController::class, 'login']); }); Route::middleware('auth:sanctum')->get('/user', function (Request $request) { return $request->user(); });Laravel側は以上で準備完了です。
Nuxt側
Nuxtのプロジェクト作成にはUniversalモードとSPAモードとありますが、SPAモードで作成します。
※1. SSRではstoreの関係上、MiddlewareでAuthの設定が上手く反映されません。
※2. プロジェクト作成時にAxiosとBootStrapを指定しています。必要ライブラリのインストール
サンプルを動かせばinstallされていますが、作業ログとして記録しておきます。
$ docker-compose exec web yarn add @nuxtjs/authAuth設定
web/nuxt.config.jsexport default { // .... modules: [ 'bootstrap-vue/nuxt', '@nuxtjs/auth', // 追記 '@nuxtjs/axios', // 追記 ], axios: { baseURL: "http://localhost", credentials: true, }, auth: { redirect: { login: '/login', logout: '/', callback: false, home: '/' }, strategies: { local: { endpoints: { login: { url: '/api/auth/login', method: 'post', propertyName: false }, user: { url: '/api/user', method: 'get', propertyName: false }, logout: false }, tokenRequired: false, tokenType: false, } }, localStorage: false, }, router: { middleware: ['auth'] }, }Store設定
store利用するためにindex.js用意しろと怒られるので作成します。
$ docker-compose exec web touch store/index.jsLoginページ設定
サンプルコードを見ていただければよいのですが、Loginページだけ記載しておきます。
web/pages/login.vue<template> <div class="container"> <h1 class="h1 pb-1 border-bottom border-dark">Login</h1> <p>ログイン状態: {{ $auth.loggedIn }}</p> <div class="row justify-content-md-center"> <div class="col-6"> <form name="login" @submit.prevent="login()"> <div class="form-group"> <label for="email">Email</label> <input type="email" class="form-control" id="email" placeholder="Enter email" v-model="form.email" required /> </div> <div class="form-group"> <label for="password">Password</label> <input type="password" class="form-control" id="password" placeholder="Enter password" v-model="form.password" required /> </div> <button type="submit" class="btn btn-success">Submit</button> </form> </div> </div> </div> </template> <script> export default { data() { return { form: { email: '', password: '' }, }; }, mounted() { // csrf対策 // nginxでRPする場合は/sanctumがapi側を見に行くようにしてください this.$axios.get('/sanctum/csrf-cookie'); }, methods: { async login() { try { const response = await this.$auth.loginWith('local', { data: this.form }); console.log(response); } catch(error) { console.log(error); } }, }, }; </script>作業は以上となります。
最後に
今回はLaravel Sanctumを利用したSPA認証について書きました。
あまりサンプルがなくて実装に苦労してしまったので、誰かにお役に立てればと思い、記事とします。
課題はSSR時にどうするかですね。そちらも解決できたらまた記事を書きたいと思います。
- 投稿日:2020-10-09T15:13:01+09:00
XAMPPで作ったLaravelプロジェクトをGitHubにアップする。*for Windows
そのままタイトル通りの記事になります。超初心者で、とりあえずGitHubにアップする手順を手っ取り早く確認したい、と言う方には読んでもらえる価値があるかも。環境はWindowsです。
※Git自体の説明はしていません。あくまでGitHubにアップする手順しか解説していません。1. Gitをダウンロードする
手順1: 以下のサイトからGitをダウンロードします。
https://gitforwindows.org/
↓↓ 赤枠の部分からダウンロードします。
手順2: ダウンロードしたらインストールします。インストールする際の諸々の設定に関しては、特にカスタムせずにデフォルトのままで進めて問題ありません。
細かくカスタムされたい方は、↓↓こちらのサイトで詳しく説明されていたので、おススメです。
https://eng-entrance.com/git-install2: Git Bashで確認する
手順1: インストールが終わったら、Git Bashを立ち上げて確認していきます。
Git BashはGit for Windowsをインストールした時に、自動的にインストールされているので、もう既にお使いのコンピューターに入っています。
Windowsのスタートメニューに『git』と入力すると、Git Bashが出てきますので、それを立ち上げます。手順2: 正常にGitがインストールされているかを確認します。Git Bash(以後、ターミナルと称します。)に、『git version』と入力します。
以下画像のようにバージョン情報が出てくれば、正常にインストールされています。
3:GitHubでアカウント登録する
GitHubにまだアカウントを持っていない場合は、以下のサイトからアカウント登録します。
https://github.com/
アカウントの登録方法は沢山の分かりやすい記事がありますので、そちらでご確認を。因みに、noteで以下の記事を発見しました!
https://note.com/snmal_jp/n/n3ef510a8181e4:Gitの初期設定をする
手順1: ターミナルからGitのコマンド操作をする為に、初期設定をしていきます。ユーザー名、メールアドレス、使用するエディターの3つの設定を行います。コマンドは以下の通りです。
ユーザー名:『git config --global user.name "Tomochan-taco"』("Tomochan-taco"の部分は、ご自身のGitHubのユーザー名を入れてください。)
メールアドレス:『git config --global user.email ***@gmail.com』(***@gmail.comの部分は、ご自身のメールアドレスを入れてください。)
使用するエディター:『git config --global core.editor "code --wait"』("code --wait"の部分は、ご自身の使用するエディターを入れてください。これはVisual Studio Codeの場合です。他に例えばATOMとかだったら、"atom --wait"です。)↓↓ 以下の画像は、メールアドレス部分のみ隠させてもらいました。('ω')
手順2: 設定確認をします。『git config user.name』『git config user.email』『git config core.editor』のコマンドで、それぞれ確認することができます。
他にも『git config --list』で、設定項目を一度に確認することができます。また、『cat ~/.gitconfig』で設定ファイルの中身を確認することができます。5:gitディレクトリを作成する
git add や git commit コマンドを操作する為に必要となる、gitディレクトリを作成します。
※ コマンドの意味については、Gitの構造自体の説明が必要となりますので、ここでは省きます。手順1: どこにでもいいので、新規フォルダを作ります。
とりあえず私の場合は、Cドライブのユーザフォルダの個人フォルダ(C:\Users\TOMOKO OHASHI)に『restaurant_menu』という名前でフォルダを作ります。(『restaurant_menu』っていうプロジェクト名のアプリを作ったんです。。チュートリアルを後日公開予定♪ww )手順2: 『restaurant_menu』フォルダに、XAMPPで作ったLaravelのプロジェクトの中身(C:\xampp\htdocs\restaurant_menuに作ったもの。)をドカーンと全部移動します。
手順3: ターミナルに戻り、cdコマンドで、『restaurant_menu』フォルダに移動します。
※ C:\xampp\htdocs に作ったプロジェクトのフォルダを、そのままgitディレクトリにしても問題ない場合は、手順1~手順3をすっ飛ばしてもらって構わないです。手順4: 『git init』コマンドで、gitディレクトリを作成します。
手順5: 『ls -a』コマンドで、フォルダの中を確認してみます。lsコマンドは、-aオプションをつけると隠しファイルも見れるようになるので、『.git』ディレクトリも見れています。(『.git』ディレクトリは元々隠しファイルになっています。)
↓↓こちらの画面でも、隠しファイルにチェックを入れると、『.git』ディレクトリが作成されていることが確認できます。
6:git add をする
『git add』コマンドを実行して、ステージに追加します。今回はワークツリー全体を追加するので、『 git add . 』と打ちます。
7:git commitをする
『git commit』コマンドを実行して、レポジトリに記録します。
登録しておいたエディタが立ち上がりますので、必要なメモがある場合は記載して閉じます。
8:GitHubで準備する
GitHub側でレポジトリを作る準備をします。GitHubにサインインしておきます。
手順1: 画面右側上部のアカウントボタンをクリックして、Your Profileをクリックします。
手順5: レポジトリ名を入力したら、後は特に何も変更せずに『Create repository』をクリックします。
手順6: すると、以下のような画面となりますので、赤枠の部分をコピーしておきます。
9:Pushする
手順1: ターミナルに戻ります。まずはGitHubのリモートレポジトリを登録します。前回の手順6でコピーしておいたコマンドをターミナルに貼り付けます。
『git remote add origin 』ですが、このコマンドは、originという名前のショートカットで、GitHubのリモートレポジトリを登録するよ、という意味になります。
手順2: 『git push -u origin master』コマンドを実行して、pushします。ここで-uオプションをつけると、これ以降は『git push』だけでpushできるようになります。
git pushコマンドは、『git push <リモート名> <ブランチ名>』という構造になり、originとmaterは、それぞれデフォルトのレポジトリ名とブランチ名になります。詳しくは、以下のQiitaの記事で解説がありました!
https://qiita.com/seri1234/items/e651b3e108a695a9280910:アップされているかを確認する
GitHubのサイトに戻って、<code>の部分をクリックします。
すると、以下画像のようにソースコードが無事アップロードされています!
以上で完了です!
- 投稿日:2020-10-09T14:28:16+09:00
Laravel5.5LTS: ライブラリを使わないマルチ認証-Fell版
Laravelの
マルチ認証
の記事はたいていコピペ
を多用してます。
コピペの多用
はバグの温床
になりやすいので条件分岐
で極力減らしてみました。前提条件: Laravel5.5 インストール
.env(DB設定)
.env//DB接続設定 DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE={データベース名} DB_USERNAME={user} DB_PASSWORD={password}AppServiceProvider.php
app/Providers/AppServiceProvider.php//DBの191文字超えエラー回避設定 class AppServiceProvider extends ServiceProvider { public function boot() { ++ \Illuminate\Support\Facades\Schema::defaultStringLength(191); } }Authとマイグレーション
認証のインストールとマイグレーション//認証のインストール $ php artisan make:auth //認証用DBテーブル作成 $ php artisan migrate //-> DBにusers・password_resetsテーブルが作成されたか確認。Adminモデルの生成
Adminモデルとマイグレーションの生成$ php artisan make:model Admin -m //-> App/Admin.php //-> database/migrations/{日付}_create_admins_table.phpAdminモデル
app/Admin.php<?php namespace App; use Illuminate\Notifications\Notifiable; use Illuminate\Foundation\Auth\User as Authenticatable; class Admin extends Authenticatable //modify { use Notifiable; protected $fillable = [ 'name', 'email', 'password', ]; protected $hidden = [ 'password', 'remember_token', ]; }Adminテーブルのマイグレーション
create_users_table.php
の内容をコピーして変更
database/migrations/{日付}create_admins_table.php<?php use Illuminate\Support\Facades\Schema; use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class CreateAdminsTable extends Migration //modify { public function up() { Schema::create('admins', function (Blueprint $table) { //modify $table->increments('id'); $table->string('name'); $table->string('email')->unique(); $table->string('password'); $table->rememberToken(); $table->timestamps(); }); } public function down() { Schema::dropIfExists('admins'); //modify } }adminテーブルのマイグレーション実行
$ php artisan migrate //adminsテーブルが生成されたか確認tinker -> adminユーザーの生成
tinker$ php artisan tinker >>> $admin = new App\Admin; >>> $admin->name = 'admin'; >>> $admin->email = 'test@test.com'; >>> $admin->password = password_hash('password', PASSWORD_DEFAULT); >>> $admin->save(); //phpMyadmin等でユーザー生成の確認auth.php(公式)
admin側の定義の追加
config/auth.php<?php return [ 'defaults' => [ 'guard' => 'user', 'passwords' => 'users', ], 'guards' => [ 'api' => [ 'driver' => 'token', 'provider' => 'users', ], 'user' => [ 'driver' => 'session', 'provider' => 'users', ], + 'admin' => [ + 'driver' => 'session', + 'provider' => 'admins', + ], ], 'providers' => [ 'users' => [ 'driver' => 'eloquent', 'model' => App\User::class, ], + 'admins' => [ + 'driver' => 'eloquent', + 'model' => App\Admin::class, + ], ], 'passwords' => [ 'users' => [ 'provider' => 'users', 'table' => 'password_resets', 'expire' => 60, ], + 'admins' => [ + 'provider' => 'admins', + 'table' => 'password_resets', + 'expire' => 60, + ], ], ];Laravelの認証機能は
「ガード」
と「プロバイダ」
を中心概念として構成されています。ガードは各リクエストごと
に、どのようにユーザーを認証するか
を定義します。たとえば、Laravelにはセッションストレージ
とクッキー
を使いながら状態を維持するsessionガード
が用意されています。ログインしていないときのリダイレクト先
app/Exceptions/Handler.php<?php namespace App\Exceptions; use Exception; use Illuminate\Auth\AuthenticationException; //add use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler; class Handler extends ExceptionHandler { protected $dontReport = [ // ]; protected $dontFlash = [ 'password', 'password_confirmation', ]; public function report(Exception $exception) { parent::report($exception); } public function render($request, Exception $exception) { return parent::render($request, $exception); } //未ログイン時 -> ガード属性のログインページにリダイレクト public function unauthenticated($request, AuthenticationException $exception) { if($request->expectsJson()){ return response()->json(['message' => $exception->getMessage()], 401); } if (in_array('admin', $exception->guards())) { return redirect()->guest(route('admin.login')); } return redirect()->guest(route('login')); } }ルーティング
route/web.php<?php Auth::routes(); // User 認証不要 Route::get('/', function () { return redirect('/home'); }); // User ログイン後 Route::group(['middleware' => 'auth:user'], function() { Route::get('/home', 'HomeController@index')->name('home'); }); // Admin 認証不要 Route::group(['prefix' => 'admin'], function() { Route::get('login', 'Admin\loginController@showLoginForm')->name('admin.login'); Route::post('login', 'Admin\LoginController@login'); }); // Admin ログイン後 Route::group(['prefix' => 'admin', 'middleware' => 'auth:admin'], function() { Route::post('logout', 'Admin\LoginController@logout')->name('admin.logout'); Route::get('home', 'HomeController@index')->name('admin.home'); });コントローラーの構成
adminフォルダ
を作成してAuthフォルダ
からLoginController.php
をコピーします。
LoginController.php(Auth)
app/Http/Controller/Auth/LoginController<?php namespace App\Http\Controllers\Auth; use App\Http\Controllers\Controller; use Illuminate\Foundation\Auth\AuthenticatesUsers; use Illuminate\Http\Request; //add use Illuminate\Support\Facades\Auth; //add class LoginController extends Controller { use AuthenticatesUsers; protected $redirectTo = '/home'; public function __construct() { $this->middleware('guest')->except('logout'); } public function logout(Request $request) { Auth::guard('user')->logout(); //modify return redirect('login'); //modify } }LoginController.php(Admin)
app/Http/Controller/Admin/LoginController.php<?php namespace App\Http\Controllers\Admin; use App\Http\Controllers\Controller; use Illuminate\Foundation\Auth\AuthenticatesUsers; use Illuminate\Http\Request; //add use Illuminate\Support\Facades\Auth; //add class LoginController extends Controller { use AuthenticatesUsers; protected $redirectTo = 'admin/home'; //modify public function __construct() { $this->middleware('guest:admin')->except('logout');//modify } public function showLoginForm() { //login.blade.phpは共用 return view('auth.login'); //modify } protected function guard() { return Auth::guard('admin'); //modify } public function logout(Request $request) { Auth::guard('admin')->logout(); //modify return redirect('admin/login'); //modify } }コントローラーの使用例(条件分岐の例)
HomeController.php
コントローラーではルート名
からguard
を判断します。
ルーティング
がしっかりしていれば問題ないと考えます。app/Http/Controller/HomeController.php<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; //add class HomeController extends Controller { /** * 条件分岐に使用できるメソッド例 * ヘルパ関数に登録しておけば便利になると思います。 * ログインしているユーザーのadmin権限の有無 public function isAdminRoute() { $bool = strpos(\Route::currentRouteName(), 'admin') !== false; return $bool; } * ログインしているユーザー情報を取得します。 public function getUser() { if ($this->isAdminRoute()) { return Auth::guard('admin')->user(); } else { return Auth::guard('user')->user(); } */ public function __construct() { $this->middleware('auth'); } public function index() { //ユーザー情報の取得テスト //dd($this->getUser()); return view('home'); } }ログイン後のリダイレクト先
app/Http/Middleware/RedirectIfAuthenticated.php<?php namespace App\Http\Middleware; use Closure; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; class RedirectIfAuthenticated { public function handle($request, Closure $next, $guard = null) { if (Auth::guard($guard)->check()) { switch ($guard) { case 'admin': return redirect('/admin/home'); break; case 'user': return redirect('/home'); break; } } return $next($request); } }ビュー
ルート名
からguard
を判断しています。
これもルーティング
がしっかりしていれば問題ないと思ってます。
ビュー
はコピペせずに条件分岐でuser
とadmin
の制御を行います。app.blade.php
resources/views/layouts/app.blade.php<!-- $now_route -> 現在のルート名 --> <?php $now_route = \Route::currentRouteName(); ?> ~~略~~ <!-- Styles --> <link href="{{ asset('css/app.css') }}" rel="stylesheet"> @if (strpos($now_route, 'admin') !== false) <style>body{background-color: tomato;}</style> @endif ~~略~~ <!-- Right Side Of Navbar --> <ul class="nav navbar-nav navbar-right"> <!-- Authentication Links --> <!-- 未ログインの`user` --> @if (is_null(Auth::guard('user')->user()) && strpos($now_route, 'admin') === false) <li><a href="{{ route('login') }}">Login</a></li> <li><a href="{{ route('register') }}">Register</a></li> <!-- 未ログインの`admin` --> @elseif (is_null(Auth::guard('admin')->user()) && strpos($now_route, 'admin') !== false) <li><a href="{{ route('admin.login') }}">Login</a></li> @endif <li class="dropdown"> <!-- ログイン中の`user` --> @if (!empty(Auth::guard('user')->user()) && strpos($now_route, 'admin') === false) <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false" aria-haspopup="true" v-pre> {{ Auth::guard('user')->user()->name }} <span class="caret"></span> </a> <ul class="dropdown-menu"> <li> <a href="{{ route('logout') }}" onclick="event.preventDefault(); document.getElementById('logout-form').submit();"> Logout</a> <form id="logout-form" action="{{ route('logout') }}" method="POST" style="display: none;"> {{ csrf_field() }} </form> <!-- ログイン中の`admin` --> @elseif (!empty(Auth::guard('admin')->user()) && strpos($now_route, 'admin') !== false) <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false" aria-haspopup="true" v-pre> {{ Auth::guard('admin')->user()->name }} <span class="caret"></span> </a> <ul class="dropdown-menu"> <li> <a href="{{ route('admin.logout') }}" onclick="event.preventDefault(); document.getElementById('logout-form').submit();"> Logout</a> <form id="logout-form" action="{{ route('admin.logout') }}" method="POST" style="display: none;"> {{ csrf_field() }} </form> @endif </li> </ul> </li> </ul> ~~略~~Login.blade.php
resources/views/auth/login.blade.php@extends('layouts.app') <?php $now_route = \Route::currentRouteName(); ?> @section('content') ~~略~~ <div class="panel-body"> <!-- 未ログインの`user` --> @if (is_null(Auth::guard('user')->user()) && strpos($now_route, 'admin') === false) <form class="form-horizontal" method="POST" action="{{ route('login') }}"> <!-- 未ログインの`admin` --> @elseif (is_null(Auth::guard('admin')->user()) && strpos($now_route, 'admin') !== false) <form class="form-horizontal" method="POST" action="{{ route('admin.login') }}"> @endif {{ csrf_field() }} ~~略~~ @endsectionHome.blade.php
resources/views/home.blade.php<?php $now_route = \Route::currentRouteName(); //ログイン者の属性条件選択の例 //ルート名からガード選択 $loginName = ''; if (strpos($now_route, 'admin') === false) { $loginName = Auth::guard('user')->user()->name; } elseif (strpos($now_route, 'admin') !== false) { $loginName = Auth::guard('admin')->user()->name; } ?> @extends('layouts.app') @section('content') <div class="container"> <div class="row"> <div class="col-md-8 col-md-offset-2"> <div class="panel panel-default"> <div class="panel-heading"> {{ $loginName . 'さん' }} <!-- 使用例 --> </div> <div class="panel-body"> @if (session('status')) <div class="alert alert-success"> {{ session('status') }} </div> @endif You are logged in! </div> </div> </div> </div> </div> @endsectionいかがでしたでしょうか?
条件分岐
のやり方を押さえることができれば改変・応用
は簡単です。
少なくとも1つ機能を増やすためにファイル間を移動
することは確実に減る
でしょう。
改修
やデバッグ作業
も同様です。
この記事は友人
がマルチ認証
に苦しんでいたため書きました。
special thanks touta
& u.LGTMお願いします!
ストックのついでにLGTMお願いします!
モチベーションがあがります!
- 投稿日:2020-10-09T13:38:10+09:00
Docker x Laravel めちゃくちゃ遅い Docker for Windows を爆速化する
@ucan-labさんのDocker x Laravel めちゃくちゃ遅い Docker for Mac を爆速化するの案4をWindows10で検証しました。
案4. ボリュームマウントを使う
- 【JavaScript】Docker上でのnpm/yarnの操作を10倍早くする方法
- Docker-compose: node_modules not present in a volume after npm install succeeds
vendorやnode_modulesのデータを名前付きボリュームに格納して、ホスト側とコンテナ側と分離して管理する案。
同期処理が発生しないので、その分速くなる。docker-compose.ymlにボリュームマウントの設定を追加して、composerとnpmのインストールを比較します。この記事ではなぜ早くなるかは触れません。
結果
composer install
とnpm install
の速度をそれぞれ比較しています。$ time composer install real 6m26.446s -> 0m57.445s # 6.7倍 user 0m9.375s -> 0m3.035s sys 0m51.148s -> 0m1.544s $ time npm install real 1m31.764s -> 0m22.720s # 4.0倍 user 0m46.022s -> 0m23.705s sys 0m32.465s -> 0m13.917sWindows10環境では4~7倍速くなりました!
参照元のMacのように20倍とはいきませんでしたが、数行の追加だけで十分早くなって満足です!環境
ホストOSの環境
- Windows 10 Home バージョン2004(OSビルド 19041.508)
- WSL2 (Ubuntu 20.04.1 LTS)
- Docker version 19.03.13, build 4484c46d9d
- docker-compose version 1.27.4, build 40524192
環境構築には下の記事が参考になります。
Windows Subsystem for Linux Installation Guide for Windows 10
Windows 10 Home で WSL 2 + Docker を使う | Qiitaコンテナ
Laravel + Nginx + MySQLの開発環境を使って検証します。
詳しくはブログで公開しています。
- php (php-fpm) 7.4.1
- composer 1.10.13
- nodejs v12.18.4
- npm 6.14.6
- Laravel 8.8.0
- mysql 8.0
- nginx 1.19.2
composerとpackage.jsonは、プロジェクト作成からlaravel/jetstreamのInertiaをインストールしたところまでの状態です。
検証するdocker-compose.yml
コメント
add
行の有無で速度を比較しています。version: '3' volumes: # add vendor-store: # add node_modules-store: # add services: php: container_name: php build: ./docker/php volumes: - ./web:/var/www - vendor-store:/var/www/laravel/vendor # add - node_modules-store:/var/www/laravel/node_modules # add environment: TZ: Asia/Tokyo nginx: image: nginx container_name: nginx ports: - 80:80 volumes: - ./web:/var/www - ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf depends_on: - php db: image: mysql:8.0 container_name: db environment: MYSQL_ROOT_PASSWORD: root MYSQL_DATABASE: database MYSQL_USER: docker MYSQL_PASSWORD: docker TZ: 'Asia/Tokyo' command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci volumes: - ./docker/db/data:/var/lib/mysql - ./docker/db/my.cnf:/etc/mysql/conf.d/my.cnf - ./docker/db/sql:/docker-entrypoint-initdb.d ports: - 3306:3306実行手順は参照元と同等です。パスを読み替えてください。
- 投稿日:2020-10-09T13:29:07+09:00
メールの送信元とは別のメアドを返信先に設定したい
自分が知らなかっただけかもだけどメモ。
あるメールに対して返信するとき、普通はFrom(送信元)のメアドが返信先に設定される。
これを変更したい場合、メールの送信元を変更したいと思いがちだけど
AWS SESから送信する場合などは、セキュリティ的な観点からメールの送信元を簡単には変えられない。
参考:制限緩和してサンドボックス外にいるSESから「Email address is not verified.」エラーが発生する | bbhそんなときにのためのReplyTo(返信先)。
ReplyToをヘッダに追加してあげると送信元とは別のメールを指定することができる。以下はLaravelの例
Mail::send('emails.welcome', $data, function($message) { $message->to('foo@example.com', 'John Smith') ->replyTo('reply@example.com', 'Reply Guy') ->subject('Welcome!'); });参考:php - "Reply-to" field in Laravel mail is not working - Stack Overflow
参考:メール 7.x Laravelそもそもメールヘッダにどんなものがあるか頭に入れておいた方が良さそう。後で読む。
メール系の知識 - Qiitaおしまい
- 投稿日:2020-10-09T12:53:32+09:00
ルーティングの基本(laravel,PHP)
web.php//特定のHTTPメソッドに対応する場合 Route:○○('viewのパスを記入','コントローラー@アクションメソッド'); //複数のHTTPメソッドに対応する場合 Route::match(['〇〇','〇〇'],'viewのパスを記入','コントローラー@アクションメソッド'); //※['〇〇','〇〇']に指定した複数のメソッドを対応させることが可能 //全てのHTTPメソッドに対応する場合 Route::any('viewのパスを記入','コントローラー@アクションメソッド');ルーティング情報をコントローラから取得する場合(ルートパラメーター)
web.php#自動的に対応する値を引数に割り当ててる場合 Route::get('viewのパスを記入/{id}','コントローラ名@アクションメソッド'); #任意の値を引数に割り当てる場合 Route::get('viewのパスを記入/{id?}','コントローラ名@アクションメソッド'); #ルートパラメータを制限したい場合 Route::get('viewのパスを記入/{id}','コントローラ名@アクションメソッド')->where([id =>'[0-9],{2,3}']) //[0-9]->0~9までの数値に対応 //{2,3} ->10桁から100桁の数値に対応 //定義済み関数のpreg_matchと同じ〇〇controller.php#自動的に対応する値を引数に割り当ててる場合 class Controller extends Controller { public function param(int $id){ return 'id:'.$id; } //.....〇〇controller.php#任意の値を引数に割り当てる場合 class Controller extends Controller { public function param(int $id =任意の値){ return 'id:'.$id; } //.....〇〇controller.php#正規表現の場合 class Controller extends Controller { public function param(int $id =任意の値){ //※任意の値はルートパラメータで制約しているため従う必要がある //例:現在は[0~9],{2-3}に指定しているので 0〜9の数値で尚且つ100桁までの数値を定義する必要がある return 'id:'.$id; } //.....web.php//可変長パラメータ Route::get('viewのパスを記入{keywd?}','コントローラ@アクションメソッド')>where('keywd','.*') //('keywd','.*') ->任意の文字が0文字~~+∞という意味 //可変長は長さが決まっていないことを挿す
- 投稿日:2020-10-09T12:47:25+09:00
brefphpを使って簡単にLaravelをサーバレス環境で動かす
はじめに
ここではbrefについてと、実際の使い方や使ってみた所感などをまとめてみようと思います。
brefphp とは?
PHPアプリケーションをAWS Lambdaに簡単にデプロイするための Composer パッケージです。
コマンド1つでサーバーからアプリケーションのデプロイまで行えます。使い方
Step serverless のインストール
bref は serverless コマンドを使用してAWS環境にデプロイを行います。
以下のコマンドでインストールしましょう。npmの場合
npm install -g serverlessyarnの場合
yarn global add serverless追加したら以下のコマンドでちゃんと実行できるか確認しましょう
$ serverless --version Framework Core: 2.4.0 Plugin: 4.0.4 SDK: 2.3.2 Components: 3.2.1Step Laravelプロジェクトの作成 [公式]
今回はLaravelで使うため、プロジェクトを作成します。
Laravelインストーラーがない場合はインストールします
composer global require laravel/installerプロジェクトを作成します。
laravel new brefphp-testStep brefphp パッケージのインストール [公式]
作成したLaravelプロジェクトのディレクトリに移動して、
brefphpをインストールします。composer require bref/bref bref/laravel-bridgeデフォルトのサーバ構成設定ファイルを作成します。
php artisan vendor:publish --tag=serverless-configStep デプロイの準備
「アクセスキーID」と「シークレットアクセスキー」の作成
デプロイ前に、デプロイ先のサーバ(AWS)のアクセスキーとシークレットキーを使用します。
IAMのユーザー追加画面でテスト用ユーザーを作りましょう。
アクセス権限の設定です。「既存のポリシーを直接アタッチ」を選択して「AdministratorAccess」を選択します。
名前の通り最強権限なので、発行されるキーは絶対に外部に漏らさないでください!
プロファイルの追加
メモした「アクセスキーID」と「シークレットアクセスキー」をプロファイルに登録します。
$ aws configure --profile <プロファイル名> AWS Access Key ID [None]: <アクセスキーID> AWS Secret Access Key [None]: <シークレットアクセスキー> Default region name [None]: Default output format [None]:すると、
~/.aws/credentials
(Windowsの場合は%USERPROFILE%/.aws/credentials
) にプロファイルが登録されます。/.aws/credentials[<プロファイル名>] aws_access_key_id = <アクセスキーID> aws_secret_access_key = <シークレットアクセスキー>Step デプロイ
以下のコマンドでデプロイします。
<プロファイル名>
は、先程(Step4)で登録した名前を指定してください。$ serverless deploy -v --aws-profile=<プロファイル名> Serverless: Packaging service... Serverless: Excluding development dependencies... Serverless: Creating Stack... Serverless: Checking Stack create progress... ~~~~~~~[色々ログ出てきて]~~~~~~~ Serverless: Stack update finished... Service Information service: laravel stage: dev region: us-east-1 stack: laravel-dev resources: 15 api keys: None endpoints: ANY - https://xxxxxxxxxx.execute-api.us-east-1.amazonaws.com/dev ANY - https://xxxxxxxxxx.execute-api.us-east-1.amazonaws.com/dev/{proxy+} functions: web: laravel-dev-web artisan: laravel-dev-artisan layers: None Stack Outputs WebLambdaFunctionQualifiedArn: arn:aws:lambda:us-east-1:000000000000:function:laravel-dev-web:2 ArtisanLambdaFunctionQualifiedArn: arn:aws:lambda:us-east-1:000000000000:function:lara![WS000000.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/157186/369830d6-c723-975d-2b78-c94add355649.jpeg) vel-dev-artisan:2 ServiceEndpoint: https://xxxxxxxxxx.execute-api.us-east-1.amazonaws.com/dev ServerlessDeploymentBucketName: laravel-dev-serverlessdeploymentbucket-o2rnhi5yd9v6生成されたエンドポイントにアクセスして、LaravelのWelcomeページが出てくれば成功です
Step 環境の削除
$ serverless remove
コマンドで環境を削除できます。$ serverless deploy -v --aws-profile=<プロファイル名> Serverless: Getting all objects in S3 bucket... Serverless: Removing objects in S3 bucket... Serverless: Removing Stack... Serverless: Checking Stack removal progress... ~~~~~~~[色々ログ出てきて]~~~~~~~ Serverless: Stack removal finished... Serverless: Stack removal finished...ローカル環境の構築
Dockerでローカル環境を構築します。
すでにローカル用のイメージは用意されているので、すぐに立ち上げることができます。Laravelプロジェクトと同じディレクトリに
docker-compose.yml
の作成docker-compose.ymlversion: "3.5" services: web: image: bref/fpm-dev-gateway ports: - '8000:80' volumes: - .:/var/task links: - php environment: HANDLER: public/index.php DOCUMENT_ROOT: public php: image: bref/php-74-fpm-dev volumes: - .:/var/task:ro
docker-compose up -d
でコンテナを起動します。1
http://localhost:8000
にアクセスするとLaravelのWelcomeページが表示されます。料金について
ローカル環境には料金はかかりません。
AWSにデプロイした際に以下のサービスを利用するため、料金が発生します。所感
個人開発で使って便利だったので、会社のプロジェクトでも導入してみました。
LambdaやAPI Gatewayによるいろいろな制限があったりして、思うように行かなかった部分もありますが、なんとかサービスもリリースしているような状態です。EC2に比べてLambdaやAPI Gatewayの料金は基本的にトラフィック依存なので、
アクセス数のそんなにないサービスでは、かなりのコスト削減になりました。発生した問題とその対策
実際にプロジェクトに導入した際に発生した問題と、それについての対策を記述します。
もし似たような問題が発生した場合は参考になればと思います。POSTで10MBを超えるファイルをアップロードできない
API GatewayのPOSTリクエストサイズの最大が10MBのため、大容量のファイルをPOSTできません。
最終的にS3にアップロードする予定だったので、S3でPresigned URL2を発行して、それに対しアップロードするようにしました。6MBを超えるデータを返せない
またもやAPI Gatewayの制約により、レスポンスの最大は6MBです。
(まぁ、6MBなんて超えることなんて稀ですが…)
こちらも一度S3にアップロードしてPresigned URLを生成し、
フロントエンドから直接S3のURLを参照するようにしました。APIのタイムアウトの最長が29秒
API Gatewayの制約上、29秒でタイムアウトしてしまいます。
なので、重い処理はAmazon SQSに投げて処理するようにしました。PR
brefのSlackコミュニティに日本語チャンネルができました。
一緒にbrefについて語りましょう?
- 投稿日:2020-10-09T12:11:08+09:00
laravel ディレクティブについてのまとめ
laravel ディレクティブについて
bladeテンプレート(view)の中で利用できる命令のこと
○○.php@foreach(連想配列as変数) //PHPのforeachと同じ @if(条件式) //phpのifと同じ @unless(変数) //falseの場合に出力 @iseet(変数) //trueの場合に出力 @empty(変数) //変数が存在しない場合のみ(null)の時に出力 @switch //phpのswitchと同じ @for //phpのfor文と同じ @break //phpのbreak文と同じ @loop //ちょっと特殊 ループ変数と呼ばれる ※わかりづらいので下記に例あり //index:インデックス番号(0スタート) //iteration:繰り返し数(1スタート) //remaining:残っている要素数 //count:配列の総数 //first:最初の項目->>>配列の先頭の時には1を返す //last:最後の項目 ->>>配列の最後尾の時には1を返す //even:偶数回目か //odd:奇数回目か //depth:入れ子レベル //parent:親のループ変数(ネストした入れ子の場合) @forelse //処理 @empty //配列が空の場合の処理 //配列が空の場合の出力を設定できる //※データの表示によって振り分けるのに@ifディレクティブよりも@forelseの方がおすすめ @php //<?phpと同じだが使用は例外的とのこと @yield(name,[,default]) //name テンプレートからプレイスホルダー(空)の変数を受け取る時に使用 //① @section(name) //default @show //② @section() @parent //default //名前が示す通りにコンテンツのセクションを定義※上記の様に複数の定義方法がある //default-> 規程のコンテンツ(アクション変数とか) @each(path,データ,仮変数,配列が空の時に実行)※※loopディレクティブの例
controller.phppublic function foreach_loop() { return view('view.foreach_loop', [ 'weeks' => [ '月', '火', '水', '木', '金', '土', '日' ] ]); }foreach_loop.php<tr> <th>値</th> <th>index</th> <th>iteration</th> <th>count</th> <th>first</th> <th>last</th> <th>even</th> <th>odd</th> <th>depth</th> </tr> @foreach ($weeks as $week) <tr> <td>{{ $week }}</td> <td>{{ $loop->index }}</td> <td>{{ $loop->iteration }}</td> <td>{{ $loop->count }}</td> <td>{{ $loop->first }}</td> <td>{{ $loop->last }}</td> <td>{{ $loop->even }}</td> <td>{{ $loop->odd }}</td> <td>{{ $loop->depth }}</td> </tr> @endforeach </body> </html>
- 投稿日:2020-10-09T09:21:38+09:00
「暗記」ダメ!!!!!!!!! 絶対!!!!!!!!
暗記ってダメなの?
学習をしていく中で1度は耳にする
「暗記」はダメ
といった論調があると思います
最初に結論を言っておくと私はこの記事で
暗記を全て否定するのではなく、拾ってくる情報リソースの多くで頻出している「単語」や「概念」は暗記しましょうね。と伝えたいです。私の背景
半年前の私は
・HTMLって何
・PHP何それ弱そう
・プログラミング=ホームページを作る事でしょ?といったようにプログラミングに関してほとんど無知の状態でした。
今では半年間毎日1日8時間の学習を継続しているので、そんなふざけた状態ではないですが、当時は間違いなく全くの初学者でした。私は初学者だった当時スクールに通うことはせずネットのPHP教材を購入し独学をはじめました。
少し話がそれますが、この半年でオンラインなどの交流会でスクールを卒業された方の話しを10人前後聞いてきたのですが、その方々の満足度は大変高い印象でした。ただし、接頭辞的な感じで、「挫折しない為には」いいですね。といった言い回しをされる方が多い印象でした笑
私も半年間独学をしてきた経験と周りの卒業された方の意見を合わせて考えると時間効率を求めるならスクールは大いにありだと思います。
スクールを通う段階としてはプロゲートで5つくらいの言語を一通りやってみてからでいいのかな〜といった印象です。
お金に余裕があって少しでも一人でやる自信がないと思っている方は即決でスクールを選んだ方が効率は絶対にいいです(こんな事言ってますがスクールの回し者ではありません笑。なんならエンジニアyoutuerみたいに一回くらい企業案件やってみたいです。この動画はテックアカ、、、、?)
さて本題に戻ります。
私はスクールには通いませんでしたがネットで教材を購入しそれを独学しました。その教材の中には「暗記してください」などとは書かれて言いませんでしたが、重要なポイントとして取り上げられているTipsはたくさんありました。
要するに何が言いたいかと言うと
単語レベルの理解はもちろん、多くの人が共通して主立って「重要」と言っている事は四の五の言わず暗記した方が後の開発効率がスムーズになる。
と言うのが私の意見です。
そんなの当たり前だろ。。記事にすることじゃないよね。。と思われるかもしれませんが
初学者の方で
・「暗記」をひとまとめにして「悪」と捉えている
・「暗記」って本当にダメなのか疑心暗鬼になっている方は少なくないと思い、この記事を書きました。
少なからず私が学習初期の段階では色んな情報に触れて暗記する事に意味はないと一括りにしてしまっていました。
暗記しなくてもいい事
大きく分けると3つ程あるかと思います。
※前提として忘れないで頂きたいのはこれは学習して半年程度且つ実務未経験者の意見です?
1. コードの書き方を暗記する
私が考えるに暗記してはいけないと情報発信されている方の本質的部分はここだと思います。
ここは私が細かく言うまでもないですが、効率が悪く、キリがないですよね。笑
これをやってしまっている方がいたら今すぐにその習慣を辞めて、コードを書いて覚えましょう!
無心で書き続けていればいつの間にか覚えます。必ずです。
2. 開発環境の構築の仕方
これはキリがないとか効率が悪いとか言うより初学者のうちにここを重点的に覚えようとすると、挫折率が上がってしまうかと思います。
サーバーやネットワークの知識が必要となってくるので初学者の段階は
「そう言うものを使っているんだな」程度の理解でいいのではないでしょうか。
3. 関数を全て覚えようとする
これもコードを暗記するに近いですが、仮に全て覚えても一生使わないものも出てくる可能性があり且つ効率が悪いからです。
経験上、使用頻度の高い関数はコードを書いて入れば勝手に覚えます。つまり使用頻度が高い=重要度の高い関数と言う認識で良いかと。暗記した方がいい事
さて、今度は逆に暗記した方がいい事について少しみていきましょう。
冒頭でも述べましたが、暗記をした方が良い内容は 拾ってくる情報リソースの多くで頻出している「単語」や「概念」の事でしたね。では具体的にはどう言った単語や概念でしょうか。
私の経験から「早めに覚えておいてよかった」「ここは早めに深く覚えておけばよかった」点から解説します。
※ここからはさらに個人的主観が強くなりますでご了承ください
以下の内応は一応、PHPを対象としていますの
if文/繰り返し文/関数/引数/戻り値/変数
と言ったどのプログラミング言語でも共通する基礎の部分は除きますざっくりですが以下2点の理解をまずは「暗記」する事を私はお勧めします。
1.$GETと$POST
2.データベースは何をしているか
詳しくは次の段落で書いていきます。
$GETと$POST
[なぜこれを覚えておいた方が良いのか]
それはPHP言語でCRUDを実装する時に超頻出の概念だからです。
(CRUDとは、システムに必要な4つの主要機能である「Create(生成)」「Read(読み取り)」「Update(更新)」「Delete(削除)」の頭文字を並べた用語です。)
CRUDはWEBアプリ制作する上で基本的な考え方になります。PHPとよく比較されるプログラミング言語が、JavaScriptです。この両者はスクリプト言語でも、動作については全く異なります。
JavaScriptはHTMLやCSS、画像と同じようにブラウザを表示しているPCにファイルをダウンロードしてから実行し動作するのに対し
PHPはWebサーバ上にファイルを置いて、以下の順で実行されます。1.ブラウザを見ているユーザがクリックなど何かの操作をする
2.その動作を受けたプログラムがサーバで動作する
3.動作結果をレスポンスとして、インターネット経由で送り、ブラウザ上にHTMLを表示する
このようにPHPのような言語は、サーバサイドのプログラミング言語と呼ばれ、PHPはサーバー側で動くプログラミング言語でこの全体の処理の中でも、$_GETと$_POSTは超頻出です。つまりこの2つの処理が何をしているのかを「暗記」する事はPHPを早く上達する上では効率が良いと言えます。
GETやPOSTについてもっと詳しく知りたいと言う方はこちらの書籍を読んでみるのもいいかと思います。
HTTP通信についての理解が深まりクライアントとサーバーが裏でどんな事をやっているかのイメージがつくかと思います。
www.amazon.co.jp/dp/4774142042データベースは何をしているか
データベースを扱うアプリケーションでは「CRUD」のアクションが基本となります。
つまり、データベースに対して行うアクションは、・データベースにデータを「新規登録」する、
・そのデータを「読み出す」、
・そのデータを「変更し上書き」登録する、
・そのデータを「削除」する、という、「基本この4つしか無い」ということです。
つまりこの流れのイメージを意識的に暗記する事でコードを書いている時に、今何やっているかの把握ができ結果として開発効率が上がると考えます。
[補足]
個人的にはSQL文法も暗記しておいた方が効率が良いのではと思っています。これも超頻出なので。笑最後に
まとめとして、頻出する単語や概念、その周りの流れは覚えてしまった方が結果的に効率が上がると言う事です。
本記事とは少しずれますが、有名な方の発言を鵜呑みにするのではなく、その意見を一回自分の頭に持ち込んで、処理して自分なりの答えを導き出すと言う事も重要です。この「脳に対する意識的な習慣」ができていると、エラー時にもイライラしなくなると思います。(エラーでイライラしてしまう人は他責思考が強い人だと思う)
この事は自戒を含めて伝えたいなと思いました。
- 投稿日:2020-10-09T09:21:38+09:00
「暗記」ダメ!!!! 絶対!!!!それって本当ですか?
暗記ってダメなの?
学習をしていく中で1度は耳にする
「暗記」はダメ
といった論調があると思います
最初に結論を言っておくと私はこの記事で
暗記を全て否定するのではなく、拾ってくる情報リソースの多くで頻出している「単語」や「概念」は暗記しましょうね。と伝えたいです。私の背景
半年前の私は
・HTMLって何
・PHP何それ弱そう
・プログラミング=ホームページを作る事でしょ?といったようにプログラミングに関してほとんど無知の状態でした。
今では半年間毎日1日8時間の学習を継続しているので、そんなふざけた状態ではないですが、当時は間違いなく全くの初学者でした。私は初学者だった当時スクールに通うことはせずネットのPHP教材を購入し独学をはじめました。
少し話がそれますが、この半年でオンラインなどの交流会でスクールを卒業された方の話しを10人前後聞いてきたのですが、その方々の満足度は大変高い印象でした。ただし、接頭辞的な感じで、「挫折しない為には」いいですね。といった言い回しをされる方が多い印象でした笑
私も半年間独学をしてきた経験と周りの卒業された方の意見を合わせて考えると時間効率を求めるならスクールは大いにありだと思います。
スクールを通う段階としてはプロゲートで5つくらいの言語を一通りやってみてからでいいのかな〜といった印象です。
お金に余裕があって少しでも一人でやる自信がないと思っている方は即決でスクールを選んだ方が効率は絶対にいいです(こんな事言ってますがスクールの回し者ではありません笑。なんならエンジニアyoutuerみたいに一回くらい企業案件やってみたいです。この動画はテックアカ、、、、?)さて本題に戻ります。
私はスクールには通いませんでしたがネットで教材を購入しそれを独学しました。その教材の中には「暗記してください」などとは書かれて言いませんでしたが、重要なポイントとして取り上げられているTipsはたくさんありました。
要するに何が言いたいかと言うと
単語レベルの理解はもちろん、多くの人が共通して主立って「重要」と言っている事は四の五の言わず暗記した方が後の開発効率がスムーズになる。
と言うのが私の意見です。
そんなの当たり前だろ。。記事にすることじゃないよね。。と思われるかもしれませんが
初学者の方で
・「暗記」をひとまとめにして「悪」と捉えている
・「暗記」って本当にダメなのか疑心暗鬼になっている方は少なくないと思い、この記事を書きました。
少なからず私が学習初期の段階では色んな情報に触れて
「暗記は効率悪いんだ」と一括りにしてしまっていました。暗記しなくてもいい事
もちろん暗記する方が圧倒的に効率が悪くなることもあると思います。
そこで、大きく分けてみると3つに分類できるかなと思います。
※前提として忘れないで頂きたいのはこれは学習して半年程度且つ実務未経験者の意見です?また、PHPやLaravel以外の言語に関しては詳しくないのでご了承ください。笑
1. コードの書き方を暗記する
私が考えるに暗記してはいけないと情報発信されている方の本質的部分はここだと思います。
ここは私が細かく言うまでもないですが、効率が悪く、キリがないですよね。笑
これをやってしまっている方がいたら今すぐにその習慣を辞めて、コードを書いて覚えましょう!
無心で書き続けていればいつの間にか覚えます。必ずです。
2. 開発環境の構築の仕方
これはキリがないとか効率が悪いとか言うより初学者のうちにここを重点的に覚えようとすると、挫折率が上がってしまうかと思います。
サーバーやネットワークの知識が必要となってくるので初学者の段階は
「そう言うものを使っているんだな」程度の理解でいいのではないでしょうか。
3. 関数を全て覚えようとする
これもコードを暗記するに近いですが、仮に全て覚えても一生使わないものも出てくる可能性があり且つ効率が悪いからです。
経験上、使用頻度の高い関数はコードを書いて入れば勝手に覚えます。つまり使用頻度が高い=重要度の高い関数と言う認識で良いかと。暗記した方がいい事
さて、今度は逆に暗記した方がいい事について少しみていきましょう。
冒頭でも述べましたが、暗記をした方が良い内容は 拾ってくる情報リソースの多くで頻出している「単語」や「概念」の事でしたね。では具体的にはどう言った単語や概念でしょうか。
私の経験から「早めに覚えておいてよかった」「ここは早めに深く覚えておけばよかった」点から解説します。
※ここからはさらに個人的主観が強くなりますでご了承ください
以下の内応は一応、PHPを対象としていますの
if文/繰り返し文/関数/引数/戻り値/変数
と言ったどのプログラミング言語でも共通する基礎の部分は除きますざっくりですが以下2点の理解をまずは「暗記」する事を私はお勧めします。
1.$GETと$POST
2.データベースは何をしているか
詳しくは次の段落で書いていきます。
$GETと$POST
[なぜこれを覚えておいた方が良いのか]
それはPHP言語でCRUDを実装する時に超頻出の概念だからです。
(CRUDとは、システムに必要な4つの主要機能である「Create(生成)」「Read(読み取り)」「Update(更新)」「Delete(削除)」の頭文字を並べた用語です。)
CRUDはWEBアプリ制作する上で基本的な考え方になります。PHPとよく比較されるプログラミング言語が、JavaScriptです。この両者はスクリプト言語でも、動作については全く異なります。
JavaScriptはHTMLやCSS、画像と同じようにブラウザを表示しているPCにファイルをダウンロードしてから実行し動作するのに対し
PHPはWebサーバ上にファイルを置いて、以下の順で実行されます。1.ブラウザを見ているユーザがクリックなど何かの操作をする
2.その動作を受けたプログラムがサーバで動作する
3.動作結果をレスポンスとして、インターネット経由で送り、ブラウザ上にHTMLを表示する
このようにPHPのような言語は、サーバサイドのプログラミング言語と呼ばれ、PHPはサーバー側で動くプログラミング言語でこの全体の処理の中でも、$_GETと$_POSTは超頻出です。つまりこの2つの処理が何をしているのかを「暗記」する事はPHPを早く上達する上では効率が良いと言えます。
GETやPOSTについてもっと詳しく知りたいと言う方はこちらの書籍を読んでみるのもいいかと思います。
HTTP通信についての理解が深まりクライアントとサーバーが裏でどんな事をやっているかのイメージがつくかと思います。
www.amazon.co.jp/dp/4774142042データベースは何をしているか
データベースを扱うアプリケーションでは「CRUD」のアクションが基本となります。
つまり、データベースに対して行うアクションは、・データベースにデータを「新規登録」する、
・そのデータを「読み出す」、
・そのデータを「変更し上書き」登録する、
・そのデータを「削除」する、という、「基本この4つしか無い」ということです。
つまりこの流れのイメージを意識的に暗記する事でコードを書いている時に、今何やっているかの把握ができ結果として開発効率が上がると考えます。
[補足]
個人的にはSQL文法も暗記しておいた方が効率が良いのではと思っています。これも超頻出なので。笑最後に
まとめとして、頻出する単語や概念、その周りの流れは覚えてしまった方が結果的に効率が上がると言う事です。
本記事とは少しずれますが、有名な方の発言を鵜呑みにするのではなく、その意見を一回自分の頭に持ち込んで、処理して自分なりの答えを導き出すと言う事も重要です。この「脳に対する意識的な習慣」ができていると、エラー時にもイライラしなくなると思います。(エラーでイライラしてしまう人は他責思考が強い人だと思う)
この事は自戒を含めて伝えたいなと思いました。