Jump to content

Return $this if static method called on an object


NotionCommotion

Recommended Posts

Is it possible to return the instance of an object when a static method is called on it?  For instance, (new SomeClass)->echo() returns $this and SomeClass::echo() return a newly created object?  Thinking I could do so by making properties also static and then creating the new object and populating it (albeit it will be a clone and not the same object).  Thanks 

<?php
class SomeClass
{
    private $services = [];
    private $paramaters = [];

    public function Foo():self
    {
        echo(__METHOD__);
        return $this;
    }

    public static function echo(string $msg, array $data=[], bool $syslog = false):self|static
    {
        echo($msg.($data?(': data: '.json_encode($data)):'').PHP_EOL);
        return $syslog?self::syslog($msg, $data):$this->getSelfOrStatic();
        
    }

    public static function syslog(string $msg, array $data=[], bool $echo = false):self|static
    {
        syslog(LOG_INFO, $msg.($data?(': data: '.json_encode($data)):''));
        return $echo?self::echo($msg, $data):$this->getSelfOrStatic();
    }

    private static function getSelfOrStatic():self|static
    {
        return isset($this)?$this:new static();
    }
}

 

Link to comment
Share on other sites

Thanks maxxd,  I'll checkout the facade object/pattern, but likely won't use it for this use.

Thanks kicken,  In hindsight, I agree chaining doesn't bring much value for this case.  "If it did" (which it doesn't), guess I could just add another traditional method which would call the static method and directly return $this (but I won't).

Link to comment
Share on other sites

Conceptually, static methods are part of a class, given how they are called, but the reality is that there is a magic object created, so that for example, static variables have a place to live.

This code works, and you can consider it, if you would like.  There are also several alternatives like return new self() or return new static() as well as return  __CLASS__.  I'm fairly sure all these actually work with PHP 8.

Consider this code:

<?php

class Foo {
    private static $callCount = 0;
    
    private $previousCallCount = 0;
    
    public static function addCount() {
        self::$callCount++;
        return self::class;
    }
    
    public function setPrevious() {
        $this->previousCallCount = self::$callCount;
    }
    
    public static function getCount() {
        return self::$callCount;
    }
    
    public function getObj() {
        return $this;
    }
    
    public function getPreviousCallCount() {
        return $this->previousCallCount;
    }
    
    public static function getCurrentCallCountStatic() {
        return self::$currentCallCount;
    }

}


echo "start " . Foo::getCount() . PHP_EOL;

Foo::addCount()::addCount();



$foo = new Foo();

$foo->setPrevious();
$foo->addCount();

echo "addCount was called, now " . Foo::getCount() . PHP_EOL;

$fooObj = $foo->getObj();
$fooObj->setPrevious();

$fooObj->addCount();

echo "addcount was called, now " . Foo::getCount() . PHP_EOL;

echo "What is fooObj's addCount?  " . $fooObj->getCount() . PHP_EOL;

echo "Previous: " . $foo->getPreviousCallCount() . PHP_EOL;
echo "Next: " . $fooObj->getPreviousCallCount() . PHP_EOL;


echo $foo === $fooObj ? 'Same objects' : 'Different Objects';

 

So I like to think of it as "there's this one object that exists to support static class use.  It's actually kind of a mess, but this code works, and even has some surprises in my opinion as in how $previousCallCount is handled.  I'm not sure what problem this solves, or why this is a good sensible solution.  If you want a fluent interface you can return the magical static object and use it fluently if you have a bunch of non static methods you would call.  From time to time I've seen people utilize this feature, but I don't recall where I last saw it, or if I understood the motivation.

A lot of your questions seem to be missing clear obvious context, so I'm never quite sure if I get why you want to explore this stuff, but I commend your consistent interest in exploring ideas within what php allows.

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.