20200722のPHPに関する記事は14件です。

自動で EC2 Autoscaling の起動設定をAttachするスクリプトを php で作った

背景

インスタンスの更新を行うたびに、手動で起動設定を作り直していた。

  1. 最新の EC2 から AMI を作る
  2. AMI から 起動設定を作る
  3. Autoscaling Group に Attach
  4. 不要になった起動設定を削除
  5. 不要になった AMI を削除

毎回この単純作業。
地味に時間がかかるのと、一つミスすると、スケールアウト時にちゃんと動かないとかトラブルになる。(開発環境でちょっとトラブルになりかけた)

ミスになりそうな単純作業は自動化しちゃえと。

なぜ PHP で書いた?

10年ぐらい慣れ親しんだ言語なので! それだけ。

前提

  • php 7.0 以上がローカルで動くこと
  • aws-cli インストール済み
  • jq コマンドインストール済み
  • 東京リージョンで使う前提

そのソースコードを公開

gist に置いてます

$ git clone https://gist.github.com/208289a6de7f76ccf7c3709b5b83e760.git autoscaling-script
$ cd $_
# list の中身を各自の環境に合わせる
$ vim autoscaling-update.php

ソースの中身

$list について

$list は各ENV、各インスタンス、オートスケーリングの設定が記載された連想配列です。

$list = [ 
    'stage' => [
        'web' => [
            'namelike' => 'stage-web',
            'autoscaling_group' => 'stage-web-autoscaling',
            'launch_namelike' => 'stage-web-launch',
            'instance_type' => 't3.micro',
            'key_name' => 'stage',
            'security_groups' => 'sg-0dce82de47bea0926',
            'iam_instance_profile' => 'stage-web-role',
        ],  
        'admin-web' => [
            'namelike' => 'stage-admin-web',
            'autoscaling_group' => 'stage-admin-web-autoscaling',
            'launch_namelike' => 'stage-admin-web-launch',
            'instance_type' => 't3.micro',
            'key_name' => 'stage',
            'security_groups' => 'sg-0dce82de47bea0926',
            'iam_instance_profile' => 'stage-admin-web-role',
        ],  
        'pointback' => [

... snip ...

        ],  
    ],  
    'prod' => [
        'web' => [
            'namelike' => 'prod-web',
            'autoscaling_group' => 'prod-web-autoscaling',
            'launch_namelike' => 'prod-web-launch',
            'instance_type' => 'm5.large',
            'key_name' => 'prod',
            'security_groups' => 'sg-8faef0d139d0af',
            'iam_instance_profile' => 'prod-web-role',
        ],  
        'admin-web' => [

... snip ...

ENV は stage (開発), prod (本番) 環境があり、
インスタンス種類は web(ユーザ画面), admin-web(管理画面), pointback(ポイントバック), batch(バッチ) が存在している想定です。

この連想配列は使われる方に合わせて自由にカスタマイズしてもらえればOKです。

$list 内の個々の記述について

個々の記述では、どういう起動設定を作り、インスタンスタイプが何で、、、どの Autoscaling Group にAttachするのかが定義されています。

            'namelike' => 'prod-web',
            'autoscaling_group' => 'prod-web-autoscaling',
            'launch_namelike' => 'prod-web-launch',
            'instance_type' => 'm5.large',
            'key_name' => 'prod',
            'security_groups' => 'sg-8faef0d139d0af',
            'iam_instance_profile' => 'prod-web-role',
  • namelike: instance名を記載します (ami の名前の一部としても使うので namelike というキーにしました)
  • autoscaling_group: Autoscaling Group 名
  • launch_namelike: 起動設定名のプレフィックスです。実行した日時にあわせて重複でエラーとならないように prod-web-launch-20200721190000 のような起動設定名が適用されます
  • instance_type: インスタンスタイプです。 t3.nano, t3.micro, ... m5.xlarge など 東京リージョンで定義されているインスタンスタイプを指定できます
  • key_name: SSHキーに何を使うかを指定します
  • security_groups: Security Group の ID を指定します。複数の場合は、半角スペースをあけて記載します
  • iam_instance_profile: IAM インスタンス Profile です

実行について

以下のように動かします。

$ ./autoscaling-update.php prod web // stage admin-web 環境の場合

$ ./autoscaling-update.php prod web // prod web 環境の場合
$ ./autoscaling-update.php prod all // prod 全環境の場合

実行すると以下のようなログが表示されます

$ ./autoscaling-update.php prod all                                                                                    ?[feature/add-attache-autoscaling-       + scripts]                                                                                                                                                                                                                            
[2020-07-21 20:22:22] 該当インスタンスいずれか一つ取得
[2020-07-21 20:22:22] execute command "aws ec2 describe-instances --region ap-northeast-1 \
 | jq -r '.Reservations[].Instances[] | select(.Tags[].Key == "aws:autoscaling:groupName") | select(.Tags[].Value == "prod-web-autoscaling") | select(.State.Name == "running") |.InstanceId'|head -1" 
[2020-07-21 20:22:23] command result .. i-02e087ffcfdc9cb4f
[2020-07-21 20:22:23] AMI 作成
[2020-07-21 20:22:23] execute command "aws ec2 create-image --region ap-northeast-1 --instance-id i-02e087ffcfdc9cb4f --no-reboot --name prod-web_20200721202223 | jq -r ".ImageId""
[2020-07-21 20:22:24] command result .. ami-04a9f007ba3509a30
[2020-07-21 20:22:24] AMI Tagging
[2020-07-21 20:22:24] execute command "aws ec2 create-tags --region ap-northeast-1 --resources ami-04a9f007ba3509a30 \
  --tags Key=Name,Value=prod-web_20200721202223 Key=Type,Value=autoscaling Key=Environment,Value=prod"
[2020-07-21 20:22:25] command result .. ami-04a9f007ba3509a30
[2020-07-21 20:22:25] AMI 作成完了待ち
[2020-07-21 20:22:25] execute command "aws ec2 wait image-available --region ap-northeast-1 --image-ids ami-04a9f007ba3509a30"
[2020-07-21 20:24:42] 起動設定 作成
[2020-07-21 20:24:42] execute command "aws autoscaling create-launch-configuration \
  --region ap-northeast-1 \
  --launch-configuration-name prod-web-launch-20200721202223 \
  --image-id ami-04a9f007ba3509a30 \
  --instance-type m5.large \
  --key-name hapi_lab \
  --security-groups sg-0a09da7b2899abf20 \
  --instance-monitoring Enabled=true \
  --iam-instance-profile prod-web-role
[2020-07-21 20:24:43] autoscaling group 更新
[2020-07-21 20:24:43] execute command "aws autoscaling update-auto-scaling-group --region ap-northeast-1 \
  --auto-scaling-group-name prod-web-autoscaling \
  --launch-configuration-name prod-web-launch-20200721202223"
[2020-07-21 20:24:44] execute command "aws autoscaling describe-launch-configurations --region ap-northeast-1 --output json"
[2020-07-21 20:24:46] prod-web-launch-202007091312 に関連する古い設定を削除します
[2020-07-21 20:24:46] execute command "aws autoscaling delete-launch-configuration --region ap-northeast-1 --launch-configuration-name prod-web-launch-202007091312"
[2020-07-21 20:24:47] prod-web-launch-202007091312 に関連する古い AMI の登録を解除します . amiId=ami-094d805c269cb018e
[2020-07-21 20:24:47] execute command "aws ec2 deregister-image --image-id ami-094d805c269cb018e"
[2020-07-21 20:24:48] 該当インスタンスいずれか一つ取得
[2020-07-21 20:24:48] execute command "aws ec2 describe-instances --region ap-northeast-1 \
 | jq -r '.Reservations[].Instances[] | select(.Tags[].Key == "aws:autoscaling:groupName") | select(.Tags[].Value == "prod-admin-web-autoscaling") | select(.State.Name == "running") |.InstanceId'|head -1" 
[2020-07-21 20:24:50] command result .. i-003be640ea8229484
[2020-07-21 20:24:50] AMI 作成
[2020-07-21 20:24:50] execute command "aws ec2 create-image --region ap-northeast-1 --instance-id i-003be640ea8229484 --no-reboot --name prod-admin-web_20200721202450 | jq -r ".ImageId""
[2020-07-21 20:24:51] command result .. ami-02751dec1db361b4c
[2020-07-21 20:24:51] AMI Tagging
[2020-07-21 20:24:51] execute command "aws ec2 create-tags --region ap-northeast-1 --resources ami-02751dec1db361b4c \
  --tags Key=Name,Value=prod-admin-web_20200721202450 Key=Type,Value=autoscaling Key=Environment,Value=prod"
[2020-07-21 20:24:52] command result .. ami-02751dec1db361b4c
[2020-07-21 20:24:52] AMI 作成完了待ち


... snip ...

課題

  • 設定ファイルとスクリプトを一緒にしている. yaml とかに分離させたい
  • userdata どうするのとか、スポットインスタンス使いたいとか、起動テンプレート使いたいとか、東京リージョン固定が嫌だとか、汎用的にはしていない
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

phpにおけるオブジェクト指向まとめ

はじめに

この記事はphpにおけるオブジェクト指向を簡単にまとめたものです。
オブジェクト指向ってなんぞや?
phpで開発を行っているがメソッドとかクラスとはよう分らんって人向けの記事で、新卒2年目のペーペーエンジニアが書いています。

そもそもオブジェクト指向って?

オブジェクト指向とは、コンピュータプログラムの設計や実装についての考え方の一つで、互いに密接に関連するデータと手続き(処理手順)をオブジェクト(object)と呼ばれる一つのまとまりとして定義し、様々なオブジェクトを組み合わせて関連性や相互作用を記述していくことによりシステム全体を構築していく手法。

上記説明で分からない場合は、
「各処理を分割、共通化し管理する。そして複数の処理を組み合わせてシステムを構築しよう」
と考えてください。たぶん合ってます。たぶん。。

念のため上記をphpで説明するとこんな感じ。

まずはオブジェクト指向ではない書き方。

<?php

class Controller_Tanaka
{
  public function action_name()
  {
    echo 'Tanaka';
  }
  public function action_occupation()
  {
    ecjp 'teacher':
  }
  public function action_walk()
  {
  }
  public function action_eat()
  {
  }

<?php

class Controller_Yamada
{
  public function action_name()
  {
    echo 'Yamada';
  }
  public function action_occupation()
  {
    ecjp 'president':
  }
  public function action_walk()
  {
  }
  public function action_eat()
  {
  }

うむ。
class_Tanakaとclass_Yamadaでおんなじ様なメソッドが複数存在していますね。
これを書き直すとこう。

<?php

class Controller_Human
{ 

 public $name;
 public $occupation;

  public function action_name($name)
  {
    $human = new Human();
    $human->name = $name
    echo $human->name;
  }
  public function action_occupation($occupation)
  {
    $human = new Human();
    $human->occupation = $occupation
    echo $human->occupation;
  }
  public function action_walk()
  {
  }
  public function action_eat()
  {
  }

人間の行動(メソッド)、特徴(プロパティ)を共通化、分割し取り扱っています。
多分これがオブジェクト指向。間違っていたらご指摘ください。。

以下用語解説

Class

大雑把に言うと「関数(メソッド)と変数(プロパティ)の塊」です。
「プログラムの処理をまとめた設計図」だと考えれば分かりやすいかも知れません。
上記の例だともちろんこれ。

class Controller_Human
{ }

メソッド

メソッドとはクラスが持っている処理のことです。上述の例ですとこいつらですね。

public function action_name($name)
  {
    $human = new Human();
    $human->name = $name
    echo $human->name;
  }
  public function action_occupation($occupation)
  {
    $human = new Human();
    $human->occupation = $occupation
    echo $human->occupation;
  }
  public function action_walk()
  {
  }
  public function action_eat()
  {
  }

プロパティ

クラスが持っているデータのことです。
上記の例だとこいつら。

 public $name;
 public $occupation;

ちなみに、メソッドと関数、プロパティと変数は基本的には同じものと考えてよいです。
呼び方が違いますが同じ働きをします。
ほんとややこしい子。。

アクセス修飾子

メソッドとプロパティの前についているpublic
こいつはどこからそのメソッドやプロパティにアクセスできるかを指定するもの。

public     クラス内、クラス外のどこからでもアクセス可能
private    同じクラス内からのみアクセス可能
protected  同じクラス、及び子クラスからアクセス可能

とりあえず全部publicで書いてました気を付けます。。

カプセル化

オブジェクトが持つデータや処理のうち、別のオブジェクトから直接利用される必要のないものを隠すことを言い、利用する場合は外部から操作するために作られた処理を設けることを言う。

継承

特定のクラスを他のクラスに引き継いで、同じメソッドを使えるようにしちゃいましょう、的なやつです。
例えば上記で作成したClass_Humanも他のクラスに継承することで同じメソッドが使えるようになります。

おわりに

とりあえず30分で調べた知識を書き殴りました。
間違っている部分等あればご一報ください。
修正するかは分かりません。
疲れたマン。

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

【PHP】独習PHP 復習

書籍のアウトプットとして

大文字小文字を区別しない

PRINT 'hello';
pRint 'hello';

この2つは問題なく動作する。

そういえば区別しないんだっけ、という感じ。

演算子(オペレータ)と被演算子(オペランド)

       ┌────┬───┬─被演算子(オペランド)
       $x = 5 + 4
          └───┴演算子(オペレータ)

値による代入と参照による代入

変数の正体

値を格納するのはメモリの役割
メモリには場所を示すアドレスが振られている。
そのアドレスをいちいち入力するのはタイプミスの元となるから人がわかりやすいように名前をつけておく─────────これが変数の正体

値による代入

=を使うのは基本的に値による代入
これはメモリ上の値を別のメモリにコピーすること

参照による代入

メモリ上のアドレスそのものを引き渡す代入
元の変数と代入した変数は同じアドレスを見ている。
どちらかを変更したら、もう片方にも影響する。
参照による代入は=&を使う
複合代入演算子&=と混同しないように

&=

左辺と右辺をビット論理積した結果を左辺に代入

$x=1;
$y= &$x;参照コピー
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

レンタルサーバーでSETENVを設定しPHPで利用する【作成中】

レンタルサーバー上の.htaccess にが記述されている。意味は下記参照。
MIMEタイプの追加(AddType)
SETENVとは直接関連しないのでこのあとにSETENVを記述する

記述のしかたは下記を参考に実施する
PHP .htaccess内に追加(SetEnv)した環境変数で開発環境/本番環境など動作環境を切り替える方法

あんまり関係なさそうだが一応参考記事
Apache の環境変数

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

Laminas 環境設定メモ

Laminas

zendが新しくなったらしいので
早く日本語訳の本出てください。

  • mac
  • VirtualBox
  • centos8
  • Laminas

つまずいた所メモ

↓とりあえずやる。
https://docs.laminas.dev/tutorials/getting-started/skeleton-application/

なんか、500になる。
ネットワーク設定が悪いのかなっと思い、
.httpd.confと.htaccessをいじる。
(httpd.confでdocumentrootとか分けられたんだね・・・分け方が分からずVirtualBoxで分けてた)

できない。_:(´ཀ`」 ∠):

public/index.phpの上のほーにexit入れてみる。
表示できた。(°▽°)

もももも、もしかして、コードがおかしい?
public/index.phpにexitをひたすら入れる。

RuntimeExceptionのとこでエラー
分からん。

プロジェクトを作り直してみた。なんかエラー出ててた。
RuntimeException.phpがなんとか。ない?とかなんとか(忘れました。

結果

composerでライブラリが読めなかったらしい。
composer.jsonがある場所で、

$ composer clear-cache
$ composer update --no-plugins

できた。

追伸

なんで拡張子がphmlなの・・・?
初めてみたんだけれど、
ググったらめっちゃ古いよって見たんだけど?
これ、今年発表されたフレームワークなんだよね?
試しに拡張子phpにしたらエラーがすごいんだけど?
推奨されてるのかなぁ・・

参考

composer installでCould not deleteといわれ、clear-cacheしてもなおらないときはcomposer update --no-pluginsをする

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

Javascriptからphpへデータを渡す方法

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

CakePHP3.8 と Laravel7.x の「書き方」の違い ~ORM周りその1~

CakePHP3.8 と Laravel7.x の「書き方」の違い ~ORM周りその1~

前: 設定周り

Model の作成・設定

クエリの要約

  • CakePHP

カスタムファインダーメソッドで実装する

メソッド名を find〇〇 にし、 Query インスタンスを return する必要がある

    public function findHyphen(Query $query, array $options)
    {
        return $query->where(['favorite' => 'KAT-TUN']);
    }

    public function findArasick(Query $query, array $options)
    {
        return $query->where(['favorite' => '嵐']);
    }

    public function findVeteran(Query $query, array $options)
    {
        return $query->where(['fan_career >' => '5']);
    }

使うときは Table::find(), Query::find() にファインダー名を渡す

$usersTable = TableRegistry::getTableLocator()->get('Users');
$query = $usersTable->find('hyphen')->find('veteran');
  • Laravel

ローカルスコープ で実装する

メソッド名を scope〇〇 にし、 Builder インスタンスを return する必要がある

    public function scopeHyphen(Builder $query)
    {
        return $query->where('favorite', '=', 'KAT-TUN');
    }

    public function scopeArasick(Builder $query)
    {
        return $query->where('favorite', '=', '嵐');
    }

    public function scopeVeteran(Builder $query)
    {
        return $query->where('fan_career', '>', '3');
    }

使うときは Model, Builder からスコープ名の関数を呼び出す

$users = Users::hyphen()->veteran()->get();

Iterable 問題(名前は勝手につけた)

ORM はそれぞれ、CakePHP => Query, Larabel => Builder だが、Iterable (簡単に言うと foreach できること)かどうかに違いがある。

  • CakePHP
$query = $usersTable->find('hyphen')->find('veteran');
foreach ($query as $entity) // foreach されるタイミングで SQL が発行・fetch され、レコードを foreach することができる
  • Laravel
$builder = Users::hyphen()->veteran();
foreach ($builder as $property) // iterable ではないので、普通のプロパティ参照のようになってしまう
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ConoHa で立ち上げた Laravel イメージだと ZipArchive が使えなかった。

状況

手元の Homestead 上では普通に使えてたので、気にせず開発していたのだけど、デプロイしたらエラー吐いたので困った。
とりあえず拡張を確認する。

$ php --ri zip
Extension 'zip' not present.

ないね。

環境

  • ConoHa VPS Laravel イメージ
  • PHP 7.2.16
  • Laravel Framework 5.8.36
  • CentOS Linux release 7.6.1810 (Core)
  • yum リポジトリは remi-php72 と remi-safe が使える

インストール

$ sudo yum install --enablerepo=remi,remi-php72 php-pecl-zip

apache 再起動

$ sudo systemctl restart httpd.service

確認

$ php --ri zip

zip

Zip => enabled
Zip version => 1.19.0
Libzip headers version => 1.7.0
Libzip library version => 1.7.3
BZIP2 compression => Yes
XZ compression => Yes
AES-128 encryption => Yes
AES-192 encryption => Yes
AES-256 encryption => Yes
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

PHP で型付のローカル変数を定義するライブラリを作った

概要

PHP で型のあるローカル変数を定義するライブラリを作った。

https://github.com/sj-i/typist

誤った型の値を代入しようとすると \TypeError を投げる。

型を書ける奴だから TypeWriter か、とも思ったけど、長かったので Typist という名前にした。
PHP 7.4 以降で利用可能。

インストール

composer require sj-i/typist

基本的な使い方

use function Typist\int;
use function Typist\string;

// int 型と string 型のローカル変数を定義
$_ = [
    int($hoge_id, 1),
    string($hoge_name, 'name'),
];

// 渡した値で初期化される
assert(1 === $hoge_id);
assert('name' === $hoge_name);

// int 型の変数へ文字列を突っ込もうとすると TypeError
$hoge_id = 'a';

// string 型の変数へ int の値を突っ込もうとすると TypeError
$hoge_name = 1;

どうなってんの?

PHP 7.4 で型付プロパティが導入された。
こいつには面白い性質があって、ある変数が型付プロパティと同じものを参照している間、その変数は同じものを参照する全ての型付プロパティで宣言された型の制約を引き継いで受けることになる。
よって指定した型の型付プロパティを持つオブジェクトを生成し、参照渡し経由で変数を型付プロパティに参照させ、オブジェクトは GC されないよう使わない変数 $_ でつかまえておくことで、この型付ローカル変数も実現できる。

なるほど分からん

型付プロパティの RFC に詳しく書いてある。
ピンとこないとしたら、たぶん PHP における参照がどういう意味のものか、がピンとこないのだと思う。俺もこの RFC を見るまでよく分かっていなかった。ので、PHP の参照について簡単に説明しよう。

PHP の参照

$a = 1;
$b =& $a;
$c =& $b;

上記のようなコードについて考えよう。
最初の 1 行目 $a = 1; の状態を雑に図示するとこう。

Untitled Diagram.png

超シンプル。

次に 2 行目の $b =& $a; の状態を、同じく雑に図示するとこう。

Untitled Diagram (3).png

$b$a を指すというより、$a が指すものと同じものを指す仲間に加わる感じ。

そしてお察しのとおり、更にその次の $c =& $b; の状態はこうなる。

Untitled Diagram (2).png

$c$b を指すように、と数珠つなぎになっていくわけではなく、やはり同じものを指す仲間に加わる感じ。

同じものを指す仲間達をひとまとめにし、(型付プロパティの RFC の言葉を借りて)参照セットとでも呼ぶことにしよう。参照セットにあるどの変数への代入も、同じセット内の他の変数の値へ影響する。同時に一括代入しているようなもの、というとらえ方もできる(実際の実装は異なるが、概念的にはそうもとらえられる)。

参照と型付プロパティ

さて、この参照セットのメンバへ、型付プロパティが含まれている場合は何が起きるだろうか?

Untitled Diagram (4).png

プロパティだと $a とか $b のままじゃ不自然なので、オブジェクト $o のプロパティだということにしよう。

$o = new class() {
    public int $a = 1;
    public float $b;
};
$o->b =& $o->a;
$c =& $o->b;

Untitled Diagram (5).png

型付プロパティは、プロパティが宣言された型の値を持つこと、読み込み時に指定した型の値だけが得られることを保証する仕組み。これを実現するには代入時に値の型の検査が必要。

$o->a へ何かの値を代入するとする。

$o->a = 1; // 合法
$o->a = 'abc'; // $o->a の型宣言は int なので違法、TypeError

分かりやすい。

しかし、次の例ではどうだろう。

$o->b = 1.5; // 合法……?
var_dump($o->a); // $o->a の型宣言は int なのに 1.5 とか出ちゃうの……?

あるいはまた、次の例ではどうだろう。

$c = new DateTime(); // 合法……?
var_dump($o->a); // $o->a の型宣言は int なのに現在日時が出ちゃうの……?

同じ参照セットに含まれる全ての型付プロパティの型で型検査を行い、すべての型検査に通る値だけが代入に成功するのでなければまずい。型宣言によって得られる筈の保証が台無しになってしまう。そして実際に、PHP はそのように順繰りの型検査を行う。

1int の型検査にも float の型検査にも通るので代入可能。
1.5int の型検査を通らないので代入不可能。
日時型は int の型検査にも float の型検査にも通らないので代入不可能。

このようにして、型付プロパティと同じ参照セットのメンバであるただのローカル変数 $c は、めでたく代入時に型検査の行われる変数になった、というわけだ。

この参照と型付プロパティについての挙動を把握すると、うまくやれば型付ローカル変数を定義するためのライブラリを作れそうな気がしてくる。

既存の実装

先に今回とってない実装方針について、他実装を紹介しつつざっくり説明。

型付プロパティの参照を取り出して参照代入でローカル変数へ突っ込めば、その変数は元の型付プロパティと同じ型の検査を受けるローカル変数になる。

比類なき nikic の人が Poor Man's Typed Variables として紹介してるのはこちらの方針。

function &int(int $i) {
    $obj = new class { public int $prop; };
    $obj->prop = $i;
    $GLOBALS['huge_memory_leak'][] = $obj;
    return $obj->prop;
}
$i =& int(0);
$i = "foobar";
// Uncaught TypeError: Cannot assign string to
// reference held by property class@anonymous::$prop
// of type int

このスライドの実装を見ると分かる通り、型付プロパティを持つオブジェクト(以下型付プロパティオブジェクト)を GC させないよう、refcount1 を保つためにグローバル変数へ生成したオブジェクトを突っ込んでる。もちろんめっちゃメモリリークする。

azjezz/typed という、型付プロパティの参照で型付ローカル変数を、というのをやってる別ライブラリがある。こちらもおおむね同じやり方。虚空から欲しい型の値を生成してる感を出すため、各変数について生成する型付プロパティオブジェクトはグローバルステートへ突っ込み、refcount を維持する。もちろんめっちゃメモリリークするので、手動のメソッド呼び出しで型付プロパティオブジェクトを開放する方法を提供している。

らなくあさんが以前に紹介していたこの手法の例示も、先にオブジェクトを生成し、プロパティの参照代入でローカル変数へ持ってくるというやり方↓。

これらの実装を見ての感想は↓のような感じ。

  • なんとなく参照代入の &かわいくない気がする
  • メモリ管理をそんなに頑張りたくない
  • 利用側で謎オブジェクトを生成するのは嫌、なんかそれっぽい関数経由で変数定義したい

今回の実装

  • & が露出しないよう参照渡し利用した
    • 型付きプロパティが型を付けたい変数と同じ参照セットに入ればよいのだから、プロパティからの参照代入ではなくプロパティへの参照代入でも同じことができる、というわけだ
    • 型指定で参照渡しした変数は psalm が別の型による再代入へ警告をくれるので、静的解析へも対応
  • 参照渡しの利用によって返り値の枠が空いたので、メモリ管理を頑張らないで済むよう型付プロパティオブジェクト(Enforcer)をそのまま return し、ローカル変数で受け取って、呼び出し側でライフタイムを管理する仕組みにした
    • refcount 維持用に持つだけでアクセスの必要はないオブジェクトなので、見た目の存在感が薄めのローカル変数として $_ という配列を用意し、そこへ突っ込んでいく
    • $_ は psalm のような静的解析ツールで未使用変数警告を出さず無視してくれる名前でもある
  • 静的メソッドと通常関数の二通りのインターフェースを用意した
  • 今のところスカラ型とクラス / interface、nullable の型指定に対応
    • iterable とか array もやれそう、ただ要素型指定できない奴とか要らない気もする
    • callable はとりあえず諦め

お前この裏技に否定的じゃなかったっけ?使い道は?

  • PHP 7.4 リリース前の去年 1 月時点でわりと否定的なことを言ってた
  • つい最近また同様に否定的なことを言う機会があった
  • その流れで、PHP 8 の機能を使って何か面白いことやれないかな、とガチャガチャ試す時、そういえばこんなのあったなと少し書いてみるのにつながる
  • ガチャガチャやってる間にそれっぽいライブラリになってしまったので、一応公開、という形
  • ローカル変数の型を実行時に強制するのがそんなに有用か、には引き続き懐疑的姿勢
  • PHP 7.4 までの言語の型機能と静的解析ツールの型推論に型アノーテーション、それに加えて webmozart/assert あたりで用足りるのではないか
    • クラスだのメソッドだの関数だの適度に小分けにコード書いてると、ローカル変数はごく短命となる筈で、引数や返り値のような断続的な型チェックでもわりと用が足りてしまい、こういうハックの有用性は薄れる筈
  • ローカル変数の寿命が長く型の動きが不安なコード、であれば、こういうのも多少使う意味があるかもしれない(PHP 7.4 だけど魂はレガシーコード、みたいな奴があれば)
  • 静的解析向けの型アノーテーションは油断すると嘘をつく場合もあるので、不安な箇所でランタイムのチェックも足す用、という意味はあるかもしれない

おまけ


  1. (「参照カウント」と呼ぶと紛らわしい話の流れなので refcount 呼ばわり) 

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

[Homebrewでさくっと]PHPとApacheとMariadb(mysql)を導入しよう!(Macユーザー向け)

はじめに なぜこの記事を書いたか

Web開発してみたい!PHPの基礎終わった!さぁ作るぞ!ってなったときに意外と次の壁になるのがWebサーバーやデータベース関連の環境構築かなぁと思います.

確かにMAMPやXAMPを使ったやり方やLinux OS(CentOSとかUbuntu)での環境構築については、日本語記事もゴロゴロ落ちています.

けれども「まずはMacで気軽に環境構築したい」、「(MAMPを使わず)出来れば今後の開発環境構築にも力になるような形で!」というような要望を満たしてくれる記事がほとんど英語で書かれたものしか見当たらなかったので書いてみました.

今回のゴール

  • Homebrewをとりあえず導入して使ってみる
  • XAMPやMAMPを使わずにローカルのMacにApacheとMariadbを導入出来るようになる

結果的に、、、

  • 楽チンに環境構築して開発の勉強に集中できる!
  • 後々Linux環境にデプロイするときにも活きる知識やterminalでの作業でCUI(コマンドラインインターフェイス)の真っ黒い画面への免疫が獲得できる!

OS/環境

MacOS 10.15.5 Catalina

まずはHomebrewを導入しよう

HomebrewとはMacでディファクトスタンダード(みんなが広く使っている事実上の標準)となっているパッケージマネージャーです.
ライブラリの過不足が無いように色々といい感じにしてくれる頼もしいソフトなので入れましょう.

//Xcode(アップルのIDE)をインストール
$ xcode-select --install

//次にHomebrewをインストール
$ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"

//Homebrewのバージョンを見てみましょう
brew -v

//brewの設定が上手く行っているか念のため,Warningが出た場合適宜指示通りにして直してみましょう
brew doctor

すでにhomebrewは入れてるよーと言う方は下のコマンドを実行してください.

$ brew update
$ brew upgrade
$ brew cleanup

※参考:さらにHomebrewについて詳しく知りたい方は,,,

Apacheの導入!...の前に

ApacehとはWebサーバーソフトウェア(HTTPサーバー)のことです.
よくわからない人はクライアント(情報を要求する側)のブラウザがこの情報欲しいよって行ってきた時に情報を返して
ウェブページを表示してくれるソフトウェアなんだなという認識で今は問題ないです.
Apacheのインストールの前に先に下の二つをインストールしてください.

//OpenLDAPとlibiconvを導入しておく
$ brew install openldap libiconv

Apacheをインストールする

//Macに最初から入っているapacheが動いているかもしれないので一応,シャットダウンとスクリプトを削除しておく
$ sudo apachectl stop
$ sudo launchctl unload -w /System/Library/LaunchDaemons/org.apache.httpd.plist 2>/dev/null

//いよいよインストール!
brew install httpd

//上手く行ったかテスト
$ sudo brew services start httpd

もし上記が上手く行っていればテストのために打ったコマンドを押した後に
http://localhost:8080にブラウザでアクセスした時に下記の画像のような画面になるはずです!
スクリーンショット 2020-07-22 2.10.57.png

Apacheの各種設定

/usr/local/etc/httpd/httpd.confを下記のように編集しよう.

//編集前
Listen 8080
//編集後
Listen 80

これでポート番号8080を受け付けず標準の80のみ受け付けるように変えました.
今後はhttp://localhost:80にアクセスしましょう.
(ポート番号なにそれ?という人はとりあえず80番という扉からのみwebサイトに訪問できるようにしたのだという認識で今はおkです.)

次にApacheが管理するコンテンツの場所をApacheに教えてやるためにDocumentRootを編集してやりましょう.
/usr/local/etc/httpd/httpd.confを開きます.

//編集前
DocumentRoot "/usr/local/var/www"
//編集後(ユーザー名の箇所は適宜自分のものに変えてください)
DocumentRoot /Users/ユーザー名/Desktop/Sites

DocumentRootの行の下にあるの記述も下記のように修正してください.

//<Directory>タグの中を下記のように
<Directory /Users/ユーザー名/Desktop/Sites>

//<Directory>ブロック内もこのように変更
# AllowOverride controls what directives may be placed in .htaccess files.
# It can be "All", "None", or any combination of the keywords:
#   AllowOverride FileInfo AuthConfig Limit
#
AllowOverride All

//mod_rewirte.soを探してコメントアウトを外してください
LoadModule rewrite_module lib/httpd/modules/mod_rewrite.so

これでデスクトップ上にあるSitesディレクトリがApacheがブラウザからのリクエストが来たときに返すコンテンツとして認識してくれるようになります.デスクトップに忘れずにSitesというディレクトリを作っておきましょう.

//Sitesというディレクトリをデスクトップに作ってやる
mkdir ~/Desktop/Sites

つぎにUserとGroupを設定します.

User ユーザー名
Group staff

サーバー名も変えておきましょう.

//編集前
#ServerName www.example.com:8080
//編集後
ServerName localhost

Apacheに変更を反映させましょう!

$ sudo apachectl -k restart

一応、Documentroot下にテスト用のファイルを置いてちゃんと動くか見てあげましょう.

//Desktop下にSitesというディレクトリを作る
$ mkdir ~/Sites
//Sitesのディレクトリの下にqiita.htmlを作りそこに文言を書き込む.(直接開いて編集してもok!)
$ echo "<h1>ここがRoot直下のファイルや!</h1>" > ~/Sites/index.html

これでブラウザのURLにhttp://localhost:80/qiita.htmlと入力してみましょう.(:80は省略可)

スクリーンショット 2020-07-22 2.27.36.png

ちなみにindex.htmlと名前を変えてあげればhttp://localhostのみでindex.htmlが開いてくれます.試してみましょう.

お疲れ様です!PHPの導入はあっさりと終わります!

PHPを導入する

//brewで入れる前にプリインストールされているPHPのバージョンを確認,メモしておいてください.
php -v

//自分が必要なPHPのバージョンを入れる,特にこだわりないのなら最新のもので良いのでは.
$ brew install php@5.6
$ brew install php@7.0
$ brew install php@7.1
$ brew install php@7.2
$ brew install php@7.3
$ brew install php@7.4
$ brew install php

最後にちゃんとbrewで入れたPHPが動いているか(Macに最初から入ったものとは違うか)
確認しましょう.

//バージョン確認
php -v
//phpのコマンドはちゃんとbrewの管理しているところにある?
which brew

せっかくPHPも導入したのでDocumentroot下で動くことを確認しましょう.

//Desktop下のSitesというディレクトリの下にindex.phpというファイルを作る
$ touch ~/Sites/index.php
//Sitesディレクトリを開いてindex.phpに下記のように記入してみる
<?php
echo "<h2>phpも動くぞ!</h2>";

これでlocalhostにアクセスしてみましょう.下記のようになるはずです.
スクリーンショット 2020-07-22 2.34.24.png

MariaDB(MySQL)を導入する前に...

今回はMariaDBというDBMS(DataBase Management System)を導入していきます.

ちなみにデータベースというのは検索/管理といったことがやりやすいように一定のルールに従って蓄積されたデータの集合体のことです.

そしてDBMSというのはそのデータベースを管理するためのソフトウェアのことです.
MariaDB、MySQL、PostgreSQLなどが有名です.(今回はNoSQLとかの話はしません.私自身が詳しくないので涙)

MariaDBはMySQLから分岐して開発がされています.MySQLの将来的なアクセスと開発を保証することが目的で開発されているので互換性があり大きな違いがありません.

今回はHomebrewでインストールやアップデートが容易なMariaDBの方の導入を行っていきますが
上記にあるように扱いの違いが少ないので将来的にMySQLを使う時にも役立ちます!

MariaDB(MySQL)をインストール、初期設定

まずMariaDBをインストールしましょう!
さらに今後自動で起動するように設定します.

$ brew install mariadb
// mariadbが今度から自動で起動するように設定(上手くいったら==>以下の文字が出ます!)
$ brew services start mariadb
==> Successfully started `mariadb` (label: homebrew.mxcl.mariadb)

引き続きMariaDBの初期設定を行います.
10回問答があるだけです.(必ずやってね!)

//下のコマンドを打つとNOTE以下のやりとりがでます!
$ sudo /usr/local/bin/mysql_secure_installation

NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MariaDB
      SERVERS IN PRODUCTION USE!  PLEASE READ EACH STEP CAREFULLY!
In order to log into MariaDB to secure it, we'll need the current
password for the root user. If you've just installed MariaDB, and
haven't set the root password yet, you should just press enter here.

Enter current password for root (enter for none):--->(1)Enterを入力してください!
OK, successfully used password, moving on

Setting the root password or using the unix_socket ensures that nobody can log into the MariaDB root user without the proper authorisation.
Enable unix_socket authentication? [Y/n] --->(2)nと回答してください!(Noってことね)
 ... skipping.

You already have your root account protected, so you can safely answer --->(3) nと回答してください!

Change the root password? [Y/n] --->(4)yと回答してください!
New password: --->(5)MariaDBの管理者パスワードを設定してください!
Re-enter new password: --->(6)再度上記で設定したパスワードを入力してください!
Password updated successfully! 

By default, a MariaDB installation has an anonymous user, allowing anyone to log into MariaDB without having to have a user account created for them.  This is intended only for testing, and to make the installation go a bit smoother.  You should remove them before moving into a production environment.

Remove anonymous users? [Y/n] ---> (7)yと回答してください!
 ... Success!

Normally, root should only be allowed to connect from 'localhost'.  This ensures that someone cannot guess at the root password from the network.

Disallow root login remotely? [Y/n] --->(8)yと回答してください!
 ... Success!

By default, MariaDB comes with a database named 'test' that anyone can access.  This is also intended only for testing, and should be removed before moving into a production environment.

Remove test database and access to it? [Y/n] --->(9)yと回答してください!
 - Dropping test database...
 ... Success!
 - Removing privileges on test database...
 ... Success!

Reloading the privilege tables will ensure that all changes made so far will take effect immediately.

Reload privilege tables now? [Y/n] --->(10)yと回答してください!
 ... Success!

Cleaning up...

All done!  If you've completed all of the above steps, your MariaDB
installation should now be secure.

Thanks for using MariaDB!

これでMariaDBの導入完了です!

今後、MariaDBの簡単な使い方の記事や生PHPを使った開発の記事も上げる予定なのでよろしくです!それではまた!
(改善点あればマサカリコメントお願いします!)

この記事の参考にしたサイト

Installing MariaDB Server on Mac OS X with Homebrew / MariaDB公式ドキュメント
macOS 10.15 Catalina Apache Setup: Multiple PHP Versions
macOS 10/15 Catalina Apache Setup: MySQL, Xdebug & More...

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

[MAMP/XAMPPを使わず]HomebrewでさくっとPHP/Apache/MariaDB(mysql)を導入しよう!(Macユーザー向け)

はじめに なぜこの記事を書いたか

Web開発してみたい!PHPの基礎終わった!さぁ作るぞ!ってなった人に意外と次の壁になるのがWebサーバーやデータベース関連の環境構築だと思います.(私がそうでした.)

確かにMAMPやXAMPPを使ったやり方や,Linux OS(CentOSとかUbuntu)での環境構築については,わかりやすい日本語記事がゴロゴロネット上に落ちています.

けれども「まずはMacで気軽に環境構築したい」,「(MAMPを使わず)出来れば今後の開発環境構築にも力になるような形で!」というような要望を満たしてくれる記事がほとんど英語で書かれたものしか見当たりません.

というわけで書いてみました.

今回のゴール

  • Homebrewをとりあえず導入して使ってみる
  • MAMPやXAMPPを使わずにローカルのMacにApacheとMariadbを導入出来るようになる

結果的に,,,

  • 楽チンにMacのローカル環境に環境構築して開発作業/勉強に集中できる!
  • 後々Linux環境を使う時にも活きる知識や,terminalでの作業でCUI(コマンドラインインターフェイス)の真っ黒い画面への免疫が獲得できる!

OS/環境

MacOS 10.15.5 Catalina

まずはHomebrewを導入しよう

HomebrewとはMacでディファクトスタンダード(みんなが広く使っている事実上の標準)となっているパッケージマネージャーです.

ライブラリの過不足が無いように色々といい感じにしてくれる頼もしいソフトなので入れましょう.

//Xcode(アップルのIDE)をインストール
$ xcode-select --install

//次にHomebrewをインストール
$ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"

//Homebrewのバージョンを見てみましょう
brew -v

//brewの設定が上手く行っているか念のため,Warningが出た場合適宜指示通りにして直してみましょう
brew doctor

すでにhomebrewは入れてるよーと言う方は下のコマンドを実行してください.

$ brew update
$ brew upgrade
$ brew cleanup

※参考:さらにHomebrewについて詳しく知りたい方は,,,

Apacheを導入する

ApacehとはWebサーバーソフトウェア(HTTPサーバー)のことです.
よくわからない人はクライアント(情報を要求する側)のブラウザがこの情報欲しいよって行ってきた時に情報を返して
ウェブページを表示してくれるソフトウェアなんだなという認識で今は問題ないです.

Apacheの導入!...の前に

Apacheのインストールの前に先に下の二つをインストールしてください.

//OpenLDAPとlibiconvを導入しておく
$ brew install openldap libiconv

Apacheをインストールする

//Macに最初から入っているapacheが動いているかもしれないので一応,シャットダウンとスクリプトを削除しておく
$ sudo apachectl stop
$ sudo launchctl unload -w /System/Library/LaunchDaemons/org.apache.httpd.plist 2>/dev/null

//いよいよインストール!
brew install httpd

//上手く行ったかテスト
$ sudo brew services start httpd

もし上記が上手く行っていればテストのために打ったコマンドを押した後に
http://localhost:8080 にブラウザでアクセスした時に下記の画像のような画面になるはずです!
スクリーンショット 2020-07-22 2.10.57.png

Apacheの各種設定

/usr/local/etc/httpd/httpd.confを下記のように編集しよう.

//編集前
Listen 8080
//編集後
Listen 80

これでポート番号8080を受け付けず標準の80のみ受け付けるように変えました.
今後は http://localhost:80 にアクセスしましょう.
(ポート番号なにそれ?という人はとりあえず80番という扉からのみwebサイトに訪問できるようにしたのだという認識で今はおkです.)

次にApacheが管理するコンテンツの場所をApacheに教えてやるためにDocumentRootを編集してやりましょう.
/usr/local/etc/httpd/httpd.confを開きます.

//編集前
DocumentRoot "/usr/local/var/www"
//編集後(ユーザー名の箇所は適宜自分のものに変えてください)
DocumentRoot /Users/ユーザー名/Desktop/Sites

DocumentRootの行の下にあるの記述も下記のように修正してください.

//<Directory>タグの中を下記のように
<Directory /Users/ユーザー名/Desktop/Sites>

//<Directory>ブロック内もこのように変更
# AllowOverride controls what directives may be placed in .htaccess files.
# It can be "All", "None", or any combination of the keywords:
#   AllowOverride FileInfo AuthConfig Limit
#
AllowOverride All

//mod_rewirte.soを探してコメントアウトを外してください
LoadModule rewrite_module lib/httpd/modules/mod_rewrite.so

これでデスクトップ上にあるSitesディレクトリがApacheがブラウザからのリクエストが来たときに返すコンテンツを入れておく場所だとWebサーバー(Apache)が認識してくれるようになります.

デスクトップに忘れずにSitesというディレクトリを作っておきましょう.

//Sitesというディレクトリをデスクトップに作ってやる
mkdir ~/Desktop/Sites

つぎにUserとGroupを設定します.

User ユーザー名
Group staff

サーバー名も変えておきましょう.

//編集前
#ServerName www.example.com:8080
//編集後
ServerName localhost

Apacheに変更を反映させましょう!

$ sudo apachectl -k restart

一応,Documentroot下にテスト用のファイルを置いてちゃんと動くか見てあげましょう.

//Desktop下にSitesというディレクトリを作る
$ mkdir ~/Sites
//Sitesのディレクトリの下にqiita.htmlを作りそこに文言を書き込む.(直接開いて編集してもok!)
$ echo "<h1>ここがRoot直下のファイルや!</h1>" > ~/Sites/index.html

これでブラウザのURLにhttp://localhost:80/qiita.html と入力してみましょう.(:80は省略可)

スクリーンショット 2020-07-22 2.27.36.png

ちなみにindex.htmlと名前を変えてあげれば http://localhost のみでindex.htmlが開いてくれます.試してみましょう.

お疲れ様です!PHPの導入はあっさりと終わります!

PHPを導入する

//brewで入れる前にプリインストールされているPHPのバージョンを確認,メモしておいてください.
php -v

//自分が必要なPHPのバージョンを入れる,特にこだわりないのなら最新のもので良いのでは.
$ brew install php@5.6
$ brew install php@7.0
$ brew install php@7.1
$ brew install php@7.2
$ brew install php@7.3
$ brew install php@7.4
$ brew install php

最後にちゃんとbrewで入れたPHPが動いているか(Macに最初から入ったものとは違うか)
確認しましょう.

//バージョン確認
php -v
//phpのコマンドはちゃんとbrewの管理しているところにある?
which brew

せっかくPHPも導入したのでDocumentroot下で動くことを確認しましょう.

//Desktop下のSitesというディレクトリの下にindex.phpというファイルを作る
$ touch ~/Sites/index.php
//Sitesディレクトリを開いてindex.phpに下記のように記入してみる
<?php
echo "<h2>phpも動くぞ!</h2>";

これでlocalhostにアクセスしてみましょう.下記のようになるはずです.
スクリーンショット 2020-07-22 2.34.24.png

MariaDB(MySQL)を導入する

今回はMariaDBというDBMS(DataBase Management System)を導入していきます.

ちなみにデータベースというのは検索/管理といったことがやりやすいように一定のルールに従って蓄積されたデータの集合体のことです.

そしてDBMSというのはそのデータベースを管理するためのソフトウェアのことです.
MariaDB, MySQL, PostgreSQLなどが有名です.(今回はNoSQLとかの話はしません.私自身が詳しくないので涙)

MariaDBはMySQLから分岐して開発がされています.MySQLの将来的なアクセスと開発を保証することが目的で開発されているので互換性があり大きな違いがありません.

今回はHomebrewでインストールやアップデートが容易なMariaDBの方の導入を行っていきますが
上記にあるように扱いの違いが少ないので将来的にMySQLを使う時にも役立ちます!

MariaDB(MySQL)をインストール,初期設定

まずMariaDBをインストールしましょう!
さらに今後自動で起動するように設定します.

$ brew install mariadb
// mariadbが今度から自動で起動するように設定(上手くいったら==>以下の文字が出ます!)
$ brew services start mariadb
==> Successfully started `mariadb` (label: homebrew.mxcl.mariadb)

引き続きMariaDBの初期設定を行います.
10回問答があるだけです.(必ずやってね!)

//下のコマンドを打つとNOTE以下のやりとりがでます!
$ sudo /usr/local/bin/mysql_secure_installation

NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MariaDB
      SERVERS IN PRODUCTION USE!  PLEASE READ EACH STEP CAREFULLY!
In order to log into MariaDB to secure it, we'll need the current
password for the root user. If you've just installed MariaDB, and
haven't set the root password yet, you should just press enter here.

Enter current password for root (enter for none):--->(1)Enterを入力してください!
OK, successfully used password, moving on

Setting the root password or using the unix_socket ensures that nobody can log into the MariaDB root user without the proper authorisation.
Enable unix_socket authentication? [Y/n] --->(2)nと回答してください!(Noってことね)
 ... skipping.

You already have your root account protected, so you can safely answer --->(3) nと回答してください!

Change the root password? [Y/n] --->(4)yと回答してください!
New password: --->(5)MariaDBの管理者パスワードを設定してください!
Re-enter new password: --->(6)再度上記で設定したパスワードを入力してください!
Password updated successfully! 

By default, a MariaDB installation has an anonymous user, allowing anyone to log into MariaDB without having to have a user account created for them.  This is intended only for testing, and to make the installation go a bit smoother.  You should remove them before moving into a production environment.

Remove anonymous users? [Y/n] ---> (7)yと回答してください!
 ... Success!

Normally, root should only be allowed to connect from 'localhost'.  This ensures that someone cannot guess at the root password from the network.

Disallow root login remotely? [Y/n] --->(8)yと回答してください!
 ... Success!

By default, MariaDB comes with a database named 'test' that anyone can access.  This is also intended only for testing, and should be removed before moving into a production environment.

Remove test database and access to it? [Y/n] --->(9)yと回答してください!
 - Dropping test database...
 ... Success!
 - Removing privileges on test database...
 ... Success!

Reloading the privilege tables will ensure that all changes made so far will take effect immediately.

Reload privilege tables now? [Y/n] --->(10)yと回答してください!
 ... Success!

Cleaning up...

All done!  If you've completed all of the above steps, your MariaDB
installation should now be secure.

Thanks for using MariaDB!

これでMariaDBの導入完了です!

今後,MariaDBの簡単な使い方の記事や生PHPを使った開発の記事も上げる予定なのでよろしくです!それではまた!
(改善点あればマサカリコメントお願いします!)

この記事の参考にしたサイト

Installing MariaDB Server on Mac OS X with Homebrew / MariaDB公式ドキュメント
macOS 10.15 Catalina Apache Setup: Multiple PHP Versions
macOS 10/15 Catalina Apache Setup: MySQL, Xdebug & More...

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

[MAMP/XAMPPを使わず]HomebrewでさくっとPHP/Apache/MariaDB(mysql)の環境構築をしよう!(Macユーザー向け)

はじめに なぜこの記事を書いたか

Web開発してみたい!HTML/CSS/PHPの基礎終わった!さぁ作るぞ!ってなった人に意外と次の壁になるのがWebサーバーやデータベース関連の環境構築だと思います.(私がそうでした.)

確かにMAMPやXAMPPを使ったやり方やLinux OS(CentOSとかUbuntu)での環境構築については,わかりやすい日本語記事がゴロゴロネット上に落ちています.

けれども「まずはMacで気軽に環境構築したい」「(MAMPを使わず)出来れば今後の開発環境構築にも力になるような形で開発環境を作りたい!」というような要望を満たしてくれる記事がほとんど英語で書かれたものしか見当たりません.

というわけで書いてみました.

今回のゴール

  • Homebrewをとりあえず導入して使ってみる
  • MAMPやXAMPPを使わずにローカルのMacにApacheとMariadbを導入出来るようになる

結果的に,,,

  • 楽チンにMacのローカル環境に環境構築して開発作業/勉強に集中できる!
  • 後々Linux環境を使う時にも活きる知識や,terminalでの作業でCUI(コマンドラインインターフェイス)の真っ黒い画面への免疫が獲得できる!

OS/環境

MacOS 10.15.5 Catalina

まずはHomebrewを導入しよう

HomebrewとはMacでディファクトスタンダード(みんなが広く使っている事実上の標準)となっているパッケージマネージャーです.

ライブラリの過不足が無いように色々といい感じにしてくれる頼もしいソフトなので入れましょう.

//Xcode(アップルのIDE)をインストール
$ xcode-select --install

//次にHomebrewをインストール
$ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"

//Homebrewのバージョンを見てみましょう
brew -v

//brewの設定が上手く行っているか念のため,Warningが出た場合適宜指示通りにして直してみましょう
brew doctor

すでにhomebrewは入れてるよーと言う方は下のコマンドを実行してください.

$ brew update
$ brew upgrade
$ brew cleanup

※参考:さらにHomebrewについて詳しく知りたい方は,,,

Apacheを導入する

ApacehとはWebサーバーソフトウェア(HTTPサーバー)のことです.
よくわからない人はクライアント(情報を要求する側)のブラウザがこの情報欲しいよって言ってきた時に,情報を返してウェブページの情報をブラウザに渡してくれるソフトウェアなんだなという認識で今は問題ないです.

Apacheの導入!...の前に

Apacheのインストールの前に先に下の二つをインストールしてください.

//OpenLDAPとlibiconvを導入しておく
$ brew install openldap libiconv

Apacheをインストールする

//Macに最初から入っているapacheが動いているかもしれないので一応,シャットダウンとスクリプトを削除しておく
$ sudo apachectl stop
$ sudo launchctl unload -w /System/Library/LaunchDaemons/org.apache.httpd.plist 2>/dev/null

//いよいよインストール!
brew install httpd

//上手く行ったかテスト
$ sudo brew services start httpd

もし上記が上手く行っていればテストのために打ったコマンドを押した後に
http://localhost:8080 にブラウザでアクセスした時に下記の画像のような画面になるはずです!
スクリーンショット 2020-07-22 2.10.57.png

Apacheの各種設定

/usr/local/etc/httpd/httpd.confを下記のように編集しよう.

//編集前
Listen 8080
//編集後
Listen 80

これでポート番号8080を受け付けず標準の80のみ受け付けるように変えました.
今後は http://localhost:80 にアクセスしましょう.
(ポート番号なにそれ?という人はとりあえず80番という扉からのみwebサイトに訪問できるようにしたのだという認識で今はおkです.)

次にApacheが管理するコンテンツの場所をApacheに教えてやるためにDocumentRootを編集してやりましょう.
/usr/local/etc/httpd/httpd.confを開きます.

//編集前
DocumentRoot "/usr/local/var/www"
//編集後(ユーザー名の箇所は適宜自分のものに変えてください)
DocumentRoot /Users/ユーザー名/Desktop/Sites

DocumentRootの行の下にあるの記述も下記のように修正してください.

//<Directory>タグの中を下記のように
<Directory /Users/ユーザー名/Desktop/Sites>

//<Directory>ブロック内もこのように変更
# AllowOverride controls what directives may be placed in .htaccess files.
# It can be "All", "None", or any combination of the keywords:
#   AllowOverride FileInfo AuthConfig Limit
#
AllowOverride All

//mod_rewirte.soを探してコメントアウトを外してください
LoadModule rewrite_module lib/httpd/modules/mod_rewrite.so

これでデスクトップ上にあるSitesディレクトリがApacheがブラウザからのリクエストが来たときに返すコンテンツを入れておく場所だとWebサーバー(Apache)が認識してくれるようになります.

デスクトップに忘れずにSitesというディレクトリを作っておきましょう.

//Sitesというディレクトリをデスクトップに作ってやる
mkdir ~/Desktop/Sites

つぎにUserとGroupを設定します.

User ユーザー名
Group staff

サーバー名も変えておきましょう.

//編集前
#ServerName www.example.com:8080
//編集後
ServerName localhost

Apacheに変更を反映させましょう!

$ sudo apachectl -k restart

一応,Documentroot下にテスト用のファイルを置いてちゃんと動くか見てあげましょう.

//Desktop下にSitesというディレクトリを作る
$ mkdir ~/Sites
//Sitesのディレクトリの下にqiita.htmlを作りそこに文言を書き込む.(直接開いて編集してもok!)
$ echo "<h1>ここがRoot直下のファイルや!</h1>" > ~/Sites/index.html

これでブラウザのURLにhttp://localhost:80/qiita.html と入力してみましょう.(:80は省略可)

スクリーンショット 2020-07-22 2.27.36.png

ちなみにindex.htmlと名前を変えてあげれば http://localhost のみでindex.htmlが開いてくれます.試してみましょう.

お疲れ様です!PHPの導入はあっさりと終わります!

PHPを導入する

//brewで入れる前にプリインストールされているPHPのバージョンを確認,メモしておいてください.
php -v

//自分が必要なPHPのバージョンを入れる,特にこだわりないのなら最新のもので良いのでは.
$ brew install php@5.6
$ brew install php@7.0
$ brew install php@7.1
$ brew install php@7.2
$ brew install php@7.3
$ brew install php@7.4
$ brew install php

最後にちゃんとbrewで入れたPHPが動いているか(Macに最初から入ったものとは違うか)
確認しましょう.

//バージョン確認
php -v
//phpのコマンドはちゃんとbrewの管理しているところにある?
which brew

せっかくPHPも導入したのでDocumentroot下で動くことを確認しましょう.

//Desktop下のSitesというディレクトリの下にindex.phpというファイルを作る
$ touch ~/Sites/index.php
//Sitesディレクトリを開いてindex.phpに下記のように記入してみる
<?php
echo "<h2>phpも動くぞ!</h2>";

これでlocalhostにアクセスしてみましょう.下記のようになるはずです.
スクリーンショット 2020-07-22 2.34.24.png

MariaDB(MySQL)を導入する

今回はMariaDBというDBMS(DataBase Management System)を導入していきます.

ちなみにデータベースというのは検索/管理といったことがやりやすいように一定のルールに従って蓄積されたデータの集合体のことです.

そしてDBMSというのはそのデータベースを管理するためのソフトウェアのことです.
MariaDB, MySQL, PostgreSQLなどが有名です.(今回はNoSQLとかの話はしません.私自身が詳しくないので涙)

MariaDBはMySQLから分岐して開発がされています.MySQLの将来的なアクセスと開発を保証することが目的で開発されているので互換性があり大きな違いがありません.

今回はHomebrewでインストールやアップデートが容易なMariaDBの方の導入を行っていきますが
上記にあるように扱いの違いが少ないので将来的にMySQLを使う時にも役立ちます!

MariaDB(MySQL)をインストール,初期設定

まずMariaDBをインストールしましょう!
さらに今後自動で起動するように設定します.

$ brew install mariadb
// mariadbが今度から自動で起動するように設定(上手くいったら==>以下の文字が出ます!)
$ brew services start mariadb
==> Successfully started `mariadb` (label: homebrew.mxcl.mariadb)

引き続きMariaDBの初期設定を行います.
10回問答があるだけです.(必ずやってね!)

//下のコマンドを打つとNOTE以下のやりとりがでます!
$ sudo /usr/local/bin/mysql_secure_installation

NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MariaDB
      SERVERS IN PRODUCTION USE!  PLEASE READ EACH STEP CAREFULLY!
In order to log into MariaDB to secure it, we'll need the current
password for the root user. If you've just installed MariaDB, and
haven't set the root password yet, you should just press enter here.

Enter current password for root (enter for none):--->(1)Enterを入力してください!
OK, successfully used password, moving on

Setting the root password or using the unix_socket ensures that nobody can log into the MariaDB root user without the proper authorisation.
Enable unix_socket authentication? [Y/n] --->(2)nと回答してください!(Noってことね)
 ... skipping.

You already have your root account protected, so you can safely answer --->(3) nと回答してください!

Change the root password? [Y/n] --->(4)yと回答してください!
New password: --->(5)MariaDBの管理者パスワードを設定してください!
Re-enter new password: --->(6)再度上記で設定したパスワードを入力してください!
Password updated successfully! 

By default, a MariaDB installation has an anonymous user, allowing anyone to log into MariaDB without having to have a user account created for them.  This is intended only for testing, and to make the installation go a bit smoother.  You should remove them before moving into a production environment.

Remove anonymous users? [Y/n] ---> (7)yと回答してください!
 ... Success!

Normally, root should only be allowed to connect from 'localhost'.  This ensures that someone cannot guess at the root password from the network.

Disallow root login remotely? [Y/n] --->(8)yと回答してください!
 ... Success!

By default, MariaDB comes with a database named 'test' that anyone can access.  This is also intended only for testing, and should be removed before moving into a production environment.

Remove test database and access to it? [Y/n] --->(9)yと回答してください!
 - Dropping test database...
 ... Success!
 - Removing privileges on test database...
 ... Success!

Reloading the privilege tables will ensure that all changes made so far will take effect immediately.

Reload privilege tables now? [Y/n] --->(10)yと回答してください!
 ... Success!

Cleaning up...

All done!  If you've completed all of the above steps, your MariaDB
installation should now be secure.

Thanks for using MariaDB!

これでMariaDBの導入完了です!

今後,MariaDBの簡単な使い方の記事や生PHPを使った開発の記事も上げる予定なのでよろしくです!それではまた!
(改善点あればマサカリコメントお願いします!)

この記事の参考にしたサイト

Installing MariaDB Server on Mac OS X with Homebrew / MariaDB公式ドキュメント
macOS 10.15 Catalina Apache Setup: Multiple PHP Versions
macOS 10/15 Catalina Apache Setup: MySQL, Xdebug & More...

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

[MAMP/XAMPPを使わず]HomebrewでさくっとPHP/Apache/MariaDB(mysql)の環境構築をする(Macユーザー向け)

はじめに

なぜこの記事を書いたか

Web開発してみたい! => (入門書やドットインストールで)HTML/CSS/PHPの基礎終わった! => さぁ作るぞ!

となった初学者にとっての次の壁になるのはWebサーバーやデータベース関連の環境構築だと思います.(私がそうでした.)

確かにMAMPやXAMPPを使ったやり方やLinux OS(CentOSとかUbuntu)での環境構築については,わかりやすい日本語記事がゴロゴロネット上に落ちています.

けれども「まずはMacで気軽に環境構築したい」「(MAMPを使わず)出来れば今後の開発環境構築にも力になるような形で開発環境を作りたい!」というような要望を満たしてくれる記事のほとんどが英語で書かれたものです。

というわけで今回タイトルにもある通り

  • Macのローカル環境で
  • Homebrew(パッケージ管理ソフト)を使って
  • PHP/Aapche(webサーバー)/MariaDB(DBMS)の環境構築をする

という3つを初学者がつまづかずに達成出来るようなガイド記事を書いてみました.

今回のゴール

  • Homebrewをとりあえず導入して使ってみる
  • MAMPやXAMPPを使わずにローカルのMacにApacheとMariadbを導入出来るようになる

結果的に,,,

  • 楽チンにMacのローカル環境に環境構築して開発作業/勉強に集中できる!
  • 後々Linux環境を使う時にも活きる知識が得られる
  • terminalでの作業をすることでCUI(コマンドラインインターフェイス)の真っ黒い画面への免疫が獲得できる!

OS/環境

MacOS 10.15.5 Catalina

まずはHomebrewを導入しよう

HomebrewとはMacでディファクトスタンダード(みんなが広く使っている事実上の標準)となっているパッケージマネージャーです.

各種のソフトウェアの導入と削除やソフトウェア同士やライブラリとの依存関係を色々といい感じにしてくれる(管理してくれる)頼もしいソフトなので入れましょう.

//Xcode(アップルのIDE)をインストール
$ xcode-select --install

//次にHomebrewをインストール
$ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"

//Homebrewのバージョンを見てみましょう
$ brew -v

//brewの設定が上手く行っているか念のため,Warningが出た場合適宜指示通りにして直してみましょう
$ brew doctor

すでにhomebrewは入れてるよーと言う方は下のコマンドを実行してください.

$ brew update
$ brew upgrade
$ brew cleanup

※参考:さらにHomebrewについて詳しく知りたい方は,,,

Apacheを導入する

ApacehとはWebサーバーソフトウェア(HTTPサーバー)のことです.
よくわからない人は「クライアント(情報を要求する側)のブラウザがこの情報欲しいよって言ってきた時に,ウェブページをブラウザが表示するのに必要な情報を加工した上で渡してくれるソフトウェアなんだな」,という認識で今は問題ないです.

Apacheの導入!...の前に

Apacheのインストールの前に先に下の二つをインストールしてください.

//OpenLDAPとlibiconvを導入しておく
$ brew install openldap libiconv

Apacheをインストールする

//Macに最初から入っているapacheが動いているかもしれないので一応,シャットダウンとスクリプトを削除しておく
$ sudo apachectl stop
$ sudo launchctl unload -w /System/Library/LaunchDaemons/org.apache.httpd.plist 2>/dev/null

//いよいよインストール!
$ brew install httpd

//上手く行ったかテスト
$ sudo brew services start httpd

もし上記が上手く行っていればテストのために打ったコマンドを押した後に
http://localhost:8080 にブラウザでアクセスした時に下記の画像のような画面になるはずです!
スクリーンショット 2020-07-22 2.10.57.png

Apacheの各種設定

/usr/local/etc/httpd/httpd.confを下記のように編集しよう.

//編集前
Listen 8080
//編集後
Listen 80

これでポート番号8080を受け付けず標準の80のみ受け付けるように変えました.
今後は http://localhost:80 にアクセスしましょう.
(ポート番号なにそれ?という人はとりあえず80番という扉からのみwebサイトに訪問できるようにしたのだという認識で今はおkです.)

次にApacheが管理するコンテンツの場所をApacheに教えてやるためにDocumentRootを編集してやりましょう.
/usr/local/etc/httpd/httpd.confを開きます.

//編集前
DocumentRoot "/usr/local/var/www"
//編集後(ユーザー名の箇所は適宜自分のものに変えてください)
DocumentRoot /Users/ユーザー名/Desktop/Sites

ちなみに自分のユーザー名がわからないおっちょこちょいな方は下記コマンドをterminalに打つと確認できます.

//私はだれ...?って聞いてます
$ echo $(whoami)

DocumentRootの行の下にあるの記述も下記のように修正してください.

//<Directory>タグの中を下記のように
<Directory /Users/ユーザー名/Desktop/Sites>

//<Directory>ブロック内もこのように変更
# AllowOverride controls what directives may be placed in .htaccess files.
# It can be "All", "None", or any combination of the keywords:
#   AllowOverride FileInfo AuthConfig Limit
#
AllowOverride All

//mod_rewirte.soを探してコメントアウトを外してください
LoadModule rewrite_module lib/httpd/modules/mod_rewrite.so

これでデスクトップ上にあるSitesディレクトリがApacheがブラウザからのリクエストが来たときに返すコンテンツを入れておく場所だとWebサーバー(Apache)が認識してくれるようになります.

デスクトップに忘れずにSitesというディレクトリを作っておきましょう.

//Sitesというディレクトリをデスクトップに作ってやる
$ mkdir ~/Desktop/Sites

つぎにUserとGroupを設定します.

User ユーザー名
Group staff

サーバー名も変えておきましょう.

//編集前
#ServerName www.example.com:8080
//編集後
ServerName localhost

Apacheに変更を反映させましょう!

$ sudo apachectl -k restart

一応,Documentroot下にテスト用のファイルを置いてちゃんと動くか見てあげましょう.

//Desktop下にSitesというディレクトリを作る
$ mkdir ~/Desktop/Sites
//Sitesのディレクトリの下にqiita.htmlを作りそこに文言を書き込む.(直接開いて編集してもok!)
$ echo "<h1>ここがRoot直下のファイルや!</h1>" > ~/Desktop/Sites/index.html

これでブラウザのURLにhttp://localhost:80/qiita.html と入力してみましょう.(:80は省略可)

スクリーンショット 2020-07-22 2.27.36.png

ちなみにindex.htmlと名前を変えてあげれば http://localhost のみでindex.htmlが開いてくれます.試してみましょう.

お疲れ様です!PHPの導入はあっさりと終わります!

PHPを導入する

//brewで入れる前にプリインストールされているPHPのバージョンを確認,メモしておいてください.
$ php -v

//自分が必要なPHPのバージョンを入れる,特にこだわりないのなら最新のもので良いのでは.
$ brew install php@5.6
$ brew install php@7.0
$ brew install php@7.1
$ brew install php@7.2
$ brew install php@7.3
$ brew install php@7.4
$ brew install php

最後にちゃんとbrewで入れたPHPが動いているか(Macに最初から入ったものとは違うか)
確認しましょう.

//バージョン確認
$ php -v
//phpのコマンドはちゃんとbrewの管理しているところにある?
$ which brew

せっかくPHPも導入したのでDocumentroot下で動くことを確認しましょう.

//Desktop下のSitesというディレクトリの下にindex.phpというファイルを作る
$ touch ~/Sites/index.php

//Sitesディレクトリを開いてindex.phpに下記のように記入してみる
<?php
echo "<h2>phpも動くぞ!</h2>";

これでlocalhostにアクセスしてみましょう.下記のようになるはずです.
スクリーンショット 2020-07-22 2.34.24.png

MariaDB(MySQL)を導入する

今回はMariaDBというDBMS(DataBase Management System)を導入していきます.

ちなみにデータベースというのは検索/管理といったことがやりやすいように一定のルールに従って蓄積されたデータの集合体のことです.

そしてDBMSというのはそのデータベースを管理するためのソフトウェアのことです.
MariaDB, MySQL, PostgreSQLなどが有名です.(今回はNoSQLとかの話はしません.私自身が詳しくないので涙)

MariaDBはMySQLから分岐して開発がされています.MySQLの将来的なアクセスと開発を保証することが目的で開発されているので互換性があり大きな違いがありません.

今回はHomebrewでインストールやアップデートが容易なMariaDBの方の導入を行っていきますが
上記にあるように扱いの違いが少ないので将来的にMySQLを使う時にも役立ちます!

MariaDB(MySQL)をインストール,初期設定

まずMariaDBをインストールしましょう!
さらに今後自動で起動するように設定します.

$ brew install mariadb
// mariadbが今度から自動で起動するように設定(上手くいったら==>以下の文字が出ます!)
$ brew services start mariadb
==> Successfully started `mariadb` (label: homebrew.mxcl.mariadb)

引き続きMariaDBの初期設定を行います.
10回問答があるだけです.(必ずやってね!)

//下のコマンドを打つとNOTE以下のやりとりがでます!
$ sudo /usr/local/bin/mysql_secure_installation

NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MariaDB
      SERVERS IN PRODUCTION USE!  PLEASE READ EACH STEP CAREFULLY!
In order to log into MariaDB to secure it, we'll need the current
password for the root user. If you've just installed MariaDB, and
haven't set the root password yet, you should just press enter here.

Enter current password for root (enter for none):--->(1)Enterを入力してください!
OK, successfully used password, moving on

Setting the root password or using the unix_socket ensures that nobody can log into the MariaDB root user without the proper authorisation.
Enable unix_socket authentication? [Y/n] --->(2)nと回答してください!(Noってことね)
 ... skipping.

You already have your root account protected, so you can safely answer --->(3) nと回答してください!

Change the root password? [Y/n] --->(4)yと回答してください!
New password: --->(5)MariaDBの管理者パスワードを設定してください!
Re-enter new password: --->(6)再度上記で設定したパスワードを入力してください!
Password updated successfully! 

By default, a MariaDB installation has an anonymous user, allowing anyone to log into MariaDB without having to have a user account created for them.  This is intended only for testing, and to make the installation go a bit smoother.  You should remove them before moving into a production environment.

Remove anonymous users? [Y/n] ---> (7)yと回答してください!
 ... Success!

Normally, root should only be allowed to connect from 'localhost'.  This ensures that someone cannot guess at the root password from the network.

Disallow root login remotely? [Y/n] --->(8)yと回答してください!
 ... Success!

By default, MariaDB comes with a database named 'test' that anyone can access.  This is also intended only for testing, and should be removed before moving into a production environment.

Remove test database and access to it? [Y/n] --->(9)yと回答してください!
 - Dropping test database...
 ... Success!
 - Removing privileges on test database...
 ... Success!

Reloading the privilege tables will ensure that all changes made so far will take effect immediately.

Reload privilege tables now? [Y/n] --->(10)yと回答してください!
 ... Success!

Cleaning up...

All done!  If you've completed all of the above steps, your MariaDB
installation should now be secure.

Thanks for using MariaDB!

これでMariaDBの導入完了です!

今後,MariaDBの簡単な使い方の記事や生PHPを使った開発の記事も上げる予定なのでよろしくです!それではまた!
(改善点あればマサカリコメントお願いします!)

この記事の参考にしたサイト

Installing MariaDB Server on Mac OS X with Homebrew / MariaDB公式ドキュメント
macOS 10.15 Catalina Apache Setup: Multiple PHP Versions
macOS 10/15 Catalina Apache Setup: MySQL, Xdebug & More...

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

Laravelの認証(web画面)

前提条件

eclipseでLaravel開発環境を構築する。デバッグでブレークポイントをつけて止める。(WindowsもVagrantもdockerも)
本記事は上記が完了している前提で書かれています
プロジェクトの作成もapacheの設定も上記で行っています

LaravelでJavaScript、CSSを使う
上記記事でnpm run devしています
本記事はnpm run devでapp.css、app.jsができている前提で書かれています

Laravelでメール送信する
上記記事でLaravelからメール送信できるようにしています
本記事はメール送信ができるようになっている前提で書かれています

Laravelでデータベースを扱う準備をする
Laravelでテーブル作成
Laravelで初期データ投入
Laravelでデータベースを操作する(Eloquent編)
本記事は上記ので作成したデータベースとレコードを使用します

認証に必要なソース生成

コマンドラインで
cd sample
composer require laravel/ui
xdebugの設定をしているとeclipseが実行していいですかというプロンプトを出すのでOKを押します

または、composer.jsonを修正

composer.json
‥‥
    "require": {
‥‥
        "laravel/tinker": "^2.0",
        "laravel/ui": "^2.1"
    },
‥‥

"laravel/ui": "^2.1"追加しました
コマンドラインで
cd sample
composer update
xdebugの設定をしているとeclipseが実行していいですかというプロンプトを出すのでOKを押します

上記composer require laravel/uicomposer updateのどちらかをしてください

コマンドラインで
php artisan ui vue --auth
eclipseプロジェクトを右クリック→リフレッシュ
/sample/app/Http/Controllers/Auth、/sample/resources/views/authに多くのファイルが現れます
/sample/database/migrations/xxxx_xx_xx_xxxxxx_create_password_resets_table.phpも現れます
/sample/routes/web.phpに2行
Auth::routes();
Route::get('/home', 'HomeController@index')->name('home');
追記されています

Model修正

(1) /sample/app/User.phpを/sample/app/Models/User.phpに移動します
/sample/app/ModelsフォルダはLaravelでデータベースを操作する(Eloquent編)で作成しました

(2) /sample/app/Models/User.php修正
namespace App;namespace App\Models;に修正

(3) /sample/config/auth.php修正

auth.php
‥‥
    'providers' => [
        'users' => [
            'driver' => 'eloquent',
            'model' => App\Models\User::class,
        ],
‥‥

providers->users->modelをApp\Models\User::classに修正

(4) /sample/app/Http/Controllers/Auth/RegisterController.php修正
use App\User;use App\Models\User;に修正

(5) /sample/database/factories/UserFactory.php修正
use App\User;use App\Models\User;に修正

動作確認その1

http://localhost/laravelSample/
画面右上にLOGIN、REGISTERのリンクが現れました
REGISTERをクリックし、Name、E-Mail Address、Password、Confirm Passwordを入力してRegisterボタンをクリック
MySQLでlaravel_sampleデータベースを確認してみましょう
select * from users;
レコードが入っています

右上のユーザー名プルダウンからLogoutをクリック
ログアウトできました

右上のユーザー名プルダウンからLOGINをクリック
先ほど登録したE-Mail Address、Passwordを入力し、Loginボタンをクリック
ログインできました

自動生成物の確認

先ほど実行したphp artisan ui vue --authで生成されたソースの中身を確認しましょう
(1) web.phpの確認
/sample/routes/web.phpに追記されたAuth::routes();
/sample/vendor/laravel/ui/src/AuthRouteMethods.phpのauth()メソッドの戻り値を実行します
AuthRouteMethods#authはAuthRouteMethods#resetPassword、AuthRouteMethods#confirmPassword、AuthRouteMethods#emailVerification
を状況にしたがって呼び出します
見ての通り、AuthRouteMethods.phpは認証に必要なルーティングが書かれているだけです
自動生成されたルーティングをまとめると下記になります

// ログイン
get('login', 'Auth\LoginController@showLoginForm')
post('login', 'Auth\LoginController@login');

// ログアウト
post('logout', 'Auth\LoginController@logout')

// ユーザー登録
get('register', 'Auth\RegisterController@showRegistrationForm')
post('register', 'Auth\RegisterController@register');

// パスワード再発行メール送信前の操作
get('password/reset', 'Auth\ForgotPasswordController@showLinkRequestForm')
post('password/email', 'Auth\ForgotPasswordController@sendResetLinkEmail')
// パスワード再発行メール送信後の操作
get('password/reset/{token}', 'Auth\ResetPasswordController@showResetForm')
post('password/reset', 'Auth\ResetPasswordController@reset')

// 特定URLアクセス時のパスワード入力要求
get('password/confirm', 'Auth\ConfirmPasswordController@showConfirmForm')
post('password/confirm', 'Auth\ConfirmPasswordController@confirm');

// ユーザー登録後のメールアドレス確認
get('email/verify', 'Auth\VerificationController@show')
get('email/verify/{id}/{hash}', 'Auth\VerificationController@verify')
post('email/resend', 'Auth\VerificationController@resend')

get('/home', 'HomeController@index')

また、web.phpに定義しているルーティングに->middleware('auth');をつけると認証済みユーザーのみアクセスできるurlになります

Route::get('sample/jscss', 'SampleController@jscss')->middleware('auth');
これでhttp://localhost/laravelSample/sample/jscssにアクセスしようとするとログイン認証を要求されます

(2) Controllerクラスの確認
上記ルーティングに書かれているコントローラークラスの中を見ると実処理はトレイトに書かれていることがわかります
各コントローラーの実処理が書かれているトレイトは/sample/vendor/laravel/ui/auth-backendに入っています
対応表です

機能 app/Http/Controllers/Auth配下のコントローラー vendor/laravel/ui/auth-backend配下のトレイト
特定URLアクセス時のパスワード入力要求 ConfirmPasswordController.php ConfirmsPasswords.php
パスワード再発行メール送信前の操作 ForgotPasswordController.php SendsPasswordResetEmails.php
ログイン、ログアウト LoginController.php AuthenticatesUsers.php
ユーザー登録 RegisterController.php RegistersUsers.php
パスワード再発行メール送信後の操作 ResetPasswordController.php ResetsPasswords.php
ユーザー登録後のメールアドレス確認 VerificationController.php VerifiesEmails.php

トレイト内の処理は読めば分かるので、紹介はすこしだけにします

・RegistersUsers.phpのregister
トレイトvendor/laravel/ui/auth-backend/RegistersUsers.phpのregisterメソッドは、app/Http/Controllers/Auth/RegisterController.phpのregisterメソッドとなります。つまり、ユーザー登録メソッドです
event(new Registered($user = $this->create($request->all())));
$this->create($request->all())部分でRegisterController.phpのcreateが呼ばれ、その中でUser::createが実行されます。User::createでusersテーブルにレコードがinsertされます
$this->guard()はAuth::guard()が実行され、SessionGuardが返ってきます。$this->guard()->login($user);でログインです

・guard
guardは認証まわりの処理が書かれたクラスです
Auth::guard()の戻り値はvendor/laravel/framework/src/Illuminate/Auth/SessionGuard.phpです
Auth::guard()は/sample/config/auth.phpの記述に対応したguardを返します。
auth.phpのdefaults->guardの値がwebなので、auth.phpのguards->web->driverの値を取り、それがsessionなので、SessionGuardを返します。SessionGuardの$this->providerには/sample/vendor/laravel/framework/src/Illuminate/Auth/EloquentUserProvider.phpが入っています。これもauth.phpで設定しているためです。auth.phpのproviders->users->driverがeloquentだからです
EloquentUserProviderの$this->modelにはApp\Models\Userが入っています。これもauth.phpで設定しているためです。auth.phpのproviders->users->modelがApp\Models\User::classだからです

・event
RegistersUsersでevent()が実行されています。event関数は与えられた引数のクラス名をキーにして、app/Providers/EventServiceProvider.phpの$listenから値を取得し、その値のクラスのhandleメソッドを実行します

・ログインの時に使う認証項目
デフォルトではログインの時、E-Mail AddressとPasswordを入力することになっていますが、入力項目をE-Mail Addressでないものにすることができます。なぜE-Mail AddressになっているかというとLoginController.phpで使っているトレイトvendor/laravel/ui/auth-backend/AuthenticatesUsers.php内のusername()関数が'email'を返しているからです。LoginControllerでusernameメソッドを定義しusersテーブルの別のカラムを返すようにすれば、emailではない項目を認証に使用できるようになります

・ユーザー登録の時に使う項目
ユーザー登録時の入力項目はデフォルトではname、email、passwordですが、もっと項目を増やしたい場合、tableにカラム追加し、viewにも項目を増やし、RegisterControllerのvalidatorメソッドとcreateに増やした項目の処理を追記し、App\Models\Userの$fillableにも増やした項目を追加します

・ログイン認証回数制限
ログイン認証を何回試みることを許可するか。その回数失敗したら何分間ログインできなくするかを設定できます
LoginControllerにmaxAttemptsとdecayMinutesというプロパティを定義します
// 最大ログイン認証回数
protected $maxAttempts = 5;
// $maxAttempts回ログイン失敗したら何分ログインできなくするか
protected $decayMinutes= 1;
これらはThrottlesLoginsというトレイトで使われています。
(コントローラー)app/Http/Controllers/Auth/LoginController.php->(トレイト)vendor/laravel/ui/auth-backend/AuthenticatesUsers.php->(トレイト)vendor/laravel/ui/auth-backend/ThrottlesLogins.php
maxAttempts()関数とdecayMinutes()関数が定義されています。そこで使われます。プロパティを定義しなかった場合、デフォルトで5回、ロック1分になっていることもわかります
また、hasTooManyLoginAttemptsが認証失敗制限回数になったか判定するメソッド、sendLockoutResponseがロックがかかったことを知らせるレスポンスを返すメソッドです

(3) viewの確認
/sample/resources/views/auth配下にviewは格納されています
説明が必要な難しい内容にはなっていません
画面の見た目は必ず変えると思います
/sample/resources/views/auth配下のbladeファイルを好きなように変更してください

Authファサード

Authファサードという認証ユーザーに関する便利メソッドを利用できます
use Illuminate\Support\Facades\Auth;
// 現在認証されているユーザーの取得
$user = Auth::user();
if (Auth::check()) {
// ユーザーはログインしている
}
上記のように簡単に認証済みユーザーを取得できたり、ログイン済みかどうか判定できます
このAuthファサードですが、Authファサード実行時呼ばれるのは、vendor/laravel/framework/src/Illuminate/Auth/AuthManager.phpです。このAuthManagerにメソッドが定義されていればAuthManagerのメソッドが呼ばれ、AuthManagerに定義されていないメソッドであれば、guardのメソッドが呼ばれます
Auth::user()ならAuthManagerにuserというメソッドは無いので、SessionGuardのuserメソッドが呼ばれます。Auth::check()ならAuthManagerにcheckというメソッドは無いので、SessionGuardのcheckメソッドが呼ばれています(SessionGuardのcheckメソッドは、SessionGuardで使われているGuardHelpersトレイトで実装されてます)
Auth::guard()なら、AuthManagerに定義されているのでAuthManagerのguardメソッドが呼ばれます
AuthManager
SessionGuard

ユーザー登録時のメールアドレス確認

ユーザー登録時に入力されたメールアドレス宛に実際にメールを送信し、そのメールに記載されているリンクをクリックしてもらい、メールアドレス確認をするように改修します

SMTPサーバーの設定をしてない方は下記記事を参考に事前にしておいてください
Laravelでメール送信する

メール送信される流れは下記です
ユーザー登録時
vendor/laravel/ui/auth-backend/RegistersUsers.phpのregisterメソッド内で
event(new Registered($user = $this->create($request->all())));
が呼ばれ、app/Providers/EventServiceProvider.phpによって登録されている
SendEmailVerificationNotificationクラスのhandleメソッドが実行され
app/Models/User.phpのsendEmailVerificationNotificationメソッドが呼ばれます
これでメールが送信されます
User.phpのsendEmailVerificationNotificationメソッドで呼んでいる$this->notifyはメール送信を実行するメソッドです。notifyメソッド定義場所は下記です
User.php->(トレイト)vendor/laravel/framework/src/Illuminate/Notifications/Notifiable.php->(トレイト)vendor/laravel/framework/src/Illuminate/Notifications/RoutesNotifications.php
$this->notifyの中では
vendor/laravel/framework/src/Illuminate/Notifications/ChannelManager.phpのsendを実行してメール送信しています

ではユーザー登録時メール送信するために必要なものを作っていきます

(1) メール本文の作成
/sample/resources/views/sample/registerUser.blade.phpファイル作成

registerUser.blade.php
<html>
    <body>
        <a href="{{$url}}">メールアドレスの確認</a>
    </body>
</html>

(2) 通知クラスの作成
/sample/app/Notificationsフォルダ作成
/sample/app/Notifications/RegisterUser.phpファイル作成

RegisterUser.php
<?php

namespace App\Notifications;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
use Illuminate\Auth\Notifications\VerifyEmail;

class RegisterUser extends VerifyEmail
{
    use Queueable;

    public function toMail($notifiable)
    {
        $verificationUrl = $this->verificationUrl($notifiable);

        return (new MailMessage)
                ->subject('ユーザー登録')
                ->view('sample.registerUser', ['url' => $verificationUrl]);

    }

}

(3) Modelの修正
/sample/app/Models/User.php修正

User.php
‥‥
use App\Notifications\RegisterUser;
‥‥
class User extends Authenticatable implements MustVerifyEmail
‥‥
    public function sendEmailVerificationNotification()
    {
        $this->notify(new RegisterUser());
    }
‥‥

use文追記
implements MustVerifyEmail追記
sendPasswordResetNotificationメソッド追加
これでvendor/laravel/framework/src/Illuminate/Auth/Listeners/SendEmailVerificationNotification.phpのhandleメソッド内のif文がtrueになります

(4) ルーティング修正
/sample/routes/web.php修正

‥
/* Auth::routes(); */ 
Auth::routes(['verify' => true]);
‥

Auth::routes()に引数['verify' => true]を渡す
これによって、vendor/laravel/ui/src/AuthRouteMethods.phpのauthメソッド内if ($options['verify'] ?? false)がtrueになり、emailVerificationメソッド内のルーティングが有効になります

動作確認その2

http://localhost/laravelSample/
画面右上のREGISTERをクリックし、Name、E-Mail Address、Password、Confirm Passwordを入力してRegisterボタンをクリック
入力したE-Mail Address充てにメールが送信されました
そのメールにあるリンクをクリックします
MySQLでlaravel_sampleデータベースを確認してみましょう
select * from users;
email_verified_atカラムにクリックした時刻が入っています

パスワードリセットの実装

ユーザーがパスワードを忘れた場合のパスワードリセットを実装します

パスワードリセット希望時にはメール送信が行われ、そのメールに記載されているリンクからパスワード再設定画面に遷移します

メール送信される流れは下記です
パスワードリセット画面でSend Password Reset Linkボタンをクリック時
vendor/laravel/ui/auth-backend/SendsPasswordResetEmails.phpのsendResetLinkEmailメソッド内の$this->broker()でvendor/laravel/framework/src/Illuminate/Auth/Passwords/PasswordBroker.phpを取得し、PasswordBrokerのsendResetLinkを実行します
PasswordBrokerのsendResetLink内で
app/Models/User.phpのsendPasswordResetNotificationメソッドが呼ばれます
これでメールが送信されます

ではそれを実行するために必要なものを作っていきます

(1) password_resetsテーブルの作成
先ほどphp artisan ui vue --authをしたときに
/sample/database/migrations/xxxx_xx_xx_xxxxxx_create_password_resets_table.php
ができています
これをデータベースに流し込みます

コマンドラインで
cd sample
php artisan migrate
xdebugの設定をしているとeclipseが実行していいですかというプロンプトを出すのでOKを押します

MySQLでlaravel_sampleデータベースを確認してみましょう
desc password_resets;
password_resetsテーブルができました

(2) メール本文の作成
/sample/resources/views/sample/resetPassword.blade.phpファイル作成

resetPassword.blade.php
<html>
    <body>
        <a href="{{$url}}">パスワードリセット</a>
        <div>このリンクは{{$limit}}分後に期限切れになります</div>
    </body>
</html>

(2) 通知クラスの作成
/sample/app/Notifications/ResetPassword.phpファイル作成

ResetPassword.php
<?php

namespace App\Notifications;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;

class ResetPassword extends Notification
{
    use Queueable;

    public $token;

    public function __construct($token)
    {
        $this->token = $token;
    }

    public function via($notifiable)
    {
        return ['mail'];
    }

    public function toMail($notifiable)
    {
        $url = url(route('password.reset', [
            'token' => $this->token,
            'email' => $notifiable->getEmailForPasswordReset(),
        ], false));

        return (new MailMessage)
                ->subject('パスワードリセット')
                ->view('sample.resetPassword', ['url' => $url, 'limit' => config('auth.passwords.'.config('auth.defaults.passwords').'.expire')]);

    }

    public function toArray($notifiable)
    {
        return [];
    }
}

(3) Modelの修正
/sample/app/Models/User.php修正

User.php
‥‥
use App\Notifications\ResetPassword;
‥‥
    public function sendPasswordResetNotification($token)
    {
        $this->notify(new ResetPassword($token));
    }
‥‥

use文追記
sendPasswordResetNotificationメソッド追加

動作確認その3

http://localhost/laravelSample/
画面右上のLOGINをクリックし、Forgot Your Password?リンクをクリック
E-Mail Addressを入力し、Send Password Reset Linkボタンをクリック
入力したE-Mail Address充てにメールが送信されました
そのメールにあるリンクをクリックします
Passwordを再設定する画面に遷移します

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