Hi All,
I'm encountering an issue that seems straightforward but has proven challenging. I've implemented a system where details of all uploaded files and images are stored in a database, associated with a model. The files themselves are stored within a "writable" directory, specifically under "writable/uploads".
I am trying to create a helper function that allows images to be served to the browser upon request. However, I'm keen on maintaining the "writable" folder's location outside the publicly accessible "public" directory for security reasons.
The files download but do not open, it looks like they are corrupt. When I access these images directly from the "writable" directory (through a file manager or directly on the server), they open without any issues, below is my code:
PHP Code:
function get_file($file_id)
{
$filesModel = model('FilesModel');
$file = $filesModel->find($file_id); //$filesModel->where('file_name', $file_id)->first();
if (!is_null($file)) {
$file_name = $file->file_name;
$mime_type = $file->mime_type;
$parts = explode('_', $file_name);
$folder = count($parts) === 2 ? date('Ymd', $parts[0]) : null;
$file_path = is_null($folder) ? WRITEPATH . 'uploads/' . $file_name : WRITEPATH . 'uploads/' . $folder . '/' . $file_name;
if (!file_exists($file_path)) {
if (!file_exists(WRITEPATH . 'uploads/' . $file_name)) {
return null;
} else {
$file_path = WRITEPATH . 'uploads/' . $file_name;
}
}
header('Content-Type: ' . $mime_type);
//header('Content-Disposition: attachment; filename="' . $file->original_name . '"');
header('Content-Disposition: inline; filename="' . $file->file_name . '";');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
//header('Content-Length: ' . $file->file_size);
flush();
readfile($file_path);
exit();
}
return $file;
}
The $file_path is correct, but the image doest show, even if manage to force it to download, it does not open with any image program,
when I try to open the downloaded file on windows, I get the error saying the file formart is not supported.
when i comment out flush() and exit(), it outputs something like below to the browser:
Code:
����JFIF��;CREATOR: gd-jpeg v1.0 (using IJG JPEG v62), quality = 85 ��C !"$"$��C��?�"�� ���}!1AQa"q2���#B��R��$3br�
Below is my helper function for saving the uploaded image and appears to work as expected:
PHP Code:
function save_file($file, int $userId): array
{
$fileinfo = ['file_id' => 0]; // Default response
if ($file->isValid() && !$file->hasMoved()) {
$filepath = WRITEPATH . 'uploads/' . $file->store();
if (file_exists($filepath)) {
$fileinfo = [
'user_id' => $userId,
'caption' => $file->getClientName(),
'file_name' => $file->getName(),
'original_name' => $file->getClientName(),
'file_size' => $file->getSize(),
'mime_type' => $file->getClientMimeType(),
];
$filesModel = model('FilesModel');
if ($filesModel->save($fileinfo)) {
$fileinfo['file_id'] = $filesModel->getInsertID();
} else {
$fileinfo['file_id'] = 0;
log_message('error', 'Failed to save file information in database.');
}
}
}
return $fileinfo;
}
(03-23-2024, 11:30 AM)themban Wrote: Hi All,
I'm encountering an issue that seems straightforward but has proven challenging. I've implemented a system where details of all uploaded files and images are stored in a database, associated with a model. The files themselves are stored within a "writable" directory, specifically under "writable/uploads".
I am trying to create a helper function that allows images to be served to the browser upon request. However, I'm keen on maintaining the "writable" folder's location outside the publicly accessible "public" directory for security reasons.
The files download but do not open, it looks like they are corrupt. When I access these images directly from the "writable" directory (through a file manager or directly on the server), they open without any issues, below is my code:
PHP Code:
function get_file($file_id)
{
$filesModel = model('FilesModel');
$file = $filesModel->find($file_id); //$filesModel->where('file_name', $file_id)->first();
if (!is_null($file)) {
$file_name = $file->file_name;
$mime_type = $file->mime_type;
$parts = explode('_', $file_name);
$folder = count($parts) === 2 ? date('Ymd', $parts[0]) : null;
$file_path = is_null($folder) ? WRITEPATH . 'uploads/' . $file_name : WRITEPATH . 'uploads/' . $folder . '/' . $file_name;
if (!file_exists($file_path)) {
if (!file_exists(WRITEPATH . 'uploads/' . $file_name)) {
return null;
} else {
$file_path = WRITEPATH . 'uploads/' . $file_name;
}
}
header('Content-Type: ' . $mime_type);
//header('Content-Disposition: attachment; filename="' . $file->original_name . '"');
header('Content-Disposition: inline; filename="' . $file->file_name . '";');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
//header('Content-Length: ' . $file->file_size);
flush();
readfile($file_path);
exit();
}
return $file;
}
The $file_path is correct, but the image doest show, even if manage to force it to download, it does not open with any image program,
when I try to open the downloaded file on windows, I get the error saying the file formart is not supported.
when i comment out flush() and exit(), it outputs something like below to the browser:
Code:
����JFIF��;CREATOR: gd-jpeg v1.0 (using IJG JPEG v62), quality = 85 ��C !"$"$��C��?�"�� ���}!1AQa"q2���#B��R��$3br�
Below is my helper function for saving the uploaded image and appears to work as expected:
PHP Code:
function save_file($file, int $userId): array
{
$fileinfo = ['file_id' => 0]; // Default response
if ($file->isValid() && !$file->hasMoved()) {
$filepath = WRITEPATH . 'uploads/' . $file->store();
if (file_exists($filepath)) {
$fileinfo = [
'user_id' => $userId,
'caption' => $file->getClientName(),
'file_name' => $file->getName(),
'original_name' => $file->getClientName(),
'file_size' => $file->getSize(),
'mime_type' => $file->getClientMimeType(),
];
$filesModel = model('FilesModel');
if ($filesModel->save($fileinfo)) {
$fileinfo['file_id'] = $filesModel->getInsertID();
} else {
$fileinfo['file_id'] = 0;
log_message('error', 'Failed to save file information in database.');
}
}
}
return $fileinfo;
}
Oops, the problem was really basic, but gave me a headache

, The issue was caused by a whitespace before <?php