I’m not very good in PHP and all server stuff, so I would appreciate any answers and advice.
I need to send JSON data and an image in one fetch to php script.
Following this question How can I serialize an input File object to JSON?, I made object from image, put it in fetch and tried to send this object in PHPMailer as an attachment, but I’ve got this error:
[Sun Jan 24 15:07:52 2021] 127.0.0.1:59260 [500]: POST /dist/php/mail.php - Uncaught Error: Object of class stdClass could not be converted to string in /home/joe/Documents/vscode-projects/html-projects/swipeskins/dist/vendor/phpmailer/phpmailer/src/PHPMailer.php:3005
So, my JavaScript code:
// firstly, declaration of variables let files, fileObject, newObject, myArray = []; // when user uploads image with input, code makes new src for <img> tag with this image form.onchange = (event) => { image.src = URL.createObjectURL(event.target.files[0]); image.onload = () => { // on load of image I give new values to variables, and make an object with info from an image files = document.querySelector('[type=file]').files; fileObject = files[0]; newObject = { 'lastModified' : fileObject.lastModified, 'lastModifiedDate' : fileObject.lastModifiedDate, 'name' : fileObject.name, 'size' : fileObject.size, 'type' : fileObject.type }; } } // And here's the fetch :) fetch(`${server}/dist/php/mail.php`, { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ 'preferences': purchase, // this is usual object 'jsonObject': newObject, // and this is an image object }) });
And here’s the mail.php code:
<?php use PHPMailerPHPMailerPHPMailer; use PHPMailerPHPMailerSMTP; use PHPMailerPHPMailerException; header('Access-Control-Allow-Origin: *'); header('Access-Control-Allow-Headers: *'); header('Access-Control-Allow-Methods: *'); header('Content-Type: application/json'); require_once "../vendor/autoload.php"; $data = json_decode(file_get_contents('php://input')); send_mail('pansfloyd@gmail.com', 'joe brock', $data); function send_mail($email, $name, $data) { $mail = new PHPMailer(true); $mail->SMTPDebug = 3; $mail->isSMTP(); $mail->Host = "smtp.gmail.com"; $mail->SMTPAuth = true; $mail->Username = "dealinmaivasha@gmail.com"; $mail->Password = "password"; //changed this :D $mail->SMTPSecure = "tls"; $mail->Port = 587; $mail->From = "dealinmaivasha@gmail.com"; $mail->FromName = "Dealin Maivasha"; $mail->addAddress($email, $name); $mail->isHTML(true); $mail->Subject = "Subject Text"; $mail->addAttachment($data->jsonObject); // SO, this is where I need to send image, and this line doesn't work at all $mail->Body = "Body"; $mail->AltBody = "This is the plain text version of the email content"; try { $mail->send(); echo "Message has been sent successfully"; } catch (Exception $e) { echo "Mailer Error: " . $mail->ErrorInfo; } }
So, the question is, how can I change line with addAttachment so it all would work?
Just in case, I tried to use console.log to see what is in newObject, here’s the result: result in console
As you see, I also got an error in console.
I also tried to use myArray variable in js like that:
myArray.push(newObject)
And then I tried to send myArray in fetch, but it didn’t work either.
I would be very grateful to any answers and recommendations!
Advertisement
Answer
Have a look at the source for the addAttachment
method of PHPMailer
. (Pasted to the end of this answer.)
You’re passing an object ($data-> jsonObject
) where the method expects a string corresponding to a file path.
The solution could take many forms – you’ve got to find some way to take the submitted data and save at least a temporary file to the server before sending it as an attachment via PHPMailer.
You’re already sending the rest of the data in a Content-type: application/json
format, but following some of the approaches in this answer which uses an enctype
of multipart/form-data
on the form could be one way.
Alternatively, you might convert the image’s data to base64 and POST it with the rest of your JSON data. Then, on the other side, decode & save to /tmp/{filename}.ext
and reference THAT as the first arg to $mail->addAttachment
.
/** * Add an attachment from a path on the filesystem. * Never use a user-supplied path to a file! * Returns false if the file could not be found or read. * Explicitly *does not* support passing URLs; PHPMailer is not an HTTP client. * If you need to do that, fetch the resource yourself and pass it in via a local file or string. * * @param string $path Path to the attachment * @param string $name Overrides the attachment name * @param string $encoding File encoding (see $Encoding) * @param string $type MIME type, e.g. `image/jpeg`; determined automatically from $path if not specified * @param string $disposition Disposition to use * * @throws Exception * * @return bool */ public function addAttachment( $path, $name = '', $encoding = self::ENCODING_BASE64, $type = '', $disposition = 'attachment' ) { ... }