凌峰创科服务平台

产品展示网站PHP源码怎么用?

  1. 产品列表展示:以卡片形式展示所有产品。
  2. 产品详情页:点击产品后,可以查看大图、名称、详细描述和价格。
  3. 后台管理:可以登录后台,添加、编辑和删除产品。
  4. 基础样式:使用现代的卡片式布局,响应式设计,在手机和电脑上都能良好显示。

项目结构

我们创建一个清晰的目录结构,这对于项目的维护至关重要。

产品展示网站PHP源码怎么用?-图1
(图片来源网络,侵删)
/product-website/
├── admin/                 # 后台管理目录
│   ├── index.php         # 后台登录页面
│   ├── login.php         # 处理登录逻辑
│   ├── dashboard.php     # 后台管理面板
│   ├── create.php        # 添加新产品页面
│   ├── edit.php          # 编辑产品页面
│   ├── process.php       # 处理创建/编辑的逻辑
│   └── delete.php        # 处理删除的逻辑
│
├── assets/               # 静态资源目录
│   └── css/
│       └── style.css     # 主样式文件
│
├── config/               # 配置文件目录
│   └── database.php      # 数据库连接配置
│
├── images/               # 产品图片存放目录
│   ├── product1.jpg
│   ├── product2.jpg
│   └── ...               # 上传的产品图片将放在这里
│
├── partials/             # 页面片段(公共部分)
│   ├── header.php        # 公共头部
│   └── footer.php        # 公共底部
│
├── index.php             # 网站首页,展示所有产品
├── product.php           # 产品详情页
└── logout.php            # 后台登出脚本

第1步:数据库准备

您需要一个数据库来存储产品信息,请执行以下SQL语句来创建products表。

CREATE DATABASE `product_showcase`;
USE `product_showcase`;
CREATE TABLE `products` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL,
  `description` text NOT NULL,
  `price` decimal(10, 2) NOT NULL,
  `image` varchar(255) NOT NULL,
  `created_at` timestamp NOT NULL DEFAULT current_timestamp(),
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

第2步:PHP源码文件

我们按照上面的目录结构,逐一创建每个文件。

config/database.php - 数据库连接配置

<?php
// 数据库配置
define('DB_HOST', 'localhost');
define('DB_USER', 'root'); // 您的数据库用户名
define('DB_PASS', '');     // 您的数据库密码
define('DB_NAME', 'product_showcase'); // 您的数据库名
// 创建连接
$conn = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME);
// 检查连接是否成功
if ($conn->connect_error) {
    die("连接失败: " . $conn->connect_error);
}
// 设置字符集,防止中文乱码
$conn->set_charset("utf8mb4");
?>

assets/css/style.css - 样式文件

/* 全局样式 */
body {
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    line-height: 1.6;
    margin: 0;
    background-color: #f4f4f4;
    color: #333;
}
.container {
    max-width: 1100px;
    margin: auto;
    overflow: hidden;
    padding: 0 2rem;
}
/* 头部样式 */
.header {
    background: #333;
    color: #fff;
    padding: 1rem 0;
    text-align: center;
}
/* 产品卡片样式 */
.product-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    gap: 2rem;
    padding: 2rem 0;
}
.product-card {
    background: #fff;
    border: 1px solid #ddd;
    border-radius: 8px;
    overflow: hidden;
    box-shadow: 0 4px 8px rgba(0,0,0,0.1);
    transition: transform 0.2s;
    text-align: center;
}
.product-card:hover {
    transform: translateY(-5px);
}
.product-card img {
    max-width: 100%;
    height: 200px;
    object-fit: cover;
}
.product-info {
    padding: 1.5rem;
}
.product-info h3 {
    margin: 0 0 0.5rem 0;
    font-size: 1.2rem;
}
.product-info p {
    color: #777;
    font-size: 0.9rem;
    margin-bottom: 1rem;
}
.btn {
    display: inline-block;
    background: #007bff;
    color: #fff;
    padding: 0.8rem 1.5rem;
    text-decoration: none;
    border-radius: 5px;
    border: none;
    cursor: pointer;
    font-size: 1rem;
    transition: background 0.2s;
}
.btn:hover {
    background: #0056b3;
}
.btn-danger {
    background: #dc3545;
}
.btn-danger:hover {
    background: #c82333;
}
.btn-success {
    background: #28a745;
}
.btn-success:hover {
    background: #218838;
}
/* 详情页样式 */
.product-detail {
    background: #fff;
    padding: 2rem;
    border-radius: 8px;
    box-shadow: 0 4px 8px rgba(0,0,0,0.1);
    display: flex;
    flex-wrap: wrap;
    gap: 2rem;
}
.product-detail img {
    max-width: 100%;
    max-height: 500px;
    object-fit: contain;
    border: 1px solid #ddd;
}
.product-detail-content h2 {
    margin-top: 0;
}
.product-detail-content p {
    font-size: 1.1rem;
    color: #555;
}
.product-detail-content .price {
    font-size: 1.5rem;
    font-weight: bold;
    color: #007bff;
    margin: 1rem 0;
}
/* 后台管理样式 */
.admin-panel .btn {
    margin-right: 0.5rem;
}
.form-group {
    margin-bottom: 1rem;
}
.form-group label {
    display: block;
    margin-bottom: 0.5rem;
    font-weight: bold;
}
.form-group input,
.form-group textarea {
    width: 100%;
    padding: 0.8rem;
    border: 1px solid #ddd;
    border-radius: 4px;
    box-sizing: border-box; /* 确保padding不会影响总宽度 */
}
.form-group textarea {
    height: 150px;
    resize: vertical;
}

partials/header.php - 公共头部

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0"><?php echo isset($page_title) ? $page_title . ' - ' : ''; ?>产品展示网站</title>
    <link rel="stylesheet" href="assets/css/style.css">
</head>
<body>
    <header class="header">
        <div class="container">
            <h1>我的产品展示网站</h1>
            <nav>
                <a href="index.php">首页</a>
                <a href="admin/index.php">后台管理</a>
            </nav>
        </div>
    </header>
    <div class="container">

partials/footer.php - 公共底部

    </div> <!-- .container -->
    <footer class="header" style="margin-top: 2rem;">
        <div class="container">
            <p>&copy; <?php echo date('Y'); ?> 产品展示网站. All Rights Reserved.</p>
        </div>
    </footer>
</body>
</html>

第3步:前台页面 (用户访问)

index.php - 首页 (产品列表)

<?php
$page_title = '首页';
require_once 'config/database.php';
require_once 'partials/header.php';
// 从数据库获取所有产品
$sql = "SELECT * FROM products ORDER BY created_at DESC";
$result = $conn->query($sql);
?>
<h2>全部产品</h2>
<div class="product-grid">
    <?php if ($result->num_rows > 0): ?>
        <?php while($row = $result->fetch_assoc()): ?>
            <div class="product-card">
                <img src="images/<?php echo htmlspecialchars($row['image']); ?>" alt="<?php echo htmlspecialchars($row['name']); ?>">
                <div class="product-info">
                    <h3><?php echo htmlspecialchars($row['name']); ?></h3>
                    <p><?php echo htmlspecialchars(substr($row['description'], 0, 100)) . '...'; ?></p>
                    <p class="price">¥ <?php echo htmlspecialchars($row['price']); ?></p>
                    <a href="product.php?id=<?php echo $row['id']; ?>" class="btn">查看详情</a>
                </div>
            </div>
        <?php endwhile; ?>
    <?php else: ?>
        <p>暂无产品。</p>
    <?php endif; ?>
</div>
<?php
require_once 'partials/footer.php';
?>

product.php - 产品详情页

<?php
require_once 'config/database.php';
// 检查是否有ID参数
if (!isset($_GET['id']) || empty($_GET['id'])) {
    die('无效的产品ID');
}
$product_id = $_GET['id'];
// 获取单个产品信息
$stmt = $conn->prepare("SELECT * FROM products WHERE id = ?");
$stmt->bind_param("i", $product_id);
$stmt->execute();
$result = $stmt->get_result();
if ($result->num_rows === 0) {
    die('产品未找到');
}
$product = $result->fetch_assoc();
$page_title = $product['name'];
require_once 'partials/header.php';
?>
<div class="product-detail">
    <div>
        <img src="images/<?php echo htmlspecialchars($product['image']); ?>" alt="<?php echo htmlspecialchars($product['name']); ?>">
    </div>
    <div class="product-detail-content">
        <h2><?php echo htmlspecialchars($product['name']); ?></h2>
        <p class="price">¥ <?php echo htmlspecialchars($product['price']); ?></p>
        <p><?php echo nl2br(htmlspecialchars($product['description'])); ?></p>
        <a href="index.php" class="btn">返回列表</a>
    </div>
</div>
<?php
$stmt->close();
$conn->close();
require_once 'partials/footer.php';
?>

第4步:后台管理页面

admin/index.php - 后台登录页

<?php
session_start();
// 如果已经登录,直接跳转到管理面板
if (isset($_SESSION['admin_logged_in']) && $_SESSION['admin_logged_in'] === true) {
    header('Location: dashboard.php');
    exit;
}
?>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">后台登录</title>
    <link rel="stylesheet" href="../assets/css/style.css">
    <style>
        body { background: #f4f4f4; display: flex; justify-content: center; align-items: center; height: 100vh; }
        .login-form { background: #fff; padding: 2rem; border-radius: 8px; box-shadow: 0 4px 8px rgba(0,0,0,0.1); width: 100%; max-width: 400px; }
        .login-form h2 { text-align: center; margin-bottom: 1.5rem; }
    </style>
</head>
<body>
    <div class="login-form">
        <h2>管理员登录</h2>
        <form action="login.php" method="post">
            <div class="form-group">
                <label for="username">用户名</label>
                <input type="text" id="username" name="username" required>
            </div>
            <div class="form-group">
                <label for="password">密码</label>
                <input type="password" id="password" name="password" required>
            </div>
            <button type="submit" class="btn" style="width: 100%;">登录</button>
        </form>
    </div>
</body>
</html>

admin/login.php - 处理登录逻辑

<?php
session_start();
// 简单的用户名密码验证,实际项目中应使用更安全的方式(如哈希密码)
$admin_username = 'admin';
$admin_password = 'password123'; // 请务必修改默认密码!
if ($_SERVER["REQUEST_METHOD"] == "POST") {
    $username = $_POST['username'];
    $password = $_POST['password'];
    if ($username === $admin_username && $password === $admin_password) {
        $_SESSION['admin_logged_in'] = true;
        header('Location: dashboard.php');
        exit;
    } else {
        $error = "用户名或密码错误";
        header('Location: index.php?error=' . urlencode($error));
        exit;
    }
}
?>

admin/dashboard.php - 后台管理面板

<?php
session_start();
if (!isset($_SESSION['admin_logged_in']) || $_SESSION['admin_logged_in'] !== true) {
    header('Location: index.php');
    exit;
}
require_once '../config/database.php';
require_once '../partials/header.php'; // 使用前台的header,但可以修改为专用的admin_header
?>
<h2>管理面板</h2>
<p>欢迎, 管理员!</p>
<a href="create.php" class="btn btn-success">添加新产品</a>
<hr style="margin: 2rem 0;">
<h3>产品列表</h3>
<table style="width: 100%; border-collapse: collapse;">
    <thead>
        <tr style="background: #f0f0f0;">
            <th style="border: 1px solid #ddd; padding: 8px;">ID</th>
            <th style="border: 1px solid #ddd; padding: 8px;">名称</th>
            <th style="border: 1px solid #ddd; padding: 8px;">价格</th>
            <th style="border: 1px solid #ddd; padding: 8px;">操作</th>
        </tr>
    </thead>
    <tbody>
        <?php
        $sql = "SELECT * FROM products";
        $result = $conn->query($sql);
        if ($result->num_rows > 0):
            while($row = $result->fetch_assoc()): ?>
                <tr>
                    <td style="border: 1px solid #ddd; padding: 8px;"><?php echo $row['id']; ?></td>
                    <td style="border: 1px solid #ddd; padding: 8px;"><?php echo htmlspecialchars($row['name']); ?></td>
                    <td style="border: 1px solid #ddd; padding: 8px;">¥ <?php echo htmlspecialchars($row['price']); ?></td>
                    <td style="border: 1px solid #ddd; padding: 8px;">
                        <a href="edit.php?id=<?php echo $row['id']; ?>" class="btn">编辑</a>
                        <a href="delete.php?id=<?php echo $row['id']; ?>" class="btn btn-danger" onclick="return confirm('确定要删除这个产品吗?');">删除</a>
                    </td>
                </tr>
            <?php endwhile;
        else: ?>
            <tr>
                <td colspan="4" style="border: 1px solid #ddd; padding: 8px; text-align: center;">暂无产品</td>
            </tr>
        <?php endif; ?>
    </tbody>
</table>
<a href="../logout.php" class="btn btn-danger" style="margin-top: 1rem;">退出登录</a>
<?php require_once '../partials/footer.php'; ?>

admin/create.php - 添加产品页面

<?php
session_start();
if (!isset($_SESSION['admin_logged_in']) || $_SESSION['admin_logged_in'] !== true) {
    header('Location: index.php');
    exit;
}
require_once '../partials/header.php';
?>
<h2>添加新产品</h2>
<form action="process.php" method="post" enctype="multipart/form-data">
    <div class="form-group">
        <label for="name">产品名称</label>
        <input type="text" id="name" name="name" required>
    </div>
    <div class="form-group">
        <label for="price">价格</label>
        <input type="number" id="price" name="price" step="0.01" required>
    </div>
    <div class="form-group">
        <label for="description">产品描述</label>
        <textarea id="description" name="description" required></textarea>
    </div>
    <div class="form-group">
        <label for="image">产品图片</label>
        <input type="file" id="image" name="image" accept="image/*" required>
    </div>
    <button type="submit" class="btn btn-success">添加产品</button>
    <a href="dashboard.php" class="btn">取消</a>
</form>
<?php require_once '../partials/footer.php'; ?>

admin/edit.php - 编辑产品页面

<?php
session_start();
if (!isset($_SESSION['admin_logged_in']) || $_SESSION['admin_logged_in'] !== true) {
    header('Location: index.php');
    exit;
}
require_once '../config/database.php';
if (!isset($_GET['id']) || empty($_GET['id'])) {
    die('无效的产品ID');
}
$product_id = $_GET['id'];
$stmt = $conn->prepare("SELECT * FROM products WHERE id = ?");
$stmt->bind_param("i", $product_id);
$stmt->execute();
$result = $stmt->get_result();
if ($result->num_rows === 0) {
    die('产品未找到');
}
$product = $result->fetch_assoc();
require_once '../partials/header.php';
?>
<h2>编辑产品</h2>
<form action="process.php" method="post" enctype="multipart/form-data">
    <input type="hidden" name="id" value="<?php echo $product['id']; ?>">
    <input type="hidden" name="current_image" value="<?php echo $product['image']; ?>">
    <div class="form-group">
        <label for="name">产品名称</label>
        <input type="text" id="name" name="name" value="<?php echo htmlspecialchars($product['name']); ?>" required>
    </div>
    <div class="form-group">
        <label for="price">价格</label>
        <input type="number" id="price" name="price" step="0.01" value="<?php echo htmlspecialchars($product['price']); ?>" required>
    </div>
    <div class="form-group">
        <label for="description">产品描述</label>
        <textarea id="description" name="description" required><?php echo htmlspecialchars($product['description']); ?></textarea>
    </div>
    <div class="form-group">
        <label for="image">更换产品图片 (留空则不更换)</label>
        <input type="file" id="image" name="image" accept="image/*">
    </div>
    <button type="submit" class="btn btn-success">更新产品</button>
    <a href="dashboard.php" class="btn">取消</a>
</form>
<?php
$stmt->close();
$conn->close();
require_once '../partials/footer.php';
?>

admin/process.php - 处理创建和编辑的逻辑

<?php
session_start();
if (!isset($_SESSION['admin_logged_in']) || $_SESSION['admin_logged_in'] !== true) {
    header('Location: index.php');
    exit;
}
require_once '../config/database.php';
if ($_SERVER["REQUEST_METHOD"] == "POST") {
    $id = $_POST['id'] ?? null;
    $name = $_POST['name'];
    $price = $_POST['price'];
    $description = $_POST['description'];
    $current_image = $_POST['current_image'];
    $new_image_name = $current_image; // 默认使用当前图片名
    // 处理图片上传
    if (isset($_FILES['image']) && $_FILES['image']['error'] == 0) {
        $target_dir = "../images/";
        $imageFileType = strtolower(pathinfo($_FILES["image"]["name"], PATHINFO_EXTENSION));
        $new_image_name = uniqid("product_", true) . "." . $imageFileType;
        $target_file = $target_dir . $new_image_name;
        // 检查文件是否为真实图片
        $check = getimagesize($_FILES["image"]["tmp_name"]);
        if($check !== false) {
            if (move_uploaded_file($_FILES["image"]["tmp_name"], $target_file)) {
                // 图片上传成功,删除旧图片(如果存在且不是默认图)
                if (!empty($current_image) && file_exists($target_dir . $current_image)) {
                    unlink($target_dir . $current_image);
                }
            } else {
                die("抱歉,上传文件时出错。");
            }
        } else {
            die("文件不是有效的图片。");
        }
    }
    if ($id) {
        // 更新产品
        $stmt = $conn->prepare("UPDATE products SET name=?, price=?, description=?, image=? WHERE id=?");
        $stmt->bind_param("sdssi", $name, $price, $description, $new_image_name, $id);
        $message = "产品更新成功!";
    } else {
        // 添加新产品
        $stmt = $conn->prepare("INSERT INTO products (name, price, description, image) VALUES (?, ?, ?, ?)");
        $stmt->bind_param("sdss", $name, $price, $description, $new_image_name);
        $message = "产品添加成功!";
    }
    if ($stmt->execute()) {
        header('Location: dashboard.php?message=' . urlencode($message));
        exit;
    } else {
        die("错误: " . $stmt->error);
    }
    $stmt->close();
}
$conn->close();
?>

admin/delete.php - 处理删除的逻辑

<?php
session_start();
if (!isset($_SESSION['admin_logged_in']) || $_SESSION['admin_logged_in'] !== true) {
    header('Location: index.php');
    exit;
}
require_once '../config/database.php';
if (!isset($_GET['id']) || empty($_GET['id'])) {
    die('无效的产品ID');
}
$product_id = $_GET['id'];
// 先获取图片名
$stmt = $conn->prepare("SELECT image FROM products WHERE id = ?");
$stmt->bind_param("i", $product_id);
$stmt->execute();
$result = $stmt->get_result();
$product = $result->fetch_assoc();
$image_name = $product['image'];
// 删除数据库记录
$stmt = $conn->prepare("DELETE FROM products WHERE id = ?");
$stmt->bind_param("i", $product_id);
if ($stmt->execute()) {
    // 删除物理图片文件
    if (!empty($image_name) && file_exists("../images/" . $image_name)) {
        unlink("../images/" . $image_name);
    }
    header('Location: dashboard.php?message=产品删除成功!');
    exit;
} else {
    die("删除失败: " . $stmt->error);
}
$stmt->close();
$conn->close();
?>

logout.php - 登出脚本

<?php
session_start();
// 清除所有session变量
$_SESSION = array();
// 销毁session
session_destroy();
// 重定向到首页
header('Location: index.php');
exit;
?>

如何使用

  1. 环境准备:确保您有一个支持PHP和MySQL的环境,例如XAMPP、WAMP或MAMP。
  2. 创建目录和文件:按照上面的目录结构,在您的Web服务器根目录下创建所有文件和文件夹。
  3. 配置数据库
    • 修改 config/database.php 文件中的数据库用户名、密码和数据库名。
    • 使用MySQL客户端(如phpMyAdmin)执行第1步的SQL语句来创建数据库和表。
  4. 设置权限:确保 images 目录有写入权限,以便上传图片。
  5. 访问网站
    • 前台访问:http://localhost/product-website/
    • 后台访问:http://localhost/product-website/admin/index.php
      • 默认登录用户名:admin
      • 默认登录密码:password123
  6. 开始使用:登录后台后,您就可以添加、编辑和删除产品了。

如何扩展

  • 分页:当产品很多时,可以在 index.php 中添加分页功能。
  • 用户注册/登录:可以为网站添加用户系统,让用户收藏产品或发表评论。
  • 购物车和订单:这是电商网站的核心功能,需要更复杂的逻辑和数据库设计。
  • 更强大的后台:可以添加产品分类、标签、库存管理等功能。
  • 前端框架:可以引入Vue.js或React来构建更动态和交互性强的用户界面。

这份源码是一个非常好的起点,它结构清晰,功能完整,非常适合学习和二次开发。

产品展示网站PHP源码怎么用?-图2
(图片来源网络,侵删)
分享:
扫描分享到社交APP
上一篇
下一篇