LNMP架构(分离部署)PHP与数据库交互示例

LNMP架构(分离部署)PHP与数据库交互示例

基于你的三台服务器地址:

  • 数据库服务器(MySQL):192.168.100.10
  • Nginx服务器:192.168.100.20
  • PHP服务器:192.168.100.30

下面将通过一个"用户信息查询"的简单例子,展示如何实现跨服务器的PHP与数据库交互。

一、数据库服务器(192.168.100.10)配置

1. 登录MySQL并创建测试数据

bash 复制代码
# 登录MySQL
mysql -uroot -predhat

执行以下SQL语句:

sql 复制代码
-- 创建测试数据库
CREATE DATABASE IF NOT EXISTS demo_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

-- 创建专门用于PHP连接的用户(仅允许从PHP服务器IP连接)
CREATE USER 'root'@'192.168.100.30' IDENTIFIED BY 'redhat';
GRANT SELECT, INSERT, UPDATE ON demo_db.* TO 'root'@'192.168.100.30';
FLUSH PRIVILEGES;

-- 切换到demo_db数据库
USE demo_db;

-- 创建用户表
CREATE TABLE IF NOT EXISTS users (
  id INT(11) NOT NULL AUTO_INCREMENT,
  name VARCHAR(50) NOT NULL COMMENT '用户名',
  age INT(3) NOT NULL COMMENT '年龄',
  email VARCHAR(100) UNIQUE NOT NULL COMMENT '邮箱',
  PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

-- 插入测试数据
INSERT INTO users (name, age, email) VALUES
('张三', 25, 'zhangsan@example.com'),
('李四', 30, 'lisi@example.com'),
('王五', 28, 'wangwu@example.com');

2. 配置MySQL允许远程连接

bash 复制代码
# 编辑MySQL配置文件
vim /etc/my.cnf

# 注释掉bind-address(如果存在)
# bind-address = 127.0.0.1

# 重启MySQL
systemctl restart mysqld

# 开放3306端口
firewall-cmd --zone=public --add-port=3306/tcp --permanent
firewall-cmd --reload

二、PHP服务器(192.168.100.30)配置

1. 安装PHP MySQL扩展

bash 复制代码
# 安装PHP MySQL扩展
yum -y install php-mysqlnd php-pdo

# 重启PHP-FPM
systemctl restart php-fpm

# 开放9000端口(PHP-FPM默认端口)
firewall-cmd --zone=public --add-port=9000/tcp --permanent
firewall-cmd --reload

2. 创建PHP测试脚本

bash 复制代码
# 创建网站根目录
mkdir -p /var/www/html

# 创建测试脚本
vim /var/www/html/user_query.php

脚本内容:

php 复制代码
<?php
// 数据库连接配置(使用数据库服务器IP)
$dbConfig = [
    'host' => '192.168.100.10',  // 数据库服务器IP
    'dbname' => 'demo_db',       // 数据库名
    'username' => 'root',    // 数据库用户
    'password' => 'redhat',  // 数据库密码
    'port' => 3306               // 数据库端口
];

try {
    // 建立数据库连接(PDO方式,推荐)
    $dsn = "mysql:host={$dbConfig['host']};dbname={$dbConfig['dbname']};port={$dbConfig['port']};charset=utf8mb4";
    $pdo = new PDO(
        $dsn,
        $dbConfig['username'],
        $dbConfig['password'],
        [
            PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
        ]
    );

    // 1. 查询所有用户
    $stmt = $pdo->query("SELECT * FROM users");
    $users = $stmt->fetchAll();

    // 2. 插入新用户(演示)
    $newUser = [
        'name' => '赵六',
        'age' => 35,
        'email' => 'zhaoliu@example.com'
    ];
    $insertStmt = $pdo->prepare("INSERT INTO users (name, age, email) VALUES (?, ?, ?)");
    $insertSuccess = $insertStmt->execute([$newUser['name'], $newUser['age'], $newUser['email']]);

} catch (PDOException $e) {
    // 捕获连接或查询错误
    die("数据库操作失败:" . $e->getMessage());
}
?>
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>PHP与MySQL交互示例</title>
    <style>
        body { font-family: Arial, sans-serif; margin: 20px; }
        .container { max-width: 800px; margin: 0 auto; }
        .user-table { width: 100%; border-collapse: collapse; margin-top: 20px; }
        .user-table th, .user-table td { border: 1px solid #ddd; padding: 8px; text-align: left; }
        .user-table th { background-color: #f2f2f2; }
        .success { color: green; }
        .error { color: red; }
    </style>
</head>
<body>
    <div class="container">
        <h1>用户信息列表</h1>
        
        <?php if (isset($insertSuccess) && $insertSuccess): ?>
            <p class="success">新用户"<?php echo $newUser['name']; ?>"插入成功!</p>
        <?php endif; ?>
        
        <?php if (!empty($users)): ?>
            <table class="user-table">
                <tr>
                    <th>ID</th>
                    <th>姓名</th>
                    <th>年龄</th>
                    <th>邮箱</th>
                </tr>
                <?php foreach ($users as $user): ?>
                <tr>
                    <td><?php echo $user['id']; ?></td>
                    <td><?php echo $user['name']; ?></td>
                    <td><?php echo $user['age']; ?></td>
                    <td><?php echo $user['email']; ?></td>
                </tr>
                <?php endforeach; ?>
            </table>
        <?php else: ?>
            <p class="error">没有查询到用户数据</p>
        <?php endif; ?>
    </div>
</body>
</html>

设置文件权限:

bash 复制代码
# 设置正确权限
chown -R apache:apache /var/www/html  # 若PHP-FPM运行用户为apache
# 或 chown -R nginx:nginx /var/www/html  # 若PHP-FPM运行用户为nginx

三、Nginx服务器(192.168.100.20)配置

1. 安装Nginx(若未安装)

bash 复制代码
安装nginx-1.24.0

2. 配置Nginx反向代理到PHP服务器

bash 复制代码
# 创建站点配置文件
vim /usr/local/nginx/conf/nginx.conf

配置内容:

nginx 复制代码
server {
    listen 80;
    server_name localhost;  # 可替换为实际域名

    # 开放文件上传大小限制
    client_max_body_size 10M;

    # 所有请求转发到PHP服务器处理
    location / {
        # 代理到PHP服务器的9000端口(PHP-FPM)
        fastcgi_pass 192.168.100.30:9000;
        # 设置PHP文件路径(PHP服务器上的实际路径)
        fastcgi_param SCRIPT_FILENAME /var/www/html$fastcgi_script_name;
        include fastcgi_params;
        
        # 超时设置
        fastcgi_connect_timeout 30s;
        fastcgi_send_timeout 30s;
        fastcgi_read_timeout 30s;
    }

    # 日志配置
    error_log /var/log/nginx/demo_error.log;
    access_log /var/log/nginx/demo_access.log main;
}

3. 重启Nginx并开放端口

bash 复制代码
# 检查配置是否正确
nginx -t

# 重启Nginx
systemctl restart nginx

# 开放80端口
firewall-cmd --zone=public --add-port=80/tcp --permanent
firewall-cmd --reload

四、测试效果

在本地电脑的浏览器中访问Nginx服务器地址:

复制代码
http://192.168.100.20/user_query.php

预期效果:

  1. 页面会显示数据库中已有的3条用户信息(张三、李四、王五)
  2. 同时会插入一条新用户"赵六"的记录
  3. 表格会展示所有用户的ID、姓名、年龄和邮箱信息

验证数据是否真的插入:

在数据库服务器上执行:

bash 复制代码
mysql -uroot -predhat -e "SELECT * FROM demo_db.users;"

可以看到查询结果中包含"赵六"的记录,说明PHP与数据库交互成功。

五、常见问题排查

  1. 连接超时

    • 检查数据库服务器3306端口是否开放
    • 验证PHP服务器是否能ping通数据库服务器(ping 192.168.100.10
    • 检查数据库用户是否允许从PHP服务器IP连接(SELECT user,host FROM mysql.user;
  2. 权限错误

    • 确保PHP脚本文件权限正确
    • 检查PHP-FPM运行用户是否有访问脚本的权限
  3. Nginx 502错误

    • 检查PHP服务器9000端口是否开放
    • 确认PHP-FPM服务是否正常运行(systemctl status php-fpm
  4. 访问被拒绝,首先查明数据库用户有没有权限访问。

通过这个简单的例子,你可以清晰地看到LNMP分离架构中PHP如何与远程数据库进行交互,包括查询数据和插入数据的基本操作。

r,host FROM mysql.user;`)

  1. 权限错误

    • 确保PHP脚本文件权限正确
    • 检查PHP-FPM运行用户是否有访问脚本的权限
  2. Nginx 502错误

    • 检查PHP服务器9000端口是否开放
    • 确认PHP-FPM服务是否正常运行(systemctl status php-fpm
  3. 访问被拒绝,首先查明数据库用户有没有权限访问。

通过这个简单的例子,你可以清晰地看到LNMP分离架构中PHP如何与远程数据库进行交互,包括查询数据和插入数据的基本操作。

相关推荐
zl9798993 小时前
MySQL-锁
数据库·mysql·database
Codeking__3 小时前
mysql——事务(下)
数据库·mysql
Q_Q5110082854 小时前
python+django/flask+springboot实践性教学系统 实训任务发布 学生作业提交 教师评阅管理系统
spring boot·python·django·flask·node.js·php
数智顾问4 小时前
时序数据库选型指南:Apache IoTDB引领数字化转型新时代——核心概念与关键技术解析
数据库
小陈又菜5 小时前
【计算机组成入门到入土】解码计算机:冯·诺依曼架构如何主宰你的每一次点击
架构·计算机组成原理
Tadas-Gao5 小时前
华为OmniPlacement技术深度解析:突破超大规模MoE模型推理瓶颈的创新设计
人工智能·架构·大模型·llm
星环科技TDH社区版5 小时前
星环科技TDH社区版详解:从零搭建企业级大数据平台
大数据·数据库·分布式·数据存储与处理
老纪的技术唠嗑局5 小时前
分布式数据库迁移OceanBase——基于网易云音乐自研CDC服务的平滑迁移方案
数据库·分布式
武子康5 小时前
Java-131 深入浅出 MySQL MyCat 深入解析 schema.xml 配置详解:逻辑库、逻辑表、数据节点全攻略
xml·java·数据库·mysql·性能优化·系统架构·mycat