永久免费的黄冈网站建设源码多少钱?费用构成与获取渠道

A−A+微博☆•••

本文按逐文件源码形式提供一个可本地运行的黄冈资讯站起始工程,包含栏目筛选、关键词检索、文章列表、正文查看和后台发布入口。将代码按目录保存并初始化 SQLite 数据库,即可在本机测试,再根据乡镇动态、教育文化、生活服务等实际栏目替换示例记录。

冻结声明说明:现有字段记录了年份“2026”和版本标签“官方版”,但版本号与适用平台均未提供,也没有授权或价格条款。因此,本文不把某个未核实的官方压缩包、平台兼容性或“永久免费”许可说成已确认事实。这里直接给出可复制保存的源码,不附压缩文件或下载链接;使用前请以实际项目的授权文本为准。

工程规格与功能

字段取值用途
PHP 运行环境PHP 8.1 或更高版本执行列表、正文和后台发布脚本
数据库驱动PDO SQLite读取与保存文章记录
数据库文件storage/site.sqlite保存栏目、标题、摘要、正文和发布状态
字符编码UTF-8处理中文标题、栏目名与正文
检索参数q、category、id按标题搜索、筛选栏目、打开指定文章
  • 资讯列表:只展示已发布记录,按发布时间倒序排列,最多读取三十条。
  • 关键词检索:使用预处理语句匹配标题,避免把用户输入直接拼入 SQL。
  • 栏目筛选:支持政务动态、乡镇资讯、教育文化和生活服务等自定义分类。
  • 正文查看:根据文章编号读取单条记录,输出时转义文字,换行转换为段落间隔。
  • 后台发布:使用服务器环境变量设置管理员凭据;后台提供带 CSRF 校验的新增发布入口。

项目目录

huanggang-site/
├── app/
│   ├── db.php
│   └── helpers.php
├── public/
│   ├── index.php
│   ├── article.php
│   └── admin.php
├── storage/
│   └── site.sqlite
└── install.sql

public 放置可由 Web 服务访问的 PHP 脚本,app 保存数据库连接和转义函数,storage 保存 SQLite 文件。请将站点根目录指向 public,不要把数据库目录暴露给访客。栏目名称、站点名称和页脚文字可在各脚本输出的 HTML 模板中修改。

数据库初始化源码

将以下语句保存为 install.sql。示例记录用于本地测试,不代表黄冈任何机构发布的真实通知。

CREATE TABLE IF NOT EXISTS articles (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  title TEXT NOT NULL,
  category TEXT NOT NULL DEFAULT '本地资讯',
  summary TEXT NOT NULL DEFAULT '',
  body TEXT NOT NULL,
  published_at TEXT NOT NULL,
  status INTEGER NOT NULL DEFAULT 1 CHECK (status IN (0, 1))
);

INSERT INTO articles (title, category, summary, body, published_at, status)
VALUES (
  '示例:乡镇便民服务安排',
  '生活服务',
  '用于检查列表摘要和正文跳转。',
  '这是本地测试用的虚构记录,请替换为经核实的公告。',
  '2026-01-01 09:00:00',
  1
);

在工程根目录创建 storage 后,可用 SQLite 命令行执行初始化:sqlite3 storage/site.sqlite < install.sql。若没有命令行工具,也可使用本机数据库管理工具运行同一份 SQL。正式发布前,应核对通知来源与发布时间,并为数据库文件设置仅服务进程可读写的权限。

数据库连接与文字转义

将下方代码分别保存为 app/db.php 和 app/helpers.php。连接脚本会在缺少存储目录时尝试创建目录;部署账户仍须具有相应写入权限。

<?php
$path = dirname(__DIR__) . '/storage/site.sqlite';
$dir = dirname($path);

if (!is_dir($dir) && !mkdir($dir, 0750, true) && !is_dir($dir)) {
    throw new RuntimeException('无法创建数据库目录');
}

$pdo = new PDO('sqlite:' . $path, null, null, [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
]);
$pdo->exec('PRAGMA foreign_keys = ON');
?>
<?php
function e($value): string
{
    return htmlspecialchars((string)$value, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
}
?>

资讯列表与搜索入口

把以下源码保存为 public/index.php。访客可用 ?q=关键词 搜标题,也可用 ?category=生活服务 查看指定栏目;两个条件可以同时使用。

<?php
require dirname(__DIR__) . '/app/db.php';
require dirname(__DIR__) . '/app/helpers.php';

$q = isset($_GET['q']) && is_string($_GET['q'])
    ? trim($_GET['q']) : '';
$category = isset($_GET['category']) && is_string($_GET['category'])
    ? trim($_GET['category']) : '';

$sql = 'SELECT id, title, category, summary, published_at
        FROM articles WHERE status = 1';
$args = [];

if ($q !== '') {
    $sql .= ' AND title LIKE :q';
    $args[':q'] = '%' . $q . '%';
}
if ($category !== '') {
    $sql .= ' AND category = :category';
    $args[':category'] = $category;
}
$sql .= ' ORDER BY published_at DESC, id DESC LIMIT 30';

$stmt = $pdo->prepare($sql);
$stmt->execute($args);
$rows = $stmt->fetchAll();
?>
<!doctype html>
<html lang="zh-CN">
<head>
  <meta charset="utf-8">
  <title>黄冈本地资讯</title>
</head>
<body>
  <h1>黄冈本地资讯</h1>
  <p>按标题关键词或栏目名查找已发布文章。</p>
  <form method="get">
    <label>标题关键词
      <input name="q" value="<?= e($q) ?>">
    </label>
    <label>栏目
      <input name="category" value="<?= e($category) ?>">
    </label>
    <button type="submit">查找</button>
  </form>
  <ul>
  <?php foreach ($rows as $row): ?>
    <li>
      <a href="article.php?id=<?= (int)$row['id'] ?>">
        <?= e($row['title']) ?>
      </a>
      <span><?= e($row['category']) ?></span>
      <time><?= e($row['published_at']) ?></time>
      <p><?= e($row['summary']) ?></p>
    </li>
  <?php endforeach; ?>
  </ul>
</body>
</html>

文章正文入口

保存为 public/article.php。编号先转换为整数,再通过预处理语句查询;访客无法打开未发布记录。正文按纯文字处理,不执行文章字段中可能出现的 HTML 标签。

<?php
require dirname(__DIR__) . '/app/db.php';
require dirname(__DIR__) . '/app/helpers.php';

$id = filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT);
if (!$id || $id < 1) {
    http_response_code(404);
    exit('未找到这篇文章');
}

$stmt = $pdo->prepare(
    'SELECT title, category, body, published_at
     FROM articles WHERE id = :id AND status = 1'
);
$stmt->execute([':id' => $id]);
$row = $stmt->fetch();

if (!$row) {
    http_response_code(404);
    exit('未找到这篇文章');
}
?>
<!doctype html>
<html lang="zh-CN">
<head>
  <meta charset="utf-8">
  <title><?= e($row['title']) ?></title>
</head>
<body>
  <article>
    <h1><?= e($row['title']) ?></h1>
    <p>栏目:<?= e($row['category']) ?></p>
    <time><?= e($row['published_at']) ?></time>
    <p><?= nl2br(e($row['body']), false) ?></p>
  </article>
  <p><a href="index.php">返回资讯列表</a></p>
</body>
</html>

后台发布入口

将以下源码保存为 public/admin.php。管理员账号与密码从服务器环境变量 HG_ADMIN_USER、HG_ADMIN_PASSWORD 读取,不要把真实密码写进源码。后台只提供新增发布,不包含编辑、删除或角色管理;对公网开放前,应使用 HTTPS,并在 Web 服务侧增加访问限制。

<?php
require dirname(__DIR__) . '/app/db.php';
require dirname(__DIR__) . '/app/helpers.php';

$user = getenv('HG_ADMIN_USER') ?: '';
$pass = getenv('HG_ADMIN_PASSWORD') ?: '';
if ($user === '' || $pass === '') {
    http_response_code(503);
    exit('尚未设置后台凭据');
}

$givenUser = $_SERVER['PHP_AUTH_USER'] ?? '';
$givenPass = $_SERVER['PHP_AUTH_PW'] ?? '';
if (!hash_equals($user, $givenUser) || !hash_equals($pass, $givenPass)) {
    header('WWW-Authenticate: Basic realm="资讯维护"');
    http_response_code(401);
    exit('需要管理员认证');
}

session_start();
if (empty($_SESSION['token'])) {
    $_SESSION['token'] = bin2hex(random_bytes(32));
}

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $token = $_POST['token'] ?? '';
    if (!is_string($token) || !hash_equals($_SESSION['token'], $token)) {
        http_response_code(403);
        exit('请求校验失败');
    }

    $title = trim((string)($_POST['title'] ?? ''));
    $category = trim((string)($_POST['category'] ?? ''));
    $summary = trim((string)($_POST['summary'] ?? ''));
    $body = trim((string)($_POST['body'] ?? ''));

    if ($title === '' || $category === '' || $body === '') {
        http_response_code(422);
        exit('标题、栏目和正文不能为空');
    }

    $stmt = $pdo->prepare(
        'INSERT INTO articles
         (title, category, summary, body, published_at, status)
         VALUES (:title, :category, :summary, :body, :published_at, 1)'
    );
    $stmt->execute([
        ':title' => $title,
        ':category' => $category,
        ':summary' => $summary,
        ':body' => $body,
        ':published_at' => date('Y-m-d H:i:s'),
    ]);

    header('Location: admin.php');
    exit;
}
?>
<!doctype html>
<html lang="zh-CN">
<head>
  <meta charset="utf-8">
  <title>资讯发布维护</title>
</head>
<body>
  <h1>发布本地资讯</h1>
  <form method="post">
    <input type="hidden" name="token"
           value="<?= e($_SESSION['token']) ?>">
    <label>标题
      <input name="title" required maxlength="200">
    </label>
    <label>栏目
      <input name="category" required maxlength="80">
    </label>
    <label>摘要
      <textarea name="summary" maxlength="500"></textarea>
    </label>
    <label>正文
      <textarea name="body" required rows="12"></textarea>
    </label>
    <button type="submit">发布文章</button>
  </form>
</body>
</html>

本地运行与后续维护

确认 PHP 已启用 PDO SQLite 后,在工程根目录初始化数据库,再用本机 PHP 开发服务器启动:php -S 127.0.0.1:8000 -t public。浏览器访问本机的 index.php 检查列表、关键词检索、栏目筛选和正文跳转;配置管理员环境变量后,再访问 admin.php 测试发布流程。

上线前应替换虚构测试记录,核对每条通知的来源、栏目和发布时间,设置独立管理员凭据,并定期备份 storage/site.sqlite。若要增加分页、文章编辑、撤稿、图片管理或多管理员权限,应分别补充输入校验、操作审计和数据库备份策略;不要仅靠隐藏后台入口保护文章数据。

【更多新闻,请关注“海报新闻”客户端】【山东手机报:及时获取本地新闻资讯】

初审编辑:赵少康

责任编辑:王石川

相关新闻

推荐阅读