PHP code example of tobento / service-upload

1. Go to this page and download the library: Download tobento/service-upload library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

tobento / service-upload example snippets


use Tobento\Service\Upload\Validator;
use Tobento\Service\Upload\ValidatorInterface;

$validator = new Validator\General(
    // Allowed file extensions:
    allowedExtensions: ['jpg', 'png', 'gif', 'webp'],

    // Restrict filenames to alphanumeric characters,
    // hyphens, underscores, spaces, and periods:
    strictFilenameCharacters: true, // default

    // Maximum allowed filename length:
    maxFilenameLength: 255, // default

    // Maximum file size in kilobytes (null = unlimited):
    maxFileSizeInKb: 2000,

    // Validate the client-provided media type against the
    // detected mime type (disabled by default):
    validateClientMediaType: true,

    // Validate that the uploaded file is not empty.
    // When enabled, files with size 0 or unknown size are rejected.
    validateNotEmpty: true,
);

var_dump($validator instanceof ValidatorInterface);
// bool(true)

use Psr\Http\Message\UploadedFileInterface;
use Tobento\Service\Upload\Exception\UploadedFileException;

try {
    $validator->validateUploadedFile(
        file: $uploadedFile, // UploadedFileInterface
    );
} catch (UploadedFileException $e) {
    // validation failed.
}

$filename = $uploadedFile->getClientFilename();

$extension = pathinfo($filename, PATHINFO_EXTENSION);
// is valid as verified

use Tobento\Service\Upload\FileStorageWriter;

$fileStorageWriter = new FileStorageWriter(
    filenames: FileStorageWriter::ALNUM,
    
    // or
    filenames: FileStorageWriter::RENAME,
    
    // or
    filenames: function (string $filename): string {
        // verify filename!
        return $verifiedFilename;
    },
);

use Tobento\Service\Upload\Exception\UploadedFileException;
use Tobento\Service\Upload\Validator;
use Tobento\Service\Upload\ValidatorInterface;

$validator = new Validator\Csv(
    allowedExtensions: ['csv'],
);

// Disable deep CSV content validation if needed returning a new instance:
$validator = $validator->withValidateCsvContent(false);

var_dump($validator instanceof ValidatorInterface);
// bool(true)

try {
    $validator->validateUploadedFile($uploadedFile);
} catch (UploadedFileException $e) {
    // CSV validation failed.
}

use Tobento\Service\Upload\Exception\UploadedFileException;
use Tobento\Service\Upload\Validator;
use Tobento\Service\Upload\ValidatorInterface;

$validator = new Validator\Ndjson(
    allowedExtensions: ['ndjson'],
);

var_dump($validator instanceof ValidatorInterface);
// bool(true)

try {
    $validator->validateUploadedFile($uploadedFile);
} catch (UploadedFileException $e) {
    // NDJSON validation failed.
}

use Tobento\Service\Upload\Exception\UploadedFileException;
use Tobento\Service\Upload\Validator;
use Tobento\Service\Upload\ValidatorInterface;

// All PDF security checks are enabled by default:
$validator = new Validator\Pdf(
    allowedExtensions: ['pdf'],
);

// Enable only specific checks (returns a new immutable instance):
$validator = $validator->withChecks(
    'encrypt',
    'js',
    'embedded',
    'launch',
    'openaction',
    'aa',
);

var_dump($validator instanceof ValidatorInterface);
// bool(true)

try {
    $validator->validateUploadedFile($uploadedFile);
} catch (UploadedFileException $e) {
    // PDF validation failed.
}

use enshrined\svgSanitize\Sanitizer;
use Tobento\Service\Upload\Exception\UploadedFileException;
use Tobento\Service\Upload\Validator;
use Tobento\Service\Upload\ValidatorInterface;

// Create a custom sanitizer (optional)
$sanitizer = new Sanitizer();
$sanitizer->removeXMLTag(true);
$sanitizer->removeRemoteReferences(true);
// $sanitizer->minify(true); // optional

$validator = new Validator\Svg(
    allowedExtensions: ['svg'],

    // You may pass a custom sanitizer:
    sanitizer: $sanitizer, // default is: new Sanitizer()
);

var_dump($validator instanceof ValidatorInterface);
// bool(true)

try {
    $validator->validateUploadedFile($uploadedFile);
} catch (UploadedFileException $e) {
    // SVG validation failed.
    echo $e->getMessage();
}

use Tobento\Service\Upload\Exception\UploadedFileException;
use Tobento\Service\Upload\Validator;
use Tobento\Service\Upload\ValidatorInterface;

$validator = new Validator\Zip(
    allowedExtensions: ['zip'],
);

// Configure optional ZIP-specific limits returning a new instance:
$validator = $validator
    ->withMaxEntries(1000) // Maximum number of files inside the ZIP (default: 2000)
    ->withMaxTotalUncompressedBytes(10_000) // Total uncompressed size limit (default: 50_000_000 (50 MB))
    ->withMaxCompressionRatio(20) // Prevent ZIP bombs (default: 200)
    ->withMaxDepth(1); // Maximum nested ZIP depth (default: 3)

var_dump($validator instanceof ValidatorInterface);
// bool(true)

try {
    $validator->validateUploadedFile($uploadedFile);
} catch (UploadedFileException $e) {
    // ZIP validation failed.
}

use Tobento\Service\Upload\Exception\UploadedFileException;
use Tobento\Service\Upload\Validator;
use Tobento\Service\Upload\ValidatorInterface;

$validator = new Validator\Combine(
    new Validator\Csv(allowedExtensions: ['csv']), // handles .csv
    new Validator\General(allowedExtensions: ['jpg', 'png']), // fallback for all other extensions
);

var_dump($validator instanceof ValidatorInterface);
// bool(true)

try {
    $validator->validateUploadedFile($uploadedFile);
} catch (UploadedFileException $e) {
    // no matching validator or validation failed
}

use Psr\Http\Client\ClientInterface;
use Psr\Http\Message\RequestFactoryInterface;
use Psr\Http\Message\StreamFactoryInterface;
use Psr\Http\Message\UploadedFileFactoryInterface as Psr17UploadedFileFactoryInterface;
use Tobento\Service\Upload\UploadedFileFactory;
use Tobento\Service\Upload\UploadedFileFactoryInterface;

$factory = new UploadedFileFactory(
    uploadedFileFactory: $uploadedFileFactory, // Psr17UploadedFileFactoryInterface
    streamFactory: $streamFactory, // StreamFactoryInterface
    client: $client, // ClientInterface (PSR-18)
    requestFactory: $requestFactory, // RequestFactoryInterface (PSR-17)
);

var_dump($factory instanceof UploadedFileFactoryInterface);
// bool(true)

use Psr\Http\Message\UploadedFileInterface;
use Tobento\Service\Upload\Exception\CreateUploadedFileException;

try {
    $uploadedFile = $factory->createFromRemoteUrl(
        url: 'https://example.com/image.jpg' // string
    );
    
    var_dump($uploadedFile instanceof UploadedFileInterface);
    // bool(true)
} catch (CreateUploadedFileException $e) {
    // creating uploaded file failed.
}

use Psr\Http\Message\UploadedFileInterface;
use Tobento\Service\Upload\Exception\CreateUploadedFileException;
use Tobento\Service\FileStorage\FileInterface;

try {
    $uploadedFile = $factory->createFromStorageFile(
        file: $file // FileInterface
    );
    
    var_dump($uploadedFile instanceof UploadedFileInterface);
    // bool(true)
} catch (CreateUploadedFileException $e) {
    // creating uploaded file failed.
}

use Tobento\Service\Upload\FileStorageWriter;
use Tobento\Service\Upload\FileStorageWriterInterface;
use Tobento\Service\Upload\Writer;
use Tobento\Service\Upload\ImageProcessor;
use Tobento\Service\FileStorage\StorageInterface;

$fileStorageWriter = new FileStorageWriter(
    // Define the file storage where to write the files to:
    storage: $storage, // StorageInterface
    
    // Define how filenames should be handled:
    filenames: FileStorageWriter::ALNUM, // RENAME, ALNUM, KEEP
    
    // Or using a closure for customized filenames:
    filenames: function (string $filename): string {
        // customize
        return $filename;
    },
    
    // Define how duplicates should be handled:
    duplicates: FileStorageWriter::RENAME, // RENAME, OVERWRITE, DENY
    
    // Define how folders should be handled:
    folders: FileStorageWriter::ALNUM, // or KEEP
    
    // Or using a closure for customized folders:
    folders: function (string $path): string {
        // customize
        return $path;
    },
    
    // Define the max folder depth limit:
    folderDepthLimit: 5,

    // Add writers handling specific file types:
    writers: [
        new Writer\Image(
            imageProcessor: new ImageProcessor(
                actions: [
                    'orientate' => [],
                    'resize' => ['width' => 2000],
                ],
            ),
        ),
        new Writer\SvgSanitizer(),
    ],
);

var_dump($fileStorageWriter instanceof FileStorageWriterInterface);
// bool(true)

use Psr\Http\Message\StreamInterface;
use Tobento\Service\Upload\Exception\WriteException;
use Tobento\Service\Upload\WriteResponseInterface;

$writeResponse = $fileStorageWriter->writeFromStream(
    stream: $stream, // StreamInterface
    filename: 'file.txt',
    folderPath: 'path/to', // or an empty string if no path at all
);

var_dump($writeResponse instanceof WriteResponseInterface);
// bool(true)

// throws WriteException if writing failed!

use Psr\Http\Message\UploadedFileInterface;
use Tobento\Service\Upload\Exception\WriteException;
use Tobento\Service\Upload\WriteResponseInterface;

$writeResponse = $fileStorageWriter->writeUploadedFile(
    file: $uploadedFile, // UploadedFileInterface
    folderPath: 'path/to', // or an empty string if no path at all
);

var_dump($writeResponse instanceof WriteResponseInterface);
// bool(true)

// throws WriteException if writing failed!

use Tobento\Service\Upload\Exception\WriteException;
use Tobento\Service\Upload\WriteResponseInterface;

$writeResponse = $fileStorageWriter->copyFile(
    path: 'foo/image.jpg', // existing file path inside the storage
    folderPath: 'path/to', // target folder, or an empty string for root
);

// Result: 'path/to/image.jpg'
// Note: copyFile() does NOT preserve the source folder structure.

var_dump($writeResponse instanceof WriteResponseInterface);
// bool(true)

// throws WriteException if copying failed!

use Psr\Http\Message\UploadedFileInterface;
use Tobento\Service\Upload\WriteResponseInterface;
use Tobento\Service\Message\MessagesInterface;

$writeResponse = $fileStorageWriter->writeUploadedFile(file: $uploadedFile, folderPath: '');

var_dump($writeResponse instanceof WriteResponseInterface);
// bool(true)

// Get the path (string) e.g. path/to/file.txt
$path = $writeResponse->path();

// Get the content (string|\Stringable):
$content = $writeResponse->content();

// Get the original filename (unmodified). Might come from client.
$originalFilename = $writeResponse->originalFilename();

// Get the messages:
$messages = $writeResponse->messages();
// MessagesInterface

use Psr\Http\Message\StreamInterface;
use Tobento\Service\Upload\Exception\WriteException;
use Tobento\Service\Upload\ImageProcessor;
use Tobento\Service\Upload\Writer;
use Tobento\Service\Upload\WriteResponseInterface;

$writer = new Writer\Image(
    imageProcessor: new ImageProcessor(
        actions: [
            'orientate' => [],
            'resize' => ['width' => 2000],
        ],
    ),
);

var_dump($writer instanceof Writer\WriterInterface);
// bool(true)

try {
    $response = $writer->write(
        path: 'path/file.svg',
        stream: $stream, // StreamInterface
        originalFilename: 'file.svg',
    );
    
    // $response is either:
    // - WriteResponseInterface (supported)
    // - null (not supported)
} catch (WriteException $e) {
    // handle the exception as needed
}

use Psr\Http\Message\StreamInterface;
use Tobento\Service\Upload\Exception\WriteException;
use Tobento\Service\Upload\Writer;
use Tobento\Service\Upload\WriteResponseInterface;

$writer = new Writer\SvgSanitizer(
    // Optional logger:
    //logger: $logger, // null|\Psr\Log\LoggerInterface
);

var_dump($writer instanceof Writer\WriterInterface);
// bool(true)

try {
    $response = $writer->write(
        path: 'path/file.svg',
        stream: $stream, // StreamInterface
        originalFilename: 'file.svg',
    );
    
    // $response is either:
    // - WriteResponseInterface (supported)
    // - null (not supported)
} catch (WriteException $e) {
    // handle the exception as needed
}

use Tobento\Service\Upload\CopyFileWrapper;

if ($inputFile instanceof CopyFileWrapper) {
    $writeResponse = $writer->copyFile(
        sourcePath: $inputFile->path(),
        folderPath: $folderPath,
    );
} else {
    $writeResponse = $writer->writeUploadedFile($inputFile, $folderPath);
}

use Tobento\Service\Upload\ImageProcessor;
use Tobento\Service\Upload\ImageProcessorInterface;
use Tobento\Service\Imager\Action;
use Tobento\Service\Imager\ActionFactoryInterface;

$imageProcessor = new ImageProcessor(
    // Define the imager actions to be processed:
    actions: [
        'orientate' => [],
        'resize' => ['width' => 300],
        new Action\Contrast(20),
    ],
    
    // Allowed actions (only these may be executed).
    // If empty, all actions are allowed unless listed in disallowedActions.    
    allowedActions: [
        Action\Greyscale::class,
    ],
    
    // Disallowed actions (these will be skipped):
    disallowedActions: [
        Action\Colorize::class,
    ],
    
    // Convert certain image types (e.g. PNG → JPEG):
    convert: ['image/png' => 'image/jpeg'],
    
    // Adjust image quality:
    quality: ['image/jpeg' => 90, 'image/webp' => 90],
    
    // Supported mime types:
    supportedMimeTypes: ['image/png', 'image/jpeg', 'image/gif'], // default
    
    // Custom action factory:
    //actionFactory: $customActionFactory, // ActionFactoryInterface
    
    // Optional logger:
    //logger: $logger, // null|\Psr\Log\LoggerInterface
);

var_dump($imageProcessor instanceof ImageProcessorInterface);
// bool(true)

// Use the following methods to modify the image processor returning a new instance:
$imageProcessor = $imageProcessor->withActions([
    'resize' => ['width' => 300],
]);

$imageProcessor = $imageProcessor->withConvert([
    'image/png' => 'image/jpeg',
]);

$imageProcessor = $imageProcessor->withQuality([
    'image/jpeg' => 90,
    'image/webp' => 90,
]);

use Tobento\Service\Upload\Exception\ImageProcessException;
use Tobento\Service\Imager\ResourceInterface;
use Tobento\Service\Imager\Response\Encoded;

$encoded = $imageProcessor->processFromResource(
    resource: $resource, // ResourceInterface
);

var_dump($encoded instanceof Encoded);
// bool(true)

// throws ImageProcessException if image cannot get processed!

use Psr\Http\Message\StreamInterface;
use Tobento\Service\Upload\Exception\ImageProcessException;
use Tobento\Service\Imager\Response\Encoded;

$encoded = $imageProcessor->processFromStream(
    stream: $stream, // StreamInterface
);

var_dump($encoded instanceof Encoded);
// bool(true)

// throws ImageProcessException if image cannot get processed!
text
../evil.txt
../../etc/passwd