フレームワークなしでPHPを用いてセッション認証機能を構築する(II.開発環境の構築)

本記事は、フレームワークなしでPHPを用いてセッション認証機能を構築する(I.概要の説明)の続きです。

I.開発環境の構築

  1. Dockerでサーバー構築
  2. テーブル作成
  3. DBとの接続設定

1.Dockerでサーバー構築

■リポジトリ

GitHub - masayan1126/docker-php-auth-system: ■フレームワークなしでPHPを用いてセッション認証機能を構築する 参考ブログ記事  https://maasaablog.com/development/php/build-session-authentication-using-php-without-framework-one/
■フレームワークなしでPHPを用いてセッション認証機能を構築する 参考ブログ記事   - GitHub - masayan1126/docker-php-auth-system: ■フレームワー...

■Dockerデスクトップアプリ

Docker Desktop - Docker
MOST COMMON

1-1.必要フォルダやファイルを準備する

チェンジディレクトリでデスクトップに移動します。今回は、デスクトップに開発用フォルダを作成して進めていきます

cd /Users/username/desktop
githubからクローン

前回の記事フレームワークなしでPHPを用いてセッション認証機能を構築する(I.概要の説明)を基に、一からフォルダを作成いただくか、面倒な方は以下のリポジトリからクローンできます。

git clone https://github.com/masayan1126/docker-php-auth-system

デスクトップにdocker-php-auth-systemというフォルダ(プロジェクトディレクトリ)が出来上がります。

エディタでプロジェクトディレクトリを開く

vscodeだと画面下部にターミナルを表示できます

1-2.イメージファイルのビルド

ビルドコマンドの実行
docker-compose build
関連ファイル

docker-compose.yml

# ymlファイルの書き方がversionにより異なるため、明示しておく必要がある

version: "3.8"

# アプリケーションを構成するコンテナの集合体。
services:
  # それぞれのサービスを識別するために名称をつける
  app_php:
    container_name: php_container
    # dockerhubのイメージを直接指定するか、Dockerfileを別途作成してそちらを参照するように指定するかの2パターンがあります。(ビルド時に複雑なことをする場合はDockerfileに記載する必要がある)
    build: ./docker/php
    # Dockerコンテナを使用した開発では、コンテナ内に入って開発作業をする必要があるので、開発に際して作成したファイルやフォルダはホストOS側にも同期が取られる必要があります。volumesでは、ホストOS側のディレクトリ:コンテナ側のディレクトリという形で指定することで同期が取れるようになります。
    volumes:
      - ./:/var/www

  web_nginx:
    container_name: nginx_container
    image: nginx
    # localhost:8030にアクセスすると、dockerコンテナ上で起動したwebサーバーのポート8000番に繋がるという仕組みです(※ホストOS側のポート番号は重複しているとエラーが生じるので注意)
    ports:
      - 8030:8000
    volumes:
      - ./:/var/www
      - ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf

  # .envファイルの「DB_HOST」とサービス名を合わせる
  db_mysql:
    image: mysql:latest
    container_name: db_container
    environment:
      MYSQL_ROOT_PASSWORD: root
      # .envファイルの「DB_DATABASE」とMYSQL_DATABASEを合わせる
      MYSQL_DATABASE: sample_db
      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:
      - 3309:3306

  phpmyadmin:
    image: phpmyadmin/phpmyadmin
    container_name: phpmyadmin
    environment:
      - PMA_ARBITRARY=1
      # dbサーバーのサービス名(db_mysql)を指定する
      - PMA_HOST=db_mysql
      - PMA_USER=root
      - PMA_PASSWORD=root
    ports:
      - 8288:80
    volumes:
      - /sessions

/docker/php/Dockerfile

# https://hub.docker.com/_/phpにあるイメージファイルを指定
FROM php:8.0-fpm
RUN apt update \
# zlibはデータの圧縮に関するアルゴリズムをライブラリ化したもの
# vimをインストール
# MariaDBデータベースのクライアントアプリケーションである「mysql」を使えるように「mariadb-client」をインストール
# libzip-devはzip圧縮時に必要となるライブラリ(libzip は、zlib を使用する)
  && apt install -y zlib1g-dev mariadb-client vim libzip-dev \
  # docker-php-ext-installはPHPに標準で備わっている拡張パッケージのインストール&有効化ができるコマンド
  # PDO_MYSQL は、PHP から MySQL データベースへのアクセスを可能にするための PHP Data Objects (PDO) インターフェイス を実装したドライバ。
  && docker-php-ext-install zip pdo_mysql \
  # gitのインストール
  && apt install -y git

# Composerのインストール
RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
RUN php composer-setup.php
RUN php -r "unlink('composer-setup.php');"
RUN mv composer.phar /usr/local/bin/composer

# 1を設定するとrootでのインストールを許可。
ENV COMPOSER_ALLOW_SUPERUSER 1
# Composerのインストール先
ENV COMPOSER_HOME /composer
# vender配下のbinにPATHを通す(ここに配置したcomposerを使用する)
ENV PATH $PATH:/composer/vendor/bin

# RUN , CMD , ENTRYPOINT , COPY , ADD を実行する時のワーキングディレクトリを指定
WORKDIR /var/www

docker/nginx/default.conf

server {
  listen 8000;
  root /var/www/php-authentication-system;
  error_log /var/log/nginx/error.log warn;
  index index.php index.html;

  # location /は先頭が/で始まるURIで一致します。つまり、全リクエストに一致します  
  # try_filesは以降に指定した順番に存在をチェックし、存在すればそれが処理されます
  # http://localhost:8000/index.php なら、 index.phpを返す。
  # ファイルが無かったら、次に$uri/なので、index.php/を探して、そこのファイルを返します。
  # それでもなければ、index.phpを無条件で返す。   
  location / {
    try_files $uri $uri/ /index.php?$query_string;
  }

  # 「*.php」のファイルにアクセスされた時にPHP-FPMと通信してPHPを実行させる
  location ~ \.php$ {
    # php-fpmが起動しているサーバーのIPとポート番号
    fastcgi_pass app_php:9000; # docker-compose.ymlで定義したサービス名(コンテナ名でも可)を指定

    # fastcgi_paramはfastCGIへ渡すパラメータを設定するディレクティブ
    include fastcgi_params;
   
    # SCRIPT_FILENAME = root / fastcgi_script_name(実行するphpファイル名)
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; # PHPで$_SERVER['SCRIPT_FILENAME']として取得できる
  }
 }

1-3.コンテナの起動

-dをつけるとバックグラウンドで実行できます

docker-compose up -d

1-4.php(app)コンテナに入る

以下のコマンドで対象のサーバーに入ることができます
docker-compose exec <サービス名> bash

docker-compose exec app_php bash

2.テーブル作成

2-1.mysqlに接続

DBホスト名を指定し、appサーバーからdockerのネットワークを利用してmysqlに接続します
(ホスト名には、ymlファイルのDBサービス名を指定します)

mysql -u root -p -h db_mysql

2-2.usersテーブルにカラムを追加する

データベースの一覧確認

以下コマンドを打つことで登録済みのデータベースの一覧が確認できます。sample_dbというdbがあることを確認します。

show databases;
使用するdbを宣言する

sample_dbにテーブルを作成し、カラムを追加してデータを入れていきたいので以下のコマンドでsample_dbを操作(使用)する宣言をおこないます

use sample_db
テーブルにカラムを追加

次に、以下のクエリを実行し、ユーザーを管理するためのusersテーブルとカラムを作成します
create table <テーブル名> (カラム名1 データ型 オプション, カラム名2 データ型 オプション…..);

create table 
  users(
    id intNOT NULL auto_increment, 
    name varchar(64)NOT NULL, 
    email varchar(191)NOT NULL, 
    password varchar(191)NOT NULL, 
    primary key(`id`), 
    unique key(`email`));
カラム名データ型オプション説明
idint(整数型)auto_increment
primary key
AUTO_INCREMENTが設定されたカラムは、新しい行が追加される毎に1ずつ自動加算される連番のカラムとなります。

カラムの値を重複不可とする場合は、プライマリーキー(主キー)を設定します。

カラムの値を重複不可とする場合は、プライマリーキー(主キー)を設定します。この時、同時にNOT NULLも設定する必要があります。

namevarchar(文字列型)
emailvarchar(文字列型)unique keyユニークキーは、カラムの値を重複不可とします。
passwordvarchar(文字列型)
GUIを使用してブラウザで確認

http://localhost:8288/にアクセスし、先ほど作成したusersテーブルがphpmyadminで確認できれば成功です。

GUIとはGraphical User Interface(グラフィカル・ユーザ・インターフェース)の略で、グラフィックベースの操作体系を持つUI(マウスやタッチパネルで操作できるインターフェース)のことです。

8288番ポートは、ymlファイルのサービス名「phpmyadmin」のports: – 8288:80の箇所で指定したポートになります。(ポートフォワーディングと呼ばれる)

ホスト(自身のPC)上でlocalhost:8288にアクセスするとphpmyadminサーバーの80番ポートへアクセスし、phpmyadminを使用することが可能です。

3.DBとの接続

3-1.使用するdbなどを定数として設定

定数(固定された値)をenvファイルにまとめて記載しておき、他のファイルから参照するという方法はよく利用される手法です。

php-authentication-system/env.php

<?php

// DB接続のための環境変数設定
// defineは定数宣言
define('DB_HOST', 'db_mysql');
define('DB_NAME', 'sample_db'); // ymlのMYSQL_DATABASEと合わせる
define('DB_USER', 'root');
define('DB_PASS', 'root');
定数名説明
DB_HOSTdb_mysqlymlファイルのmysqlサービス名
DB_NAMEsample_dbymlファイルのMYSQL_DATABASE
DB_USERroot
DB_PASSroot

3-2.DB接続設定

PHPでmysqlを操作する方法はいくつかあるのですが、今回は一般的なPDO(PHP Data Objects)で行いたいと思います。

PHPには、データベースに接続するために用意されたクラス(PDOクラス)があり、これを利用することで比較的容易にmysqlへ接続することが可能です。

※オブジェクト指向については以前投稿した【PHP】アニメ「NARUTO」でオブジェクト指向を説明してみるを参照ください。

また、接続の際には.envファイルで設定した環境変数を使用します。

php-authentication-system/database/dbconnect.php

<?php

// phpは<?phpのタグで開始する 
/** * require_onceはファイルを1度だけ読み込む。(同じプログラムの中に 
* 2回同じ外部ファイルへのrequire_onceを書いても、2回目は読み込まれない) 
*/ require_once ( dirname(__FILE__) . '/../env.php');
// dirname(__FILE__)にはそのファイルが存在するディレクトリの絶対パスが入る
function connectToDatabase () { 
  $host = DB_HOST; 
  $db = DB_NAME; 
  $user = DB_USER; 
  $pass = DB_PASS;

  /** * dsn(データソースネーム)はデータベースの接続情報に付ける識別用の名前 
  * デフォルトのポート番号 (3306) 
  */ $dsn = "mysql:host=$host;dbname=$db;charset=utf8mb4"; 
  /** * その処理をすることにより例外エラーが生じる処理については、try ~ catchで例外エラーを受けることができるようにする 
  * new PDO('DSN','ユーザー名','パスワード',オプション); 
  * pdoからインスタンスを生成する 
  * pdoクラスの詳細 -> https://php.net/manual/en/class.pdo.php
  */ 
    try {
        $pdo = new PDO($dsn, $user, $pass, [
            PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, // PDOのエラー時に例外(PDOException)がthrowされる
            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, // 取得したデータを連想配列で返す
        ]);

        return $pdo;

    } catch (PDOException $e) {
        echo '接続失敗しました。' . h($e->getMessage()); // echoでブラウザに出力
        exit(); // returnは呼び出し元に値を返す。exitはその時点で処理を中止し値は返さない
    }

}

ここまでで、3層サーバーの構築とテーブル作成、PHPのプログラムからmysqlに接続するための設定を完了しましたので、今回は以上になります。次回はⅢ.開発(前半)になります。

コメント

タイトルとURLをコピーしました