zend-mail
zend-mail copied to clipboard
message cloning and headers
- [x] I was not able to find an open or closed issue matching what I'm seeing.
- [x] This is not a question. (Questions should be asked on chat (Signup here) or our forums.)
I have a service that has an injected default message. It has some default fields, such as encoding, from_name, from which are equal for any mail sent.
Internally it will create a clone from the default message and then it will add the actual rendered content, to subject. etc. It also adds Content-Type and an X-Header.
However at some point I noticed messages were having duplicate Content-Type and X-Header headers and some servers will deny those messages. Every time a message is sent and additional header is added. (this is a long running process)
Code to reproduce the issue
$defaultMessage = new \Zend\Mail\Message();
$defaultMessage->setFrom('[email protected]');
$message1 = clone $defaultMessage;
$message1->getHeaders()->addHeaderLine('X-Something', 1);
$message2 = clone $defaultMessage;
$message2->getHeaders()->addHeaderLine('X-Something', 2);
print $message1->toString();
print $message2->toString();
Expected results
Headers should be unique due to the clone of the default message
Date: Thu, 14 Jun 2018 08:53:20 +0000
From: [email protected]
X-Something: 1
Date: Thu, 14 Jun 2018 08:53:20 +0000
From: [email protected]
X-Something: 2
Actual results
Date: Thu, 14 Jun 2018 08:53:20 +0000
From: [email protected]
X-Something: 1
X-Something: 2
Date: Thu, 14 Jun 2018 08:53:20 +0000
From: [email protected]
X-Something: 1
X-Something: 2
I'm aware normally one should create a new Message for each Message you attempt to sent. I have changed my code to do this, but I still think this should simply work. I'm wondering why clone doesn't really clone...
ps. I'm on php72 and am using 2.10.0 of zend-mail (2.9 also had this)
i've added in my project wrapper which implements __clone:
https://github.com/eventum/eventum/blob/v3.5.1/src/Mail/MailMessage.php#L651-L659
however it still doesn't work, so more deeper __clone() methods needed: https://github.com/eventum/eventum/pull/364
probably need deeper clone in AddressList type headers, which have the address values as objects.
however, doing it properly would mean add __clone() in all objects themselves, not doing top level cloning.
I am under the impression that if you do not specify a __clone method a deep clone was performed by default?
rather opposite:
http://php.net/manual/en/language.oop5.cloning.php
When an object is cloned, PHP 5 will perform a shallow copy of all of the object's properties. Any properties that are references to other variables will remain references.
and as objects are always references in php5+, the result is that cloned subobjects remain shared.
This repository has been closed and moved to laminas/laminas-mail; a new issue has been opened at https://github.com/laminas/laminas-mail/issues/28.