message cloning and headers
basz opened this issue · 5 comments
- I was not able to find an open or closed issue matching what I'm seeing.
- 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('its@me.com');
$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: its@me.com
X-Something: 1
Date: Thu, 14 Jun 2018 08:53:20 +0000
From: its@me.com
X-Something: 2
Actual results
Date: Thu, 14 Jun 2018 08:53:20 +0000
From: its@me.com
X-Something: 1
X-Something: 2
Date: Thu, 14 Jun 2018 08:53:20 +0000
From: its@me.com
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: eventum/eventum#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 laminas/laminas-mail#28.