0

I have some abstract knowledge of OOP but this is the first time I am trying to code some OOP in PHP. I want to create a class that will have some attributes from construction but some attributes that dynamically change.

I am a little confused about all the terms (objects, classes, methods,...) so I do not know exactly what to search for. I made a simplified example below.

This is where I declared my class, that will accept 2 parameters on construction and calculate the third one, which is the higher number (please ignore that I don't check the type).

class test{
  public function __construct($p1, $p2){
    $this->p1 = $p1;
    $this->p2 = $p2;
    $this->p_max = max(array($this->p1, $this->p2));
  }
}

Then I initialize the object and check the p_max:

$test = new test(1,2);
echo $test->p_max; // Prints 2

But if I change p1 and p2, the p_max won't change:

$test->p1 = 3;
$test->p2 = 4;
echo $test->p_max; // Prints 2 (I want 4)

How should I define the p_max inside my class to update every time I change p1 or p2? Is there a way without turning p_max into a method?

1
  • you have a typo in your constructor max(array($this->p1, $this->p2) is missing a closing ) Commented May 3, 2019 at 15:47

2 Answers 2

1

You can achieve this, using the magic __get method, which will be called, if a property of a class is accessed, but not defined. This is pretty hacky in my opinion, but works just as you want it to.

<?php
class test {
    public function __construct($p1, $p2) {
        $this->p1 = $p1;
        $this->p2 = $p2;
    }

    public function __get($name) {
        if ('p_max' === $name) {
            return max(array($this->p1, $this->p2));
        }
    }
}

$test = new test(1,2);
echo $test->p_max; // Prints 2

$test->p1 = 3;
$test->p2 = 4;
echo $test->p_max; // Prints 4

Doing it this way, the max value will be calculated every time, you access this property.

Edit: Because the __get method will only be called for a property, which is not defined in the class itself, this wont work, if you assign the variable a value in the constructor or create it as property.

Edit2: I´d like to point out - again - that it´s pretty hacky to do it this way. For a way cleaner way, go with AbraCadaver´s answer. That´s how I personally would do it, too.

Sign up to request clarification or add additional context in comments.

Comments

1

You don't really need to use a magic method, just a method that returns the calculated value:

class test{
  public function __construct($p1, $p2){
    $this->p1 = $p1;
    $this->p2 = $p2;
  }    

  public function p_max() {
    return max($this->p1, $this->p2);
  }
}

$test->p1 = 3;
$test->p2 = 4;
echo $test->p_max(); // call method

You can also accept optional arguments to p_max() to set new values and return the calculated value:

class test{
  public function __construct($p1, $p2){
    $this->p1 = $p1;
    $this->p2 = $p2;
  }    

  public function p_max($p1=null, $p2=null) {
    $this->p1 = $p1 ?? $this->p1;
    $this->p2 = $p2 ?? $this->p2;

    return max($this->p1, $this->p2);
  }
}

echo $test->p_max(3, 4); // call method

Also notice that max accepts multiple arguments so you don't have to specify an array.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.