0
1

VSCode PHP MySQL Docker環境構築(Mac OS) 記録用

Last updated at Posted at 2024-07-29

WEBアプリ開発を少しやってみたかったので独学で
持ち得る知識をフル活用してみた。

MacBook Air(M1)にて環境構築〜ログイン機能が完成するまでの作業メモ

スクリーンショット 2024-07-15 14.29.38.png

<?php
echo "Hello, World!";
?>

version: '3.8'

services:
  php:
    image: arm64v8/php:8.2-apache
    ports:
      - "8888:80"
    volumes:
      - ./src:/var/www/html
    networks:
      - app-network
  mysql:
    image: mysql:5.7
    platform: linux/amd64
    container_name: mysql-container
    environment:
      MYSQL_ROOT_PASSWORD: rootpassword
      MYSQL_DATABASE: testdb
      MYSQL_USER: user
      MYSQL_PASSWORD: password
    ports:
      - "3306:3306"
    networks:
      - app-network

networks:
  app-network:
    driver: bridge

スクリーンショット 2024-07-15 15.15.35.png

スクリーンショット 2024-07-15 15.13.50.png

Error response from daemon: Conflict. The container name "/mysql-container" is already in use by container "ab40002890513d6c82e122a8bb052a1de9875a82eff662fdac7c9743980bce56". You have to remove (or rename) that container to be able to reuse that name.

このエラーは、すでに同じ名前のコンテナが存在しているため、新しいコンテナを作成できないことが原因です。この問題を解決するためには、既存のコンテナを削除するか、コンテナの名前を変更する必要があります。

container_name: php-mysql-container

スクリーンショット 2024-07-15 15.21.53.png

irochi@irochi-macbook src % docker ps
CONTAINER ID   IMAGE            COMMAND                   CREATED          STATUS          PORTS                               NAMES
cb871d6f5c1f   php:8.2-apache   "docker-php-entrypoi…"   33 seconds ago   Up 31 seconds   0.0.0.0:8888->80/tcp                php-docker-php-1
8b3b6d7fcd16   mysql:5.7        "docker-entrypoint.s…"   33 seconds ago   Up 31 seconds   0.0.0.0:3306->3306/tcp, 33060/tcp   php-mysql-container
irochi@irochi-macbook src % 

スクリーンショット 2024-07-15 15.23.46.png

<?php
$servername = "php-mysql-container";
$username = "user";
$password = "password";
$dbname = "testdb";

// MySQL データベースへの接続
$conn = new mysqli($servername, $username, $password, $dbname);

// 接続をチェック
if ($conn->connect_error) {
    die("Connection failed: " . $conn->connect_error);
}
echo "Connected successfully";

// 簡単なクエリの実行
$sql = "SELECT 1";
$result = $conn->query($sql);

if ($result) {
    echo "Query successful.";
} else {
    echo "Error: " . $conn->error;
}

// 接続を閉じる
$conn->close();

?>

スクリーンショット 2024-07-15 17.56.50.png

/Users/irochi/php-docker
├── docker-compose.yml
├── Dockerfile
├── mysql-init/
│    └── init.sql
└── src/
    ├── index.php
    └── db_test.php
CREATE DATABASE IF NOT EXISTS todoapp;

USE todoapp;

CREATE TABLE IF NOT EXISTS tasks (
    id INT AUTO_INCREMENT PRIMARY KEY,
    title VARCHAR(255) NOT NULL,
    description TEXT,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

INSERT INTO tasks (title, description) VALUES 
('Sample Task 1', 'This is the first sample task'),
('Sample Task 2', 'This is the second sample task')
version: '3.8'

services:
  php:
    build: .
    ports:
      - "8888:80"
    volumes:
      - ./src:/var/www/html
    networks:
      - app-network
  mysql:
    image: mysql:5.7
    platform: linux/amd64
    container_name: php-mysql-container
    environment:
      MYSQL_ROOT_PASSWORD: rootpassword
      MYSQL_DATABASE: testdb
      MYSQL_USER: user
      MYSQL_PASSWORD: password
    ports:
      - "3306:3306"
    volumes:
      - ./mysql-init:/docker-entrypoint-initdb.d // New!
    networks:
      - app-network

networks:
  app-network:
    driver: bridge
docker exec -it php-mysql-container mysql -u user -p
irochi@irochi-macbook src % docker exec -it php-mysql-container mysql -u user -p

Enter password:  ←passwordと入力
ERROR 1044 (42000): Access denied for user 'user'@'%' to database 'todoapp'

スクリーンショット 2024-07-15 18.40.00.png

init.sql
GRANT ALL PRIVILEGES ON todoapp.* TO 'user'@'%'; -- 権限付与

スクリーンショット 2024-07-15 18.51.25.png

<?php
// データベース接続情報
$servername = "php-mysql-container"; // MySQLコンテナのホスト名
$username = "user"; // MySQLのユーザー名
$password = "password"; // MySQLのパスワード
$dbname = "todoapp"; // 使用するデータベース名

// MySQL データベースへの接続
$conn = new mysqli($servername, $username, $password, $dbname);

// 接続をチェック
if ($conn->connect_error) {
    die("Connection failed: " . $conn->connect_error); // 接続エラーの場合、エラーメッセージを表示してスクリプトを終了
}

// SQLクエリを準備
$sql = "SELECT id, title, description, created_at FROM tasks";

// クエリを実行
$result = $conn->query($sql);

// 結果を確認
if ($result->num_rows > 0) {
    // データが存在する場合、各行を出力
    echo "<h1>ToDo List</h1>";
    echo "<table border='1'>";
    echo "<tr><th>ID</th><th>Title</th><th>Description</th><th>Created At</th></tr>";
    while($row = $result->fetch_assoc()) {
        echo "<tr>";
        echo "<td>" . $row["id"] . "</td>";
        echo "<td>" . $row["title"] . "</td>";
        echo "<td>" . $row["description"] . "</td>";
        echo "<td>" . $row["created_at"] . "</td>";
        echo "</tr>";
    }
    echo "</table>";
} else {
    // データが存在しない場合、メッセージを表示
    echo "No tasks found";
}

// 接続を閉じる
$conn->close();
?>

スクリーンショット 2024-07-15 18.54.09.png

データベースから値の取得を完了

ログイン機能を作ってみる

CREATE DATABASE IF NOT EXISTS todoapp;

GRANT ALL PRIVILEGES ON todoapp.* TO 'user'@'%';

USE todoapp;

CREATE TABLE IF NOT EXISTS tasks (
    id INT AUTO_INCREMENT PRIMARY KEY,
    title VARCHAR(255) NOT NULL,
    description TEXT,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

INSERT INTO tasks (title, description) VALUES 
('Sample Task 1', 'This is the first sample task'),
('Sample Task 2', 'This is the second sample task');

CREATE TABLE IF NOT EXISTS User (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    mail_address VARCHAR(255) NOT NULL,
    password VARCHAR(255) NOT NULL
);

INSERT INTO User (name, mail_address, password) VALUES
('佐藤   一郎', 'sato@example.com', MD5('password123')),
('木下   たかし', 'kinoshita@example.com', MD5('password456'));

ログイン画面

<!DOCTYPE html>
<html>
<head>
    <title>Todoログイン</title>
</head>
<body>
    <h2>ログイン</h2>
    <form method="post" action="authenticate.php">
        <label for="mail_address">メールアドレス:</label>
        <input type="email" name="mail_address" required><br><br>
        <label for="password">パスワード:</label>
        <input type="password" name="password" required><br><br>
        <input type="submit" value="Login">
    </form>
</body>
</html>

ログイン認証

<?php
session_start();

// データベース接続情報
$servername = "php-mysql-container";
$username = "user";
$password = "password";
$dbname = "todoapp";

// MySQL データベースへの接続
$conn = new mysqli($servername, $username, $password, $dbname);

// 接続をチェック
if ($conn->connect_error) {
    die("Connection failed: " . $conn->connect_error);
}

// POSTデータの取得
$mail_address = $_POST['mail_address'];
$password = md5($_POST['password']); // パスワードをMD5でハッシュ化

// SQLクエリを準備
$sql = "SELECT * FROM User WHERE mail_address = '$mail_address' AND password = '$password'";
$result = $conn->query($sql);

// 結果を確認
if ($result->num_rows > 0) {
    // ユーザーが存在する場合
    $row = $result->fetch_assoc();
    $_SESSION['username'] = $row['name'];
    header("Location: welcome.php");
} else {
    // ユーザーが存在しない場合
    echo "メールアドレスまたはパスワードが違います。";
}

// 接続を閉じる
$conn->close();
?>
<?php
session_start();

// セッションにユーザー名が設定されているか確認
if (!isset($_SESSION['username'])) {
    header("Location: login.php");
    exit();
}

$username = $_SESSION['username'];
?>

<!DOCTYPE html>
<html>
<head>
    <title>Welcome</title>
</head>
<body>
    <h2>ようこそ、<?php echo htmlspecialchars($username); ?>さん</h2>
</body>
</html>

スクリーンショット 2024-07-17 6.59.50.png

スクリーンショット 2024-07-17 7.00.13.png

スクリーンショット 2024-07-17 7.00.27.png

login.php

<!DOCTYPE html>
<html>
<head>
    <title>Todoログイン</title>
    <style>
        .error { color: red; }
    </style>
</head>
<body>
    <h2>ログイン</h2>
    <?php if (isset($_GET['error'])): ?>
        <p class="error">メールアドレスまたはパスワードが違います。</p>
    <?php endif; ?>
    <form method="post" action="authenticate.php" onsubmit="return validateForm()">
        <label for="mail_address">メールアドレス:</label>
        <input type="email" name="mail_address" id="mail_address" required><br><br>
        <label for="password">パスワード:</label>
        <input type="password" name="password" id="password" required><br><br>
        <input type="submit" value="Login">
    </form>
    <script>
        function validateForm() {
            var mail_address = document.getElementById("mail_address").value;
            var password = document.getElementById("password").value;
            if (mail_address === "" || password === "") {
                alert("メールアドレスとパスワードを入力してください。");
                return false;
            }
            return true;
        }
    </script>
</body>
</html>

authenticate.php

<?php
session_start();

// データベース接続情報
$servername = "php-mysql-container";
$username = "user";
$password = "password";
$dbname = "todoapp";

// MySQL データベースへの接続
$conn = new mysqli($servername, $username, $password, $dbname);

// 接続をチェック
if ($conn->connect_error) {
    die("Connection failed: " . $conn->connect_error);
}

// POSTデータの取得
$mail_address = $_POST['mail_address'];
$password = md5($_POST['password']); // パスワードをMD5でハッシュ化

// SQLクエリを準備
$sql = "SELECT * FROM User WHERE mail_address = '$mail_address' AND password = '$password'";
$result = $conn->query($sql);

// 結果を確認
if ($result->num_rows > 0) {
    // ユーザーが存在する場合
    $row = $result->fetch_assoc();
    $_SESSION['username'] = $row['name'];
    header("Location: welcome.php");
} else {
    // ユーザーが存在しない場合
    header("Location: login.php?error=1");
    exit();
}

// 接続を閉じる
$conn->close();
?>

welcome.php

<?php
session_start();

// セッションにユーザー名が設定されているか確認
$username = isset($_SESSION['username']) ? $_SESSION['username'] : null;
?>

<!DOCTYPE html>
<html>
<head>
    <title>Welcome</title>
</head>
<body>
    <?php if ($username): ?>
        <h2>ようこそ、<?php echo htmlspecialchars($username); ?>さん</h2>
        <form method="post" action="logout.php">
            <input type="submit" value="ログアウト">
        </form>
    <?php else: ?>
        <h2>ログインしてください。</h2>
        <form method="post" action="login.php">
            <input type="submit" value="ログイン画面に戻る">
        </form>
    <?php endif; ?>
</body>
</html>

logout.php

<?php
session_start();
session_destroy();
header("Location: login.php");
exit();
?>

機能面は終了

BootStrapの適用(CDN)

スクリーンショット 2024-07-17 7.23.15.png

スクリーンショット 2024-07-17 7.24.20.png

スクリーンショット 2024-07-17 7.24.45.png

スクリーンショット 2024-07-17 7.25.11.png

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1