【PHP】MySQLデータベースを関連付けて操作し、ECSにデータベースをデプロイする

Mac コンピューターで VS Code を使用して PHP を開発し、それを MySQL データベースに関連付けてから、データベースを ECS にデプロイします。

1. PHPとMySQLをインストールする

Mac に PHP と MySQL がインストールされていることを確認してください。Homebrew を使用してインストールできます。

$ brew install php 
$ brew install mysql

mysql をインストールした後、次の文を思い出してください。

MySQL is configured to only allow connections from localhost by default

To connect run:
    mysql -u root

次のコマンドを使用して、インストール ステータスをクエリします。

$ php -v
$ mysql --version

MySQL サービスを開始します。

$ brew services start mysql

MySQL サービスを再起動します。

$ brew services restart mysql

MySQL サービスを停止します。

$ brew services stop mysql

2. MySQL ユーザー、データベース、権限を作成する

MySQL にログインします。

// 无密码直接用这一句登录
$ mysql -u root
// 也可以用这指令,输密码是直接回车跳过就是
$ mysql -u root -p

新しいデータベースを作成します。

$ CREATE DATABASE mydatabase;

新しいユーザーを作成し、パスワードを設定します (myuser と mypassword を独自の設定に置き換えます)。

$ CREATE USER'myuser'@'localhost' IDENTIFIED BY'mypassword';

新しいユーザーにデータベースへのアクセスを許可します。

$ GRANT ALL PRIVILEGES ON mydatabase.*TO'myuser'@'localhost';

権限を更新します。

$ FLUSH PRIVILEGES;

MySQL を終了します。

$ EXIT;

3. MySQL に接続するように PHP を構成する

MySQL データベースに接続するには、PHP コードで PDO または mysqli 拡張機能を使用する必要があります。

MySQL サービスが実行中であること、および適切なユーザー、データベース、権限が作成されていることを確認してください。

1).PDO

<?php
$host = '127.0.0.1';
$db   = 'your_database';
$user = 'your_username';
$pass = 'your_password';
$charset = 'utf8mb4';

$dsn = "mysql:host=$host;dbname=$db;charset=$charset";
$options = [
    PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
    PDO::ATTR_EMULATE_PREPARES   => false,
];

try {
    $pdo = new PDO($dsn, $user, $pass, $options);
} catch (\PDOException $e) {
    throw new \PDOException($e->getMessage(), (int)$e->getCode());
}
?>

2).mysqli拡張子

<?php

// 数据库连接配置
$host = 'localhost';
$dbname = 'mydatabase';
$username = 'myusername';
$password = 'mypassword';

// 创建 mysqli 连接对象
$conn = new mysqli($host, $username, $password, $dbname);

// 检查连接是否成功
if ($conn->connect_error) {
    die("连接失败: " . $conn->connect_error);
}

// 执行查询语句
$query = "SELECT * FROM users";
$result = $conn->query($query);

// 处理结果集
if ($result->num_rows > 0) {
    while ($row = $result->fetch_assoc()) {
        echo $row['username'] . "<br>";
    }
} else {
    echo "没有结果";
}

// 关闭数据库连接
$conn->close();

?>

4. VS Code で PHP コードを作成して実行する

 デモ:https://github.com/Gamin-fzym/php_test_demo

注: Launch Built-in Web サーバー構成を使用して実行する場合は、「localhost:0」を別のポートに変更する必要があります。そうしないと、実行するたびにポート番号がランダムに生成され、非常に不便です。

{
    "name": "Launch Built-in web server",
    "type": "php",
    "request": "launch",
    "runtimeArgs": [
        "-dxdebug.mode=debug",
        "-dxdebug.start_with_request=yes",
        "-S",
        "localhost:8080"
    ],
    "program": "",
    "cwd": "${workspaceRoot}",
    "port": 9003,
    "serverReadyAction": {
        "pattern": "Development Server \\(http://localhost:([0-9]+)\\) started",
        "uriFormat": "http://localhost:%s/index.html",
        "action": "openExternally"
    }
}

インデックス.html

市情報フォーム

<!DOCTYPE html>
<html>
<head>
    <title>城市信息表单</title>
</head>
<body>
    <h1>城市信息表单</h1>
    <form action="http://localhost:8080/city.php" method="post">
        <label for="cityName">城市名称:</label>
        <input type="text" id="name" name="name" required><br><br>

        <label for="cityCode">城市编码:</label>
        <input type="text" id="code" name="code" required><br><br>

        <label for="cityCode">增删改查:</label>
        <input type="text" id="mark" name="mark" required><br><br>

        <input type="submit" value="提交">
    </form>

    <p id="jsonResponse"></p>

    <script>
        document.querySelector('form').addEventListener('submit', function (event) {
            event.preventDefault();
            // 方式一:PHP 中使用这种方式获取 $name = $_POST['name'] ?? '';
            var form = event.target;
            var formData = new FormData(form);
            fetch(form.action, {
                method: 'POST',
                body: formData
            })
            .then(response => response.json())
            .then(data => {
                document.getElementById('jsonResponse').textContent = JSON.stringify(data);
            })
            .catch(error => console.error('请求接口失败', error));

            /*
            // 方式二:PHP中用这种方式获取 $data = json_decode(file_get_contents('php://input'), true);  $name = $data['name'] ?? '';
            var form = event.target;
            var name = form.elements.name.value;
            var code = form.elements.code.value;
            var mark = form.elements.mark.value;
            var requestData = {
                name: name,
                code: code,
                mark: parseInt(mark) // mark 1:增 2:删 3:改 4:查
            };

            var xhr = new XMLHttpRequest();
            xhr.open('POST', form.action);
            xhr.setRequestHeader('Content-Type', 'application/json');
            // xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
            xhr.onload = function () {
                if (xhr.status === 200) {
                    var data = JSON.parse(xhr.responseText);
                    document.getElementById('jsonResponse').textContent = JSON.stringify(data);
                } else {
                    console.error('请求接口失败');
                }
            };
            xhr.send(JSON.stringify(requestData));
            */
        });
    </script>
</body>
</html>

pdoConnect.php

PDO 接続 MySQL パッケージ

<?php
$host = '127.0.0.1';
$port = 3306; // MySQL默认的是3306端口
$db = 'city_database';
$user = 'gamin';
$pass = '123456';
$charset = 'utf8mb4';

$dsn = "mysql:host=$host;port=$port;dbname=$db;charset=$charset";
$options = [
    PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
    PDO::ATTR_EMULATE_PREPARES   => false,
];

// 连接数据库
try {
    $pdo = new PDO($dsn, $user, $pass, $options);
    createCitiesTable();
} catch (\PDOException $e) {
    throw new \PDOException($e->getMessage(), (int)$e->getCode());
}

// 创建城市表
function createCitiesTable() {
    $tb_name = "cities";
    // 检查表是否已存在
    $isTableExists = checkTableExists($tb_name);
    if (!$isTableExists) { 
        // 创建表
        $sql = "CREATE TABLE $tb_name (
            id INT AUTO_INCREMENT PRIMARY KEY,
            name VARCHAR(255) NOT NULL,
            code INT NOT NULL
        )";
        global $pdo;
        $pdo->exec($sql);
    } else {
         
    }
}

// 检查表是否存在
function checkTableExists($tableName) {
    global $pdo;
    $stmt = $pdo->query("SHOW TABLES LIKE '$tableName'");
    return $stmt->rowCount() > 0;
}

?>

出力.php

出力パッケージ

<?php

class ErrorCode {
    const FAILURE = -1;
    const SUCCESS = 0;
    const INVALID_INPUT = 100;
    const MISSING_PARAMETER = 101;
    const DATABASE_ERROR = 200;
    const FILE_NOT_FOUND = 201;
    const METHOD_NOT_ALLOW = 405;
    const INTERNAL_SERVER_ERROR = 500;
    const DATA_NOT_FOUND = 1000;

    public static function getErrorMessage($errorCode) {
        switch ($errorCode) {
            case self::FAILURE:
                return "Operation failed.";
            case self::SUCCESS:
                return "Operation succeeded.";
            case self::INVALID_INPUT:
                return "Invalid input provided.";
            case self::MISSING_PARAMETER:
                return "Required parameter is missing.";
            case self::DATABASE_ERROR:
                return "Database error occurred.";
            case self::FILE_NOT_FOUND:
                return "File not found.";
            case self::METHOD_NOT_ALLOW:
                return "Method not allowed.";   
            case self::INTERNAL_SERVER_ERROR:
                return "Internal Server Error.";   
            case self::DATA_NOT_FOUND:
                return "No matching data found.";  
            default:
                return "Unknown error occurred.";
        }
    }
}

function outputJSON(int $errorCode, $data = []) {
    // 构建要返回的数据
    $response = [
        'code' => $errorCode,
        'message' => ErrorCode::getErrorMessage($errorCode),
        'data' => $data
     ];
    
    // 设置响应内容为 JSON 格式
    header('Content-Type: application/json');

    // 将数据转换为 JSON 字符串
    $json = json_encode($response);

    // 输出 JSON 字符串
    echo $json;
}

?>

city.php

都市の追加、削除、変更、およびクエリ

<?php
require "pdoConnect.php";
require "output.php";

$tb_name = "cities";

// 检查POST数据
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    /* 方式一: */
    // 获取数据并验证
    $name = $_POST['name'] ?? '';
    $code = $_POST['code'] ?? '';
    $mark = $_POST['mark'] ?? 0;

    /* 方式二:表单中Content-Type用'application/json'时,用这种方式获取传参 
    // 获取 JSON 数据并解析
    $data = json_decode(file_get_contents('php://input'), true);
    // 获取数据并验证
    $name = $data['name'] ?? '';
    $code = $data['code'] ?? '';
    $mark = $data['mark'] ?? 0;
    */

    if (empty($name) || empty($code) || $mark == 0) {
        outputJSON(ErrorCode::MISSING_PARAMETER);
        return;
    }

    // mark 1:增 2:删 3:改 4:查
    if ($mark == 1) {
        // 插入数据
        $result = changeData("INSERT INTO $tb_name (name, code) VALUES (:name, :code)", ['name' => $name, 'code' => $code]);
        if ($result) {
            outputJSON(errorCode::SUCCESS);
        } else {
            outputJSON(errorCode::FAILURE);
        }
    } else if ($mark == 2) {
        // 删除数据
        $result = changeData("DELETE FROM $tb_name WHERE code = :code", ['code' => $code]);
        if ($result) {
            outputJSON(errorCode::SUCCESS);
        } else {
            outputJSON(errorCode::FAILURE);
        }
    } else if ($mark == 3) {
        // 更新数据
        $result = changeData("UPDATE $tb_name SET name = :name WHERE code = :code", ['name' => $name, 'code' => $code]);
        if ($result) {
            outputJSON(errorCode::SUCCESS);
        } else {
            outputJSON(errorCode::FAILURE);
        }
    } else if ($mark == 4) {
        // 查询数据
        $result = findData("SELECT * FROM $tb_name WHERE code = :code", ['code' => $code]);
        if ($result) {
            // 查询成功,至少有一条匹配的数据
            outputJSON(errorCode::SUCCESS,$result);
        } else {
            // 查询失败,没有匹配的数据
            outputJSON(ErrorCode::DATA_NOT_FOUND);
        }
    }

}

// 改变数据 插入|更新|删除
function changeData(string $sql, array $arr) {
    global $pdo;
    $stmt = $pdo->prepare($sql);
    $result = $stmt->execute($arr);
    return $result;
}

// 查询数据
function findData(string $sql, array $arr) {
    global $pdo;
    $stmt = $pdo->prepare($sql);
    $stmt->execute($arr);
    $result = $stmt->fetch();
    return $result;
}

?>

cityList.php

ページごとの都市リストのクエリ

<?php
require("pdoConnect.php");
require("output.php");

// 检查POST数据
if ($_SERVER['REQUEST_METHOD'] === 'POST') { 
    try {
        // 获取数据并验证
        $page = isset($_POST['page']) ? intval($_POST['page']) : 1; // 当前页码,默认为第一页
        $pageSize = isset($_POST['pageSize']) ? intval($_POST['pageSize']) : 10; // 每页数据条数,默认为 10

        // 对页码进行有效性检查
        $page = max(1, intval($page)); ;
        // 确保每页记录数为正整数
        $pageSize = max(1, intval($pageSize)); ;

        // 表名
        $tb_name = "cities";

        // 查询总记录数
        $countSql = "SELECT COUNT(*) AS total FROM $tb_name";
        $countStmt = $pdo->prepare($countSql);
        $countStmt->execute();
        $totalItems = $countStmt->fetchColumn();
        // 计算总页数
        $totalPages = ceil($totalItems / $pageSize);

        // 对页码进行有效性检查
        $page = min($page, $totalPages);
        // 计算偏移量
        $offset = ($page - 1) * $pageSize;

        // 查询当前页的数据
        $sql = "SELECT * FROM $tb_name LIMIT :offset, :pageSize";
        $stmt = $pdo->prepare($sql);
        $stmt->bindValue(':offset', $offset, PDO::PARAM_INT);
        $stmt->bindValue(':pageSize', $pageSize, PDO::PARAM_INT);
        $stmt->execute();

        $pagedData = $stmt->fetchAll(PDO::FETCH_ASSOC);

        // 构建要返回的数据
        $response = [
            'page' => $page,
            'pageSize' => $pageSize,
            'totalPages' => $totalPages,
            'totalItems' => $totalItems,
            'data' => array_map(function ($item) {
                return $item;
            }, $pagedData)
        ];
        outputJSON(ErrorCode::SUCCESS, $response);
    } catch (Exception $e) {
        // 发生错误时返回错误响应
        outputJSON(ErrorCode::INTERNAL_SERVER_ERROR);
    }
} else {
    // 非 POST 请求返回错误响应
    outputJSON(ErrorCode::METHOD_NOT_ALLOW);
}

?>

5. ローカル開発環境をテストする

ローカル開発環境で PHP スクリプトをテストし、MySQL データベースと正しく対話できることを確認します。

6. MySQL データベースを ECS にデプロイする

1).ECS インスタンスを作成する

Alibaba Cloud 管理コンソールにログインし、ECS インスタンスを作成します。

2).MySQLをインストールする

SSH 経由で ECS インスタンスに接続し、適切なパッケージ マネージャーを使用して MySQL をインストールします。

3).ローカルデータベースをエクスポートする

启动MySQL服务:
$ brew services start mysql
登录到MySQL:
$ mysql -u root -p
授予相应的权限:
$ GRANT PROCESS ON *.* TO 'gamin'@'localhost';
刷新权限:
$ FLUSH PRIVILEGES;
退出MySQL:
$ EXIT;

导出数据库:
格式
mysqldump -u [username] -p [database_name] > [filename].sql
示例
mysqldump -u gamin -p city_database > /Users/gamin/Desktop/files/city.sql

4).データベースをオンライン MySQL にインポートします。

ユーザー権限を設定し、データベースを作成し、ローカル データベース データを ECS 上の MySQL インスタンスにインポートします。データベースの「管理」を直接選択して管理ページに入り、直接インポートすることもできます。

インポート中にエラーが報告されました。このエラーは、MySQL が文字セット照合規則 utf8mb4_0900_ai_ci を認識しないことが原因で発生しました。これは通常、MySQL のバージョンが古く、特定の文字セットの照合順序をサポートしていないことが原因です。

utf8mb4_0900_ai_ci を、MySQL でサポートされている文字セット照合順序 (utf8mb4_general_ci や utf8mb4_unicode_ci など) に置き換えます。インポート ファイル内の create table ステートメントを変更し、文字セットの照合規則を適切な値に変更します。

インポート成功

5).指定したIPにデータベースアクセス許可を設定します。

7. PHP コードを ECS にデプロイする

1).Webサーバーの設定

PHP リクエストを処理するために、ECS に Web サーバーとして Nginx または Apache をインストールして構成します。

2).PHP コード内のデータベース接続情報を更新します。

ECS インスタンス上の MySQL を指すようにします。

<?php
$host = '121.43.232.240';
$port = 3306; // MySQL默认的是3306端口
$db = 'php_test_demo';
$user = 'php_test_demo';
$pass = 'iaTejKANGwWb6yLd';
$charset = 'utf8mb4';

$dsn = "mysql:host=$host;port=$port;dbname=$db;charset=$charset";
$options = [
    PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
    PDO::ATTR_EMULATE_PREPARES   => false,
];

// 连接数据库
try {
    $pdo = new PDO($dsn, $user, $pass, $options);
    createCitiesTable();
} catch (\PDOException $e) {
    throw new \PDOException($e->getMessage(), (int)$e->getCode());
}

// 创建城市表
function createCitiesTable() {
    $tb_name = "cities";
    // 检查表是否已存在
    $isTableExists = checkTableExists($tb_name);
    if (!$isTableExists) { 
        // 创建表
        $sql = "CREATE TABLE $tb_name (
            id INT AUTO_INCREMENT PRIMARY KEY,
            name VARCHAR(255) NOT NULL,
            code INT NOT NULL
        )";
        global $pdo;
        $pdo->exec($sql);
    } else {
         
    }
}

// 检查表是否存在
function checkTableExists($tableName) {
    global $pdo;
    $stmt = $pdo->query("SHOW TABLES LIKE '$tableName'");
    return $stmt->rowCount() > 0;
}

?>

3).PHP コードを ECS にデプロイする

ここでは PHP ファイルをパゴダに直接アップロードしていますが、もちろん、バージョン管理を行わずに直接アップロードするのはあまり科学的ではありません。FTP、SCP、または Git を使用してファイルを転送することもできます。

4).ECS セキュリティ グループに移動してポート 3306 を解放します。

8. リモート環境をテストする

テストを容易にするために、以前に作成したフォーム ページもサイトにデプロイしました。

ページにアクセスしてテストした後、通常はローカルから MySQL にインポートされたデータをクエリでき、また通常はオンライン データベースに接続して他の操作を実行することもできます。

https://www.lnktools.com/page/index.html

実稼働環境にデプロイする前に、アプリケーションが必要なすべてのセキュリティおよびパフォーマンスのテストに合格していることを確認してください。さらに、機密情報 (データベース認証情報など) が暗号化され、適切なセキュリティ対策が ECS インスタンスに設定されていることを確認してください。

おすすめ

転載: blog.csdn.net/u012881779/article/details/134472774