3v4l.org

run code in 300+ PHP versions simultaneously
<?php final readonly class Product { public function __construct( public string $id, public string $name, public string $description, public int $price = 10, ) { } } final class Cart { /** * @param Product[] $products */ public function __construct( public string $id, public array $products = [], public int $total = 0, public int $quantity = 0, ) { } public function addProduct(Product $product): void { $this->products[] = $product; $this->quantity++; $this->total += $product->price; } } final readonly class ProductRepository { public function find(string $id): Product { // Simulate loading from database return new Product($id, "product-$id", "description-$id"); } public function findByIds(array $ids): array { // Simulate loading from database $products = []; foreach ($ids as $id) { $products[] = $this->find($id); } return $products; } } final readonly class CartRepository { private ReflectionClass $reflector; public function __construct( private ProductRepository $productRepository, ) { $this->reflector = new ReflectionClass(Cart::class); } public function serialize(Cart $cart): string { return json_encode([ 'id' => $cart->id, 'products' => array_column($cart->products, 'id'), 'total' => $cart->total, 'quantity' => $cart->quantity, ]); } public function unserialize(string $data): Cart { var_dump('...Unserializing cart...'); $previousCart = json_decode($data, true); $newCart = $this->reflector->newLazyGhost(function(Cart $newCart) use ($previousCart): void { var_dump('...Loading products...'); $products = $this->productRepository->findByIds($previousCart['products']); $this->reflector->getProperty('products')->setValue($newCart, $products); }); $this->reflector->getProperty('id')->setRawValueWithoutLazyInitialization($newCart, $previousCart['id']); $this->reflector->getProperty('total')->setRawValueWithoutLazyInitialization($newCart, $previousCart['total']); $this->reflector->getProperty('quantity')->setRawValueWithoutLazyInitialization($newCart, $previousCart['quantity']); return $newCart; } } $productRepository = new ProductRepository(); $repository = new CartRepository($productRepository); $cart = new Cart('#cart-01'); $cart->addProduct($productRepository->find('1')); $cart->addProduct($productRepository->find('2')); $cart->addProduct($productRepository->find('3')); // Usually, the $serialized string would be stored in a database or in the // session $serialized = $repository->serialize($cart); // A new HTTP request is made and the $serialized string is retrieved from the // DB or the sessions $newCart = $repository->unserialize($serialized); var_dump($newCart); var_dump($newCart->total); $newCart->products; var_dump($newCart);
Output for git.master, git.master_jit
string(24) "...Unserializing cart..." lazy ghost object(Cart)#9 (3) { ["id"]=> string(8) "#cart-01" ["products"]=> uninitialized(array) ["total"]=> int(30) ["quantity"]=> int(3) } int(30) string(22) "...Loading products..." object(Cart)#9 (4) { ["id"]=> string(8) "#cart-01" ["products"]=> array(3) { [0]=> object(Product)#10 (4) { ["id"]=> string(1) "1" ["name"]=> string(9) "product-1" ["description"]=> string(13) "description-1" ["price"]=> int(10) } [1]=> object(Product)#11 (4) { ["id"]=> string(1) "2" ["name"]=> string(9) "product-2" ["description"]=> string(13) "description-2" ["price"]=> int(10) } [2]=> object(Product)#12 (4) { ["id"]=> string(1) "3" ["name"]=> string(9) "product-3" ["description"]=> string(13) "description-3" ["price"]=> int(10) } } ["total"]=> int(30) ["quantity"]=> int(3) }

This tab shows result from various feature-branches currently under review by the php developers. Contact me to have additional branches featured.

Active branches

Archived branches

Once feature-branches are merged or declined, they are no longer available. Their functionality (when merged) can be viewed from the main output page


preferences:
44.31 ms | 408 KiB | 5 Q