{"id":1298,"date":"2026-05-10T18:00:00","date_gmt":"2026-05-10T17:00:00","guid":{"rendered":"https:\/\/wade.one\/blog\/?p=1298"},"modified":"2026-05-10T18:00:00","modified_gmt":"2026-05-10T17:00:00","slug":"php-8-5-clone-with-makes-value-objects-less-annoying","status":"publish","type":"post","link":"https:\/\/wade.one\/blog\/2026\/05\/10\/php-8-5-clone-with-makes-value-objects-less-annoying\/","title":{"rendered":"PHP 8.5 Clone With Makes Value Objects Less Annoying"},"content":{"rendered":"<p>PHP value objects have become much nicer over the last few releases, but cloning them has still been more awkward than it should be. Readonly properties are useful, immutable objects are useful, and <code>withSomething()<\/code> methods are useful. The annoying part has been writing the same cloning ceremony again and again just to change one property safely.<\/p>\n<p>PHP 8.5&#8217;s release announcement calls this &#8220;Clone With&#8221;, and the <a href=\"https:\/\/wiki.php.net\/rfc\/clone_with_v2\">clone-with RFC<\/a> explains the real motivation: making <code>clone<\/code> work properly with readonly properties and common wither-style patterns. That is exactly the kind of small language feature that matters in domain code, because value objects are only pleasant if they stay lightweight.<\/p>\n<p>I would not use this as an excuse to make everything immutable. PHP applications still need simple mutable objects in plenty of places. But for money values, date ranges, identifiers, request options, API payload objects, and other things where accidental mutation causes pain, clone-with syntax lowers the cost of doing the cleaner thing.<\/p>\n<p>The important caveat is validation. If a value object has invariants, cloning with a changed property should not become a side door around them. That is where PHP&#8217;s newer property tooling starts to fit together: readonly, asymmetric visibility, property hooks, and clone-with are more interesting as a set than as isolated features. The direction is good: less boilerplate, more explicit object state.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>PHP 8.5&#8217;s clone-with syntax makes immutable value objects easier to work with, especially around readonly properties.<\/p>\n","protected":false},"author":0,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"jetpack_post_was_ever_published":false},"categories":[28,13],"tags":[35,36,149,148],"class_list":["post-1298","post","type-post","status-publish","format-standard","hentry","category-php","category-programming","tag-php","tag-php-8-5","tag-readonly","tag-value-objects"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.6 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>PHP 8.5 Clone With Makes Value Objects Less Annoying - wade.one<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/wade.one\/blog\/2026\/05\/10\/php-8-5-clone-with-makes-value-objects-less-annoying\/\" \/>\n<meta property=\"og:locale\" content=\"en_GB\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"PHP 8.5 Clone With Makes Value Objects Less Annoying - wade.one\" \/>\n<meta property=\"og:description\" content=\"PHP 8.5&#039;s clone-with syntax makes immutable value objects easier to work with, especially around readonly properties.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/wade.one\/blog\/2026\/05\/10\/php-8-5-clone-with-makes-value-objects-less-annoying\/\" \/>\n<meta property=\"og:site_name\" content=\"wade.one\" \/>\n<meta property=\"article:published_time\" content=\"2026-05-10T17:00:00+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/wade.one\/blog\/wp-content\/uploads\/2015\/02\/Wade-Logo-cropped.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1518\" \/>\n\t<meta property=\"og:image:height\" content=\"1506\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@wadewomersley\" \/>\n<meta name=\"twitter:site\" content=\"@wadewomersley\" \/>\n<meta name=\"twitter:label1\" content=\"Estimated reading time\" \/>\n\t<meta name=\"twitter:data1\" content=\"1 minute\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/wade.one\\\/blog\\\/2026\\\/05\\\/10\\\/php-8-5-clone-with-makes-value-objects-less-annoying\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/wade.one\\\/blog\\\/2026\\\/05\\\/10\\\/php-8-5-clone-with-makes-value-objects-less-annoying\\\/\"},\"author\":{\"name\":\"\",\"@id\":\"\"},\"headline\":\"PHP 8.5 Clone With Makes Value Objects Less Annoying\",\"datePublished\":\"2026-05-10T17:00:00+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/wade.one\\\/blog\\\/2026\\\/05\\\/10\\\/php-8-5-clone-with-makes-value-objects-less-annoying\\\/\"},\"wordCount\":229,\"publisher\":{\"@id\":\"https:\\\/\\\/wade.one\\\/blog\\\/#\\\/schema\\\/person\\\/8b4739f8f8bb2cff5d792d4b8779fcc3\"},\"keywords\":[\"php\",\"php-8-5\",\"readonly\",\"value-objects\"],\"articleSection\":[\"PHP\",\"Programming\"],\"inLanguage\":\"en-GB\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/wade.one\\\/blog\\\/2026\\\/05\\\/10\\\/php-8-5-clone-with-makes-value-objects-less-annoying\\\/\",\"url\":\"https:\\\/\\\/wade.one\\\/blog\\\/2026\\\/05\\\/10\\\/php-8-5-clone-with-makes-value-objects-less-annoying\\\/\",\"name\":\"PHP 8.5 Clone With Makes Value Objects Less Annoying - wade.one\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/wade.one\\\/blog\\\/#website\"},\"datePublished\":\"2026-05-10T17:00:00+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/wade.one\\\/blog\\\/2026\\\/05\\\/10\\\/php-8-5-clone-with-makes-value-objects-less-annoying\\\/#breadcrumb\"},\"inLanguage\":\"en-GB\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/wade.one\\\/blog\\\/2026\\\/05\\\/10\\\/php-8-5-clone-with-makes-value-objects-less-annoying\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/wade.one\\\/blog\\\/2026\\\/05\\\/10\\\/php-8-5-clone-with-makes-value-objects-less-annoying\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/wade.one\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"PHP 8.5 Clone With Makes Value Objects Less Annoying\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/wade.one\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/wade.one\\\/blog\\\/\",\"name\":\"wade.one\",\"description\":\"wade womersley - york based software engineer\",\"publisher\":{\"@id\":\"https:\\\/\\\/wade.one\\\/blog\\\/#\\\/schema\\\/person\\\/8b4739f8f8bb2cff5d792d4b8779fcc3\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/wade.one\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-GB\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/wade.one\\\/blog\\\/#\\\/schema\\\/person\\\/8b4739f8f8bb2cff5d792d4b8779fcc3\",\"name\":\"Wade Womersley\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-GB\",\"@id\":\"https:\\\/\\\/wade.one\\\/blog\\\/wp-content\\\/uploads\\\/2015\\\/02\\\/200px.png\",\"url\":\"https:\\\/\\\/wade.one\\\/blog\\\/wp-content\\\/uploads\\\/2015\\\/02\\\/200px.png\",\"contentUrl\":\"https:\\\/\\\/wade.one\\\/blog\\\/wp-content\\\/uploads\\\/2015\\\/02\\\/200px.png\",\"width\":202,\"height\":200,\"caption\":\"Wade Womersley\"},\"logo\":{\"@id\":\"https:\\\/\\\/wade.one\\\/blog\\\/wp-content\\\/uploads\\\/2015\\\/02\\\/200px.png\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"PHP 8.5 Clone With Makes Value Objects Less Annoying - wade.one","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/wade.one\/blog\/2026\/05\/10\/php-8-5-clone-with-makes-value-objects-less-annoying\/","og_locale":"en_GB","og_type":"article","og_title":"PHP 8.5 Clone With Makes Value Objects Less Annoying - wade.one","og_description":"PHP 8.5's clone-with syntax makes immutable value objects easier to work with, especially around readonly properties.","og_url":"https:\/\/wade.one\/blog\/2026\/05\/10\/php-8-5-clone-with-makes-value-objects-less-annoying\/","og_site_name":"wade.one","article_published_time":"2026-05-10T17:00:00+00:00","og_image":[{"width":1518,"height":1506,"url":"https:\/\/wade.one\/blog\/wp-content\/uploads\/2015\/02\/Wade-Logo-cropped.png","type":"image\/png"}],"twitter_card":"summary_large_image","twitter_creator":"@wadewomersley","twitter_site":"@wadewomersley","twitter_misc":{"Estimated reading time":"1 minute"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/wade.one\/blog\/2026\/05\/10\/php-8-5-clone-with-makes-value-objects-less-annoying\/#article","isPartOf":{"@id":"https:\/\/wade.one\/blog\/2026\/05\/10\/php-8-5-clone-with-makes-value-objects-less-annoying\/"},"author":{"name":"","@id":""},"headline":"PHP 8.5 Clone With Makes Value Objects Less Annoying","datePublished":"2026-05-10T17:00:00+00:00","mainEntityOfPage":{"@id":"https:\/\/wade.one\/blog\/2026\/05\/10\/php-8-5-clone-with-makes-value-objects-less-annoying\/"},"wordCount":229,"publisher":{"@id":"https:\/\/wade.one\/blog\/#\/schema\/person\/8b4739f8f8bb2cff5d792d4b8779fcc3"},"keywords":["php","php-8-5","readonly","value-objects"],"articleSection":["PHP","Programming"],"inLanguage":"en-GB"},{"@type":"WebPage","@id":"https:\/\/wade.one\/blog\/2026\/05\/10\/php-8-5-clone-with-makes-value-objects-less-annoying\/","url":"https:\/\/wade.one\/blog\/2026\/05\/10\/php-8-5-clone-with-makes-value-objects-less-annoying\/","name":"PHP 8.5 Clone With Makes Value Objects Less Annoying - wade.one","isPartOf":{"@id":"https:\/\/wade.one\/blog\/#website"},"datePublished":"2026-05-10T17:00:00+00:00","breadcrumb":{"@id":"https:\/\/wade.one\/blog\/2026\/05\/10\/php-8-5-clone-with-makes-value-objects-less-annoying\/#breadcrumb"},"inLanguage":"en-GB","potentialAction":[{"@type":"ReadAction","target":["https:\/\/wade.one\/blog\/2026\/05\/10\/php-8-5-clone-with-makes-value-objects-less-annoying\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/wade.one\/blog\/2026\/05\/10\/php-8-5-clone-with-makes-value-objects-less-annoying\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/wade.one\/blog\/"},{"@type":"ListItem","position":2,"name":"PHP 8.5 Clone With Makes Value Objects Less Annoying"}]},{"@type":"WebSite","@id":"https:\/\/wade.one\/blog\/#website","url":"https:\/\/wade.one\/blog\/","name":"wade.one","description":"wade womersley - york based software engineer","publisher":{"@id":"https:\/\/wade.one\/blog\/#\/schema\/person\/8b4739f8f8bb2cff5d792d4b8779fcc3"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/wade.one\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-GB"},{"@type":["Person","Organization"],"@id":"https:\/\/wade.one\/blog\/#\/schema\/person\/8b4739f8f8bb2cff5d792d4b8779fcc3","name":"Wade Womersley","image":{"@type":"ImageObject","inLanguage":"en-GB","@id":"https:\/\/wade.one\/blog\/wp-content\/uploads\/2015\/02\/200px.png","url":"https:\/\/wade.one\/blog\/wp-content\/uploads\/2015\/02\/200px.png","contentUrl":"https:\/\/wade.one\/blog\/wp-content\/uploads\/2015\/02\/200px.png","width":202,"height":200,"caption":"Wade Womersley"},"logo":{"@id":"https:\/\/wade.one\/blog\/wp-content\/uploads\/2015\/02\/200px.png"}}]}},"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack-related-posts":[{"id":1109,"url":"https:\/\/wade.one\/blog\/2023\/03\/26\/php-8-2-vs-7-4\/","url_meta":{"origin":1298,"position":0},"title":"PHP 8.2 vs 7.4","author":"Wade","date":"March 26, 2023","format":false,"excerpt":"PHP is a widely used programming language that has been evolving rapidly in recent years. PHP 8.2 is the latest release, which came out on November 25th, 2021. This version brings several improvements, new features, and bug fixes, making it more efficient and secure than PHP 7.4. In this blog\u2026","rel":"","context":"In &quot;PHP&quot;","block_context":{"text":"PHP","link":"https:\/\/wade.one\/blog\/category\/php\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1152,"url":"https:\/\/wade.one\/blog\/2026\/03\/25\/php-8-5-4-released-upgrade-if-you-re-on-8-5\/","url_meta":{"origin":1298,"position":1},"title":"PHP 8.5.4 Released: Upgrade if You&#8217;re on 8.5","author":"Wade","date":"March 25, 2026","format":false,"excerpt":"PHP 8.5.4 is a bug-fix release, not a feature release. If you are already on PHP 8.5, you should update. If you are still on 8.4, this alone is not the reason to jump.","rel":"","context":"In &quot;PHP&quot;","block_context":{"text":"PHP","link":"https:\/\/wade.one\/blog\/category\/php\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1299,"url":"https:\/\/wade.one\/blog\/2026\/05\/11\/php-8-5-nodiscard-is-a-small-api-safety-feature\/","url_meta":{"origin":1298,"position":2},"title":"PHP 8.5 NoDiscard Is a Small API Safety Feature","author":"","date":"May 11, 2026","format":false,"excerpt":"PHP 8.5's NoDiscard attribute gives library and application code a direct way to say that ignoring a return value is probably a bug.","rel":"","context":"In &quot;PHP&quot;","block_context":{"text":"PHP","link":"https:\/\/wade.one\/blog\/category\/php\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1296,"url":"https:\/\/wade.one\/blog\/2026\/05\/08\/php-8-5s-uri-extension-fixes-a-real-web-problem\/","url_meta":{"origin":1298,"position":3},"title":"PHP 8.5&#8217;s URI Extension Fixes a Real Web Problem","author":"","date":"May 8, 2026","format":false,"excerpt":"PHP 8.5's new URI extension is not flashy, but it gives PHP a better built-in answer for parsing modern URLs.","rel":"","context":"In &quot;PHP&quot;","block_context":{"text":"PHP","link":"https:\/\/wade.one\/blog\/category\/php\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1297,"url":"https:\/\/wade.one\/blog\/2026\/05\/09\/php-8-5s-pipe-operator-is-for-readable-code-not-clever-code\/","url_meta":{"origin":1298,"position":4},"title":"PHP 8.5&#8217;s Pipe Operator Is for Readable Code, Not Clever Code","author":"","date":"May 9, 2026","format":false,"excerpt":"The PHP 8.5 pipe operator is useful when it makes data transformations read forwards, but it should not become a new way to hide simple code.","rel":"","context":"In &quot;PHP&quot;","block_context":{"text":"PHP","link":"https:\/\/wade.one\/blog\/category\/php\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1300,"url":"https:\/\/wade.one\/blog\/2026\/05\/12\/php-8-5-fatal-error-backtraces-are-an-operations-feature\/","url_meta":{"origin":1298,"position":5},"title":"PHP 8.5 Fatal Error Backtraces Are an Operations Feature","author":"","date":"May 12, 2026","format":false,"excerpt":"PHP 8.5 adding backtraces to fatal errors is a practical production debugging improvement, not just nicer developer output.","rel":"","context":"In &quot;PHP&quot;","block_context":{"text":"PHP","link":"https:\/\/wade.one\/blog\/category\/php\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]}],"_links":{"self":[{"href":"https:\/\/wade.one\/blog\/wp-json\/wp\/v2\/posts\/1298","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wade.one\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wade.one\/blog\/wp-json\/wp\/v2\/types\/post"}],"replies":[{"embeddable":true,"href":"https:\/\/wade.one\/blog\/wp-json\/wp\/v2\/comments?post=1298"}],"version-history":[{"count":1,"href":"https:\/\/wade.one\/blog\/wp-json\/wp\/v2\/posts\/1298\/revisions"}],"predecessor-version":[{"id":1312,"href":"https:\/\/wade.one\/blog\/wp-json\/wp\/v2\/posts\/1298\/revisions\/1312"}],"wp:attachment":[{"href":"https:\/\/wade.one\/blog\/wp-json\/wp\/v2\/media?parent=1298"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wade.one\/blog\/wp-json\/wp\/v2\/categories?post=1298"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wade.one\/blog\/wp-json\/wp\/v2\/tags?post=1298"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}