Добавление нового пользователя: пошаговое руководство на PHP
Безопасное добавление пользователя через PDO
Цель: защитить приложение от SQL-инъекций при вставке данных нового пользователя. Используется в проектах, работающих с различными базами данных (MySQL, PostgreSQL и др.). Основное преимущество - поддержка именованных плейсхолдеров и автоматическое экранирование.
$dsn = 'mysql:host=localhost;dbname=test;charset=utf8mb4';
$pdo = new PDO($dsn, 'root', '', [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
]);
$stmt = $pdo->prepare('INSERT INTO users (username, email, password) VALUES (:username, :email, :password)');
$stmt->execute([
'username' => $_POST['username'],
'email' => $_POST['email'],
'password' => password_hash($_POST['password'], PASSWORD_DEFAULT),
]);
echo 'Пользователь создан';
Пояснение: сначала устанавливается соединение с настройками. Подготовленный запрос отделяет код от данных. Пароль хешируется функцией password_hash. В случае ошибки PDO выбросит исключение.
Как создать пользователя с помощью MySQLi?
Цель: использовать встроенное расширение MySQLi для работы с MySQL. Подходит для проектов, где нет возможности перейти на PDO или требуется специфичная функциональность MySQL. MySQLi поддерживает как процедурный, так и объектно-ориентированный стиль.
$mysqli = new mysqli('localhost', 'root', '', 'test');
if ($mysqli->connect_error) {
die('Ошибка подключения: ' . $mysqli->connect_error);
}
$stmt = $mysqli->prepare('INSERT INTO users (username, email, password) VALUES (?, ?, ?)');
$stmt->bind_param('sss', $username, $email, $hashedPassword);
$username = $_POST['username'];
$email = $_POST['email'];
$hashedPassword = password_hash($_POST['password'], PASSWORD_DEFAULT);
if ($stmt->execute()) {
echo 'Пользователь создан';
} else {
echo 'Ошибка: ' . $stmt->error;
}
$stmt->close();
$mysqli->close();
Пояснение: после создания объекта mysqli проверяется подключение. Затем готовится запрос с вопросительными знаками. bind_param привязывает переменные с указанием типов ('s' - строка). Выполнение проверяется по возвращаемому значению.
Как реализовать регистрацию через Laravel Eloquent?
Цель: использовать встроенные механизмы Laravel для быстрого создания пользователей. Подходит для проектов на этом фреймворке, где уже настроена миграция и модель User.
use App\Models\User;
use Illuminate\Support\Facades\Hash;
use Illuminate\Http\Request;
public function register(Request $request) {
$validated = $request->validate([
'name' => 'required|max:255',
'email' => 'required|email|unique:users',
'password' => 'required|min:8|confirmed',
]);
$user = User::create([
'name' => $validated['name'],
'email' => $validated['email'],
'password' => Hash::make($validated['password']),
]);
return response()->json(['message' => 'Пользователь создан', 'user' => $user], 201);
}
Пояснение: метод validate проверяет входные данные. User::create массово присваивает атрибуты (необходимо указать fillable в модели). Hash::make хеширует пароль. Возвращается JSON-ответ.
Расширенные примеры с кодом и результатами
Пример 1: PDO с транзакцией и проверкой уникальности
try {
$pdo->beginTransaction();
// Проверка на дубликат email
$stmtCheck = $pdo->prepare('SELECT COUNT(*) FROM users WHERE email = :email');
$stmtCheck->execute(['email' => $_POST['email']]);
if ($stmtCheck->fetchColumn() > 0) {
throw new Exception('Email уже зарегистрирован');
}
// Вставка
$stmtInsert = $pdo->prepare('INSERT INTO users (username, email, password) VALUES (:username, :email, :password)');
$stmtInsert->execute([
'username' => $_POST['username'],
'email' => $_POST['email'],
'password' => password_hash($_POST['password'], PASSWORD_DEFAULT),
]);
$pdo->commit();
echo 'Пользователь создан';
} catch (Exception $e) {
$pdo->rollBack();
echo 'Ошибка: ' . $e->getMessage();
}
Вывод при успехе: "Пользователь создан" Вывод при дубликате: "Ошибка: Email уже зарегистрирован"
Пример 2: MySQLi с использованием хранимой процедуры
$mysqli = new mysqli('localhost', 'root', '', 'test');
// Предполагается, что хранимая процедура sp_create_user уже создана
$stmt = $mysqli->prepare('CALL sp_create_user(?, ?, ?)');
$stmt->bind_param('sss', $username, $email, $hashedPassword);
$username = $_POST['username'];
$email = $_POST['email'];
$hashedPassword = password_hash($_POST['password'], PASSWORD_DEFAULT);
if ($stmt->execute()) {
$result = $stmt->get_result();
$row = $result->fetch_assoc();
echo 'Пользователь создан, ID: ' . $row['id'];
} else {
echo 'Ошибка: ' . $stmt->error;
}
Вывод: "Пользователь создан, ID: 42"
Пример 3: Laravel регистрация с AJAX-запросом и валидацией
// routes/api.php
Route::post('/register', 'AuthController@register');
// AuthController
public function register(Request $request) {
$validator = Validator::make($request->all(), [
'name' => 'required|string|max:255',
'email' => 'required|string|email|max:255|unique:users',
'password' => 'required|string|min:8',
]);
if ($validator->fails()) {
return response()->json(['errors' => $validator->errors()], 422);
}
$user = User::create([
'name' => $request->name,
'email' => $request->email,
'password' => Hash::make($request->password),
]);
return response()->json(['message' => 'Пользователь создан', 'user' => $user], 201);
}
// Пример JavaScript (фрагмент)
/*
fetch('/api/register', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({name: 'Ivan', email: 'ivan@example.com', password: 'secret123'})
}).then(response => response.json()).then(data => console.log(data));
*/
Ответ JSON при успехе:
{"message":"Пользователь создан","user":{"id":1,"name":"Ivan","email":"ivan@example.com"}}
При ошибке валидации:
{"errors":{"email":["The email has already been taken."]}}