PHP Shopping Website with Cart - Returning a HTML String
You might want to decompose it into smaller pieces that will be easier to follow and eventually modify.

You could also learn a bit about dependency injection. Creating new instances all around anytime you need them is not very good.

Here is a very simple rewrite of your code and a lot of pieces are missing but I hope it gives some general guideline.

It uses PHP 7.4 features, if you can't use those, of course ignore all the typehints, etc..

Also it might make sense to depend on interfaces instead of classes directly, but didn't want to go this far as I think it could be too much for you at one go.



Dont be shy to define structures.

class Product
{
  public int $id;
  public string $name;
  public float $price;

  public function __construct(int $id, string $name, float $price)
  {
    $this-&gt;id =  $id;
    $this-&gt;name = $name;
    $this-&gt;price = $price;
  }
}




Create product repository

class ProductsRepository
{
    /**
     * @param array&lt;int&gt; $ids
     * @return array&lt;int, Product&gt;
     */ 
    function getProducts(array $ids): array
    {
        // get it from somewhere
    }
}




Structure for item in cart holds a bit more.

class CartItem
{
  public int $productId;
  public string $name;
  public float $unitPrice;
  public int $quantity;
  public function __construct(int $productId, string $name, float $unitPrice, int $quantity = 1)
  {
    $this-&gt;productId = $productId;
    $this-&gt;name = $name;
    $this-&gt;unitPrice = $unitPrice;
    $this-&gt;quantity = $quantity;
  }
  public function getTotalPrice(): float
  {
    return $this-&gt;unitPrice * $this-&gt;quantity;
  }
}




Cart holds many items, allows to iterate them, and add them and it knows the product repository to allow it doing so.

class Cart
{
  private ProductsRepository $products;
  /** @var array&lt;CartItem&gt; */
  private array $items;
  public function __construct(ProductsRepository $products, array $items = [])
  {
    $this-&gt;products = $products;
    $this-&gt;items = $items;
  }
  public function getItems(): array
  {
    return $this-&gt;items;
  }

  public function getTotalPrice(): int
  {
    // count it here, or have it in property and make sure it is updated while adding items.
  }

  public function add(int $productId, int $quantity = 1)
  {
    if (isset($this-&gt;items[$productId])) {
      // already in cart =&gt; increase quatity
    } else {
      $product = $this-&gt;products-&gt;getProduct($productId);
      //handle product not exists, not on stock, etc.
      $this-&gt;items[$productId] = new CartItem($product-&gt;id, $product-&gt;name, $product-&gt;price, $quantity);
    }
  }
}




We will store cart in session, this will take care of it.

class CartSessionStorage
{
  // we need it for the Cart instances
  // and maybe we wont store product names in session but load them from products repo?
  private ProductsRepository $products;

  public function loadCart(): Cart
  {
    // load from session
  }
  public function saveCart(Cart $cart): void
  {
    // save to session
  }
}




Renderer knows the html structure and some localization/formatting rules.

class CartRenderer
{
  private Formatter $formatter;
  public function __construct(Formatter $formatter)
  {
    $this-&gt;formatter = $formatter;
  }
  public function renderCart(Cart $cart): string
  {
    $html = '';
    // your rendering here;
    foreach ($cart-&gt;getItems() as $item) {
    //you can use heredoc, but add some html escaping, nor heredoc nor your code handle it
    $html .= 
      &lt;&lt;&lt;HTML
      &lt;div&gt;write html here&lt;div&gt;and dont mind if u use &lt;span&gt;{$item-&gt;getTotalPrice()}&lt;/span&gt;
      HTML;
    }
    return $html;
  }
}




Put it all together.

$products = new ProductsRepository();
$storage = new SessionCartStorage(products);
$formatter = new Formatter();
$renderer = new CartRenderer($formatter);




And there you go.

$cart = $storage-&gt;loadCart();

// form submission?
$cart-&gt;add($productId, $quantity);
$storage-&gt;saveCart($cart);

// render it
echo $renderer-&gt;renderCart($cart);