Категории

Создание интернет-магазина на PHP и MySQL: пошаговое руководство для новичков

2025-10-20 15:03:29 | Статья из категории: создание сайтов

В этой статье мы рассмотрим базовые шаги по созданию простого интернет-магазина с использованием PHP и MySQL. Цель — дать понимание архитектуры и основных компонентов, которые можно в дальнейшем расширять под свои задачи.

1. Подготовка окружения

Для работы понадобятся:

2. Создание базы данных

Создайте базу данных и необходимые таблицы:

CREATE DATABASE shop;
USE shop;

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

CREATE TABLE products (
  id INT AUTO_INCREMENT PRIMARY KEY,
  name VARCHAR(255) NOT NULL,
  description TEXT,
  price DECIMAL(10, 2) NOT NULL,
  image_url VARCHAR(255),
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

CREATE TABLE orders (
  id INT AUTO_INCREMENT PRIMARY KEY,
  user_id INT NOT NULL,
  product_id INT NOT NULL,
  quantity INT DEFAULT 1,
  status ENUM('new', 'processed', 'shipped', 'cancelled') DEFAULT 'new',
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  FOREIGN KEY (user_id) REFERENCES users(id),
  FOREIGN KEY (product_id) REFERENCES products(id)
);

3. Стартовые PHP-файлы

Ниже приведены минимальные реализации основных файлов проекта. Разместите их в корне вашего веб-проекта.

3.1. config.php — подключение к базе данных

<?php
$host = 'localhost';
$dbname = 'shop';
$username = 'root'; // замените на ваше имя пользователя БД
$password = '';     // замените на ваш пароль

try {
    $pdo = new PDO("mysql:host=$host;dbname=$dbname;charset=utf8", $username, $password);
    $pdo->  setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
    die("Ошибка подключения к БД: " . $e->  getMessage());
}
?>  

3.2. register.php — регистрация пользователя

<?php
session_start();
require_once 'config.php';

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $username = trim($_POST['username']);
    $email = trim($_POST['email']);
    $password = $_POST['password'];

    if (empty($username) || empty($email) || empty($password)) {
        $error = "Все поля обязательны.";
    } else {
        $stmt = $pdo->  prepare("SELECT id FROM users WHERE email = ? OR username = ?");
        $stmt->  execute([$email, $username]);
        if ($stmt->  fetch()) {
            $error = "Пользователь с таким email или логином уже существует.";
        } else {
            $hash = password_hash($password, PASSWORD_DEFAULT);
            $pdo->  prepare("INSERT INTO users (username, email, password_hash) VALUES (?, ?, ?)")
                ->  execute([$username, $email, $hash]);
            header("Location: login.php");
            exit;
        }
    }
}
?>  

<h2>  Регистрация</h2>  
<?php if (!empty($error)): ?>  
    <p style="color:red;">  <?php echo htmlspecialchars($error); ?>  </p>  
<?php endif; ?>  
<form method="POST">  
    Логин: <input type="text" name="username" required>  <br>  <br>  
    Email: <input type="email" name="email" required>  <br>  <br>  
    Пароль: <input type="password" name="password" required>  <br>  <br>  
    <button type="submit">  Зарегистрироваться</button>  
</form>  
<a href="login.php">  Уже есть аккаунт? Войти</a>  

3.3. login.php — авторизация

<?php
session_start();
require_once 'config.php';

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $email = trim($_POST['email']);
    $password = $_POST['password'];

    $stmt = $pdo->  prepare("SELECT id, username, password_hash FROM users WHERE email = ?");
    $stmt->  execute([$email]);
    $user = $stmt->  fetch();

    if ($user && password_verify($password, $user['password_hash'])) {
        $_SESSION['user_id'] = $user['id'];
        $_SESSION['username'] = $user['username'];
        header("Location: index.php");
        exit;
    } else {
        $error = "Неверный email или пароль.";
    }
}
?>  

<h2>  Вход</h2>  
<?php if (!empty($error)): ?>  
    <p style="color:red;">  <?php echo htmlspecialchars($error); ?>  </p>  
<?php endif; ?>  
<form method="POST">  
    Email: <input type="email" name="email" required>  <br>  <br>  
    Пароль: <input type="password" name="password" required>  <br>  <br>  
    <button type="submit">  Войти</button>  
</form>  
<a href="register.php">  Нет аккаунта? Зарегистрироваться</a>  

3.4. index.php — главная страница с товарами

<?php
session_start();
require_once 'config.php';

$stmt = $pdo->  query("SELECT id, name, price, image_url FROM products ORDER BY created_at DESC");
$products = $stmt->  fetchAll();
?>  

<h1>  Интернет-магазин</h1>  

<?php if (!empty($_SESSION['user_id'])): ?>  
    <p>  Привет, <?php echo htmlspecialchars($_SESSION['username']); ?>  ! <a href="logout.php">  Выйти</a>  </p>  
<?php else: ?>  
    <p>  <a href="login.php">  Войдите</a>   или <a href="register.php">  зарегистрируйтесь</a>  </p>  
<?php endif; ?>  

<h2>  Товары</h2>  
<?php if ($products): ?>  
    <ul>  
    <?php foreach ($products as $p): ?>  
        <li>  
            <?php if (!empty($p['image_url'])): ?>  
                <img src="<?php echo htmlspecialchars($p['image_url']); ?>  " alt="<?php echo htmlspecialchars($p['name']); ?>  " width="100">  
            <?php endif; ?>  
            <h3>  <a href="product.php?id=<?php echo $p['id']; ?>  ">  <?php echo htmlspecialchars($p['name']); ?>  </a>  </h3>  
            Цена: <?php echo number_format($p['price'], 2, ',', ' '); ?>   руб.
        </li>  
    <?php endforeach; ?>  
    </ul>  
<?php else: ?>  
    <p>  Товары отсутствуют.</p>  
<?php endif; ?>  

3.5. product.php — карточка товара и заказ

<?php
session_start();
require_once 'config.php';

if (!isset($_GET['id']) || !is_numeric($_GET['id'])) {
    die("Товар не найден.");
}

$productId = (int)$_GET['id'];
$stmt = $pdo->  prepare("SELECT * FROM products WHERE id = ?");
$stmt->  execute([$productId]);
$product = $stmt->  fetch();

if (!$product) {
    die("Товар не найден.");
}

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    if (empty($_SESSION['user_id'])) {
        $error = "Требуется авторизация для оформления заказа.";
    } else {
        $quantity = (int)($_POST['quantity'] ?? 1);
        if ($quantity < 1) $quantity = 1;

        $pdo->  prepare("INSERT INTO orders (user_id, product_id, quantity) VALUES (?, ?, ?)")
            ->  execute([$_SESSION['user_id'], $productId, $quantity]);

        // Простое уведомление админу
        mail('admin@example.com', 'Новый заказ', "Пользователь {$_SESSION['username']} заказал {$product['name']} ({$quantity} шт.)");

        $success = "Заказ успешно оформлен!";
    }
}
?>  

<h1>  <?php echo htmlspecialchars($product['name']); ?>  </h1>  

<?php if (!empty($product['image_url'])): ?>  
    <img src="<?php echo htmlspecialchars($product['image_url']); ?>  " alt="<?php echo htmlspecialchars($product['name']); ?>  ">  
<?php endif; ?>  

<p>  <?php echo nl2br(htmlspecialchars($product['description'])); ?>  </p>  
<p>  <strong>  Цена:</strong>   <?php echo number_format($product['price'], 2, ',', ' '); ?>   руб.</p>  

<?php if (!empty($success)): ?>  
    <p style="color:green;">  <?php echo $success; ?>  </p>  
<?php else: ?>  
    <form method="POST">  
        <label>  Количество: <input type="number" name="quantity" value="1" min="1">  </label>  <br>  <br>  
        <button type="submit">  Купить</button>  
    </form>  
<?php endif; ?>  

<p>  <a href="index.php">  ← Назад к товарам</a>  </p>  

3.6. logout.php — выход из аккаунта

<?php
session_start();
session_destroy();
header("Location: index.php");
exit;
?>  

4. Простая админка (admin/)

Создайте папку admin и файл admin/index.php:

admin/index.php

<?php
session_start();
require_once '../config.php';

// Простейшая проверка: только авторизованные (в реальности — роль админа!)
if (empty($_SESSION['user_id'])) {
    header("Location: ../login.php");
    exit;
}

$stmt = $pdo->  query("SELECT o.id, u.username, p.name, o.quantity, o.status, o.created_at 
                     FROM orders o 
                     JOIN users u ON o.user_id = u.id 
                     JOIN products p ON o.product_id = p.id 
                     ORDER BY o.created_at DESC");
$orders = $stmt->  fetchAll();
?>  

<h1>  Админка: заказы</h1>  
<p>  <a href="../index.php">  ← На сайт</a>  </p>  

<table border="1" cellpadding="8">  
<tr>  
  <th>  ID заказа</th>  
  <th>  Пользователь</th>  
  <th>  Товар</th>  
  <th>  Кол-во</th>  
  <th>  Статус</th>  
  <th>  Дата</th>  
</tr>  
<?php foreach ($orders as $o): ?>  
<tr>  
  <td>  <?php echo $o['id']; ?>  </td>  
  <td>  <?php echo htmlspecialchars($o['username']); ?>  </td>  
  <td>  <?php echo htmlspecialchars($o['name']); ?>  </td>  
  <td>  <?php echo $o['quantity']; ?>  </td>  
  <td>  <?php echo htmlspecialchars($o['status']); ?>  </td>  
  <td>  <?php echo $o['created_at']; ?>  </td>  
</tr>  
<?php endforeach; ?>  
</table>  

5. Безопасность (минимум)

6. Что дальше?

Этот каркас можно расширять:

Главное — начать с простого, протестировать каждую часть и постепенно усложнять систему.

Комментарии

Пока нет комментариев. Будьте первым!

Оставить комментарий

← Назад к списку статей

Важно: Блог-эксперимент

Блог только запустил, все статьи генерирую через нейросеть т.к. лень, возможны ошибки. Просто чтобы вы знали и не запускали ядерный реактор по моим статьям ))
Если у вас есть вопросы, или Нашли неточность? пишите в коментах — вместе поправим и сделаем статью более качественной. Я лично объясню нюансы из практики.

Посетителей сегодня: 0


Кто я | Контакты и регион

© Digital Specialist | Не являемся сотрудниками Google, Яндекса и NASA