如何获取Webpack Encore生成的图片路径及PHPMailer邮件图片嵌入问题
Hey there! Let's tackle your embedded image path issue with PHPMailer in Symfony 4, especially since Webpack Encore is renaming your images with those random hashes like myimagename.65342324b5.jpg. I've dealt with this exact scenario before, so here's a step-by-step solution:
1. First: Grab the Hashed Image Path from Webpack Encore's Manifest
Webpack Encore generates a manifest.json file in your public/build directory after compiling assets. This file maps your original image filenames to their hashed production versions. We'll use this to get the correct path every time.
In your Symfony controller or mail service, read the manifest to fetch the hashed path:
// Get the full path to the manifest file $manifestPath = $this->getParameter('kernel.project_dir') . '/public/build/manifest.json'; // Make sure the manifest exists (run encore dev/production if not!) if (!file_exists($manifestPath)) { throw new \RuntimeException('Webpack manifest missing — did you run `yarn encore dev` or `production`?'); } // Parse the manifest into an array $manifest = json_decode(file_get_contents($manifestPath), true); // Define your original image path (relative to your assets directory, e.g., assets/images/myimagename.jpg) $originalImagePath = 'images/myimagename.jpg'; // Fetch the hashed path from the manifest (note the leading slash in the key) if (!isset($manifest["/$originalImagePath"])) { throw new \RuntimeException("Image $originalImagePath not found in the manifest — double-check your Encore config!"); } $hashedImageRelativePath = $manifest["/$originalImagePath"]; // Get the absolute local path to the image (for PHPMailer to read) $imageLocalPath = $this->getParameter('kernel.project_dir') . '/public/build' . $hashedImageRelativePath;
2. Embed the Image in PHPMailer Correctly
Now that you have the correct local path, use PHPMailer's AddEmbeddedImage() method to attach the image as an embedded resource, then reference it via a unique CID (Content ID) in your HTML email.
Here's a full working example:
use PHPMailer\PHPMailer\PHPMailer; use PHPMailer\PHPMailer\Exception; // ... (include the manifest code above here) // Initialize PHPMailer with your remote SMTP config $mail = new PHPMailer(true); try { // SMTP settings (match your remote environment's config!) $mail->isSMTP(); $mail->Host = 'your-smtp-host.example.com'; $mail->SMTPAuth = true; $mail->Username = 'your-smtp-username'; $mail->Password = 'your-smtp-password'; $mail->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS; // Use ENCRYPTION_STARTTLS if port 587 $mail->Port = 465; // Adjust to 587 if using STARTTLS // Set sender and recipient $mail->setFrom('your-email@example.com', 'Your Name'); $mail->addAddress('recipient@example.com', 'Recipient Name'); // Email content setup $mail->isHTML(true); $mail->Subject = 'Test Email with Embedded Image'; // Define a unique CID for your image (can be any string, just make it unique per email) $imageCid = 'my-embedded-image-123'; // Add the embedded image using the local path we fetched earlier $mail->AddEmbeddedImage($imageLocalPath, $imageCid, 'My Image.jpg'); // Reference the CID in your HTML $mail->Body = <<<HTML <p>Hi there,</p> <p>Check out this embedded image:</p> <img src="cid:$imageCid" alt="My Awesome Image" style="max-width: 100%;" /> HTML; $mail->AltBody = 'You need an HTML-enabled email client to view the image.'; // Send the email $mail->send(); echo 'Email sent successfully!'; } catch (Exception $e) { echo "Oops, something went wrong: {$mail->ErrorInfo}"; }
3. Key Notes to Avoid Headaches
- Always compile assets first: Make sure you run
yarn encore dev(for local) oryarn encore production(for remote) to generate the manifest and hashed files. If the manifest is missing, your code will throw an error. - File permissions: Ensure your remote server's PHP process has read access to the
public/builddirectory and the image files. - Remote SMTP troubleshooting: Since you had issues with Swift Mailer before, double-check that your remote environment allows outgoing SMTP connections on the port you're using (some hosts block port 465/587 by default). If PHPMailer throws connection errors, reach out to your hosting provider to confirm SMTP access.
内容的提问来源于stack exchange,提问作者R Lopez

