Refactor error handling in file upload process to improve logging and provide specific error codes

This commit is contained in:
Fabian Schieder 2026-01-25 23:02:40 +01:00
parent 2338e22447
commit 60cc9322cf

View File

@ -31,7 +31,8 @@ $file = $_FILES['uploadFile'];
$fileError = isset($file['error']) ? (int)$file['error'] : UPLOAD_ERR_NO_FILE;
if ($fileError !== UPLOAD_ERR_OK)
{
header('Location: account.php?upload=err');
error_log('Upload: PHP upload error=' . $fileError);
header('Location: account.php?upload=err&code=php_' . $fileError);
exit();
}
@ -39,7 +40,8 @@ if ($fileError !== UPLOAD_ERR_OK)
$tmp = isset($file['tmp_name']) ? (string)$file['tmp_name'] : '';
if ($tmp === '' || !is_uploaded_file($tmp))
{
header('Location: account.php?upload=err');
error_log('Upload: tmp invalid. tmp=' . $tmp);
header('Location: account.php?upload=err&code=tmp');
exit();
}
@ -54,31 +56,44 @@ $mime = $finfo->file($tmp);
if (!$mime || !isset($allowedMimeToExt[$mime]))
{
header('Location: account.php?upload=err');
error_log('Upload: invalid mime=' . (string)$mime);
header('Location: account.php?upload=err&code=mime');
exit();
}
$ext = $allowedMimeToExt[$mime];
// Wichtig: Auf Linux ist ein Pfad mit führendem "/" ein Pfad ab Dateisystem-Root.
// Für move_uploaded_file() brauchen wir einen Dateisystempfad; die Public-URL ist separat.
// Zielordner: assets/images/profilePictures relativ zum Projekt (upload.php liegt im Webroot)
$relativeTargetDir = 'assets/images/profilePictures';
// Kandidat 1: relativ zu __DIR__ (robust gegen VHost/Alias)
$dirTargetDir = rtrim(__DIR__, "\\/") . DIRECTORY_SEPARATOR . str_replace('/', DIRECTORY_SEPARATOR, $relativeTargetDir);
// Kandidat 2: relativ zu DOCUMENT_ROOT (nur wenn gesetzt)
$documentRoot = isset($_SERVER['DOCUMENT_ROOT']) ? (string)$_SERVER['DOCUMENT_ROOT'] : '';
$webRoot = rtrim($documentRoot, "\\/");
$docRootTrim = rtrim($documentRoot, "\\/");
$docTargetDir = ($docRootTrim !== '')
? $docRootTrim . DIRECTORY_SEPARATOR . str_replace('/', DIRECTORY_SEPARATOR, $relativeTargetDir)
: '';
// Wichtig: relativer Zielpfad MUSS mit '/' beginnen, sonst entsteht z.B. "Websiteassets/...".
$relativeTargetDir = '/assets/images/profilePictures';
// Bevorzugt __DIR__. Falls __DIR__ aus irgendeinem Grund nicht ins Projekt zeigt, und DOCUMENT_ROOT plausibel ist, nutze DOCUMENT_ROOT.
$targetDir = $dirTargetDir;
if ($docTargetDir !== '' && !is_dir($dirTargetDir) && is_dir($docTargetDir))
{
$targetDir = $docTargetDir;
}
$targetDir = $webRoot !== ''
? $webRoot . $relativeTargetDir
: rtrim(__DIR__, "\\/") . $relativeTargetDir;
error_log('Upload: resolved targetDir=' . $targetDir . ' (DOCUMENT_ROOT=' . $documentRoot . ', __DIR__=' . __DIR__ . ')');
if (!is_dir($targetDir))
{
$mkOk = @mkdir($targetDir, 0755, true);
if (!$mkOk)
{
error_log('Upload: mkdir failed for ' . $targetDir);
header('Location: account.php?upload=err');
$lastErr = error_get_last();
$lastErrMsg = (is_array($lastErr) && isset($lastErr['message'])) ? (string)$lastErr['message'] : 'unknown';
error_log('Upload: mkdir failed for ' . $targetDir . ' - ' . $lastErrMsg);
header('Location: account.php?upload=err&code=mkdir');
exit();
}
}
@ -86,7 +101,7 @@ if (!is_dir($targetDir))
if (!is_writable($targetDir))
{
error_log('Upload: targetDir not writable: ' . $targetDir);
header('Location: account.php?upload=err');
header('Location: account.php?upload=err&code=perm');
exit();
}