Search code examples
phpoopscope-resolution

Get Classname of Inherited Class when using Scope Resolution Operator (::)


Possible Duplicate:
Functionality of PHP get_class

For a small ORM-ish class-set, I have the following:

class Record {
  //Implementation is simplified, details out of scope for this question.
  static public function table() {
    return strtolower(preg_replace('/([a-z])([A-Z])/', '$1_$2', get_class()))."s";
  }

  static public function find($conditions) {
    //... db-selection calls go here.
    var_dump(self::table());
  }
}

class Payment extends Record {
}

class Order extends Record {
  public $id = 12;
  public function payments() {
    $this->payments = Payment::find(array('order_id', $this->id, '='));
  }
}

$order = new Order();
$order->payments();
#=> string(7) "records"

I would expect this code to print:

#=> string(8) "payments"

But, instead, it prints records. I have tried self::table(), but that gives the same result.

Edit, after some questions in the comments table() is a method that simply maps the name of the Class to the table in wich its objects live: Order lives in orders, Payment lives in payments; records does not exist!). When I call Payments::find(), I expect it to search on the table payments, not on the table records, nor on the table orders.

What am I doing wrong? How can I get the classname of the class on which ::is called, instead of the class in which is was defined?

Important part is probably the get_class(), not being able to return the proper classname.


Solution

  • You can use get_called_class if you're using php 5.3 or higher. It gives you the class the static method is called on, not the one where the method is actually defined.

    UPDATE

    You need the class name of the class on which 'find' is called. You can fetch the class name in the find method and provide it as a parameter to the table (maybe rename it to getTableForClass($class)) method. get_called_class will give you the Payment class, the table method derives the table name and returns it:

    class Record {
        //Implementation is simplified, details out of scope for this question.
        static public function getTableForClass($class) {
            return strtolower(preg_replace('/([a-z])([A-Z])/', '$1_$2', $class))."s";
        }
    
        static public function find($conditions) {
            //... db-selection calls go here.
            $className = get_called_class();
            $tableName = self::getTableForClass($class);
    
            var_dump($tableName);
        }
     }