PHP OOP (Value Objects / Data Access Objects) concepts

I just started learning PHP OOP, previously I did PHP in a procedural manner. I was reading this article and I have some quick questions,

  • How is a constructor usually defined for value objects? As one that takes parameters in all "data members" or sticks to the default constructor and uses mutator / accessor methods to set / get data?

  • Is this really the recommended way to start doing PHP OOP? To be honest, the concepts explained in the article were a little confusing for me.

Greetings

+2


a source to share


2 answers


Objects must always be in a valid state. This means that the object always behaves (methods) and contains information (member variables) that make sense. The purpose of a constructor is to create an object in a valid state.

For value objects, the constructor must take the minimum number of arguments for the object to be meaningful. For example, if you have an RGB value object, would it make sense in your application if red was the string "monkey", green was NULL, and blue was an array?

final class RGB {
    $r, $g, $b;
}

$mycolor = new RGB;

// NULL, what value of red is that supposed to be?
var_dump($mycolor->r);

// We are free to set these values too, even though they do not make sense.
$mycolor->r = 'monkey';
$mycolor->g = NULL;
$mycolor->b = array('foo', 'bar');

      

This is exactly what this object allows. $ mycolor refers to an object that is not in a valid state. How can we ensure that an RGB object always has three values, red, blue, and green, and that they are all between 0 and 255?

final class RGB {

    private $r;
    private $g;
    private $b;

    public function __construct($r, $g, $b) {

        // are our arguments numbers?

        if (!is_numeric($r)) {
            throw new Exception('Value of red must be a number');
        }
        if (!is_numeric($g)) {
            throw new Exception('Value of green must be a number');
        }
        if (!is_numeric($b)) {
            throw new Exception('Value of blue must be a number');
        }

        // are our arguments within range 0-255?

        if ($r < 0 || $r > 255) {
            throw new Exception('Value of red must be 0-255');
        }
        if ($g < 0 || $g > 255) {
            throw new Exception('Value of green must be 0-255');
        }
        if ($b < 0 || $b > 255) {
            throw new Exception('Value of blue must be 0-255');
        }

        // our arguments are fine.

        $this->r = $r;
        $this->g = $g;
        $this->b = $b;

    }

    //*// Canadian support

    public function getColour() {

        return $this->getColor();

    }

    public function getColor() {

        return array($this->r, $this->g, $this->b);

    }

}

$mycolor = new RGB;  // error! missing three arguments
$mycolor->r = 'monkey'; // error! this field is private

// exception! the constructor complains about our values not being numbers
$mycolor2 = new RGB('monkey', NULL, array('foo', 'bar'));

// exception! the constructor complains our numbers are not in range
$mycolor3 = new RGB(300, 256, -10);

$mycolor4 = new RGB(255, 0, 0); // ahh... a nice shade of red
var_dump($mycolor4->getColor()); // we can read it out later when we need to

      



If your constructor requires three arguments and it throws an exception if all three are not numbers between 0 and 255, you will always define member variables with good values.

You must also make sure that the variables of type "red", "blue" and "green" are private. Otherwise, anyone can write whatever they want. Of course, if they are private, no one can read them. To create a read-only operation, we define a getColor () method that accesses the private member variables for us.

This version of the RGB object will always have the correct state.

Hopefully this sheds some light on the nature of OOP and gives you an opportunity to start thinking.

+2


a source


  • To create objects that act as neutral data containers, I would use a classic designer __contruct()

    , then you can use magic __get

    and __set

    to access the properties. Another way to input data is with db string object, for example you can find more information about this by googling "dependency injection"

  • You can run it like in most OOP languages ​​with a main class, but MVC is widely used for web problems.



Do you have previous experience with OOP programming?

+1


a source







All Articles