SHINYA TECH

公務員(行政職)から34歳でエンジニア転職した人

#13 Composer, ライブラリを使って環境変数を管理する

f:id:kshinya-tech:20220222033042p:plain

これまでデータベースへの接続情報をソースコードにベタ書きしていました。

しかし、ソースコードを誰かに見られた場合、機密データが漏洩し、データが流出する危険性があります。

そこで、ライブラリを使用して、機密データを別途管理できる仕組みを取り入れました。

ライブラリとComposer

ライブラリとは

ライブラリは使いたい部品が入っている道具箱。

特定の機能を提供するコードをひとまとめにしたもの。

ライブラリを使用すると車輪の再発明をしなくて済む。

  • 学習の際は、どんどん車輪の再発明をした方がよいが、開発の現場だと、車輪の再発明はよくない。
  • なぜなら、先人が作ったライブラリを使用した方が、すでに多くの人に利用されているため、バグが少ないから。

Composerを用いてライブラリを使う

PHPでライブラリを導入したいときはComposerを使うと便利。

ComposerはPHPの依存管理ツール。

Composerを使わない場合

  • 1つのライブラリを使う際に、依存関係にある他のライブラリをいちいちインストールしないといけない。
  • チーム開発時に、人によって使用しているライブラリのバージョンがバラバラとなり、エラーの原因となる。

Composerを使う場合

  • プロジェクトが使用しているライブラリとそのバージョンを統一できる。
  • ライブラリが依存しているライブラリもセットでインストールできる。
  • プロジェクトごとにライブラリを管理できる。

Composerの仕組み

composer.jsonとcomposer.lockファイルで依存するライブラリを定義する。

  • composer.json

    • プロジェクトで使用するライブラリを一覧にしたもの
  • composer.lock

    • 実際にどのライブラリの、どのバージョンをダウンロードしたかをひとまとめにしたもの
    • composer.lockがある状態でcomposer installすると、composer.lockに記されたバージョンのライブラリがインストールされる。
    • なので、チーム内で同じバージョンのライブラリを使用できる!

Composerの使い方

init

  • 対話形式でcomposer.jsonを作成する(プロジェクトの初期に一度だけ実行)
composer init

require

  • 新しいライブラリを追加する
    • composer.jsonにライブラリが、composer.lockに実際にインストールしたものが記載される
composer require <ライブラリ名>

install

  • composer.jsonもしくはcomposer.lockに従ってライブラリをインストールする
    • チーム開発時に使用。共通のバージョンのライブラリを使うことができる。
composer install

remove

  • ライブラリを取り除く
composer remove <ライブラリ名>

環境変数を管理する

機密データをソースコードとは別で管理する

機密データをソースコードから分離するのに環境変数を使用する。

通常の変数

  • PHPのコードの中で定義し、実行したプロセス内でのみ使用できる。
  • コードに直接記述するので、コードを見れば変数の中身が分かってしまう。
  • また、環境によって切り替えることができない。

    環境変数

  • PHPが動いているOSに保存し、PHPアプリケーションに渡す仕組み。
  • OSに格納される変数である。
  • PHPのコードに直接記述しないので、コードを見ても変数の中身が分からない。
  • また、環境によって切り替えることができる。

ライブラリ(phpdotenv)を使用する

今は設定する必要がないので、Enterでスキップしていく。

srcディレクトリーにcomposer.jsonファイルが作成される。

sk@MacBook-Air part2 % docker-compose exec app composer init


  Welcome to the Composer config generator



This command will guide you through creating your composer.json config.

Package name (<vendor>/<name>) [root/html]:
Description []:
Author [, n to skip]: n
Minimum Stability []:
Package Type (e.g. library, project, metapackage, composer-plugin) []:
License []:

Define your dependencies.

Would you like to define your dependencies (require) interactively [yes]?
Search for a package:
Would you like to define your dev dependencies (require-dev) interactively [yes]?
Search for a package:

{
    "name": "root/html",
    "require": {}
}

Do you confirm generation [yes]? yes

ここからは、GitHub上のREADMEを読みながら、進めていく。

phpdotenvをインストール

sk@MacBook-Air part2 % docker-compose exec app composer require vlucas/phpdotenv

srcディレクトリー直下に.envファイルを作成して、データベースへの接続情報を記述する。

DB_HOST="db"
DB_USERNAME="book_log"
DB_PASS="pass"
DB_DATABASE="book_log"

PHPファイルを編集する。

.envファイルへのカレントディレクトリからのパスを正しく記する必要がある点に注意。

(カレントディレクトリと同じ階層にある場合は以下のように/..を付ける。)

<?php
// Composerのautoloadを読み込む。
// これにより各ライブラリをPHPファイル内で呼び出せるようになる
// 後で理解すればOK.composerを使用するときは書いておく。
require __DIR__ . '/../vendor/autoload.php';

// データベースとの接続の関数を定義
function dbConnect()
{
    // 以下の記述はオブジェクト指向を学んでから理解すればOK
    // 環境変数をPHPファイルに読み込む
    $dotenv = Dotenv\Dotenv::createImmutable(__DIR__ . '/..');
    $dotenv->load();

    $dbHost = $_ENV['DB_HOST'];
    $dbUsername = $_ENV['DB_USERNAME'];
    $dbPassword = $_ENV['DB_PASSWORD'];
    $dbDatabase = $_ENV['DB_DATABASE'];

    $link = mysqli_connect($dbHost, $dbUsername, $dbPassword, $dbDatabase);
    if (!$link) {
        echo 'Error: データベースに接続できません' . PHP_EOL;
        echo 'Debugging error: ' . mysqli_connect_error() . PHP_EOL;
        exit;
    }
    return $link;
}

// companiesテーブルが既に存在していたら、削除する関数を定義
function dropTable($link)
{
    $dropTableSql = 'DROP TABLE IF EXISTS reviews';
    $result = mysqli_query($link, $dropTableSql);
    if ($result) {
        echo 'テーブルを削除しました' . PHP_EOL;
    } else {
        echo 'Error: テーブルの削除に失敗しました' . PHP_EOL;
        echo 'Debugging Error: ' . mysqli_error($link) . PHP_EOL . PHP_EOL;
    }
}

// companiesテーブルを作成する関数を定義
function createTable($link)
{
    $createTableSql = <<<EOT
CREATE TABLE reviews (
    id INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY,
    title VARCHAR(255),
    author VARCHAR(30),
    status VARCHAR(30),
    score INTEGER,
    summary VARCHAR(500),
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
) DEFAULT CHARACTER SET = utf8mb4;
EOT;
    $result = mysqli_query($link, $createTableSql);
    if ($result) {
        echo 'テーブルを作成しました' . PHP_EOL;
    } else {
        echo 'Error: テーブルの作成に失敗しました' . PHP_EOL;
        echo 'Debugging Error: ' . mysqli_error($link) . PHP_EOL . PHP_EOL;
    }
}

// データベースとの接続 -> テーブルの初期化(削除・作成)-> データベースの切断 を実行
$link = dbConnect();
dropTable($link);
createTable($link);
mysqli_close($link);

実行結果

sk@MacBook-Air part2 % docker-compose exec app php databases/initialize_reviews_table.php
テーブルを削除しました
テーブルを作成しました