【PHP】- 项目通用目录架构及示例demo

一. 前言

在PHP项目开发中,合理的目录结构有助于提高代码的可维护性、可扩展性和团队协作效率。尽管具体的目录架构可能会根据项目的规模、类型(如是否使用框架)以及团队的习惯有所不同,但这里提供一个通用且推荐的PHP项目目录结构示例,适用于非框架或轻量级框架的项目。如果你正在使用像LaravelSymfony这样的现代PHP框架,它们通常会有自己推荐的目录结构。

二. 通用PHP项目目录结构

my-php-project/
├── app/                   # 应用程序的核心代码
│   ├── Controllers/       # 控制器,处理用户请求和响应
│   ├── Models/            # 数据模型和业务逻辑
│   ├── Views/             # 视图文件,用于展示数据
│   └── Services/          # 服务类,封装复杂业务逻辑或第三方服务交互
│
├── config/                # 配置文件
│
├── public/                # 公共访问目录,放置前端控制器(index.php)和静态资源
│   ├── css/
│   ├── js/
│   ├── images/
│   └── index.php          # 前端控制器,所有HTTP请求入口
│
├── src/                   # 源代码,如果应用较大,可以将核心逻辑与app分离
│
├── tests/                 # 测试代码,包括单元测试、集成测试等
│
├── vendor/                # Composer依赖包目录
│
├── .env                   # 环境变量配置文件
├── composer.json          # Composer配置文件,定义项目依赖
├── phpunit.xml            # PHPUnit配置文件
└── README.md              # 项目说明文档

细节说明

  • app/: 这是应用程序的核心部分,通常包含控制器、模型、视图和服务层。
  • Controllers/: 包含控制请求流的应用逻辑,负责接收请求、调用相应的模型方法并返回视图给客户端。
  • Models/: 数据模型,表示数据库中的表或其他数据源,并包含相关的业务逻辑。
  • Views/: 用户界面部分,通常是HTML模板,也可能结合模板引擎使用。
  • Services/: 服务层,用于组织复杂的业务逻辑或者与外部系统交互的逻辑。
  • config/: 存放应用程序的各种配置文件,例如数据库连接信息、第三方API密钥等。
  • public/:Web服务器的根目录,应包含所有可以通过Web直接访问的文件。index.php作为前端控制器,所有的HTTP请求都会通过它进入应用程序。
  • src/: 如果你的项目足够大,可能需要将核心逻辑从app/中分离出来放入此目录。
  • tests/: 单元测试、功能测试等自动化测试代码存放的地方,确保代码质量。
  • vendor/: 使用Composer管理的所有第三方库和依赖项会自动安装到这个目录下。
  • .env: 环境变量配置文件,用于存储不同环境下的配置参数(如开发、测试、生产环境),不建议将其提交到版本控制系统中。
  • composer.json: 定义了项目的依赖关系以及脚本命令等信息。
  • phpunit.xml: PHPUnit的配置文件,指定了测试套件的位置、报告格式等设置。
  • README.md: 提供关于项目的基本信息、如何安装、运行和贡献等内容。

示例demo

以下是一个简单的PHP Web项目示例,展示了一个基本的用户管理系统。该项目包括用户的注册、登录和查看用户列表功能。我们将使用MVC(Model-View-Controller)架构来组织代码,并结合MySQL数据库存储数据。
项目目录结构

my-web-project/
├── app/
│   ├── Controllers/       # 控制器
│   │   ├── UserController.php
│   ├── Models/            # 模型
│   │   ├── UserModel.php
│   ├── Views/             # 视图
│   │   ├── register.php
│   │   ├── login.php
│   │   ├── users.php
│   │   └── header.php
│
├── config/                # 配置文件
│   ├── database.php
│
├── public/                # 公共访问目录
│   ├── css/
│   │   └── style.css
│   ├── js/
│   │   └── script.js
│   └── index.php          # 前端控制器
│
├── .env                   # 环境变量配置文件
├── composer.json          # Composer配置文件
└── README.md              # 项目说明文档

1. 数据库设计

创建一个名为 users 的表:

CREATE DATABASE my_web_project;

USE my_web_project;

CREATE TABLE users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    username VARCHAR(50) NOT NULL UNIQUE,
    password VARCHAR(255) NOT NULL,
    email VARCHAR(100) NOT NULL UNIQUE,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

2. 核心代码

config/database.php连接数据库的配置文件:

<?php

$host = 'localhost';
$port = 3306;
$dbname = 'my_web_project';
$username = 'root';
$password = 'root';

try {
    $pdo = new PDO("mysql:host=$host;dbname=$dbname;charset=utf8mb4", $username, $password);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
    die("数据库连接失败: " . $e->getMessage());
}

return $pdo;

app/Models/UserModel.php 用户模型,负责与数据库交互:

<?php

class UserModel {
    private $pdo;

    public function __construct($pdo) {
        $this->pdo = $pdo;
    }

    // 注册新用户
    public function register($username, $password, $email) {
        $hashedPassword = password_hash($password, PASSWORD_DEFAULT);
        $stmt = $this->pdo->prepare("INSERT INTO users (username, password, email) VALUES (?, ?, ?)");
        return $stmt->execute([$username, $hashedPassword, $email]);
    }

    // 用户登录
    public function login($username, $password) {
        $stmt = $this->pdo->prepare("SELECT * FROM users WHERE username = ?");
        $stmt->execute([$username]);
        $user = $stmt->fetch(PDO::FETCH_ASSOC);

        if ($user && password_verify($password, $user['password'])) {
            return $user;
        }
        return false;
    }

    // 获取所有用户
    public function getAllUsers() {
        $stmt = $this->pdo->query("SELECT id, username, email, created_at FROM users");
        return $stmt->fetchAll(PDO::FETCH_ASSOC);
    }
}

app/Controllers/UserController.php用户控制器,处理请求逻辑:

<?php

require_once '../Models/UserModel.php';

class UserController {
    private $userModel;

    public function __construct($pdo) {
        $this->userModel = new UserModel($pdo);
    }

    // 显示注册页面
    public function showRegisterForm() {
        require_once '../Views/register.php';
    }

    // 处理注册请求
    public function register() {
        if ($_SERVER['REQUEST_METHOD'] === 'POST') {
            $username = $_POST['username'];
            $password = $_POST['password'];
            $email = $_POST['email'];

            if ($this->userModel->register($username, $password, $email)) {
                echo "注册成功!";
            } else {
                echo "注册失败,请重试。";
            }
        }
    }

    // 显示登录页面
    public function showLoginForm() {
        require_once '../Views/login.php';
    }

    // 处理登录请求
    public function login() {
        if ($_SERVER['REQUEST_METHOD'] === 'POST') {
            $username = $_POST['username'];
            $password = $_POST['password'];

            $user = $this->userModel->login($username, $password);
            if ($user) {
                echo "登录成功!欢迎回来,{$user['username']}!";
            } else {
                echo "用户名或密码错误。";
            }
        }
    }

    // 显示用户列表
    public function showUsers() {
        $users = $this->userModel->getAllUsers();
        require_once '../Views/users.php';
    }
}

public/index.php前端控制器,路由请求到相应的控制器方法:

<?php

require_once '../config/database.php';
require_once '../app/Controllers/UserController.php';

$pdo = require '../config/database.php';
$userController = new UserController($pdo);

$action = $_GET['action'] ?? 'home';

switch ($action) {
    case 'register':
        if ($_SERVER['REQUEST_METHOD'] === 'POST') {
            $userController->register();
        } else {
            $userController->showRegisterForm();
        }
        break;

    case 'login':
        if ($_SERVER['REQUEST_METHOD'] === 'POST') {
            $userController->login();
        } else {
            $userController->showLoginForm();
        }
        break;

    case 'users':
        $userController->showUsers();
        break;

    default:
        echo "欢迎来到用户管理系统!";
        break;
}

3. 视图文件

app/Views/register.php注册表单:

<?php require_once 'header.php'; ?>

<h1>注册</h1>
<form method="POST" action="?action=register">
    <label>用户名:<input type="text" name="username" required></label><br>
    <label>密码:<input type="password" name="password" required></label><br>
    <label>邮箱:<input type="email" name="email" required></label><br>
    <button type="submit">注册</button>
</form>

app/Views/login.php登录表单:

<?php require_once 'header.php'; ?>

<h1>登录</h1>
<form method="POST" action="?action=login">
    <label>用户名:<input type="text" name="username" required></label><br>
    <label>密码:<input type="password" name="password" required></label><br>
    <button type="submit">登录</button>
</form>

app/Views/users.php用户列表:

<?php require_once 'header.php'; ?>

<h1>用户列表</h1>
<table border="1">
    <tr>
        <th>ID</th>
        <th>用户名</th>
        <th>邮箱</th>
        <th>注册时间</th>
    </tr>
    <?php foreach ($users as $user): ?>
        <tr>
            <td><?= htmlspecialchars($user['id']) ?></td>
            <td><?= htmlspecialchars($user['username']) ?></td>
            <td><?= htmlspecialchars($user['email']) ?></td>
            <td><?= htmlspecialchars($user['created_at']) ?></td>
        </tr>
    <?php endforeach; ?>
</table>

4. 运行项目

  • 将项目代码放到Web服务器(如Apache/Nginx)的根目录。
  • 创建数据库并导入SQL脚本。
  • 访问 http://localhost/my-web-project/public/index.php?action=register
    注册新用户。
  • 登录后可以查看用户列表。

这个示例展示了如何构建一个简单的PHP Web项目,涵盖了用户注册、登录和用户管理的基本功能。通过MVC架构分离了业务逻辑、数据访问和视图展示,为项目的扩展和维护提供了良好的基础。

三. 总结

这种目录结构旨在为开发者提供清晰的层次感和良好的组织方式,使得无论是个人开发还是团队协作都能更加高效。当然,具体实施时可以根据项目的具体需求进行调整。例如,在使用特定框架时,如Laravel,其推荐的目录结构会有一些不同,但整体理念相似。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天下·第二

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值