简体   繁体   中英

Dynamically changing attribute in PHP

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?

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM