cloudinary/cloudinary_php
Official Cloudinary PHP SDK for uploading and managing images/videos, applying transformations, optimizing delivery, and working with URLs and resources. Supports signed requests, authentication, and integration with Cloudinary’s API for media workflows.
Installation
composer require cloudinary/cloudinary_php
Register the service provider in config/app.php (Laravel 5.5+ auto-discovers).
Configuration
Add credentials to .env:
CLOUDINARY_CLOUD_NAME=your_cloud_name
CLOUDINARY_API_KEY=your_api_key
CLOUDINARY_API_SECRET=your_api_secret
Publish the config file:
php artisan vendor:publish --provider="Cloudinary\CloudinaryLaravel\CloudinaryServiceProvider"
Edit config/cloudinary.php for default settings (e.g., folder structure, transformations).
First Use Case Upload an image from a request:
use Cloudinary\Cloudinary;
use Cloudinary\Configuration\Configuration;
$cloudinary = new Cloudinary(new Configuration([
'cloud' => [
'cloud_name' => env('CLOUDINARY_CLOUD_NAME'),
'api_key' => env('CLOUDINARY_API_KEY'),
'api_secret' => env('CLOUDINARY_API_SECRET'),
],
]));
$result = $cloudinary->uploadApi()->upload(
fopen($_FILES['image']['tmp_name'], 'r'),
['folder' => 'user_uploads']
);
$result = $cloudinary->uploadApi()->upload(
fopen($_FILES['file']['tmp_name'], 'r'),
['folder' => 'uploads/' . auth()->id()]
);
$result = $cloudinary->uploadApi()->upload(
'https://example.com/image.jpg',
['folder' => 'remote_uploads']
);
$url = $cloudinary->url()->transformation([
'width' => 500,
'height' => 300,
'crop' => 'limit',
'gravity' => 'face'
])->generate('sample.jpg');
$url = $cloudinary->url()->transformation([
'effect' => 'sepia'
])->generate('private.jpg', ['expires' => time() + 3600]);
$cloudinary->deleteResourcesByTag('user_' . auth()->id());
// OR delete by public ID
$cloudinary->deleteResources(['public_id' => 'sample.jpg']);
$publicIds = ['image1.jpg', 'image2.jpg'];
$cloudinary->deleteResources($publicIds);
Create a custom Cloudinary adapter for Storage::disk():
// config/filesystems.php
'cloudinary' => [
'driver' => 'cloudinary',
'cloudinary' => [
'cloud_name' => env('CLOUDINARY_CLOUD_NAME'),
'api_key' => env('CLOUDINARY_API_KEY'),
'api_secret' => env('CLOUDINARY_API_SECRET'),
],
],
Then use it like any other disk:
Storage::disk('cloudinary')->put('folder/file.jpg', fopen('local.jpg', 'r'));
Use accessors/mutators in models:
class Product extends Model {
public function getImageUrlAttribute() {
return $this->image_id
? $this->cloudinary()->url()->generate($this->image_id)
: null;
}
public function setImageUrlAttribute($url) {
$result = $this->cloudinary()->uploadApi()->upload($url);
$this->image_id = $result['public_id'];
}
}
API Key/Secret Mismatch
Authentication failed errors..env and ensure no trailing spaces in credentials.Folder Permissions
['folder' => 'user_' . auth()->id() . '/uploads']
Transformation Errors
Invalid transformation or broken images.generate() method to test URLs before rendering.Rate Limiting
429 Too Many Requests.Private Assets
Route::get('/private/{id}', function ($id) {
$url = $this->cloudinary->url()->generate($id, ['expires' => time() + 300]);
return redirect()->to($url);
});
Default Folder
config/cloudinary.php:
'default_folder' => 'app_uploads',
Transformation Caching
$url = $cloudinary->url()->transformation([
'fetch_format' => 'auto',
'quality' => 'auto'
])->generate('image.jpg', ['c_name' => 'my_cache']);
Async Uploads
upload() method with async:
$result = $cloudinary->uploadApi()->upload($file, ['async' => true]);
Custom Upload Presets
$cloudinary->uploadApi()->upload($file, [
'upload_preset' => 'my_preset_name'
]);
Webhooks
// Example: Listen for upload notifications
$cloudinary->uploadApi()->upload($file, [
'notification_url' => route('cloudinary.webhook')
]);
Middleware for Transformations
public function handle($request, Closure $next) {
$response = $next($request);
$response->setContent(
str_replace(
'sample.jpg',
$this->cloudinary->url()->transformation(['width' => 800])->generate('sample.jpg'),
$response->getContent()
)
);
return $response;
}
Fallback for Local Storage
try {
$url = $cloudinary->url()->generate('image.jpg');
} catch (\Exception $e) {
$url = Storage::disk('local')->url('fallback/image.jpg');
}
Testing
.env.testing file with a dummy Cloudinary account or mock the client:
$cloudinary = Mockery::mock(Cloudinary::class);
$cloudinary->shouldReceive('url')->andReturnSelf();
$cloudinary->shouldReceive('generate')->andReturn('http://test.url/image.jpg');
How can I help you explore Laravel packages today?