Very often I see an object in a project that is basically just a data container. There is no functionality, only private properties and set of getters and setters. If you are lucky, there is some sort of validation in the setters for the inputs, but that is not always the case. And every time I see these object in PHP, I hear people call them Anemic Domain Models. However from my experience this is not always the case. They are just a symptom of a fundemental problem in PHP. There is no decend way to pass data around. You have so few data types in PHP. And the only way you can add more is to use objects. You need only positive integer? You can either check for the validity every single time you pass a regular integer around, or you can use an object. Need a valid phone number? Use an integer or string and always validate or use an object. Need an address? Use an array and validate not only the values of each key, but the existence of the keys themselves. Or use an object for that. What is PHP missing, and why programmers are so often forced to use object, are structs. Like the ones there are in C#. The functionality I am looking for is this:

struct cappedInteger
{
    int cappedInteger
    {
        get
        {
            return cappedInteger;
        }
        set
        {
            cappedInteger = (value < 100) ? value : 100;
        }
    }
}

This will give me new data type cappedInteger that I can use for type declaration in methods and functions. Suddenly I don't have to pass an object to my method every time I just need a validated data.

Functions, callbacks and Type Declarations

Event more convoluted is the situation with functions in PHP. While functions can be anonymous, can be assigned to variable and passed as an argument, they are not a PHP type. Only Callbacks/Callables are. This means that validating a function is of required type (eg has correct parameters and return types) is a nightmare in PHP. You had to make a reflection of the function and validate it every sigle time before use. So as above, you can use objects for that. This wasn't impossible, but quite complicated before PHP7. But with PHP 7, there is a hack for it in the form of anonymous classes.

<?php
/**
 * Class Tester
 *
 * @property EventInterface $event
 */
class Tester
{
    /** @var EventInterface */
    protected $event = null;
    public function callMethod()
    {
        if($this->event !== null) $this->event->call($this, 1);
    }

    public function __set($name, $value)
    {
        if($name == 'event') {
            $rp = new ReflectionProperty(self::class, $name);
            preg_match('#@var[ \t]+(\S+)#', (string) $rp->getDocComment(), $m);
            $type = $m[1];
            if(($value instanceof $type) === false) {
                throw new InvalidArgumentException();
            }
            $this->$name = $value;
        }
    }

    public function setEvent(EventInterface $event)
    {
        $this->event = $event;
    }
}

interface EventInterface
{
    public function call(Tester $class, int $number);
}

//Test set-up
$test = new Tester();
$text = "Variable to be used inside the function";

// Test 1 - will work
$test->event = new class($text) implements EventInterface {
    private $useVariable;
    public function __construct($var)
    {
        $this->useVariable = $var;
    }
    public function call(Tester $class, int $number)
    {
        echo "Only me can be added here";
    }
};
$test->callMethod();

//Test 2 - will not work
try {
    $test->event = function(Tester $tester, int $int) use ($text) {
        echo 'I should not work';
    };
    $test->callMethod();
} catch (InvalidArgumentException $e) {
    echo 'Could not call a simple function';
}

//Test 3 - will not work
try {
    $test->event = new class {
        public function call(Tester $class, int $number)
        {
        echo 'I should not work';
        }
    };
    $test->callMethod();
} catch (InvalidArgumentException $e) {
    echo 'Could not call a class not implementing interface';
}

With either magical __set method or with specific set* method we can enforce that a variable assigned to an object property will implement an interface. An interface, that has only the callback definition in it. This callback then can be created by writing a named class implementing the interface (quite cumbersome, but the only option before PHP7) or writing an anonymous class. What is more, anonymous class gives you better encapsulation – you will have hard time using $this of the class method where you are creating the anonymous class. But you are still free to use any variables from the parent scope by using the constructor. So you get the same functionality as with a anonymous function.