文件
freeshop/avatar_upload.php
2026-08-16 17:03:10 +08:00

87 行
3.2 KiB
PHP

此文件含有模棱两可的 Unicode 字符
此文件含有可能会与其他字符混淆的 Unicode 字符。 如果您是想特意这样的,可以安全地忽略该警告。 使用 Escape 按钮显示他们。
<?php
require __DIR__ . '/includes/init.php';
header('Content-Type: application/json; charset=utf-8');
if (empty($_SESSION['user_id'])) {
http_response_code(401);
echo json_encode(['ok' => false, 'msg' => '请先登录']);
exit;
}
$user = currentUser();
if (!$user) {
http_response_code(401);
echo json_encode(['ok' => false, 'msg' => '登录已过期']);
exit;
}
if (!isset($_FILES['avatar']) || !is_array($_FILES['avatar']) || $_FILES['avatar']['error'] !== UPLOAD_ERR_OK) {
$errMap = [
UPLOAD_ERR_INI_SIZE => '文件超过服务器限制(php.ini 中 upload_max_filesize',
UPLOAD_ERR_FORM_SIZE => '文件超过表单限制',
UPLOAD_ERR_PARTIAL => '文件上传不完整',
UPLOAD_ERR_NO_FILE => '未选择文件',
UPLOAD_ERR_NO_TMP_DIR => '服务器临时目录不存在',
UPLOAD_ERR_CANT_WRITE => '服务器写入失败',
UPLOAD_ERR_EXTENSION => '文件类型被禁止',
];
$code = $_FILES['avatar']['error'] ?? UPLOAD_ERR_NO_FILE;
echo json_encode(['ok' => false, 'msg' => $errMap[$code] ?? '上传错误,请重试']);
exit;
}
$file = $_FILES['avatar'];
$v = validateUploadedImage($file, [
'allowed' => ['image/jpeg', 'image/png', 'image/webp', 'image/gif'],
'maxBytes' => 2 * 1024 * 1024,
'minDim' => 64,
]);
if (!$v['ok']) {
echo json_encode(['ok' => false, 'msg' => $v['error']]);
exit;
}
$ext = $v['ext'];
$uploadDir = __DIR__ . '/storage/uploads/avatars';
if (!is_dir($uploadDir)) {
if (!@mkdir($uploadDir, 0755, true) && !is_dir($uploadDir)) {
echo json_encode(['ok' => false, 'msg' => '服务器无法创建上传目录(请检查 storage/uploads 目录权限)']);
exit;
}
}
if (!is_writable($uploadDir)) {
echo json_encode(['ok' => false, 'msg' => '上传目录不可写(请给 storage/uploads/avatars 目录写入权限)']);
exit;
}
$fileName = $user['id'] . '_' . time() . '_' . bin2hex(random_bytes(4)) . '.' . $ext;
$filePath = $uploadDir . '/' . $fileName;
if (!reencodeImage($file['tmp_name'], $ext, $filePath)) {
echo json_encode(['ok' => false, 'msg' => '文件保存失败(请检查 storage/uploads/avatars 目录权限)']);
exit;
}
try {
$chk = db()->query("SHOW COLUMNS FROM " . tn('users') . " LIKE 'avatar'");
if ($chk && $chk->rowCount() === 0) {
db()->exec("ALTER TABLE " . tn('users') . " ADD COLUMN avatar VARCHAR(255) NULL DEFAULT NULL AFTER invited_by");
}
} catch (Throwable $e) {
}
$oldAvatar = $user['avatar'] ?? '';
if ($oldAvatar && strpos($oldAvatar, 'storage/uploads/avatars') !== false) {
$oldPath = __DIR__ . '/' . $oldAvatar;
if (file_exists($oldPath) && is_file($oldPath)) {
@unlink($oldPath);
}
}
$dbAvatar = 'storage/uploads/avatars/' . $fileName;
try {
db()->prepare('UPDATE ' . tn('users') . ' SET avatar=? WHERE id=?')
->execute([$dbAvatar, $user['id']]);
} catch (Throwable $e) {
echo json_encode(['ok' => false, 'msg' => '数据库更新失败:' . $e->getMessage()]);
exit;
}
unset($_SESSION['user_id'], $_SESSION['user']);
Logger::info('用户上传头像', ['user_id' => $user['id'], 'file' => $fileName]);
echo json_encode([
'ok' => true,
'msg' => '头像更新成功',
'data' => ['url' => $dbAvatar]
]);
exit;