k911672 / todo-php-docker2

0 stars 0 forks source link

dockerを用いたphpの環境構築 #1

Open k911672 opened 3 years ago

k911672 commented 3 years ago

dockerの設定

ファイルのインストールは省略

1. docker-compose.ymlの設定

kimuranaoki@kimuranaokinoMacBook-Pro todo-php-docker % pwd
/Users/kimuranaoki/michael-php/todo-php/todo-php-docker
kimuranaoki@kimuranaokinoMacBook-Pro todo-php-docker % vim docker-compose.yml 
kimuranaoki@kimuranaokinoMacBook-Pro todo-php-docker % cat docker-compose.yml 
version: '3'
services:
  web:
    container_name: nginx-app
    image: nginx:1.15.6
    ports:
      - "8000:80"
    depends_on: 
      - app
    volumes:
      - ./docker/web/default.conf:/etc/nginx/conf.d/default.conf
      - .:/var/www/html
  app:
    container_name: php-app
    build: ./docker/php
    volumes:
     - .:/var/www/html
    depends_on:
      - mysql
  mysql:
    container_name: mysql-app
    image: mysql:5.7
    environment:
      MYSQL_DATABASE: common
      MYSQL_USER: michael
      MYSQL_PASSWORD: 11922960Kim@
      MYSQL_ROOT_PASSWORD: 11922960Kim@
    ports:
      - "3306:3306"
    volumes:
      - mysql-data:/var/lib/mysql
volumes:
  mysql-data:

2. docker-composeの起動

kimuranaoki@kimuranaokinoMacBook-Pro todo-php-docker % docker-compose up -d
Docker Compose is now in the Docker CLI, try `docker compose up`
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them
WARNING: Image for service app was built because it did not already exist. To rebuild this image you must use `docker-compose build` or `docker-compose up --build`.
Creating mysql-app ... done
Creating php-app   ... done
Creating nginx-app ... done

3. コンテナの起動確認

kimuranaoki@kimuranaokinoMacBook-Pro todo-php-docker % docker-compose ps
  Name                 Command              State              Ports            
--------------------------------------------------------------------------------
mysql-app   docker-entrypoint.sh mysqld     Up      0.0.0.0:3306->3306/tcp,:::33
                                                    06->3306/tcp, 33060/tcp     
nginx-app   nginx -g daemon off;            Up      0.0.0.0:8000->80/tcp,:::8000
                                                    ->80/tcp                    
php-app     docker-php-entrypoint php-fpm   Up      9000/tcp  

動いているコンテナだけ出てくる。

コンテナをストップする場合

kimuranaoki@kimuranaokinoMacBook-Pro todo-php-docker % docker-compose down
Stopping nginx-app ... done
Stopping php-app   ... done
Stopping mysql-app ... done
Removing nginx-app ... done
Removing php-app   ... done
Removing mysql-app ... done
Removing network todo-php-docker_default
k911672 commented 3 years ago

dokcerの設定直し

インフラの勉強で習ったdocker-compose.ymlの設定を今回のphpの勉強に反映させてる。

version: '2'
services:
  web:
    container_name: app-php-todo
    build: ./app/
    image: app-php-todo
    ports:
      - "80:80"
    depends_on: 
      - mysql
    volumes:
      - ~/michael-php/todo-php/todo-php-docker:/var/www/app/
  mysql:
    container_name: mysql-php-todo
    build: ./mysql/
    image: mysql-php-todo
    environment:
      MYSQL_DATABASE: todo
      MYSQL_USER: naoki
      MYSQL_PASSWORD: 11922960Kim@
      MYSQL_ROOT_PASSWORD: 11922960Kim@
      TZ: "Asia/Tokyo"
    ports:
      - "3309:3306"
    volumes:
      - ~/michael-php/todo-php/todo-php-docker/docker/docker-php-todo/mysql/db-data:/var/lib/mysql

mysqlのデータの保存先はdocker-compose up -dで自動で生成される

k911672 commented 3 years ago

直し

各Dockerfileも設定直している(インフラ勉強時のファイルの設定から変更していない)

k911672 commented 3 years ago

データベース接続

bash-5.1# mysql -u naoki -h mysql -p
Enter password: 
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MySQL connection id is 4
Server version: 5.7.34 MySQL Community Server (GPL)

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MySQL [(none)]> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| todo               |
+--------------------+
2 rows in set (0.030 sec)
MySQL [(none)]> use todo
Database changed
MySQL [todo]> show tables;
Empty set (0.006 sec)
k911672 commented 3 years ago

TablePlusの使用

初期設定

スクリーンショット 2021-06-20 13 47 05

テーブルの作成

カラム名の変更

ALTER TABLE テーブル名 CHANGE COLUMN 既存カラム名 新しいカラム名 型名 (オプション);

ALTER TABLE users CHANGE COLUMN `PASSWORD` `password` varchar(20); 
SELECT * FROM users;

レコードの挿入(デモデータの作成)

k911672 commented 3 years ago

mysqlのデータの取得

データベース接続

<?php

const DB_HOST = 'mysql:dbname=todo; host=mysql';
const DB_USER = 'naoki';
const DB_PASSWORD = '11922960Kim@';

try {
    $pdo = new PDO(DB_HOST, DB_USER, DB_PASSWORD,[
        PDO :: ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,//データベースから返って来る値を連想配列で返す。
        PDO :: ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,//例外を表示する。
        PDO :: ATTR_EMULATE_PREPARES => false//SQLインジェクション対策
    ]);
    echo "接続成功\n";
} catch(PDOException $e){
    echo "接続失敗\n". $e->getMessage()."\n";
    exit();
}

?>

データベースのレコードをphpで反映

<?php 
require 'db_connection.php';

$sqlUsers = 'select * from users where id = :id';
$stmtUsers = $pdo->prepare($sqlUsers);
$stmtUsers->bindValue('id', 1, PDO::PARAM_INT);
$stmtUsers->execute();

$users = $stmtUsers->fetchAll();

$sqlTodos = 'select * from todos where id = :id';
$stmtTodos = $pdo->prepare($sqlTodos);
$stmtTodos->bindValue('id', 1, PDO::PARAM_INT);
$stmtTodos->execute();

$todos = $stmtTodos->fetchAll();

foreach ($users[0] as $usersColumn => $usersRecord) {
    echo $usersColumn.' : '.$usersRecord."\n";
}
foreach ($todos[0] as $todosColumn => $todosRecord) {
    echo $todosColumn.' : '.$todosRecord."\n";
}

?>

index.php

<?php 
require 'db_connection.php';

$sqlUsers = 'select * from users where id = :id';
$stmtUsers = $pdo->prepare($sqlUsers);
$stmtUsers->bindValue('id', 1, PDO::PARAM_INT);
$stmtUsers->execute();

$users = $stmtUsers->fetchAll();

$sqlTodos = 'select * from todos where id = :id';
$stmtTodos = $pdo->prepare($sqlTodos);
$stmtTodos->bindValue('id', 1, PDO::PARAM_INT);
$stmtTodos->execute();

$todos = $stmtTodos->fetchAll();

foreach ($users[0] as $usersColumn => $usersRecord) {
    echo $usersColumn.' : '.$usersRecord."\n";
}
foreach ($todos[0] as $todosColumn => $todosRecord) {
    echo $todosColumn.' : '.$todosRecord."\n";
}

?>

db_connection.phpの設定を反映できるようrequireする。

require 'db_connection.php';

ビルドの実行

docker-compose up -d --build

これを行わないと、データベースとphpが繋がらない。

k911672 commented 3 years ago

todoリスト作成用にMVCモデルへのファイルの書き換え

controllers/TodoController.php

class TodoController {
    const DB_HOST = 'mysql:dbname=todo; host=mysql';
    const DB_USER = 'naoki';
    const DB_PASSWORD = '11922960Kim@';

    public function index() {
        try {
            $pdo = new PDO(TodoController::DB_HOST, TodoController::DB_USER, TodoController::DB_PASSWORD,[
                PDO :: ATTR_DEFAULT_FETCH_MODE => PDO :: FETCH_ASSOC,//データベースから返って来る値を連想配列で返す。
                PDO :: ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,//例外を表示する。
                PDO :: ATTR_EMULATE_PREPARES => false//SQLインジェクション対策
            ]);
            echo "接続成功\n";
            return $pdo;
        } catch(PDOException $e){
            echo "接続失敗\n". $e->getMessage()."\n";
            exit();
        }
    }
}

DBの呼び出しをTodoControllerクラスで作成。

views/todos/index.php

<?php 
require_once("../../controllers/TodoController.php");
$todoController = new TodoController;

$pdo = $todoController->index();

$sqlTodos = 'select * from todos where id = :id';

$stmtTodos = $pdo->prepare($sqlTodos);
$stmtTodos->bindValue('id', 3, PDO::PARAM_INT);
$stmtTodos->execute();

$todos = $stmtTodos->fetchAll();

var_dump($todos);

foreach ($todos[0] as $todosColumn => $todosRecord) {
    echo $todosColumn.' : '.$todosRecord."\n";
}

?>

下記の用にcontrollerの内容を記述している

require_once("../../controllers/TodoController.php");
$todoController = new TodoController;

$pdo = $todoController->index();

dockerディレクトリ内の変更

docker/docker-php-todo/app/nginx/dev.naoki.com.conf

server {
    listen       80;
    server_name  dev.naoki-php-todo.work ;

    gzip_static on;
    gzip_types image/png image/gif image/jpeg text/javascript text/css;
    gzip_min_length 1000;
    gzip on;

    root /var/www/app/views/todos;
    index index.php index.html index.htm;

    access_log  /var/log/nginx/dev.access.log main;
    error_log  /var/log/nginx/dev.error.log;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass unix:/var/run/php-fpm.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
        include fastcgi_params;
    }
}

下記、ファイルの参照先を変更

    root /var/www/app/views/todos;

また、dockerの内容を書き換えたので、docker-compose up -d --buildを実行し、コンテナ内に反映させる。

クエリの修正

$sqlTodos = 'select * from todos';

これだとuser全員のtodoを読み取ってしまうので、 ↓

$sqlTodos = 'select * from todos where user_id=1';

にしておこう!

DBの読み取りディレクトリ

こちらはmodelディレクトリにおく →読み取ったデータはcontrollerディレクトリ内のファイルに移し、controller内のファイルから、view内のファイルにデータを飛ばし表示する。 記述は割愛。

k911672 commented 3 years ago

weher句への値の追加

下記では$titel_idの変数はwhere句に入らない。

$sqlDetails = 'select * from todos where user_id=1 and title='."$titel_id";

下記のようにbindValue()を使う。

$sqlDetails = 'select * from todos where user_id=1 and title=:title_id';
$stmtDetails = $details->prepare($sqlDetails);
$stmtDetails->bindValue('title_id', $todo_id, PDO::PARAM_STR);
k911672 commented 3 years ago

$_GETの活用

GETパラメーターはURLを値として読み取る。

「URL ? GETパラメーター」となる。

 <a href="./detail.php?todo_id=<? echo $todo['title']?>"><?php echo $todo['title']; ?></a>

上記を$_GETで読み取ると、 「var_dump($_GET)」は 「todo_id => $todo['title']の値」となる。