Adding Length dimension to a Crate Object
I see no problem, given your comment, to have a 'stretchy' crate, but in my example code below you can control whether the crate can be stretched or not.

class Crate
{
    private $length, $width, $height;
    private $resizable = true;

    function __construct(float $length, float $width, float $height)
    {
        list($this-&gt;length, $this-&gt;width, $this-&gt;height) = [$length, $width, $height];
    }

    function getDimensions(): array
    {
        return [$this-&gt;length, $this-&gt;width, $this-&gt;height];
    }

    function isResizable()
    {
        return $this-&gt;resizable;
    }

    function fixateSize()
    {
        $this-&gt;resizable = false;
    }

    function addLength(float $extraLength): float 
    {
        return $this-&gt;length += $this-&gt;isResizable() ? $extraLength : 0;
    }
}


I've added three methods; getDimensions(), isResizable() and fixateSize(). Note that there's no function to undo the fixateSize(). That is intentional: What would be the point of fixating the size if you can undo it?

I've made the dimension and resize fields private. Only the Crate class should be responsible for manipulating these. Child classes should use the methods of Crate to change them, hence the getDimensions() method.

Note how addLength() now returns the new length, and how it doesn't add the $extraLength when the crate size is fixated. Instead of returning the new length you could return a boolean, indicating whether the extra length is accepted. Another reason for not accepting the extra length could be that the crate would become too long.

I wouldn't use the CrateService class, that just overly complicated, and the addLength() method that returns a new object is just weird. The name of the method doesn't suggest this at all. A better name would have been cloneAndStretch().