<?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);
You have javascript disabled. You will not be able to edit any code.