免费咨询热线135-3532-1113
免费获取方案
首页/新闻资讯/软件开发/PHP网站设计怎么入门?目录结构、路由、数据库设计与基础安全

PHP网站设计怎么入门?目录结构、路由、数据库设计与基础安全

发布: 栏目:软件开发 作者:万户网络 阅读:3
PHP网站设计怎么入门?从零设计一个小型PHP站点:目录结构怎么分、入口文件和路由怎么写、数据库表怎么设计、模板与逻辑如何分离,并附可运行的简短代码示例和基础安全要点。

PHP网站设计怎么入门?目录结构、路由、数据库设计与基础安全

PHP 网站设计入门,关键不在于背语法,而在于先把网站的"骨架"想清楚:一个入口文件接收所有请求,路由把请求分发给对应的处理代码,处理代码通过数据库层读写数据,再交给模板输出页面。把这条线理顺,哪怕不用任何框架,也能写出结构清晰、方便维护的小型站点。

本文以"一个带文章列表和详情页的小型内容站"为例,按目录结构、入口与路由、数据库设计、模板分离、基础安全的顺序,讲解基于 PHP 的网站设计思路,并给出简短的代码示例。示例面向 PHP 7.4 及以上版本,选型与框架对比、漏洞排查不在本文展开,可以参考站内技术栏目的相关文章。

一、先理解 PHP 站点的基本流程

一次访问网页,在 PHP 站点里大致经历这几步:

  1. 浏览器发出请求,Web 服务器(Nginx 或 Apache)把请求交给 PHP 处理。
  2. PHP 执行入口文件,读取配置、启动会话、加载需要的代码。
  3. 根据网址判断要执行哪段业务逻辑(路由)。
  4. 业务逻辑查询或写入数据库,得到数据。
  5. 把数据交给模板,生成 HTML。
  6. 把 HTML 返回给浏览器。

初学者常见的问题,是把第 2 到第 5 步全部写在同一个文件里:一边查数据库,一边拼 HTML,还夹杂着判断逻辑。小站点刚开始能跑,页面一多就难以维护。设计的目的,就是把这几步拆开。

二、目录结构怎么分

下面是一个适合小型站点的目录结构:

mysite/
├── public/            # 对外开放的目录(Web 根目录)
│   ├── index.php      # 入口文件
│   ├── css/
│   ├── js/
│   └── uploads/       # 上传文件(需限制可执行)
├── app/
│   ├── config.php     # 配置(数据库、站点名等)
│   ├── db.php         # 数据库连接
│   ├── routes.php     # 路由表
│   ├── controllers/   # 业务处理
│   │   ├── HomeController.php
│   │   └── ArticleController.php
│   ├── models/        # 数据读写
│   │   └── Article.php
│   └── views/         # 模板
│       ├── layout.php
│       ├── home.php
│       └── article_show.php
└── storage/           # 日志、缓存(不对外)

这个结构有几条重要的设计原则:

  • 只把 public/ 作为 Web 根目录:配置文件、业务代码、日志都放在根目录之外,即使服务器配置出问题,也不会被直接访问到。
  • 按职责分层:控制器负责处理请求,模型负责读写数据,视图负责输出页面,互相之间依赖关系清晰。
  • 配置集中管理:数据库账号、站点名称等放在配置文件中,不散落在各处。
  • 上传目录单独隔离:上传目录里不允许执行脚本,这点在服务器配置里要单独设置。

三、入口文件与简单路由

所有请求都由 public/index.php 接收,再由它分发。先看一个最简版本的入口文件:

<?php
// public/index.php
declare(strict_types=1);

require __DIR__ . '/../app/config.php';
require __DIR__ . '/../app/db.php';

$routes = require __DIR__ . '/../app/routes.php';

$path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
$method = $_SERVER['REQUEST_METHOD'];

foreach ($routes as [$routeMethod, $pattern, $handler]) {
    if ($routeMethod === $method && preg_match($pattern, $path, $matches)) {
        array_shift($matches);
        [$class, $action] = $handler;
        require __DIR__ . '/../app/controllers/' . $class . '.php';
        (new $class())->$action(...$matches);
        exit;
    }
}

http_response_code(404);
echo '页面不存在';

路由表可以非常简单:

<?php
// app/routes.php
return [
    ['GET', '#^/$#',                    ['HomeController',    'index']],
    ['GET', '#^/article/(\d+)$#',       ['ArticleController', 'show']],
];

要让 /article/12 这样的网址生效,需要 Web 服务器把不存在的文件请求都转发给 index.php。以 Nginx 为例,核心配置是:

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

这样做的好处:网址整洁,对搜索引擎友好;所有请求经过同一个入口,方便统一做日志、权限、错误处理。

四、数据库怎么设计

入门阶段不要追求复杂,关键是把表结构设计得"够用、不浪费"。以文章表为例:

CREATE TABLE article (
    id INT UNSIGNED NOT NULL AUTO_INCREMENT,
    title VARCHAR(200) NOT NULL,
    summary VARCHAR(500) NOT NULL DEFAULT '',
    content MEDIUMTEXT NOT NULL,
    category_id INT UNSIGNED NOT NULL DEFAULT 0,
    status TINYINT NOT NULL DEFAULT 1,
    created_at DATETIME NOT NULL,
    updated_at DATETIME NOT NULL,
    PRIMARY KEY (id),
    KEY idx_category (category_id),
    KEY idx_status_created (status, created_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

设计时可以遵循这些习惯:

  1. 每张表都有自增主键:简单、稳定,便于关联和分页。
  2. 字符集用 utf8mb4:能存储中文和 emoji,避免乱码。
  3. 给常用查询条件建索引:比如按分类查、按状态加时间排序,索引要贴合实际查询。
  4. 字段类型贴合内容:标题用 VARCHAR,正文用 TEXT 系列,状态用 TINYINT。
  5. 预留时间字段:创建时间和更新时间几乎总会用到。
  6. 不要把多个含义塞进同一个字段:比如用逗号拼接多个标签,后期查询会很麻烦,应该拆成关联表。

数据库连接推荐使用 PDO,并开启异常模式:

<?php
// app/db.php
function db(): PDO {
    static $pdo = null;
    if ($pdo === null) {
        $cfg = require __DIR__ . '/config.php';
        $dsn = "mysql:host={$cfg['db_host']};dbname={$cfg['db_name']};charset=utf8mb4";
        $pdo = new PDO($dsn, $cfg['db_user'], $cfg['db_pass'], [
            PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
            PDO::ATTR_EMULATE_PREPARES   => false,
        ]);
    }
    return $pdo;
}

五、模型层:把数据读写集中起来

模型层只做一件事:和数据库打交道。控制器不应该直接写 SQL,这样以后换表结构或优化查询时,只需要改模型。

<?php
// app/models/Article.php
class Article {
    public static function find(int $id): ?array {
        $stmt = db()->prepare('SELECT * FROM article WHERE id = :id AND status = 1');
        $stmt->execute([':id' => $id]);
        $row = $stmt->fetch();
        return $row ?: null;
    }

    public static function latest(int $limit = 10): array {
        $stmt = db()->prepare(
            'SELECT id, title, summary, created_at FROM article
             WHERE status = 1 ORDER BY created_at DESC LIMIT :n'
        );
        $stmt->bindValue(':n', $limit, PDO::PARAM_INT);
        $stmt->execute();
        return $stmt->fetchAll();
    }
}

这里用到了预处理语句:SQL 里只放占位符,用户传入的值通过参数绑定,这是防止 SQL 注入基础且有效的做法。

六、控制器与模板:逻辑和页面分开

控制器接收请求,调用模型取数据,再把数据交给模板:

<?php
// app/controllers/ArticleController.php
require __DIR__ . '/../models/Article.php';

class ArticleController {
    public function show(string $id): void {
        $article = Article::find((int)$id);
        if (!$article) {
            http_response_code(404);
            echo '文章不存在';
            return;
        }
        $title = $article['title'];
        ob_start();
        require __DIR__ . '/../views/article_show.php';
        $content = ob_get_clean();
        require __DIR__ . '/../views/layout.php';
    }
}

模板只负责输出,里面不要出现查询数据库的代码,并且所有来自数据库或用户的内容都要转义后再输出:

<!-- app/views/article_show.php -->
<article>
  <h1><?= htmlspecialchars($article['title'], ENT_QUOTES, 'UTF-8') ?></h1>
  <div class="meta"><?= htmlspecialchars($article['created_at']) ?></div>
  <div class="body"><?= nl2br(htmlspecialchars($article['content'], ENT_QUOTES, 'UTF-8')) ?></div>
</article>

layout.php 放页面公共部分,比如页头、导航、页脚,通过 $title 和 $content 两个变量拼出完整页面。这样每个页面只需要写自己的内容,公共部分改一处全站生效。

七、基础安全:入门阶段必须做到的几件事

安全是一个独立的大话题,这里只列入门时必须养成的习惯,具体的漏洞原理和排查方法,可以参考站内关于 PHP 网站安全的专门文章:

  1. 所有数据库查询使用预处理语句,不要拼接 SQL 字符串。
  2. 输出到页面的内容一律转义,防止脚本注入。
  3. 密码使用 password_hash() 存储,password_verify() 校验,不要自己写加密逻辑,更不要明文存储。
  4. 表单提交加 CSRF 令牌,防止被第三方页面诱导提交。
  5. 上传文件限制类型与大小,并重命名保存,上传目录禁止执行脚本。
  6. 关闭生产环境的错误回显,错误写进日志,不要把报错信息展示给访客。
  7. 配置文件放在 Web 根目录之外,数据库账号使用最小权限。
  8. 保持 PHP 与组件的版本更新,及时修复已知漏洞。

八、从"能跑"到"好维护"的几个进阶方向

当站点跑起来、功能逐渐增多,可以考虑逐步引入:

  • 统一的错误处理与日志:用统一的异常处理,把错误记录到文件,便于排查。
  • 配置区分环境:开发、测试、生产使用不同的配置,避免误操作。
  • 分页与缓存:列表页加分页,热点数据加缓存,减轻数据库压力。
  • 后台管理:为内容更新做一个带登录和权限的管理界面。
  • 自动化部署与备份:代码用版本管理,数据库定期备份。
  • 选用成熟框架:当项目规模变大、团队协作增多,再评估是否引入框架来统一规范。

不必一开始就做这些。先把"入口—路由—控制器—模型—视图"这条线跑通,理解每一层存在的理由,再按需要升级,比一上来就套用复杂框架更容易学扎实。

九、小型站点和正式业务站点的差别

用上面的方式,已经可以做出个人博客、产品展示页、内部小工具这类站点。如果是企业对外的正式官网,需要额外考虑的事情会更多,包括:搜索引擎优化的页面细节、移动端适配、访问速度、后台内容管理、备案、服务器安全与日常维护等。这时是自己继续开发,还是交给专业团队,取决于时间、人力和长期维护的成本。

广州万户网络提供网站建设与软件开发服务,建站套餐的参考价格为 1280 / 2680 / 3880 / 6800 元起,具体档位根据页面数量、设计方式和功能需求评估,以实际需求报价为准,详细内容可查看 建站价格方案。

常见问题

Q:学 PHP 网站设计,要不要一开始就用框架? A:建议先用原生 PHP 把请求流程、路由、数据库和模板的关系理解清楚,再学习框架。这样用框架时,能明白它每一层在做什么,而不是只会照着文档写。

Q:PHP 网站设计里,目录结构为什么要把 public 单独拿出来? A:只把 public 作为 Web 根目录,配置文件和业务代码放在目录之外,可以避免配置、源码被直接访问,是降低泄露风险的基础做法。

Q:数据库操作用 mysqli 还是 PDO? A:两者都可以,PDO 支持多种数据库,预处理语句写法统一,入门时更方便。关键是无论哪种,都要使用预处理语句和参数绑定。

Q:基于 PHP 的网站设计,数据库表要不要一开始就设计得很完整? A:不需要追求一步到位。先满足当前功能,保证主键、字符集、常用索引合理,后续再根据需求增加字段或拆分表,并做好迁移记录。

Q:做完的 PHP 站点怎么上线? A:需要准备服务器环境(Web 服务器、PHP、数据库)、域名、备案(国内服务器)、HTTPS 证书,并配置好目录权限和伪静态规则,上线前关闭错误回显并做好备份。

如果你想把自己的业务做成一个稳定可维护的网站,却不确定该自己写还是找人做,可以把业务需求和预算告诉我们,广州万户网络可以先帮你评估方案,咨询电话:13535321113。需要更多开发方面的技术内容,也可以浏览 软件开发栏目,把基础打牢之后,再决定下一步怎么走。

需要网站建设、软件开发或爬虫定制?

模板建站1280元起,价格公开不加价。电话/微信 13535321113

免费获取方案
电话
免费咨询热线13535321113
微信
微信二维码
微信号:13535321113
点击复制
拨打电话 加微信