タグ: PHP

  • 【Laravel】Gateとは

    【Laravel】Gateとは

    参加しているLaravelのプロジェクトでGateというものを扱うタイミングがあった。
    それの忘備録です。

    Gateとは

    Laravelは特定のリソースに対するユーザーアクションを認可する手軽な方法を提供している

    • 組み込み認証サービス
    • 認証されているユーザーでもDBのレコードの更新や削除ができない

    Laravelが提供しているアクションを認可する2つの具体例が次

    • Gate
    • Policy

    これらはRoutesやControllerのようなもの、と考えてok

    Gate

    クロージャーベースのシンプルなアプローチを提供する

    Policy

    Controllerの様に特定のModelやリソース周辺のロジックをひと塊にまとめる

    今回は「Gate」についてまとめる

    Gate

    Gateは、ユーザーが特定のアクションを実行することを許可されているかどうかを判断する単なるクロージャーである。

    • 通常、GateはGate Facadesを使用してApp\Providers\AuthServiceProviderクラスのbootメソッド内で定義される
    • Gateは常に最初の引数としてユーザーインスタンスを受け取る
    • オプションで関連するEloquentモデルなど追加の引数を受け取れる

    Gateを使った例

    <?php
    use App\Models\Post;
    use App\Models\User;
    use Illuminate\Support\Facades\Gate;
    
    /**
     * 全認証/認証サービスを登録
     *
     * @return void
     */
    public function boot()
    {
        $this->registerPolicies();
    
        Gate::define('update-post', function (User $user, Post $post) {
            return $user->id === $post->user_id;
        });
    }

    上記の例では、ユーザーが特定のApp\Models\Postモデルを更新できるかどうかを判断するGateを定義した。ユーザーのidとPostを作成したuser_idを比較している。

    アクションの認可

    Gateを使用してアクションを認可するにはGate Facadesが提供するallowsかdeniesメソッドを使う必要がある。すでに認証済みのユーザーをこれらのメソッドに渡す必要はない。Laravelは自動的にユーザーをGateクロージャーに渡す。一般的には、認可が必要なアクションを実行する前に、アプリケーションのController内でGate認可メソッドを呼び出す。

    <?php
    namespace App\Http\Controllers;
    
    use App\Http\Controllers\Controller;
    use App\Models\Post;
    use Illuminate\Http\Request;
    use Illuminate\Support\Facades\Gate;
    
    class PostController extends Controller
    {
        /**
         * 指定した投稿を更新
         *
         * @param \Illuminate\Http\Request $request
         * @param \App\Models\Post $post
         * @return \Illuminate\Http\Response
         * /
        public function update(Request $request, Post $post)
        {
            if (! Gate::allows('update-post', $post)) {
                abort(403);
            }
        
            // 投稿を更新する処理
        }
    }

    この様にLaravelのGateを使えば、そのユーザーに対してアクションを制限することができる。

  • Laravelでアプリケーションを開発するときの大まかな流れ

    Laravelでアプリケーションを開発するときの大まかな流れ

    今日はLaravelでアプリケーションを開発するときの大まかな流れを備忘録として説明したいと思います。

    アプリケーションの立ち上げ

    まずはLaravelでアプリケーションを立ち上げます。次のいずれかのコマンドを入力して、アプリケーションを作成します。ちなみにアプリケーションの名前をlaravel-appとしています。ここは皆さんの任意の名前をつけてください。

    $ composer create-project 'laravel/laravel=8.5.19' --prefer-dist laravel-app
    $ laravel new laravel-app

    このどちらかのコマンドを実行するとlaravel-appというアプリのデフォルトが作成されます。

    DBを用意する

    今度はアプリケーションで用いるDBを用意します。これにはLaravelの特徴的な要素でもあるMigrationファイルを用いて用意します。

    Databese自体の用意

    その前に、LaravelではDBの中身をいろいろと操作できますが、唯一Laravelからだとできない操作が「Database自体の作成」です。まずはDBの作成を直接しましょう。ターミナルからMySQLに接続したら、以下のコマンドでDatabaseを作りましょう。ちなみに、Databaseの名前はlaravelにしました。

    mysql> CREATE DATABASE laravel

    これを実行すると”Query OK, 1 row affected (0.00 sec)”と返ってきて、Databaseを作成することができます。

    tableの用意

    次にそのDatabaseにtableを用意します。ここからのDB周りの操作はすべてLaravel上で作業できますので、次のようにファイルを書いてください。

    そもそもですがMVCモデルをとっているLaravelにおいて、DBとやりとりをするのはModelなのでまずはModelらへんを見ていくことにしましょう。まずターミナルで次のコマンドを実行してください。仮のtable名はmemoです。

    $ php artisan make:model Memo -m

    上記のコマンドを実行することで「app > Models」にMemo.phpというModelファイルが生成されます。加えて上記のコマンドに”- m”というオプションを付けることで、migrationファイルを一緒に生成してくれます。このmigrationファイルは「database > migrations」にファイルを生成した日時と先ほど命名したModel名の複数形と、、、などが命名されたmigrationファイルが生成されます。今回、作成したファイルでいうと「2021_08_06_174912_create_memos_table.php」というファイルが生成されました。

    migrationファイルの編集

    それぞれのmigrationファイルを編集して、対応するそれそれのtableの仕様を書いていきます。

    migrationファイルを編集し終わったら、ターミナルで以下のコマンドを実行します。

    $ php artisan migration

    このコマンドによってMySQLに先程書いた仕様が反映されたtableが生成されます。MySQLで以下のコマンドを実行すると、実際にtableが作成されたのが確認できます。

    mysql> show tables from laravel

    ログイン機能を実装する

    今度はcomposerを用いて、手軽にログイン機能を実装しましょう。まずは以下のコマンドを入力してください。

    $ composer require laravel/ui
    $ php artisan ui bootstrap --auth
    $ npm install && npm run dev

    これらのコマンドを実行すると、認証周りの機能とBootstrapのデザインを用いて実装することができます。実際にLaravelを”php artisan serve”で起動して、サイトを見てみると、サイトの右上に「Login(ログイン)」と「Regester(登録)」のボタンが増えているのが確認できます。

    このRegesterボタンをクリックして、遷移したページで情報を入力すると、実際にユーザー登録もできますし、登録したユーザーの情報もDatabaseのUsersテーブルで確認することができます。

    Laravelのテンプレートファイル

    • @extends
    • @yield
    • @section

    上記の3つを用いて、サイトのviewをテンプレート化する!

    軽く触れておくと、テンプレートファイル化しておくていちいち同じ構造を書き直さなくてもいいから、汎用性が高くなるよ!これくらいの説明でも伝わるよね?!

    @extends

    • 子要素に用いる
    • @extends(‘layouts.auth’)と書くと、そのファイルは親要素であるlayouts > auth.blade.phpに当て込まれる

    @yield

    • 親要素
    • @yield(‘content’)と書くと、子要素の@section(‘content’) ~ @endsection部分を親要素に出力できる

    @section

    • 子要素
    • @section(‘content’) ~ @endsectionと書くと、@extends(‘layouts.register’)で指定したファイル(今回だとlayouts > register.blade.php)の@yield(‘content’)部分に出力したコードを表示できる

    Form周りの作り方

    LaravelでForm周りの作り方を説明する。

    Formを作るときの注意点

    Webアプリケーションを作るときに、 Formを作ることは頻繁に登場する。このときにformの開始タグの直後に次のコードを挿入しておいてほしい。

    <form action="/" method="POST">
        @csrf
        <input type="text">
        <button type="submit">送信する</button>
    </form>

    この「csrf」はCross-site Request Forgeryの略で、認証済みユーザーに代わって不正なコマンドを実行する、悪意のある攻撃の一種である。「@csrf」をinput開始タグの直後に挿入することで、LaravelはCSRFトークンを生成して、このCross-site Request Forgeryを防止することができる。詳しいことは別記事に記載するが、Laravelではこのコマンドを入力することでこのCross-site Request Forgeryを防止することができる。

    dd関数について

    dd関数とは、引数に変数(もちろん文字列でも数値でもいいが、目的には適していない)を入力すると、ブラウザでその引数の中身を参照できる。要はデバック用の関数で、開発の際はこのdd()に変数を入れるとよい。またdd()はそこで処理が止まるので、それ以降のコードは読まれない。

    また似たような関数にdump関数があるが、これはdd()とは異なりdump()以降のコードも読まれる。

  • tailwindcssをインストールできなかった話【解決済み】

    tailwindcssをインストールできなかった話【解決済み】

    今回は僕がLaravelでアプリケーションを作成しているときに遭遇したTailwindcssをインストールできなかったお話とそれを解決した方法をご紹介したいと思います。

    問題が生じた背景

    僕はYoutubeの教材でLaravelを用いたアプリケーションの開発の勉強をしていました。その教材ではcssのデザインにTailwindcssという、cssのフレームワークを使うそうでした。教材の冒頭でLaravelをインストールし終わったあとに、このTailwindcssもインストールするように案内されます。そのときの教材に書いてあるコードは以下です。

    npm install tailwindcss

    これをターミナルに入力して実行しました。すると次のようなエラーが返ってきました。

    npm ERR! code ENOTDIR
    npm ERR! syscall open
    npm ERR! path /Users/tomoyasusunagawa/node_modules/color-name/npm-shrinkwrap.json
    npm ERR! errno -20
    npm ERR! ENOTDIR: not a directory, open '/Users/tomoyasusunagawa/node_modules/color-name/npm-shrinkwrap.json'
    
    npm ERR! A complete log of this run can be found in:
    npm ERR!     /Users/tomoyasusunagawa/.npm/_logs/2021-08-09T08_50_35_395Z-debug.log

    最初はビックリしましたが、よく読むと真ん中ら辺に「npm-shrinkwrap.jsonはディレクトリではありません」みたいなことを言われています。

    解決した方法

    (そんなこと、僕に言われても)という気も一瞬しましたが、すかさずGoogle先生に聞いたところ、次のように実行すると期待通りにTailwindcssをインストールできると書いてありました。

    $ cd [PATH_TO_DIR]
    $ npm init -y
    $ npm install tailwindcss postcss-cli autoprefixer

    作業ディレクトリに移動して、npmパッケージを使う準備をして、tailwindcssのインストールをする、的な意味のコマンドらしいです。

    無事にさきほどのエラー文も返って来なくなったので、正常にインストールできたことが確認できました。

  • Laravelで新しいWebアプリを始める方法

    Laravelで新しいWebアプリを始める方法

    タイトルの通りです。この夏にWeb開発を勉強しようと思って、ReactやVue.js、Ruby on Railsなどで迷ったのですが、Webサイト制作上がりでPHPは理解しているのでなるべく勉強の負担を減らそうと考えて「Laravel」をフレームワークに選びました。

    以前にFuel PHPを使っていたのですが、Webサイト制作でとっくに忘れました。

    Laravelでアプリを始める

    自分のパソコンにLaravelをインストールできたら、アプリケーションを作成したいディレクトリまで移動します。そこで次のコマンドを入力してください。以下の「〇〇」にはディレクトリの名前というか、アプリケーションの名前を入力してください。

    $ laravel new 〇〇

    これを入力するとLaravelの初期の状態のアプリケーションが作成されます。

    「laravelコマンドがない」と言われたとき

    プログラミングにはエラーがつきものです。上記のコマンドを入力して以下のように返されることがあります。

    zsh: command not found: laravel

    このように言われたときは以下のコマンドを実行して、パスを通しましょう👍

    $ export PATH="$PATH:$HOME/.composer/vendor/bin"

    これは ~/.composer/vendor/bin のパスを通すコマンドで、これを実行するとlaravelコマンドが使えるようになるそうな。

    以上、よいプログラミングライフを!

  • 【知らなきゃ損】三項演算子が便利って話

    【知らなきゃ損】三項演算子が便利って話

    皆さん、こんにちは。すなです。

    最近、エンジニアをしていて「やっぱりプログラミングって楽しいなぁ」とつくづく感じる日々です。

    今日はそのプログラミングの技術的なお話。

    要はif-else構文と同じ

    エンジニアの皆さん、変数に何かを代入するときにif-elseで場合分けして代入するみたいなシチュエーション、よくありませんか?

    文章だけだと分からないので下の例を。

    $result = file_get_contents($file_path);
    if ($result) {
      $announce = "ファイルを取得しました";
    } else {
      $announce = "ファイルがありません";
    }
    echo $announce;

    これはfile_get_contentsというurl先のWebページの内容を取得できるPHPの関数です。返り値として読み込んだデータを返し、失敗した場合はFALSEを返します。

    したいことに対してコードが多過ぎる

    これ$announceに文字を代入したいだけなのに、控えめに言って無駄が多過ぎますよね?

    変数に文字列を代入するために、if-else構文で3行使ってますし、変数に文字列を代入するほぼ一緒のコードが2回出てきます。

    三項演算子を使おう

    そんな時は今回ご紹介する「三項演算子」を使いましょう。

    さっきと同じコードを三項演算子を使って書いてみます。

    $result = file_get_contents($file_path);
    $announce = $result ? "ファイルを取得しました" : "ファイルがありません";
    echo $announce;

    見てください、この収納の良さ。それでいて綺麗ですね。

    三項演算子に初めて触れる方は何をしてるかさっぱり分からないかも知れませんね。実は大したことないので、解説します。

    条件式 ? trueのとき : falseのとき

    もう答え書いちゃいました。そういうことです。

    すみません、ちゃんと解説しますね。

    $condition = true;
    $result = $condition ? "これはtrueです" : "これはfalseです";
    echo $result;
    // これはtrueです

    条件式

    最初に条件式を書きます。ここがtrueかfalseになります。上記の例で言うと$conditionの位置が条件式で、これの中身を判定します。

    ? true

    条件式のあとに「?」を書いて、その次に条件式がtrueだったときに返す値を入れます。上記の例は$conditionがtrueのとき、「これはtrueです」を返します。

    : false

    そのあとに「:」を続けて、今度は条件式がfalseだったときに返す値を入れます。上記の例は$conditionがfalseのとき、「これはfalseです」を返します。

    さっきの例全体としては、$conditionがtrueなので三項演算子は全体として「これはtrueです」を返します。それが「$result = 」と繋がっているので、$resultに「これはtrueです」が代入されます。

    もちろん$condition === falseのときは$resultに「これはfalseです」が入ります。

    他の例

    他にも例を見てみましょう。

    $age = 18;// 自分の年齢
    $alcohol = 20 < $age ? "最初の一杯は?" : "飲酒は二十歳になってから";
    print $alcohol;
    // 飲酒は二十歳になってから

    $ageに皆さんの年齢を代入してみてください。そのあと、三項演算子の「条件式」のところで真偽を判定します。例の場合は、「20 < $age」がfalseなので、$alcoholには「飲酒は二十歳になってから」が代入されます。


    // 入力されたパスワードが合っていたとして
    echo $password === $_POST["password"] ? "ログインしました" : "パスワードが間違っています";
    // ログインしました

    これはformタグから入力されたパスワードを判定して、ログインするかしないかを返します。三項演算子自体が文字列を表すので、echoで直接出力すると結果が表示されます。