SHINYA TECH

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

#7 PHPからMySQLに接続する方法

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

PHPからMySQLに接続する方法を学び、読書ログサービスに実装しました。

PHPからMySQLに接続する方法

PHPからMySQLを利用するときはMySQLiを使う。

(オブジェクト指向学習後は別の方法もある模様)

MySQLに接続するにはmysqli_connect関数を使う

mysqli_connect('ホスト名', 'ユーザ名', 'パスワード', 'データベース名')

$link = mysqli_connect('db', 'book_log', 'pass', 'book_log');

MySQLに接続できないケースを想定して、対策する

  • mysqli_connect()は接続に失敗した場合に FALSEを返すことを利用して、アプリケーションを終了させる。
$link = mysqli_connect('db', 'book_log', 'pass', 'book_log');

    if (!$link) {
        echo 'Error: データベースに接続できませんでした' . PHP_EOL;
        echo 'Debugging error:' . mysqli_connect_error() . PHP_EOL;
        exit;
    }

なぜ?

  • データベースに接続できないことは様々な要因で起こり得る(例えば、アクセスの集中等)。
  • その際にエラーメッセージを表示していないと、ユーザは「問題なくアプリケーションは動いている」と思って使用した後に 「登録されてねぇーじゃないか!」 なるのを防ぐため。
  • 上記コードではエラーの内容も表示されるようにしている(echo 'Debugging error:' . mysqli_connect_error() . PHP_EOL;)が、本来はログにはきだして、エラーの内訳はユーザに見えないようにすべき。

PHPからMySQLとの接続を切断方法

MySQLの使用が完了したら、MySQLとの接続は切っておく。

  • 接続を切るにはmysql_close関数を使う
mysqli_close($link);
// $linkはmysqli_connect()が返すリンクID

読書ログサービスへの実装

データベースへの接続処理は関数として定義して使用した。

<?php

// MySQLへの接続処理を関数として定義
function dbConnect()
{
    $link = mysqli_connect('db', 'book_log', 'pass', 'book_log');

    if (!$link) {
        echo 'Error: データベースに接続できませんでした' . PHP_EOL;
        echo 'Debugging error:' . mysqli_connect_error() . PHP_EOL;
        exit;
    }

    echo 'データベースに接続できました' . PHP_EOL;

    // データベースと切断する際に、接続情報を使用するため、returnで返す
    return $link;
}

// 読書ログ登録の関数を定義
function createReview()
{
    echo '読書ログを登録してください' . PHP_EOL;
    echo '書籍名:';
    $title = trim(fgets(STDIN));

    echo '著者名:';
    $author = trim(fgets(STDIN));

    echo '読書状況(未読、読んでいる、読了):';
    $status = trim(fgets(STDIN));

    echo '評価(5点満点の整数):';
    $score = trim(fgets(STDIN));

    echo '感想:';
    $summary = trim(fgets(STDIN));

    echo '登録が完了しました' . PHP_EOL . PHP_EOL;
    // 連想配列の各キーに上記にて、変数に代入された値を格納していく。
    return [
        'title' => $title,
        'author' => $author,
        'status' => $status,
        'score' => $score,
        'summary' => $summary,
    ];
}

// 読書ログ表示の関数を定義
function getReviews($reviews)
{
    echo '読書ログを表示します' . PHP_EOL;

    foreach ($reviews as $review) {
        echo '書籍名:' . $review['title'] . PHP_EOL;
        echo '著者名:' . $review['author'] . PHP_EOL;
        echo '読書状況:' . $review['status'] . PHP_EOL;
        echo '評価:' . $review['score'] . PHP_EOL;
        echo '感想:' . $review['summary'] . PHP_EOL;
        echo '-----------------' . PHP_EOL;
    }
}

// MySQLとの接続処理
// 切断処理をする際に接続情報が必要なため、別途$link変数に格納している
$link = dbConnect();

// 配列を初期化
$reviews = [];

while (true) {
    echo '1. 読書ログを登録' . PHP_EOL;
    echo '2. 読書ログを表示' . PHP_EOL;
    echo '9. アプリケーションを終了' . PHP_EOL;
    echo '実行したい番号(1,2,9)を入力してください:';
    $i = trim(fgets(STDIN));

    if ($i === '1') {
        // 読書ログを登録する
        $reviews[] = createReview();
    } elseif ($i === '2') {
        // 読書ログを表示する
        getReviews($reviews);
    } elseif ($i === '9') {
        // MySQLとの切断処理
        mysqli_close($link);
        break;
    }
}

備忘録(つまづいた点)

Warning: mysqli_close() expects parameter 1 to be mysqli, null given in ...

のエラーメッセージの処理に苦戦。

解決した方法

  1. MySQLへの接続処理を関数として定義した際function dbConnect()の戻り値にreturn $linkを設定。
  2. function dbConnect()使用時に、別途$linkという変数を定義して、その中に戻り値が格納されるようにした。

感想(参考URL)

変数のスコープについて理解しないといけないな。

www.php.net