9

I am trying to extend a PHP class without rewriting the whole thing. Here is an example:

<?
$a = new foo();
print $a->xxx();
$b = new bar();
print $b->xxx();

class foo {
  const something = 10;

  public function xxx() {
    $this->setSomething();
    return $this->something;
  }

  private function setSomething() {
    $this->something = self::something;
  }
}

class bar extends foo {

  public function xxx() {
    $this->setSomething();
    $this->something++;
    return $this->something;
  }

}
?>

However when I run the script I get the following error:

Fatal error: Call to private method foo::setSomething() from context 'bar' in test.php on line 23

It would seem that bar is not inheriting the private function setSomething(). How would I fix this without modifying the foo class?

safarov
  • 7,793
  • 2
  • 36
  • 52
Kenneth Vogt
  • 985
  • 4
  • 12
  • 28
  • You can't change `setSomething()` to `protected` ? – alex Apr 09 '12 at 06:50
  • As I stated above, the foo class is not to be modified. How else can I do this? – Kenneth Vogt Apr 09 '12 at 06:53
  • You use the right tool for the job, that is, make it `protected`. – alex Apr 09 '12 at 06:54
  • I understand your point however I do not have acces to change the original class. Perhaps I oversimplified the example. The original class is from another file that is merely included with require(). – Kenneth Vogt Apr 09 '12 at 06:57
  • In that case the author don't want it to be available in subclass. Or didnt think about in design phase. So this is a by design rule of that parent class. – Shiplu Mokaddim Apr 09 '12 at 07:00
  • Then contact the original author and make clear that you need to extend the class. – deceze Apr 09 '12 at 07:01
  • Oh well, I was trying to do something that is clearly beyond the original design scope. I would hate to say they didn't think about it, I don't think they could have anticipated what I have in mind. – Kenneth Vogt Apr 09 '12 at 07:06
  • Just write your own method, if you can't set the original class's method to `protected`. – s3c Apr 16 '22 at 09:22

6 Answers6

15

No, you can not fix this without modifying the foo class. Because an inherited class can not access parent class's private members. It's a very basic rule.

Declare setSomething() as protected. It'll be solved.

See manual

Shiplu Mokaddim
  • 56,364
  • 17
  • 141
  • 187
8

Private members are not inheritable, you can not use them in sub class. They are not accessible outside the class.

You must need to make that function as protected or public. Protected members are accessible to that class and for the inherited class. So, your best bet is to make that function Protected.

Shakti Singh
  • 84,385
  • 21
  • 134
  • 153
7

bar is inheriting the function alright, but it can't call it. That's the whole point of private methods, only the declaring class can call them.

deceze
  • 510,633
  • 85
  • 743
  • 889
4

Try reflection

http://php.net/manual/en/class.reflectionclass.php

Also:

Call private methods and private properties from outside a class in PHP

Community
  • 1
  • 1
zad
  • 3,355
  • 2
  • 24
  • 25
1

Did you try this?

class bar extends foo {

    public function xxx() {
      $this->something = parent::xxx();
      $this->something++;
      return $this->something;
    }
}

Note the parent::xxx(); is public, so it should work... even though it looks like a static call.

Frank Forte
  • 2,031
  • 20
  • 19
0

Without modifying the original class, there is no way for the inherited class to directly call private methods of the parent class.

Christian Mann
  • 8,030
  • 5
  • 41
  • 51