NotionCommotion Posted March 25, 2023 Share Posted March 25, 2023 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(); } } Quote Link to comment https://forums.phpfreaks.com/topic/316045-return-this-if-static-method-called-on-an-object/ Share on other sites More sharing options...
maxxd Posted March 25, 2023 Share Posted March 25, 2023 Sounds like Laravel's facades - maybe that could serve as an example? Quote Link to comment https://forums.phpfreaks.com/topic/316045-return-this-if-static-method-called-on-an-object/#findComment-1606825 Share on other sites More sharing options...
kicken Posted March 25, 2023 Share Posted March 25, 2023 Static methods do not have a $this object, regardless of how they are called. To me, what you're asking for doesn't really make sense to do either. In your example code, I'd just make your echo / syslog function return void. Quote Link to comment https://forums.phpfreaks.com/topic/316045-return-this-if-static-method-called-on-an-object/#findComment-1606826 Share on other sites More sharing options...
maxxd Posted March 25, 2023 Share Posted March 25, 2023 That's kinda why I referred to the facade objects/pattern; it seems like it covers the underlying ask but in a way that makes sense. Quote Link to comment https://forums.phpfreaks.com/topic/316045-return-this-if-static-method-called-on-an-object/#findComment-1606834 Share on other sites More sharing options...
NotionCommotion Posted March 26, 2023 Author Share Posted March 26, 2023 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). Quote Link to comment https://forums.phpfreaks.com/topic/316045-return-this-if-static-method-called-on-an-object/#findComment-1606839 Share on other sites More sharing options...
gizmola Posted March 29, 2023 Share Posted March 29, 2023 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. Quote Link to comment https://forums.phpfreaks.com/topic/316045-return-this-if-static-method-called-on-an-object/#findComment-1606926 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.