I'm trying to find the name of the current class when calling a static method. To illustrate, let me define a few classes:

abstract class AbstractClass
{
  public function foo()
  {
    return class_name($this);
    # class_name(); gives just "AbstractClass"
  }

  public static function bar()
  {
    return class_name($this);
  }
}

class ConcreteClassOne extends AbstractClass
{
  public function test_non_static()
  {
     return foo();  # gives "ConcreteClassOne"
  }

  public static function test_static()
  {
     # doesn't work because there's not an instance of the class, obviously
     # However, I would like to find a way of getting "ConcreteClassOne" as the return value in this context
     return bar();
  }
}

class ConcreteClassTwo extends AbstractClass
{
  public function test_non_static()
  {
     return foo();  # gives "ConcreteClassTwo"
  }

  public static function test_static()
  {
     # See above
     return bar();
  }
}

Any ideas on how to get the desired behavior? Being able to do this would really "DRY up" my code, but I can't seem to find a way to do it--nothing that I've googled for or tried has yielded any results so far.

    When writing the static method you already know the name of its class, so why do you need to find it out at runtime?

      The reason for this is that I want to use that name in the function. I'm making an implementation of the Active Record design pattern. The classes specify the table names. So, for a subclass named "Ticket", the table name is "tickets". Say I'm implementing a static function called "count", called like so:

      Ticket::count();

      It needs to execute a query like this:

      "select count(id) from tickets"

      There are other subclasses of this Active Record class, such as User:

      User::count();

      "select count(id) from users"

      So on and so forth.

        I have been hunting for a solution in the PHP manual, but I am afraid that it just seems impossible - PHP5's reflection mechanisms require knowledge of the class/method/function names to work.

        A possible workaround is to have each class keep its name as a static member variable... but that means manual configuration of class names.

          I had thought of that strategy as well, but it seems less than ideal. It may be what I end up doing in the end--it's better than copying and pasting the implementations of the methods in the separate classes.

          Thanks for your help. If you find or think of anything, please let me know.

            This is a well know feature/limitation of PHP 5. Might be changed in PHP 6 but I wouldn't hold me breath.

            The real question is why use static methods at all? I know you are probably trying to save the cost of instantiating an object but is that really a problem? Go with dynamic methods and don't worry about performance unless it really becomes an issue. Makes programing under PHP so much easier.

            // Use
            $count = Ticket::getInstance()->count();
            
            // Instead of
            $count = Ticket::count();
            
            
              3 months later

              (I'm boakes, by the way -- I can't use that account anymore because the email I registered was for an employer I no longer work for.)

              I was just looking up another problem and found that the CLASS predefined constant will provide the desired behavior.

              Also, in response to ahundiak -- I had let it go for the time being -- it completely goes against tons of good design (and even the complete purpose of static methods). As soon as you start instantiating objects all over without needing them just for a single method, you've incurred a setup cost for nothing. Further, it makes the code just that much more verbose for no real reason, which is never good. My final solution provided is more flexible, in my opinion.

              ahundiak wrote:

              This is a well know feature/limitation of PHP 5. Might be changed in PHP 6 but I wouldn't hold me breath.

              The real question is why use static methods at all? I know you are probably trying to save the cost of instantiating an object but is that really a problem? Go with dynamic methods and don't worry about performance unless it really becomes an issue. Makes programing under PHP so much easier.

              // Use
              $count = Ticket::getInstance()->count();
              
              // Instead of
              $count = Ticket::count();
              
              
                divokz wrote:

                Also, in response to ahundiak -- I had let it go for the time being -- it completely goes against tons of good design (and even the complete purpose of static methods). As soon as you start instantiating objects all over without needing them just for a single method, you've incurred a setup cost for nothing. Further, it makes the code just that much more verbose for no real reason, which is never good. My final solution provided is more flexible, in my opinion.

                Well. Another good design feature of OOP is to use objects. If you want to use functions then use functions.

                The problem you will soon run into is that as you attempt to add more static functions the code will get messier and messier. Especially if you need to rely on eval. I have gone down the static route a number of times and almost always end up refactoring. But maybe thats just me.

                  To each his own. I've never run into problems as of yet, but I can imagine what you mean.

                    ahundiak wrote:

                    Might be changed in PHP 6 but I wouldn't hold me breath.

                    5.3, in fact.

                      Weedpacket wrote:

                      5.3, in fact.

                      Cool. Couple of more years until it's stable then we should all be good to go.

                        20 days later

                        I was just looking up another problem and found that the CLASS predefined constant will provide the desired behavior.

                        This is actually incorrect -- CLASS always evaluates to the name of the class in which the static function was defined, not the class from which it was called.

                        This code:

                        class MyParent {
                            public static function say_hi() {
                                echo("<p>Hi, this is " . __CLASS__ . "!</p>");
                            }
                        }
                        
                        class MyDaughter extends MyParent {
                        }
                        
                        class MySon extends MyParent {
                        }
                        
                        MyParent::say_hi();
                        MyDaughter::say_hi();
                        MySon::say_hi();

                        ...produces this output...

                        Hi, this is MyParent!

                        Hi, this is MyParent!

                        Hi, this is MyParent!

                          2 years later

                          Hi,

                          Though I am not a technical person but found your post to be very informative.

                          I would like to share a link where a Software Testing Engineer of my company (Mindfire Solutions) has done a very good analysis on PHP development Applications.

                          Here is the link on PHP.
                          Hope you find it useful.

                            4 days later
                            Write a Reply...