Luminova Framework

PHP Luminova: HTTP Uploaded File Object

Last updated: 2025-12-30 08:28:45

Represents an HTTP uploaded file, allowing validation, configuration, and modification of file properties before uploading to the server.

The Luminova File Uploaded Object represents an incoming file prepared for upload to the server. It provides detailed information about the file and allows customization before passing it to the local uploader handler (Luminova\Storage\Uploader) or the remote storage handler (Luminova\Storage\Storage) for final processing.

This class supports files uploaded either as raw binary blobs or as native PHP temporary files. It allows you to define structured validation rules such as:

  • Supported file formats
  • Maximum and minimum allowed sizes
  • Behavior when a file with the same name already exists
  • Optional filename changes
  • Creation of symbolic links (symlinks) for files stored in private directories

The uploaded file object class is optimized for easy integration with the local uploader handler (Luminova\Storage\Uploader), which efficiently handles both small and large file uploads. When passed to the uploader, detailed upload progress messages are provided, and all configured rules are automatically applied.


Examples

Accessing File Object

When a file is uploaded, the Luminova HTTP Request object (Luminova\Http\Request) automatically includes all details about the current request, including any uploaded files.

Accessing Files in Controller Classes:

// app/Controllers/Http/UploadController.php
namespace App\Controllers\Http;

use Generator;
use Luminova\Base\Controller;
use Luminova\Attributes\Route;
use Luminova\Attributes\Prefix;

#[Prefix('/api/(:root)')]
class UploadController extends Controller 
{
    #[Route('/api/upload', methods: ['POST'])]
    public function doUpload(): int 
    {
        $files = $this->request->getFile('image');

        // Handle multiple files
        if ($files instanceof Generator) {
            foreach ($files as $file) {
                // Process each uploaded file
            }

            return STATUS_SUCCESS;
        }

        // Handle a single uploaded file
        return STATUS_SUCCESS;
    }
}

Notes:

  • Use $this->request->getFile('field_name') to access uploaded files.
  • If multiple files are uploaded using the same field name, a Generator is returned.
  • For single file uploads, a single File object is returned.

Upload Configuration:

Setting upload configurations for the file object

use Luminova\Http\Request;

// HTTP Request object
$request = new Request();

// Get file object from HTTP request object
$file = $request->getFile('image');

// Set various upload configurations
$file->setConfig([
    'upload_path'   => root('writeable/storages/uploads/'),
    'max_size'      => 10485760,
    'min_size'      => 1024,
    'allowed_types' => 'png|jpg|gif|pdf',
    'chunk_length'  => 5242880,
    'if_existed'    => File::IF_EXIST_RETAIN,
    'symlink'       => '/public/assets/symlink',
]);

// Validate the file before proceeding with upload
if ($file->validate()->isError()) {
    throw new InvalidException(sprintf(
        'File validation failed: (%d) %s.',
        $file->getError(),
        $file->getMessage()
    ));

} 

echo 'File is valid for upload';

Explanation:

  1. upload_path: Specifies the writeable/storages/uploads/ as the path where the file will be saved on the server.
  2. max_size: Defines the maximum allowable file size. In this example, 10MB is the maximum size.
  3. min_size: Sets the minimum allowable size for the file, such as 1KB in the example.
  4. allowed_types: Restricts file types to specific extensions (png, jpg, gif, pdf).
  5. chunk_length: Enables chunked file uploads, useful for large files (5MB chunks in this case).
  6. if_existed: Rule to determines how to handle existing files (e.g, File::IF_EXIST_RETAIN) retains old versions of files.
  7. symlink: Creates a symlink in the specified path /public/assets/symlink once the upload completes.

Handling Binary Uploads

When a client-side library sends your image as raw binary data (BLOB), you may see:

  • $file->extension returns "bin" instead of "png".
  • $file->type (or $file->getMime()) returns "application/octet-stream" instead of "image/png".

Uploading it without proper handling will result in your file being stored as file-name.bin.Below is the recommended workflow to detect and correct the real extension and MIME type before saving the file.


1. Extend Custom MIME and Extensions

Luminova ships with a built-in MIME database that covers common file types.You only need to extend it when handling custom or vendor-specific uploads.

Custom MIME definitions can be registered during application class or inside an upload controller (for example, in an onCreate() method).

use Luminova\Utility\MIME;

// Load a custom MIME database from a JSON file
MIME::database('/writable/custom/mime.json');

// Load from a plain text MIME list
MIME::database('/writable/custom/mime.txt');

// Load from a PHP file that returns an array
MIME::database('/writable/custom/mime.php');

// Load a compiled MIME magic database (.mgc) for binary detection
MIME::database('/writable/custom/mime.mgc');

// Register a MIME type manually
MIME::register('custom', 'application/custom-type');

Note:The MIME module already includes standard file types.Only register additional mappings when the default list does not cover your use case.


2. Temporarily Allow BIN Extension

When handling raw or BLOB-based uploads, files may initially be detected as generic binary data.To avoid early rejection, allow the .bin extension during the first validation phase.

// Get the uploaded file from the HTTP request
$file = $request->getFile('file');

$file->setConfig([
    'allowed_types' => 'png|jpg|gif|bin',
    // other upload options...
]);

Why this matters:The .bin extension acts as a safe placeholder until the file’s real MIME type is detected and mapped.Once detection completes, Luminova resolves the correct extension based on the MIME database.


3. Post-Process and Correct the Extension

Once the file is received, raw binary files (with .bin) need proper extension assignment.Use Luminova's MIME detector to determine the correct MIME type and map it to the appropriate extension.

use Luminova\Http\MIME;

// If the uploaded file has a '.bin' extension
if ($file->getExtension() === 'bin') {
    // 1) Detect the actual MIME type from the temp file or raw data
    $mime = $file->getMimeFromFile() 
        ?? $file->getMime() 
        ?? '';

    // 2) Find the correct extension for the detected MIME
    $ext = MIME::findExtension($mime);

    // 3) Build a new filename (preserve original name without '.bin')
    $filename = rtrim($file->getName(), '.bin');

    // Optionally, generate a completely new name
    // $filename = uniqid('file_');

    // 4) Update the file name and extension
    $file->setName("{$filename}.{$ext}", true);
}

This step ensures uploaded binary blobs are properly recognized and stored with the correct extension, preventing issues with downstream processing or client downloads.


4. Validate and Upload

After correcting the file extension, run your standard validation and upload workflow.

use Luminova\Storage\Uploader;
use Luminova\Exceptions\InvalidException;

// Validate the file
if (!$file->valid()) {
    throw new InvalidException(sprintf(
        'File validation failed: (%d) %s.',
        $file->getError(),
        $file->getMessage()
    ));
}

// Perform the upload
$status = Uploader::upload($file);

// Uploading using moveTo
// $file->moveTo('target')

// Using chunked uploads
// $status = Uploader::chunk($file, null, $chunkIndex, $totalChunks);

// Output final status or message
echo $file->getMessage();

Notes:

  • Validation ensures size, type, and other restrictions are enforced.
  • Luminova's Uploader class handles both standard and chunked uploads.
  • $file->getMessage() provides human-readable feedback for logging or display.

Class Definition


Constants

Custom Upload Error Codes

These constant define additional custom error code.

ConstantTypeValueDescription
UPLOAD_ERR_NO_SIZEint9Custom upload error: file has no size.
UPLOAD_ERR_MIN_SIZEint10Custom upload error: file is below the minimum allowed size.
UPLOAD_ERR_NO_FILE_DATAint11Upload error no temp file or data.
UPLOAD_ERR_SKIPPEDint12Upload error no skip existing file.

Existing File handling Rules

These constant are available rules for handling existing files.

ConstantTypeValueDescription
IF_EXIST_RETAINstringretainKeep the existing file and save the new one with a random prefix.
IF_EXIST_OVERWRITEstringoverwriteOverwrite the existing file if it already exists.
IF_EXIST_RENAMEstringrenameRename the existing file with a random prefix and save the new one.
IF_EXIST_SKIPstringskipSkip the upload if the file already exists.

Properties

index

Represents a single uploaded file, with magic property access for its metadata.

Zero-based index when multiple files are uploaded.

protected int $index = 0;

name

The original filename (basename).

protected ?string $name = null;

type

The MIME type reported by the client (e.g., "image/jpeg").

protected ?string $type = null,

size

The file size in bytes.

protected int $size = 0,

extension

The file extension (derived from name or MIME).

protected ?string $extension = null,

temp

The temporary filesystem path, if available (e.g, temp_name).

protected ?string $temp = null,

error

protected int $error = UPLOAD_ERR_NO_FILE,

content

Raw binary file contents (for blob/chunked uploads).

protected Psr\Http\Message\StreamInterface|string|null $content


isBlob

True if uploaded as raw binary/blob or via chunking.

protected bool $isBlob = false

message

A validation or error message, if any.

protected ?string $message = null

Accessing file instance properties via $file->propertyName:

echo $file->name;       // e.g. "photo.jpg"
echo $file->type;       // e.g. "image/jpeg"
echo $file->mime;       // e.g. "image/png" (after detect)
echo $file->size;       // e.g. 204800
echo $file->extension;  // e.g. "jpg"
echo $file->temp;       // e.g. "/tmp/phpYzdqkD"
echo $file->error;      // e.g. UPLOAD_ERR_OK (0)
echo $file->message;    // e.g. "File size exceeds limit."
echo $file->content;    // e.g. binary data as string
echo $file->index;      // e.g. 0
echo $file->isBlob;    // true|false

Methods

constructor

Constructs a File object for handling uploaded file data.

public __construct(
    int $index = 0,
    ?string $name = null,
    ?string $type = null,
    int $size = 0,
    ?string $extension = null,
    ?string $temp = null,
    int $error = UPLOAD_ERR_NO_FILE,
    \Psr\Http\Message\StreamInterface|string|null $content = null,
    bool $isBlob = false
)

Parameters:

ParameterTypeDescription
$indexintThe index of the file in the uploaded file array, typically representing the position in a multi-file upload scenario.
$namestring|nullThe original name of the uploaded file. This includes the file name and its extension (e.g., document.pdf).
$typestring|nullThe MIME type of the file (e.g., image/jpeg, application/pdf). This is used to identify the type of file uploaded for further processing or validation.
$sizeintThe size of the uploaded file in bytes. This value is essential for checking file size limits and ensuring compliance with upload restrictions.
$extensionstring|nullThe file extension (e.g., jpg, png, pdf). This allows quick identification of the file type based on its extension and can be used for validation or categorization.
$tempstring|nullThe temporary file path where the uploaded file is stored on the server. This is the location from which the file can be moved or processed.
$errorintThe error code associated with the file upload (e.g, UPLOAD_ERR_OK, UPLOAD_ERR_INI_SIZE).
$contentStreamInterface|string|nullThe file's content in string format, typically used when the file data is stored directly in memory as an alternative to using the temp.
$isBlobboolIndicates whether the uploaded file is handled as a binary large object (BLOB), which is commonly used for in-memory file storage (default: false).

Throws:

Examples:

Create a new uploaded file object.

From a standard PHP upload:

$file = new File(
    index:    0,
    name:     $_FILES['photo']['name'],
    type:     $_FILES['photo']['type'],
    size:     $_FILES['photo']['size'],
    extension: pathinfo($_FILES['photo']['name'], PATHINFO_EXTENSION),
    temp:     $_FILES['photo']['tmp_name'],
    error:    $_FILES['photo']['error'],
    content:  null,
    isBlob:  false
);

From raw binary (BLOB) data:

$binaryData = file_get_contents('php://input');
$file = new File(
    index:     0,
    name:      'upload.bin',
    type:      'application/octet-stream',
    size:      strlen($binaryData),
    extension: 'bin',
    temp:      null,
    error:     UPLOAD_ERR_OK,
    content:   $binaryData,
    isBlob:   true
);

getIndex

Gets the index of the file.

public getIndex(): int

Return Value:

int - Return the index of the file.


getName

Gets the name of the file.

public getName(): ?string

Return Value:

string|null - Return the name of the file.


getType

Gets the MIME type of the file.

public getType(): ?string

Return Value:

string|null - Return the MIME type of the file.


getMime

Gets the MIME type of the file.

Alias: getType.

public getMime(): ?string

Return Value:

string|null - Return the MIME type of the file.


getClientFilename

Retrieve the filename sent by the client.

Alias: getName.

public getClientFilename(): ?string

Return Value:

string|null - Returns filename sent by the client or null if none was provided.


getClientMediaType

Retrieve the media type sent by the client.

Alias: getType.

public getClientMediaType(): ?string

Return Value:

string|null - Returns media type sent by the client or null if none was provided.


getStream

Retrieve the media type sent by the client.

Alias: getType.

public getStream(): StreamInterface

Return Value:

Psr\Http\Message\StreamInterface - Returns stream representation of the uploaded file.

Throws:

Note:If the moveTo() method or Uploader methods has been called previously, this method will throw an exception.


getMimeFromFile

Detect and cache the MIME type from a temporary file or raw binary content.

This method will:

  1. If a temp file path ($file->temp) is set, use it for detection.
  2. Otherwise, fall back to raw binary data ($file->content).
  3. Cache the result in $file->mime and return it.
public getMimeFromFile(): ?string

Return Value:

string|null - Return the detected MIME type (e.g., image/png), or null if no source is available or detection fails.

Useful for cases where the file is uploaded as (BLOB), typically,the MIME type may default to application/octet-stream.


getSize

Gets the size of the file in bytes.

public getSize(): int

Return Value:

int - Return the size of the file in bytes.


getExtension

Gets the file extension.

public getExtension(): ?string

Return Value:

string|null - Return the file extension.


getTemp

Gets the temporary file path.

public getTemp(): ?string

Return Value:

string|null - Return the temporary file path.


getError

Gets the error code of the file upload.

public getError(): int

Return Value:

int - Return the error code of the file upload.


getMessage

Gets the validation message.

public getMessage(): ?string

Return Value:

string|null - Return the validation message.


getConfig

Gets the file upload configurations.

The returned configuration object may contain the following properties:

  • uploadPath (string|null): The target path where uploaded files will be saved.
  • maxSize (int|null): Maximum allowed file size in bytes.
  • minSize (int|null): Minimum allowed file size in bytes.
  • allowedTypes (array|string|null): List of permitted file extensions.
  • chunkLength (int|null): Length of each file chunk in bytes (used for chunked uploads).
  • ifExisted (string): Strategy to apply if the file already exists (e.g., overwrite, retain, rename, skip).
  • symlink (string|null): Path to create a symbolic link of the uploaded file.
  • base64Strict (bool): Whether to enforce strict Base64 decoding for Base64-encoded uploads.
  • data (mixed|null): Additional custom configuration information.
public getConfig(): Luminova\Http\UploadConfig

Return Value:

Luminova\Http\UploadConfig - Returns the instance of upload configuration.

Note:The property value maybe be null if not configured.


setName

Sets the file name, with an option to replace its extension.

public setName(string $name, bool $replaceExtension = true): self

Parameters:

ParameterTypeDescription
$namestringThe desired name of the file, without directory paths.
$replaceExtensionbool(optional) If true, updates the file extension based on the provided name (default: true).

Return Value:

self - Returns the current file instance.

Throws:


setConfig

Configure file upload behavior and restrictions.

Applies upload rules such as size limits, allowed file types, storage location. The configurationcan be provided as a UploadConfig instance or an associative array.

public setConfig(Luminova\Http\UploadConfig|array<string,string|int> $config): self

Parameters:

ParameterTypeDescription
$configUploadConfig|array<string,string|int>Upload configuration options.

Return Value:

self - Returns the current file instance.

Options

The configurations will be used in validating file before uploading to server.

ConfigurationTypeDescription
upload_pathstringThe path where files will be uploaded.
max_sizeintMaximum allowed file size in bytes.
min_sizeintMinimum allowed file size in bytes.
allowed_typesstring|string[]A list or string of allowed file types, separated by a pipe symbol (e.g., png\|jpg\|gif).
chunk_lengthintWrite length of chunk in bytes. Default: 5242880.
if_existedstringDefines how to handle existing files (e.g., File::IF_EXIST_RENAME, File::IF_EXIST_*). Default: File::IF_EXIST_OVERWRITE.
symlinkstringA valid path to create a symlink after upload completion (e.g., /writeable/storages/, /public/assets/).
datamixedAdditional custom configuration data.
base64_strictboolIf true, base64_decode() will return false on invalid characters.

Throws:

Examples:

Using array Configuration:

$file->setConfig([
    'upload_path'    => '/writeable/uploads',
    'max_size'       => 5_000_000,
    'base64_strict'  => true,
]);

Using a UploadConfig object

use Luminova\Http\UploadConfig;

$config = UploadConfig::fromArray([
    'uploadPath'   => '/writeable/uploads',
    'maxSize'      => 5_000_000,
    'allowedTypes' => ['jpg', 'png'],
]);

$file->setConfig($config);
use Luminova\Http\UploadConfig;

$config = new UploadConfig(
    uploadPath:      '/writeable/uploads/',
    maxSize:         5_000_000,
    allowedTypes:    ['jpg', 'png'],
    base64Strict:    true
);

$file->setConfig($config);

moveTo

Move the uploaded file to a new location.

Commonly used by the Luminova\Storage\Uploader class to provide feedback on upload errors or processing issues.

public moveTo(string $targetPath): void 

Parameters:

ParameterTypeDescription
$targetPathstringThe descriptive error or feedback message.

Throws:


setMessage

Sets the file's error or feedback message and status code.

Commonly used by the Luminova\Storage\Uploader class to provide feedback on upload errors or processing issues.

public setMessage(string $message, int $code = UPLOAD_ERR_CANT_WRITE): self

Parameters:

ParameterTypeDescription
$messagestringThe descriptive error or feedback message.
$codeintThe status code (e.g., UPLOAD_ERR_* or File::UPLOAD_ERR_*) Defaults to UPLOAD_ERR_CANT_WRITE.

Return Value:

self - Returns the current file instance.


isStream

Checks if file content is stream.

public isStream(): bool

Return Value:

bool - Returns true if file is stream, false otherwise.


isUploaded

Checks if file was uploaded successfully.

public isUploaded(): bool

Return Value:

bool - Returns true if file was uploaded, false otherwise.


isBlob

Determines if the file is uploaded as a BLOB (Binary Large Object).

This method checks whether the file was uploaded as a BLOB,typically used for large file uploads or when the file's content is handled directly in binary form.

public isBlob(): bool

Return Value:

bool - Returns true if the file is a BLOB, otherwise false.


isBase64Encoded

Determines if the uploaded content string is likely to be Base64-encoded.

public isBase64Encoded(): bool

Return Value:

bool - Returns true if the content is likely to be Base64-encoded, false otherwise.

Example:

Setting base64 strict validation:

If true, base64_decode() will return false on invalid characters.

$file->setConfig([
    'base64_strict' => true
]);

isError

Checks if an error occurred during the file upload process.

public isError(): bool

Return Value:

bool - Returns true if an error occurred; false otherwise.


free

Clears all file-related data, resets configuration, and removes the temporary file if it exists.

This method is typically called after processing or canceling an upload to ensure no temporary resources are left behind and the file object is safely reset.

public free(): void

validate

Validates the uploaded file using configured rules such as file size, type, and upload status.

This method performs a full validation using valid() and returns the current file instance.Use isError() to determine if validation failed.

public validate(): self

Return Value:

self - Returns the current File instance.

Example:

Validate a file:

if ($file->validate()->isError()) {
    echo $file->getMessage(); // Error message
    echo $file->getCode(); // Error code
}

valid

Executes file validation checks against the defined configuration rules.

This method performs a comprehensive check to verify if the file aligns with custom configuration constraints.

  • Ensures upload completed without native PHP errors.
  • Checks for non-zero size and temporary file/content availability.
  • Validates against maximum/minimum file size constraints.
  • Verifies the file extension against allowed types (if defined).
public valid(): bool

Return Value:

bool - Returns true if the file passes all validations; otherwise false.

If a validation rule fails, an appropriate error code and message are set call $file->getMessage() for error or upload feedback message. And $file->getCode() or $file->getError() for upload error code.


toArray

Get array representation of uploaded file object.

This method creates an array from file-object properties into an associative array.

public toArray(): array

Return Value:

array<string, mixed> - Returns an array of file upload.