Какие принципы SOLID здесь нарушены?
сразу бросается в глаза O+I я бы сказал
представь, что после нужно будет считать площадь только маленьких фигур (area < 3) или добавится интерфейс с текстурой и нужно будет считать только пушистые.
не, формально принцип O пока еще не нарушен, и класс Box можно расширять, добавляя в потомках getTotalAreaSmall и getTotalAreaFluffy. но Box уже сейчас выглядит не просто как Box (который просто хранит фигуры), а как BoxThatCountsColored, а его потомки будут называться BoxThatCountsColoredAndSmallAndFluffy например :)
Сделал через Visitor, по моему получилось неплохо.<?php

interface IVisitor {

	public function getResult();

	public function visit(IShape $element): void;
}

interface IShape {

	public function accept(IVisitor $visitor): void;
}

interface IArea extends IShape {

	public function getArea(): float;
}

interface IFillColor extends IShape {

	public function setFillColor(string $rgb);

	public function getFillColor(): int;
}

trait TFillColor {

	protected $fillColor = 0;

	public function getFillColor(): int {
		return $this->fillColor;
	}

	public function setFillColor(string $rgb) {
		$this->fillColor = (int)hexdec($rgb);
	}
}

class Line implements IArea {

	protected $length;

	public function __construct(float $length) {
		$this->length = $length;
	}

	public function getArea(): float {
		return $this->length;
	}

	public function accept(IVisitor $visitor): void {
		$visitor->visit($this);
	}
}

class Rectangle implements IShape, IFillColor {

	use TFillColor;

	protected $width;

	protected $height;

	public function __construct(float $width, float $height) {
		$this->width = $width;
		$this->height = $height;
	}

	public function getArea(): float {
		return $this->width * $this->height;
	}

	public function accept(IVisitor $visitor): void {
		$visitor->visit($this);
	}
}

class Box {

	/**@var IShape[] $shapes */
	protected $shapes = [];

	public function addShape(IShape $shape): self {
		$this->shapes[] = $shape;

		return $this;
	}

	public function executeVisitor(IVisitor $visitor) {
		foreach ($this->shapes as $shape) {
			$shape->accept($visitor);
		}

		return $visitor->getResult();
	}
}

class TotalAreaWithColor implements IVisitor {

	protected $total = 0;

	protected $color;

	public function __construct(int $color) {
		$this->color = $color;
	}

	public function visit(IShape $element): void {
		if ($element instanceof IFillColor && $element->getFillColor() === $this->color) {
			$this->total += $element->getArea();
		}
	}

	public function getResult() {
		return $this->total;
	}
}

$rect  = new Rectangle(4, 10);
$rect->setFillColor("FF0000");

$line = new Line(10);

echo (new Box())
	->addShape($rect)
	->addShape($line)
	->executeVisitor(new TotalAreaWithColor(hexdec("FF0000")));