Web Analytics Made Easy -
StatCounter Question about call_user_func with non static methods - CodingForum

Announcement

Collapse
No announcement yet.

Question about call_user_func with non static methods

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Question about call_user_func with non static methods

    I must clean some warnings/notices form some lib we use and I get the following error:
    Strict Standards: Non-static method users::setId() cannot be called statically, assuming $this from compatible context users in users.php on line 100
    These are lines 99 and 100 of users.php:
    PHP Code:
    if ($this->propertyExists($this->className$first.$key))
        
    call_user_func(array($this->className'set'.ucfirst($first).$key), $value); 
    OK I understand the error (setId is not a static method of the class "users"). For now, error reporting is off and everything is working (as far as we know) but I want to get rid of all notices/warnings to improve the code.

    call_user_func runs something like users::setId(2); currently but it should run $this->setId(2); to get rig of the Strict Standards notice.

    Is there a way to use call_user_func (or one of it's "friend") to run it as $this->setId(2); ?

    Hope I'm clear...

    Many thanks!

  • #2
    I don't know why it's not working for you, maybe because you should pass $this instead of $this->className..? because you've got to pass the class/object to it. So e.g.
    PHP Code:
    <?php

    error_reporting
    (E_ALL);

    class 
    MyClass
    {
      public function 
    __construct()
      {
        
    call_user_func(array($this'helloWorld'));
      }


      public function 
    helloWorld()
      {
        echo 
    'Hello World';
      }
    }

    new 
    MyClass();
    Will call the helloWorld method, does that clear it up? Because it is accessing the method via $this->method() like you wanted and not users::method.

    Compared to say
    PHP Code:
    class MyClass
    {
      public function 
    __construct()
      {
        
    call_user_func(array('MyClass''helloWorld'));
        
    /* Or
        call_user_func(array('self', 'helloWorld'));
        */
      
    }


      public static function 
    helloWorld()
      {
        echo 
    'Hello World';
      }
    }

    new 
    MyClass(); 

    Comment


    • #3
      "My" code works, but I use error_reporting(E_ALL | E_STRICT); And I think it's E_STRICT who issue my errors...

      Quote from the PHP doc:
      The function to be called. Class methods may also be invoked statically using this function by passing array($classname, $methodname) to this parameter.
      I guess E_STRICT don't like a non static method to be called statically... Which is the reason of my post... How to correctly do this?
      Last edited by AlexV; Apr 7, 2009, 04:45 PM.

      Comment


      • #4
        This is one of the things bothering me about the recent changes in PHP. Up to what, 5.2.3, you could use $this as an object in a callback for call_user_func without a strict warning, and now you cannot.
        Anyway, two versions ago I wouldn't have suggested this since my tests indicated that there was overhead. However, unless my tests were inaccurate or zend has changed it, there appears to be almost no overhead involved now.
        Use reflection for it.
        I can't test this, but it should be something like this:
        PHP Code:
        $reflectClass = new ReflectionClass($this->className->getClass()); // Assuming that this.className is an instance
        $reflectMethod $reflectClass->getMethod('set'.ucfirst($first).$key);
        if (
        null !== $reflectMethod)
        {
            
        $result $reflectMethod->invoke($this->className$value);
        }
        else
        {
            print 
        'No such method.';

        Edit:
        Wait a minute, what am I thinking here? Objects can be used as callback methods.
        I'm guessing here that $this->className is actually a string representation of a class, not an instance of a class. This is why you're getting the strict warning, you should be passing that as an instance of the $this->className, not as a string.

        The above code is only really useful if you're using an abstract factory to centralize all of you're calls.

        Edit:
        Yes I know what it was I was thinking about now. Its the ctor's of classes, they are not static so you pretty much have to use reflection if you want to use an abstract factory without using static methods to generate an instance.

        Last edited by Fou-Lu; Apr 7, 2009, 09:26 PM.
        PHP Code:
        header('HTTP/1.1 420 Enhance Your Calm'); 
        Been gone for a few months, and haven't programmed in that long of a time. Meh, I'll wing it ;)

        Comment


        • #5
          I have use reflection class before, but i feel that since you are doing it in the same class, won't it be great to do it in the class, rather than to create a new reflection object... so here is what i have come up with.
          PHP Code:
          class test
          {
              public function 
          __construct()
              {
                  
              }

              public function 
          get($type)
              {
                  
          $method "_get_{$type}";
                  if(
          method_exists($this$method))
                  {
                      return 
          $this->$method();
                  }
                   return 
          false;
              }

              protected function 
          _get_a()
              {
                  return 
          "This is from the protected \"a\" function.";
              }
              
              protected static function 
          _get_b()
              {
                  return 
          "This is from the protected static \"b\" function.";
              }
              
                  private function 
          _get_c()
              {
                  return 
          "This is from the private \"c\" function.";
              }
          }


          $t = new test();
          echo 
          $t->get("a");
          echo 
          "<br/>";
          echo 
          $t->get("b");
          echo 
          "<br/>";
          echo 
          $t->get("c"); 
          Last edited by kokjj87; Apr 8, 2009, 12:04 AM.

          Comment

          Working...
          X