PHP sample projects
Last updated: Feb-03-2025
We've created a sample project to get you started with integrating Cloudinary into your PHP application.
Product Catalog app
The Product Catalog app provides a dynamic solution for managing a back office product catalog with rich media and metadata. It showcases a complete image and video workflow, from upload to delivery. Each product includes a name, metadata (SKU, price, and category), an AI-generated description, an image, and a video—all seamlessly integrated with Cloudinary for advanced media management.
Features
-
General functionality
- Add new products to the catalog.
- View all products stored in the database.
- Explore individual product details with comprehensive metadata, image, and video.
- Edit product details as needed.
-
Image workflow
- Client-side upload: Upload images directly from the client side using the Upload Widget, eliminating backend dependencies.
- AI-generated descriptions: Leverage Cloudinary’s AI Content Analysis to auto-generate captions for images.
- Metadata management: Save user-entered product information as metadata in Cloudinary for easy retrieval.
- Database integration: Store details including Cloudinary public IDs for streamlined delivery.
- Dynamic delivery: Generate URLs with on-the-fly transformations, including resizing, cropping, and overlays.
-
Video workflow
- Client-side upload: Upload videos directly from the client side using the Upload Widget, bypassing backend processes.
-
Asynchronous moderation: Ensure video compliance through AI-driven content moderation.
- Approved videos are rendered on the page when manually refreshed.
- Rejected videos are flagged with actionable feedback.
- Enhanced playback: Use Cloudinary's Video Player for seamless video rendering.
-
Optional:
- Webhook integration: Receive real-time notifications for moderation results.
- Live updates: Product pages auto-refresh to automatically display the latest approved videos.
This app serves as a robust starting point for building an e-commerce platform or any application requiring integrated image and video workflows.
See the Product Catalog app in Action
Code example: Image and video processing
Here's an excerpt from the code showing how to handle image and video processing after a client-side upload. It includes adding user-provided metadata and initiating automated video moderation.
<?php
require_once __DIR__ . '/../vendor/autoload.php';
require_once __DIR__ . '/../includes/database.php';
require_once __DIR__ . '/../includes/functions.php';
require_once __DIR__ . '/../config/cloudinary_config.php';
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$name = $_POST['name'];
$sku = $_POST['sku'];
$price = $_POST['price'];
$category = $_POST['category'];
// Get external ids for metadata fields.
$allFieldsResponse = $api->listMetadataFields();
$allFields = $allFieldsResponse['metadata_fields'] ?? [];
$externalIds=[];
checkAndAppendExternalId($allFields, "Description", $externalIds);
checkAndAppendExternalId($allFields, "SKU", $externalIds);
checkAndAppendExternalId($allFields, "Price", $externalIds);
checkAndAppendExternalId($allFields, "Category", $externalIds);
// Set up metadata entries for submission to Cloudinary
$metadata =
$externalIds['SKU'] . '=' . $sku . '|' .
$externalIds['Category'] . '=["' . $category . '"]|' .
$externalIds['Price'] . '=' . $price . '|' .
$externalIds['Description'] . '=' . $description;
// Handle image metadata updates
if (!empty($_POST['image_url'])) {
$product_image_url = $_POST['image_url']; // Retrieve the secure URL from the form submission
$image_public_id = $_POST['image_id']; // Retrieve the public ID from the form submission
// Update metadata
$cloudinary_result = $cld->uploadApi()->explicit($image_public_id, ["type"=>"upload","metadata" => $metadata]);
$image_caption = $cloudinary_result['info']['detection']['captioning']['data']['caption'] ?? null; // Save the image alt text from the response
} else {
// If there's no image, set values to null.
$product_image_url = null;
$image_public_id = null;
$image_caption = null;
}
// Handle video moderation and metadata
if (!empty($_POST['video_url'])) {
$product_video_url = $_POST['video_url'];
// Hold the video public ID temporarily until moderation status is confirmed.
$video_public_id_temp = $_POST['video_id'];
// Set metadata and mark the video for moderation.
$cloudinary_result = $cld->uploadApi()->explicit($video_public_id_temp, ['type' => 'upload', 'resource_type' => 'video', 'moderation' => 'aws_rek_video', "metadata" => $metadata]);
// Set initial values, pending moderation
$product_video_url = null;
$video_public_id = "pending";
$video_moderation_status="pending";
} else {
// Set values in case there's no video.
$product_video_url="invalid";
$video_public_id = "invalid";
$video_moderation_status=null;
$video_public_id_temp=null;
}
// Save the values in the database.
$product_id = saveProduct($pdo, $name, $product_image_url, $product_video_url, $image_public_id, $video_public_id, $video_moderation_status, $image_caption, $video_public_id_temp);
header("Location: products.php");
exit;
}
?>
Code example: Smart image cropping and overlay
Here's an excerpt showing smart cropping the image and adding an overlay:
if ($product['image_public_id']) {
// Create the image transformation to smart-crop the image to a square and overlay a watermark.
$image_url = $cld->image($product['image_public_id'])
->resize(
Resize::fill()
->width(500)
->height(500)
->gravity(Gravity::autoGravity())
)
->overlay(
Overlay::source(Source::image("cloudinary_logo1")->resize(Resize::scale()->width(50)))
->position(
(new Position())
->gravity(Gravity::compass(Compass::northEast()))
->offsetX(10)
->offsetY(10)
)
)
->toUrl();
}
Code example: Video rendering
Here's an excerpt rendering the approved video using Cloudinary's Video Player:
<!-- Display product video if available -->
<?php if ($product['video_public_id'] && $product['video_public_id']!='pending' && $product['video_public_id']!='invalid' && $product['video_moderation_status']!='rejected'): ?>
<div>
<video id="doc-player" controls muted class="cld-video-player cld-fluid"></video>
</div>
<script>
// Initialize the Cloudinary video player with a unique ID
const player = cloudinary.videoPlayer('doc-player', { cloudName: '<?php echo $_ENV['CLOUDINARY_CLOUD_NAME']; ?>' });
player.source('<?php echo $product['video_public_id']; ?>');
</script>
<?php elseif (isset($message)): ?>
<p><?php echo htmlspecialchars($message); ?></p>
<?php endif; ?>