{
    "href": "/post/2015/06/30/modernizing-serialized-php-objects-with-class-alias/",
    "relId": "2015/06/30/modernizing-serialized-php-objects-with-class-alias",
    "title": "Modernizing Serialized PHP Objects with class_alias()",
    "author": "pmjones",
    "markup": "html",
    "tags": [
        {
            "href": "/tag/legacy/",
            "relId": "legacy",
            "title": "Legacy",
            "author": null,
            "created": null,
            "updated": [],
            "markup": "markdown"
        },
        {
            "href": "/tag/php/",
            "relId": "php",
            "title": "PHP",
            "author": null,
            "created": null,
            "updated": [],
            "markup": "markdown"
        },
        {
            "href": "/tag/programming/",
            "relId": "programming",
            "title": "Programming",
            "author": null,
            "created": null,
            "updated": [],
            "markup": "markdown"
        }
    ],
    "created": "2015-06-30 14:14:58 UTC",
    "updated": [
        "2015-06-30 14:14:58 UTC"
    ],
    "html": "<p>Several weeks ago, a correspondent presented a legacy situation that I've never had to deal with. He was working his way through <a href=\"https://leanpub.com/mlaphp\">Modernizing Legacy Applications in PHP</a>, and realized the codebase was storing serialized PHP objects in a database. He couldn't refactor the class names without seriously breaking the application.</p>\n<blockquote>\n<p>I was carefully moving my classes to a PSR-0/4 structure when I found this. The application saves the output of <code>serialize($shoppingCart)</code> in a BLOB column, and unserializes it later to recreate the ShoppingCart object. The serialized object string looks like this:</p>\n<pre><code>O:12:\"ShoppingCart\":17:{s:13:\"\\00Basket\\00items\";a:25:{...}; ...}</code></pre>\n<p>See how the class name is embedded in the serialized string? If I rename the ShopppingCart class to PSR-0/4 namespace, then the old class won't be found when the application tries to <code>unserialize()</code> the serialized representation. How can I begin refactoring this without breaking the whole application?</p>\n</blockquote>\n<p>Before I was able to reply, my correspondent ended up changing the serialization strategy to use JSON, which was a rather large change. It ended up well, but it turns out there is a less intrusive solution: <a href=\"http://php.net/class_alias\"><code>class_alias()</code></a>.</p>\n<p>If you're in a serialized situation, and you need to change a class name, you can use a <code>class_alias()</code> to point the old class name to the new one. (Call <code>class_alias()</code> early in execution, probably before you register your autoloader.) You can then rename and move the class according to PSR-0/4 rules, and PHP will handle the rest for you.</p>\n<p>For example, if you renamed <em>ShoppingCart</em> to <em>Domain\\Orders\\Cart</em>, you might do this:</p>\n<pre><code>class_alias('Domain\\Orders\\Cart', 'ShoppingCart');</code></pre>\n<p>Now when you call <code>unserialize($shoppingCart)</code> to create an object, PHP will create it as an instance of <em>Domain\\Orders\\Cart</em> instead of <em>ShoppingCart</em>. Re-serialized representations of the recreated object will retain the new class name, not the old one: <code>O:18:\"Domain\\Orders\\Cart\":...</code>.</p>\n<p>As soon as there are no more serialized representations using the old class name, you can remove the <code>class_alias()</code> call entirely.</p>\n<hr>\n<p class=\"reddit-links\">Read the Reddit discussion about this post <a href=\"https://www.reddit.com/r/PHP/comments/3bmtio/modernizing_serialized_php_objects_with_class/\">here</a>.</p>\n"
}
