2

I have the following case with class inheritance:

class Entity
{
  public $db; //connection

  ...
}

and classes Customer and Product extending Entity class:

class Customer extends Entity
{
   public $cname;
   public $cdesc;

   private function populate($row)
   {
     foreach($row as $key=>$val) $this->$key=$val;
   }

   public function fetch()
   {
     $sql="SELECT cname,cdesc FROM customers";
     $rst=$this->db->query($sql);
     $row=$rst->fetch_assoc();
     $this->populate($row);
   }
}

class Product extends Entity
{
   public $pname;
   public $pdesc;

   private function populate($row)
   {
     foreach($row as $key=>$val) $this->$key=$val;
   }

   public function fetch()
   {
     $sql="SELECT pname,pdesc FROM products";
     $rst=$this->db->query($sql);
     $row=$rst->fetch_assoc();
     $this->populate($row);
   }
}

As one can see here, each child class has the same function populate($row) which gets database row fetched from child class and populates corresponding class' variables; this function automatically fills variables: $this->cname=$row['cname'], $this->cdesc=$row['cdesc'] etc. (look at my other post here).

Now I'd like to pull this function from children to parent class Entity and inherit it by all child classes but there's a problem. This function with $this->$key=$val dynamically fills (tries to fill) parent class variables and I'd like to fill child class variables. How to define that this function fills child class variables? (I'd like to have here something like child::$key=$val but child:: does not exist).

Community
  • 1
  • 1
sbrbot
  • 6,169
  • 6
  • 43
  • 74
  • You're working with _object_ variables here, not _class_ variables (denoted by `static` in php), and there's no child/parent relationship for objects. – georg Sep 08 '14 at 19:59
  • Duplicate found on Programmers: http://programmers.stackexchange.com/questions/151910/can-i-use-a-child-class-variables-in-its-parent-class - Excerpt: It's not possible. – GolezTrol Sep 08 '14 at 20:00
  • Indeed, I work here with object variables not (static and by all children shared) class variables. The question stays, how to define a function in parent class that would change variables of its children. – sbrbot Sep 08 '14 at 20:03
  • 2
    @sbrbot: yes, but there's no such thing as a "child" or "parent" object. Only classes can be "children" or "parents". – georg Sep 08 '14 at 20:06
  • What you are doing works. You can always modify variables by name. – Daniel Williams Sep 08 '14 at 20:08

3 Answers3

2

Perhaps i am missing something but you can make the function protected then access it in child classes:

class Entity
{
    protected  $db; //connection

    protected  function populate($row)
    {
        foreach($row as $key=>$val) $this->$key=$val;
    }
}


class Customer extends Entity
{
    public $cname;
    public $cdesc;

    public function fetch()
    {
        $sql="SELECT cname,cdesc FROM customers";
        $rst=$this->db->query($sql);
        $row=$rst->fetch_assoc();
        $this->populate($row);
    }
}

class Product extends Entity
{
    public $pname;
    public $pdesc;

    public function fetch()
    {
        $sql="SELECT pname,pdesc FROM products";
        $rst=$this->db->query($sql);
        $row=$rst->fetch_assoc();
        $this->populate($row);
    }
}
Steve
  • 20,703
  • 5
  • 41
  • 67
  • Yes, you missed this, problem is "$this->" in populate() function of parent class. $this-> should refer to child object's $this-> – sbrbot Sep 08 '14 at 22:05
  • @sbrbot Could you please do a live example ( http://codepad.viper-7.com/ or similar) that shows the my code failing and your working, because i cant work out what you mean by child object (i dont belive there is such a thing), and i am really curious now – Steve Sep 08 '14 at 22:20
  • 1
    Sorry user574632 for my late response, I tested it and it works as expected. Surprisingly, that what you posted here I did at the beginning of all this and has some errors with calling my function and changed it into second approach. But seems that problem was with something else. However, your post made me to retest the thing and now had better code. If you're a little bit upset about my first (not the best) response, that's fine, I would react probably the same way. I appreciate your effort to help me. – sbrbot Sep 12 '14 at 10:42
  • @sbrbot not upset at all, just curious. Glad you got it sorted and glad I could help. – Steve Sep 12 '14 at 23:17
1

If you're trying to access specific data about one Product from another Product simply by the relation, then you can't do it.

If you're wanting to access child data from the parent, then I'd recommend creating an Interface that defines standardised ways to get the data you want:

interface EntityInterface
{
    public function getName();
    public function getDescription();
}

Then your Product simply defines the methods...

class Product extends Entity implements EntityInterface
{
    public $pname;

    public function getName() {
        return $this->pName;
    }
}

And your top-level Entity class uses those accessors:

class Entity
{
    public function printName() {
        echo $this->getName();
    }
}
Joe
  • 15,669
  • 4
  • 48
  • 83
1

This is what Abstract classes are for. You define what you want in your parent class and then your children implement it. More or less, this is what Joe described, just rolled into a convenient class

abstract class Entity
{
    // Note that we're defining this here and not in the child 
    // so we're guaranteed this is set
    /* @var string */
    public $pName;

    public function printName() {
        echo $this->getName();
    }

    abstract public function getName($name);
}

class Product extends Entity
{
    //Note that, just like an interface, this has to implement it just like the parent
    public function getName($name) {
        return $this->pName;
    }
}
Machavity
  • 30,841
  • 27
  • 92
  • 100
  • Thank's @Machavity, I know wery well what abstract class is, problem here is that function form parent class should fill variables not of this parent class ($this) but of child class and that function has to know from which child variables. – sbrbot Sep 08 '14 at 22:08