tags:

views:

50

answers:

2

I have parent class c1 with function hi(). class c2 extends c1 and contains singleton access through method i(). In class c2 I want to make method with the same name as in c1, which I can call in static scope, but in this method I whan to use singleton instance and call method with the same name from parent class.

class c1{
  function hi(){
    echo 'very '.$this->a;
  }
}

class c2 extends c1{
    private static $i;
    public static function i()  {
        return (self::$i)?self::$i:(self::$i = new self);
    }    

    public $a='cool';
  function hi(){
    self::i()->hi(); // here I want to call hi() from c1 but in instance scope
  }
}

c2::hi(); //must echo: very cool

In real example
c1 is mysqli
c2 is my custom db class
and hi() is commit()
I want to be able to call db::commit(), so i dont need to write db::i()->commit();



EDIT: PHP < 5.3

A: 

Normally the way to invoke the class's parent's method is to use the parent:: keyword, but this only works when you run in instance scope, not in static scope.

But you can't run hi() as both a static function and a non-static function.

class c1
{
  function hi() {
    echo 'very '.$this->a;
  }
}

class c2 extends c1
{
  private static $i;

  public static function i()  {
        return (self::$i)? self::$i: (self::$i = new c2());
  }

  public $a='cool'; // not static

  function hi() {
    parent::hi();
  }

  static function do_hi() {
    $i = self::i();
    $i->hi();
  }
}

c2::do_hi(); // echoes: very cool

Additional comment: Strangely, PHP allows you to call instance methods as if they were static methods, using the :: syntax. In my opinion, this is wrong and it leads to confusing code. You should pretend that this usage is not possible, and instead call function statically only if you declare them static.

I don't think that trying to be clever and force code to do double-duty is a good practice. Also you should not be too fond of one-line functions that are complex and hard to read or modify. It's common for programmers to favor overly compact code, but you'll find that it makes the code hard to maintain. Project requirements inevitably change, and you'll end up having to pull apart your one-line gems anyway.

Bill Karwin
I can`t call statically. I have to call commit on mysqli instance with existing connection which I get from method i().
codez
Yes, I thought about giving different names, but i wanted to keep original.
codez
A: 

you can call mysqli_commit statically:

parent::commit();
kgb