LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (http://www.linuxquestions.org/questions/programming-9/)
-   -   PHP5 - OOP heritance and static functions and self:: (http://www.linuxquestions.org/questions/programming-9/php5-oop-heritance-and-static-functions-and-self-654365/)

emi_ramo 07-08-2008 01:26 PM

PHP5 - OOP heritance and static functions and self::
 
Hi all!
I'm doing a DB access classes and I pretended to do the statically, except the main BD class, that needs to open and close the database. To do so, I decided to do an abstract class to define the basic per table functions, as basic scape, read, update and remove and then the final classes for each table:

Code:

$db = new database();

abstract class db_table
{
  protected abstract function name();
  protected abstract function escape(array &$data);

  public function read(array $data, array $order = array())
  {
      global $db;
      return $db->read(self::name(), self::escape($data), $order);
  }
  public function insert(array &$data);
  {
      global $db;
      self::escape(&$data);
      $db->insert(self::name(), &$data);
  }
 
  public function update(array &$data);
  {
      global $db;
      self::escape(&$data);
      $db->update(self::name(), &$data);
  }
}

class db_users extends db_table
{
  protected function name()
  {
      return 'users';
  }

  function escape(array &$user)
  {
      ( some mysql_real_escape_string stuff... )

      return $user;
  }
 
  function read_by_id($id)
  {
      $user = self::read(array('id' => $id));

      if(is_array($user))
        return $user;
     
      return NULL;
  }
}

// This will fail
db_users::read(array(id=>'someid',passwd=>'somepassword'));

With the code as here it gives an error saying db_table::name and db_table::escape is not callable on static plus abstract situation. But I'm calling it through users class, which has name and escape functions declared. Is there any possibility to do something similar, without needing of getInstance(), redeclaring the same function on each table class or just not using static classes?

May be using some combination with get_class and eval, or reflecting, or something similar?

If not, I know the solution... ;(

excel28 07-08-2008 01:32 PM

Did you try to remove 'self::' from name and escape calls?

emi_ramo 07-08-2008 01:37 PM

It gives a "Call to undefined function name()"...

What I'm looking for is some self:: equivalence but not just for the abstract class but the final one. Just as parent:: is for the final to access the abstract. Or some trick to have the same functionallity.

Thanks for speed, excel!
emi

excel28 07-08-2008 07:10 PM

Looking at the first post, calling db_users::read means function "read" is a static function. But looking at your db_table class, it is not a static function.

Try to create an instance of db_users first, then have the object call the function "read".

AdaHacker 07-08-2008 08:51 PM

Currently, PHP binds self at compile-time rather than run-time. So whenever you use self in a class, it always refers to whatever class the code appears in. In your example, the call self::name() in db_table::read() will always resolve to db_table::name(), even though you're calling it from db_user, which overrides name().

I've read that this will be fixed in PHP 5.3, but for now, you're pretty much out of luck. I did find one work-around in the comments on php.net, but it's very ugly. Basically, it involves looping through a backtrace in your parent class method to determine the name of the child class that called the method. When you have that, you can statically execute the method in the child using call_user_func(). Kind of a brilliant hack as a proof-of-concept, but the thought of using it in a production app makes me feel really dirty.

Personally, I would advise you to just bite the bullet and use instance methods. They're nice, clean, work correctly, and don't have the reek of ugly, ugly hackery about them.

emi_ramo 07-09-2008 04:28 AM

SOLVED!!

Thanks, AdaHacker.
Your info has been much useful. I suppose that I will rewrite (copy-paste) the basic functions until PHP 5.3 will be released.

emi


All times are GMT -5. The time now is 07:33 AM.