Search code examples
phpobjectclone

PHP deep clone object


The scenario: fetch an email template from the database, and loop through a list of recipients, personalising the email for each.

My email template is returned as a nested object. It might look a little like this:

object(stdClass) {
    ["title"] => "Event Notification"
    ["sender"] => "[email protected]"
    ["content"] => object(stdClass) {
        ["salutation"] => "Dear %%firstname%%,"
        ["body"] => "Lorem ipsum %%recipient_email%% etc etc..."
    }
}

Then I loop through the recipients, passing this $email object to a personalise() function:

foreach( $recipients as $recipient ){
    $email_body = personalise( $email, $recipient );
    //send_email();
}

The issue, of course, is that I need to pass the $email object by reference in order for it to replace the personalisation tags - but if I do that, the original object is changed and no longer contains the personalisation tags.

As I understand, clone won't help me here, because it'll only create a shallow copy: the content object inside the email object won't be cloned.

I've read about getting round this with unserialize(serialize($obj)) - but everything I've read says this is a big performance hit.

So, two finally get to my two questions:

  1. Is unserialize(serialize($obj)) a reasonable solution here?
  2. Or am I going about this whole thing wrong? Is there a different way that I can generate personalised copies of that email object?

Solution

  • You could add a __clone() method to your email class. Which is automatically called when an instance of this class is cloned via clone(). In this method you can then manually add the template.

    Example:

    class Email {
        function __clone() {
            $this->template = new Template();
        }
    }
    

    .

    unserialize(serialize($object)); // would be another solution...