Does Static Method in PHP Have Any Difference with Non-Static Method

Does static method in PHP have any difference with non-static method?

Except that, if you try to use $this in your method, like this :

class t {
protected $a = 10;
public function tt() {
echo $this->a;
echo 1;
}
}
t::tt();

You'll get a Fatal Error when calling the non-static method statically :

Fatal error: Using $this when not in object context in ...\temp.php on line 11

i.e. your example is a bit too simple, and doesn't really correspond to a real-case ;-)


Also note that your example should get you a strict warning (quoting) :

Calling non-static methods statically
generates an E_STRICT level warning.

And it actually does (At least, with PHP 5.3) :

Strict Standards: Non-static method t::tt() should not be called statically in ...\temp.php on line 12
1

So : not that good ;-)


Still, statically calling a non-static method doesnt't look like any kind of good practice (which is probably why it raises a Strict warning), as static methods don't have the same meaning than non-static ones : static methods do not reference any object, while non-static methods work on the instance of the class there're called on.


Once again : even if PHP allows you to do something (Maybe for historical reasons -- like compatibility with old versions), it doesn't mean you should do it !

PHP static methods vs non-static methods/standard functions

To call a non-static method you need to instantiate the class (use the new keyword to create a new instance of the class).

When calling a static method you don't have to "new it up" but it won't have direct access to any of the non-static properties or methods. There are dozens of use-cases / scenarios where you might want to use one over the other.

To be quite honest it has never even crossed my mind to think about performance of using one over the other. If it got to a point where it made that much of a noticeable difference (and all major steps had been taken to increase efficiency) then I would imagine that either the maintenance costs of such a big application would outweigh the need for the increased efficiency or the logic behind the app is fairly flawed to begin with.


Examples for static and non-static

If I was going to use a class for the example in your question then I would use the static version as nothing in the method is reliant on other properties of the class and you then don't have to instantiate it:

Session::start_new_session()

vs

$session = new Session();

$session->start_new_session();

Also, static properties on a class will remember state that would have otherwise been lost if you were to use a non-static property and instantiation:

class Session
{
protected static $sessionStarted = false;

static function start_new_session()
{
if (!static::$sessionStarted) {
session_start();
static::$sessionStarted = true;
}
}
}

Then even if you did:

$session = new Session();

$hasStated = $session::sessionStarted;

$hasStarted would still be true.

You could even do something like:

class Session
{
protected static $sessionStarted = false;

public function __construct()
{
$this->startIfNotStarted();
}

function startIfNotStarted()
{
if (!static::$sessionStarted) {

session_start();

static::$sessionStarted = true;
}
}
}

This way you don't need to worry about starting the session yourself as it will be started when you instantiate the class and it will only happen once.

This approach wouldn't be suitable if you had something like a Person class though as the data would be different each time and you wouldn't want to use the same data in difference instantiations.

class Person
{
protected $firstname;

protected $lastname;

public function __construct($firstname, $lastname)
{
$this->firstname = $firstname;
$this->lastname = $lastname;
}

public function getFullname()
{
return "{$this->firstname} {$this->lastname}";
}
}
$person1 = new Person('John', 'Smith');
$person2 = new Person('Jane', 'Foster');

$person1->fullname(); // John Smith
$person2->fullname(); // Jane Foster

If you were to use static methods / properties for this class then you could only ever have one person

class Person
{
protected static $firstname;

protected static $lastname;

static function setName($firstname, $lastname)
{
static::$firstname = $firstname;
static::$lastname = $lastname;
}

static function getFullname()
{
return static::$firstname . ' ' . static::$lastname;
}
}
Person::setName('John', 'Smith');
Person::setName('Jane', 'Foster');

Person::getFullname(); //Jane Foster

The debates

You are probably going to see a lot of debates over which is better and what the best practices are when it comes to PHP (not just about static and not-static methods).

I wouldn't get bogged down with it though! If you find that one side makes more sense to you (and whatever you're building at the time) then go with that one. Standards and opinions change all the time in this community and half of the stuff that was a problem 5 years ago (or even less) will actually be non-issues today.

Take the Laravel framework as an example -- one of the (many) debates is that Facades are bad because they're static and make use of magic methods which is hard to test and debug. Facades are actually very easy to test and with the use of stack trace error reporting it isn't hard to debug at all. That's not to say their aren't caveats when it comes to testing static methods, but this is more to do with mocking/spying -- this answer goes into it in a little more detail.

That being said, if you find the majority of people are saying the same thing and there isn't really a debate for the other side, there is probably a reason e.g. don't use mysql_ functions or don't run queries inside a loops.

PHP: Static and non Static functions and Objects

Static functions, by definition, cannot and do not depend on any instance properties of the class. That is, they do not require an instance of the class to execute (and so can be executed as you've shown without first creating an instance). In some sense, this means that the function doesn't (and will never need to) depend on members or methods (public or private) of the class.

static method vs non-static method

Before we go any further: Please, get into the habbit of always specifying the visibility/accessibility of your object's properties and methods. Instead of writing

function foo()
{//php 4 style method
}

Write:

public function foo()
{
//this'll be public
}
protected function bar()
{
//protected, if this class is extended, I'm free to use this method
}
private function foobar()
{
//only for inner workings of this object
}

first off, your first example A::foo will trigger a notice (calling a non-static method statically always does this).

Secondly, in the second example, when calling A::foo(), PHP doesn't create an on-the-fly instance, nor does it call the method in the context of an instance when you called $a->foo() (which will also issue a notice BTW). Statics are, essentially, global functions because, internally, PHP objects are nothing more than a C struct, and methods are just functions that have a pointer to that struct. At least, that's the gist of it, more details here

The main difference (and if used properly benefit) of a static property or method is, that they're shared over all instances and accessible globaly:

class Foo
{
private static $bar = null;
public function __construct($val = 1)
{
self::$bar = $val;
}
public function getBar()
{
return self::$bar;
}
}
$foo = new Foo(123);
$foo->getBar();//returns 123
$bar = new Foo('new value for static');
$foo->getBar();//returns 'new value for static'

As you can see, the static property $bar can't be set on each instance, if its value is changed, the change applies for all instances.

If $bar were public, you wouldn't even need an instance to change the property everywhere:

class Bar
{
public $nonStatic = null;
public static $bar = null;
public function __construct($val = 1)
{
$this->nonStatic = $val;
}
}
$foo = new Bar(123);
$bar = new Bar('foo');
echo $foo->nonStatic, ' != ', $bar->nonStatic;//echoes "123 != foo"
Bar::$bar = 'And the static?';
echo $foo::$bar,' === ', $bar::$bar;// echoes 'And the static? === And the static?'

Look into the factory pattern, and (purely informative) also peek at the Singleton pattern. As far as the Singleton pattern goes: Also google why not to use it. IoC, DI, SOLID are acronyms you'll soon encounter. Read about what they mean and figure out why they're (each in their own way) prime reasons to not go for Singletons

What is the difference between static functions and function outside of a class in PHP?

1) What is difference between static function and normal function

While they are functions, I'd prefer to call them methods of a given class. One is a static method and the other is an instance method.

Static Method: $item = Item::getDetail(15);

Instance Method: $item = getDetail(15);

(refer to FuzzyTree's correct syntax above in the comments, however.)

2) How to use static function and normal function (if you simple exemplify is good)

Static means you do not have to instantiate (declare an object reference). That is, you can simply use the method. So, in your example, while the answer may be the same, the way you called that method/function is different, as you noted above.

In Java, for example, you have the Math class. It does not require instantiation to use, and in fact you cannot that I know of because its constructor is private. You can simply use a method by referencing the class and the method name you wish to use,

Math.pow(d1, d2);  //no instantiation needed

in PHP this might be,

MyClass::pow(d1,d2); //no instantiation needed

Java: when to use static methods

3) Ask performance between static function and normal function. Which is better?

Better is a matter of your design. If you have to create an object every time you want to do the power of a number that will create more memoryusage than simply using the class directly. I do not have benchmark proof, but it seem logical since you are not handling the method the same way in memory. I do not think it will matter in real world unless you are doing a lot of complicated actions.

Performance of static methods vs instance methods

might also interest you.

What is the difference between static methods in a Non static class and static methods in a static class?

The only difference is that static methods in a nonstatic class cannot be extension methods.


In other words, this is invalid:

class Test
{
static void getCount(this ICollection<int> collection)
{ return collection.Count; }
}

whereas this is valid:

static class Test
{
static void getCount(this ICollection<int> collection)
{ return collection.Count; }
}

Is it possible to declare a method static and nonstatic in PHP?

You can do this, but it's a bit tricky. You have to do it with overloading: the __call and __callStatic magic methods.

class test {
private $text;
public static function instance() {
return new test();
}

public function setText($text) {
$this->text = $text;
return $this;
}

public function sendObject() {
self::send($this->text);
}

public static function sendText($text) {
// send something
}

public function __call($name, $arguments) {
if ($name === 'send') {
call_user_func(array($this, 'sendObject'));
}
}

public static function __callStatic($name, $arguments) {
if ($name === 'send') {
call_user_func(array('test', 'sendText'), $arguments[0]);
}
}
}

This isn't an ideal solution, as it makes your code harder to follow, but it will work, provided you have PHP >= 5.3.

PHP: What if I call a static method in non-static way

As Baba already pointed out, it results in an E_STRICT depending on your configuration.

But even if that's no problem for you, I think it's worth mentioning some of the pitfalls which may result from calling static methods in a non-static way.

If you have a class hierarchy like

class A {
public static function sayHello() {
echo "Hello from A!\n";
}

public function sayHelloNonStaticWithSelf() {
return self::sayHello();
}

public function sayHelloNonStaticWithStatic() {
return static::sayHello();
}
}

class B extends A {
public static function sayHello() {
echo "Hello from B!\n";
}

public function callHelloInMultipleDifferentWays() {
A::sayHello();
B::sayHello();
$this->sayHelloNonStaticWithSelf();
$this->sayHelloNonStaticWithStatic();
$this->sayHello();
}
}

$b = new B();
$b->callHelloInMultipleDifferentWays();

This produces the following output:

Hello from A!
// A::sayHello() - obvious

Hello from B!
// B::sayHello() - obvious

Hello from A!
// $this->sayHelloNonStaticWithSelf()
// self alweays refers to the class it is used in

Hello from B!
// $this->sayHelloNonStaticWithStatic()
// static always refers to the class it is called from at runtime

Hello from B!
// $this->sayHello() - obvious

As you can see, it's easy to achieve unexpected behaviour when mixing static and non-static method calls and techniques.

Therefore, my advice also is:
Use Class::method to explicitly call the static method you mean to call.
Or even better don't use static methods at all because they make your code untestable.



Related Topics



Leave a reply



Submit