简体   繁体   中英

php polymorphism - Call a parent function in polymorphed child function - problem with get_class($this)

I created a function to automatically assign values from a select in whatever matching variables available in the related class

class FR_Object{

    protected $me;

    public function __construct()
      {
          $this->me = new ReflectionClass($this);
      }

 public function setFrom($data)
      {
          if (is_array($data) && count($data)) {
              $valid = get_class_vars(get_class($this));
              foreach ($valid as $var => $val) {
                  if (isset($data[$var])) {
                      $this->$var = $data[$var];
                  }
              }
          }
      }
}

Parent class:

class FR_Event extends FR_Object_DB {

    public $EventsID;
    public $Subject;
    public $Description;
    public $UserID;
    public $Username;
    public $Address;
    public $Longitude;
    public $Latitude;
    public $EventStartDate;
    public $EventEndDate;
    public $EventsTypeID;
    public $CountryID;
    public $CityID;
    public $Status;
    public $Lang;
    public $When;

public function getLang($lang){

        $sql = "SELECT      e.EventsID, Subject, Description, UserID, Username, Address, Longitude, Latitude, EventStartDate, EventEndDate, EventsTypeID, CountryID, CityID, Status, Lang
                FROM        Events e
                INNER JOIN  EventsDetails d
                    ON      e.EventsID = d.EventsID
                WHERE       e.EventsID = " . $this->EventsID .
               "   AND         Lang = " . $lang;


        $result = $this->selectOneRow($sql);
        if ($result) {
            $this->setFrom($result);
        }else{
            $this->Lang = null;
            $this->Subject = null;
            $this->Description = null;
        }
    }
}

child class:

class FR_Invitation extends FR_Event{

    public $invites;

public function getLang($lang){
        parent::getLang($lang);

        $sql = "SELECT      InvitationID, Email, InvitationDate, ConfirmationName, UserID
                FROM        Invitation i
                INNER JOIN  ConfirmationStatus s on i.ConfirmationStatusID = s.ConfirmationStatusID
                WHERE       EventsID = " . $this->EventsID .
               " AND        Lang = " . $this->Lang;

        $this->invites = $this->select($sql);
    }
}

My problem is that a function in a parent class is called in a child class like this:

parent::getLang($lang).

parent::getLang($lang) uses setFrom but at that point $this is not the parent class anymore.

It's the child!

Does someone see a way to alter this function for normal usage and when called by way of parent:: or do I have to just throw it to the bin and go for more traditional (and longer) methods?

Simply don't overwrite the setForm function in the child class and it will use the setForm in the parent class it is extending.

However, it seems to have a clear misunderstanding of OO inheritance. Best you take the time read through the relevant documentation .

You need to use setter injection (google it) and pass either the result of get_class_vars or the calling class name.

class FR_Object {
    public function setFrom($data, $vars) {
         if (is_array($data) && count($data)) {
              $valid = $vars;
              foreach ($valid as $var => $val) {
                   if (isset($data[$var])) {
                       $this->$var = $data[$var];
                   }
              }
         }
    }
}

class FR_Invitation {
    public function setFrom($data, $vars) {
        parent::setForm($data, $vars);
    }
}

I don't see why you couldn't leave it as is. The only consequence in that case would be that $invites would also be returned by the get_class_vars() call.

An option to do the behaviour you are talking about could be to pass an optional parameter to the setFrom() function.

public function setFrom($data, $class = null)
{
    $class = $class == null ? get_class($this) : $class;
    if (is_array($data) && count($data)) {
        $valid = get_class_vars(get_class($this));
        foreach ($valid as $var => $val) {
            if (isset($data[$var])) {
            $   this->$var = $data[$var];
            }
        }
    }
}

Then in your parent, Event class use this call to setFrom.

$this->setFrom($result, get_class());

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