53

Why some developers create one method that returns new static? What is the reason to have a method that returns new static? I am not asking what is the difference between static and self, or what static & self mean. For example, here is one simple class:

<?php

class Expression
{
    public static function make()
    {
        return new static;
    }


    public function find($value)
    {
        return '/' . $value .'/';
    }

    public function then($value)  
    {
        return $this->find($value);
    }

    public function hi($value)  
    {
        return "hi";
    }

}

As you can see, there is a static method make() which returns new static. Then, some developers call other methods like this:

$regex = Expression::make()->find('www');

What is the purpose of this? I see that here we don't use new Expression syntax, and if that's the point - then why not make all methods static? What is the difference, what is the reason to have that one method that returns new static (while other methods are not static)?

PeraMika
  • 3,539
  • 9
  • 38
  • 63
  • 3
    Possible duplicate of [what means new static?](http://stackoverflow.com/questions/15898843/what-means-new-static) – Ankur Tiwari May 26 '16 at 12:17
  • 2
    The answer to [New self vs. new static](http://stackoverflow.com/questions/5197300/new-self-vs-new-static?rq=1) explains the difference clearly. –  May 26 '16 at 12:20
  • 1
    @Ankur Tiwari I am **not** asking what is the difference between _static_ & _self_, or what _static_ & _self_ do. – PeraMika May 26 '16 at 12:30
  • 1
    @jeyoung My question is not about the difference between New self vs. new static... – PeraMika May 26 '16 at 12:38
  • 1
    @PeraMika It looked like you did not understand the purpose of `new static()`, but if you do... It's for re-use. You can define the static `make` method in a single base class and you will have the same functionality from derived classes. –  May 26 '16 at 12:43
  • @jeyoung deceze gave a nice explanation, it's basically an alternative constructor... Thanks – PeraMika May 26 '16 at 12:58

2 Answers2

73

new static instantiates a new object from the current class, and works with late static bindings (instantiates the subclass if the class was subclassed, I expect you understand that).

Having a static method on a class which returns a new instance of same is an alternative constructor. Meaning, typically your constructor is public function __construct, and typically it requires a certain bunch of parameters:

class Foo {
    public function __construct(BarInterface $bar, array $baz = []) { ... }
}

Having an alternative constructor allows you to provide different defaults, or convenience shortcuts to instantiate this class without having to supply those specific arguments and/or for being able to provide different arguments which the alternative constructor will convert to the canonical ones:

class Foo {

    public function __construct(BarInterface $bar, array $baz = []) { ... }

    public static function fromBarString($bar) {
        return new static(new Bar($bar));
    }

    public static function getDefault() {
        return new static(new Bar('baz'), [42]);
    }

}

Now, even though your canonical constructor requires a bunch of complex arguments, you can create a default instance of your class, which will probably be fine for most uses, simply with Foo::getDefault().

The canonical example in PHP for this is DateTime and DateTime::createFromFormat.

In your concrete example the alternative constructor doesn't actually do anything, so it's rather superfluous, but I expect that's because it's an incomplete example. If there's indeed an alternative constructor which does nothing other than new static, it's probably just meant as convenience syntax over (new Foo)->, which I find questionable.

thisisboris
  • 431
  • 1
  • 3
  • 13
deceze
  • 510,633
  • 85
  • 743
  • 889
  • 1
    Now I understand the purpose of it, thank you very much! – PeraMika May 26 '16 at 12:50
  • 1
    I guess that the constructor is really empty and this is made just for sugar. Probably that the developer prefer to call new object this way in order to concact them. So instead of write: `$search = (new Expression)->find("wow");`, he can just wrote `$search = Expression::make()->find("wow")`. Of course it's the same. – Max Cuttins Dec 04 '18 at 19:56
30

Complete answer here

TLDR
get_called_class().

class A {
    public static function get_self() {
        return new self();
    }

    public static function get_static() {
        return new static();
    }
}

class B extends A {}

echo get_class(A::get_self()); // A
echo get_class(A::get_static()); // A
echo get_class(B::get_self());  // A
echo get_class(B::get_static()); // B
Sergey Shuchkin
  • 2,037
  • 19
  • 9
  • 14
    Not really an answer to the question, but still useful, clearly shows the difference between self and static. – Przemek K. Jul 08 '17 at 12:06
  • @sergeyshuchkin great Example... with little description more helpful it will be – Er. Amit Joshi Apr 03 '21 at 08:22
  • 4
    It seems this answer was shamelessly copied without attribution and then incorrectly modified from this other more complete answer by @BoltClock https://stackoverflow.com/a/5197655/190955 The answer was then edited for correctness - back to the original. I tried to edit in an attribution and the more complete explanation, but the edit queue is full. – TonyG Feb 11 '22 at 19:03