Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

php call class method from static method inside same class but non instantiated

php 5.3+

Sorry for the long question, but I want to learn this completely.

I know I can't call a non-static same class method from inside a static method, without the class being instantiated as an object.

class Person 
{
    private $people_array;

    function data_all_get()
    { // touch database, return array of people
      $this->people_array = // etc dbquery results
    }

    static function showPeople()
    {  // call class method
       $people_data = $this->data_all_get();
       // Fatal error: Using $this when not in object context
    }
} // end class Person

From searching on SO, I found some interesting approaches, but wondering how each approach affects the code environment.

My questions are below:

I could instantiate the class as an object inside the static method, to gain access to the non-static method

static function showPeople()
{  // instantiate as object
   $person = New Person();
   // call class method
   $people_data = $this->data_all_get();
}

Q1 - what problems could this cause ? in my situation, the class does not have a constructor so no other class methods nor vars would be affected by the instance. Would this new object just take up a little space in memory during script execution? Doesn't seem too bad...


the other option would be to convert the "data_all_get" method into a static method, so it could be called from inside the static method "showPeople", i.e.

self::showPeople()

the "data_all_get" method is being used by other methods in the class when it is instantiated as an object, to set the value of the private var, to reduce trips to the database, if it is already set. I know this probably could be part of a constructor function, but I never have a need for this "Person" object to be instatiated more than once per php script request, the class is mostly used to group functions and vars together for organization ...

Q2 - what are the implications of making "data_all_get" into a static method ? are there any? if the method was static, but it sets the value of the private var $people_array (which is not static), I think that var would be able to be updated or overwritten if the object ever needed to be instantiated a second time in a single script request, correct? Plus since the property is not static other methods of the class can access it.

Q3 - Could I call the static method "data_all_get" as many times as I wanted without "breaking anything" (a loaded question IK).

Q4 - Does it simply use additional memory every time the static method is called?

Thank you

like image 550
Steve Wasiura Avatar asked Oct 24 '12 01:10

Steve Wasiura


People also ask

How can we call static method from same class in php?

Example Explained Here, we declare a static method: welcome(). Then, we call the static method by using the class name, double colon (::), and the method name (without creating an instance of the class first).

Can you call a static method from a non-static instance method if not why and if so how?

A static method can call only other static methods; it cannot call a non-static method. A static method can be called directly from the class, without having to create an instance of the class.

Can I call non-static method from static method php?

PHP 8.0 no longer allows to call non-static class methods with the static call operator ( :: ). Calling non-static methods statically raised a PHP deprecation notice in all PHP 7 versions, and raised a Strict Standards notice in PHP 5 versions.

Can we call a static method with the same class object?

Static methods are the methods in Java that can be called without creating an object of class. They are referenced by the class name itself or reference to the Object of that class.


1 Answers

class Person 
{
    private static $people_array;

    static public function data_all_get()
    { 
         self::$people_array = //DBStuff
    }

    static public function showPeople()
    {  
        $people_data = self::data_all_get();
    }
 }

Just a few notes, some perhaps obvious. 1) As is you aren't returning anything so obviously the above code will fail. There's nothing wrong, per say, with the code above. In answer to your Q1 all you've done is taken a pair of function calls using a global variable and encapsulated them inside of a class. I would advise against sometimes using this as an instantiated class and sometimes not doing so, as it will make your final code less readable and more difficult for people to understand when they're looking it over.

If you're worried about instantiating this more than once, you might want to look at the singleton design pattern, but in general if you're planning to instantiate the class at some point I would re-examine why you're calling these statically in the first place. There's nothing wrong with that, per say, other than it 'feels wrong' to me.

Q2) The only implication of making data_all_get into a static array is then it's referencing a static property, which in turn means this property will be inaccessible if instantiated. Also, you're losing the ability to instantiate multiple versions of this class (if that matters) and basically turning people_array into a global variable. That's not necessarily bad, but without knowing what the rest of your functionality is doing it's hard to say what the implications are.

Q3) The only issue running it multiple times is A) wiping out whatever is in people array, and B) Multiple DB calls. Without seeing what other code is going on this questions is more or less impossible to answer.

Q4) The memory for a method the size of what you have listed here is negligible to the point of not being worth talking about. The concern comes in with the DB call itself, and the number of rows being accessed there

Lastly, it's a bit odd as you have this code written now, since showPeople does the exact same thing as data_all_get. You probably want to write some logic inside of showPeople to see if $people_array is empty or not, and if so, run data_all_get and if not, return people_array. This will avoid additional DB reads. If you're going to go read the DB each time anyways, then you might as well have data_all_get return $people_array, in which case none of this needs to be inside a class, and it can just be a function call which returns what it finds in the db.

like image 144
DaOgre Avatar answered Oct 29 '22 06:10

DaOgre