Загрузка данных
<?php
header('Content-Type: application/json; charset=utf-8');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type, Authorization');
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
http_response_code(204);
exit;
}
$host = 'web.edu';
$db = 'db_name';
$user = 'user';
$pass = 'password';
$charset = 'utf8mb4';
$dsn = "mysql:host=$host;dbname=$db;charset=$charset";
$options = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false,
];
try {
$pdo = new PDO($dsn, $user, $pass, $options);
} catch (\PDOException $e) {
http_response_code(500);
echo json_encode(['error' => 'Не удалось подключиться к базе данных']);
exit;
}
/* ---------- Вспомогательные функции ---------- */
function jsonResponse($data, int $code = 200): void {
http_response_code($code);
echo json_encode($data, JSON_UNESCAPED_UNICODE);
exit;
}
function requireAuth(): void {
$header = $_SERVER['HTTP_AUTHORIZATION']
?? $_SERVER['REDIRECT_HTTP_AUTHORIZATION']
?? '';
if (!preg_match('/Bearer\s+(\S+)/i', $header, $m)) {
jsonResponse(['error' => 'Требуется Bearer-токен'], 401);
}
if ($m[1] !== 'test-bearer-token-12345') {
jsonResponse(['error' => 'Невалидный токен'], 403);
}
}
function readJsonBody(): array {
$data = json_decode(file_get_contents('php://input'), true);
if (!is_array($data)) {
jsonResponse(['error' => 'Некорректный JSON в теле запроса'], 400);
}
return $data;
}
/**
* Валидация полей пользователя.
* $requireAll = true — создание (все поля обязательны),
* false — обновление (проверяются только переданные).
*/
function validateUserPayload(array $data, bool $requireAll): void {
$errors = [];
if ($requireAll || array_key_exists('name', $data)) {
if (!isset($data['name']) || !is_string($data['name']) || trim($data['name']) === '') {
$errors['name'] = 'Поле name обязательно и не может быть пустым';
} elseif (mb_strlen($data['name']) > 255) {
$errors['name'] = 'Длина name не должна превышать 255 символов';
}
}
if ($requireAll || array_key_exists('email', $data)) {
if (!isset($data['email']) || !is_string($data['email']) || trim($data['email']) === '') {
$errors['email'] = 'Поле email обязательно';
} elseif (!filter_var($data['email'], FILTER_VALIDATE_EMAIL)) {
$errors['email'] = 'Некорректный формат email';
}
}
if ($requireAll || array_key_exists('age', $data)) {
if (!isset($data['age']) || !is_int($data['age'])) {
$errors['age'] = 'Поле age обязательно и должно быть целым числом';
} elseif ($data['age'] < 0 || $data['age'] > 120) {
$errors['age'] = 'age должен быть в диапазоне 0..120';
}
}
if ($errors) {
jsonResponse(['error' => 'Ошибка валидации', 'fields' => $errors], 400);
}
}
function formatUser(array $row): array {
return [
'id' => (int)$row['idusers'],
'name' => $row['name'],
'email' => $row['email'],
'age' => (int)$row['age'],
'createdAt' => $row['created_at'],
'updatedAt' => $row['updated_at'],
];
}
function fetchUser(PDO $pdo, int $id): array {
$stmt = $pdo->prepare("SELECT * FROM users WHERE idusers = :id");
$stmt->execute([':id' => $id]);
$row = $stmt->fetch();
if (!$row) {
jsonResponse(['error' => 'Пользователь не найден'], 404);
}
return $row;
}
/* ---------- Маршрутизация ---------- */
// Поддержка: ?action=...&id=... и /users/{id}
$method = $_SERVER['REQUEST_METHOD'];
$action = $_GET['action'] ?? '';
// ID из query или из пути /users/{id}
$userId = null;
if (isset($_GET['id']) && ctype_digit((string)$_GET['id'])) {
$userId = (int)$_GET['id'];
} elseif (preg_match('#/users/(\d+)#', $_SERVER['REQUEST_URI'] ?? '', $m)) {
$userId = (int)$m[1];
}
// Определяем действие, если не задано явно
if ($action === '') {
$action = match (true) {
$method === 'POST' => 'create_user',
$method === 'GET' && $userId !== null => 'get_user',
$method === 'GET' => 'list_users',
$method === 'PUT' && $userId !== null => 'update_user',
$method === 'DELETE' && $userId !== null => 'delete_user',
default => '',
};
}
/* ---- 1. Создание пользователя ---- */
if ($action === 'create_user' && $method === 'POST') {
requireAuth();
$data = readJsonBody();
validateUserPayload($data, true);
try {
$stmt = $pdo->prepare(
"INSERT INTO users (name, email, age, created_at, updated_at)
VALUES (:name, :email, :age, NOW(), NOW())"
);
$stmt->execute([
':name' => $data['name'],
':email' => $data['email'],
':age' => $data['age'],
]);
$row = fetchUser($pdo, (int)$pdo->lastInsertId());
jsonResponse(formatUser($row), 201);
} catch (\PDOException $e) {
error_log('SQL error: ' . $e->getMessage());
jsonResponse(['error' => 'Ошибка при создании пользователя'], 500);
}
}
/* ---- 2. Список с пагинацией ---- */
if ($action === 'list_users' && $method === 'GET') {
requireAuth();
$page = max(1, (int)($_GET['page'] ?? 1));
$pageSize = min(100, max(1, (int)($_GET['pageSize'] ?? 10)));
try {
$total = (int)$pdo->query("SELECT COUNT(*) FROM users")->fetchColumn();
$stmt = $pdo->prepare(
"SELECT * FROM users ORDER BY idusers ASC LIMIT :limit OFFSET :offset"
);
$stmt->bindValue(':limit', $pageSize, PDO::PARAM_INT);
$stmt->bindValue(':offset', ($page - 1) * $pageSize, PDO::PARAM_INT);
$stmt->execute();
jsonResponse([
'page' => $page,
'pageSize' => $pageSize,
'total' => $total,
'items' => array_map('formatUser', $stmt->fetchAll()),
]);
} catch (\PDOException $e) {
error_log('SQL error: ' . $e->getMessage());
jsonResponse(['error' => 'Ошибка при получении списка'], 500);
}
}
/* ---- 3. Получение одного пользователя ---- */
if ($action === 'get_user' && $method === 'GET') {
requireAuth();
if ($userId === null) {
jsonResponse(['error' => 'Не указан id пользователя'], 400);
}
try {
jsonResponse(formatUser(fetchUser($pdo, $userId)));
} catch (\PDOException $e) {
error_log('SQL error: ' . $e->getMessage());
jsonResponse(['error' => 'Ошибка при получении пользователя'], 500);
}
}
/* ---- 4. Обновление пользователя ---- */
if ($action === 'update_user' && $method === 'PUT') {
requireAuth();
if ($userId === null) {
jsonResponse(['error' => 'Не указан id пользователя'], 400);
}
$data = readJsonBody();
validateUserPayload($data, false);
try {
$row = fetchUser($pdo, $userId);
$stmt = $pdo->prepare(
"UPDATE users
SET name = :name, email = :email, age = :age, updated_at = NOW()
WHERE idusers = :id"
);
$stmt->execute([
':name' => $data['name'] ?? $row['name'],
':email' => $data['email'] ?? $row['email'],
':age' => $data['age'] ?? (int)$row['age'],
':id' => $userId,
]);
jsonResponse(formatUser(fetchUser($pdo, $userId)));
} catch (\PDOException $e) {
error_log('SQL error: ' . $e->getMessage());
jsonResponse(['error' => 'Ошибка при обновлении пользователя'], 500);
}
}
/* ---- 5. Удаление пользователя ---- */
if ($action === 'delete_user' && $method === 'DELETE') {
requireAuth();
if ($userId === null) {
jsonResponse(['error' => 'Не указан id пользователя'], 400);
}
try {
fetchUser($pdo, $userId); // 404, если нет
$pdo->prepare("DELETE FROM users WHERE idusers = :id")
->execute([':id' => $userId]);
http_response_code(204);
exit;
} catch (\PDOException $e) {
error_log('SQL error: ' . $e->getMessage());
jsonResponse(['error' => 'Ошибка при удалении пользователя'], 500);
}
}
http_response_code(400);
echo json_encode(['error' => 'Некорректный запрос'], JSON_UNESCAPED_UNICODE);