- What does symfony/polyfill-deepclone actually do?
- It is a pure-PHP implementation of the deepclone PHP extension's functions: deepclone_to_array() converts a value graph into a plain array of scalars and nested arrays, and deepclone_from_array() rebuilds that graph. Object identity, references, cycles and private property state are preserved through the round trip. It also ships the DeepClone\NotInstantiableException and DeepClone\ClassNotFoundException classes so code written against the native extension works unchanged.
- How do I install symfony/polyfill-deepclone in a Laravel application?
- Install it with composer require symfony/polyfill-deepclone. Because it only defines global functions and exception classes, there is no service provider, config file or facade to register; Composer's autoloading is enough. You can then call deepclone_to_array() and deepclone_from_array() anywhere in your app, jobs, or tests.
- Is symfony/polyfill-deepclone compatible with Laravel 10, 11 and 12, and which PHP versions does it support?
- The package is framework-agnostic: it declares plain functions and classes, so it works in any Laravel version that meets the PHP constraint listed in its composer.json. It does not hook into Laravel's container or bootstrap, so there is no version-specific integration to break. Always run composer why-not or check the platform requirement before adding it to older applications.
- Why use deepclone_to_array instead of serialize and unserialize for deep copies?
- The array representation preserves PHP's copy-on-write behaviour for strings and scalar arrays, so repeatedly cloning a prototype is significantly more memory efficient than unserialize(serialize()). It also keeps object identity, shared references and cycles intact instead of silently duplicating them. The result contains only scalars and arrays, which makes it safer to inspect, diff and store.
- Does the polyfill conflict with the native deepclone extension on PHP 8.3+?
- No. When the native deepclone extension is loaded, the polyfill does nothing because the extension already provides the same functions. The native extension is roughly four to five times faster, so it is a drop-in performance win once available. Use feature detection such as function_exists('deepclone_to_array') if you want to branch explicitly in benchmarks or tests.
- What is DEEPCLONE_HYDRATE_PRESERVE_REFS and should I enable it globally?
- It is a flag for the hydration path that keeps shared references intact when rebuilding a graph from an array. Enabling it for every DTO and model clone adds work and changes semantics, so opt in only where shared state genuinely matters, such as cache payloads or reactive components. Benchmark your critical paths before making it a global default.
- Can I use deepclone_to_array output as a cache serialization format?
- Yes. The array format is cache friendly: dumped with var_export() into a .php file, OPcache maps it into shared memory so deserialization becomes essentially free. This is the same wire format used by Symfony's VarExporter\DeepCloner, which keeps Laravel and Symfony caching layers consistent. Malformed or hand-edited payloads now raise errors in v1.43.2 instead of producing a wrong graph.
- Why should I pin symfony/polyfill-deepclone to v1.43.1 or later?
- v1.43.1 separated ArrayObject and ArrayIterator storage from the cloned payload, fixing a defect where objects wrapping SPL iterators could bleed iterator state after cloning. That matters for config bags, paginators and third-party packages built on SPL. v1.43.0 and below carry the defect, so pin to v1.43.1 or newer.
- What happens when deepclone_from_array receives a malformed payload?
- Starting with v1.43.2, the polyfill reports malformed payloads the way the native extension does instead of degrading silently and returning a wrong object graph. That turns a class of data-corruption bugs into catchable, loggable failures, which is valuable for queue workers and anything cloning data pulled from cache or a queue. Audit broad try/catch blocks and any code that assumed cloning could never fail.
- Does the polyfill work with Eloquent models, Request objects, resources and closures?
- It handles ordinary objects well, which helps with cases like replicate(), fresh(), cloning a Request inside middleware, or isolating test fixtures while keeping relations shared. Custom __clone() logic and uncloneable values such as open file streams or resources can still fail, and those cases surface as DeepClone\NotInstantiableException or class-not-found errors. Closures need the allow_named_closures option to round trip, and deep cloning still costs real time, so avoid it in hot real-time paths unless you have benchmarked it.