-1

Consider a static class (private constructor, only static methods & variables).

Now the rough class definition would look like this:

class A{
   private function __construct(){}
   public static test(){};
}
class B{
   private function __construct(){}
}

Is it somehow possible to call something like B::A::test() ?

Or maybe through a variable? Something like B::$A::test() ?

I guess it is possible by some general call catching, but I can't figure it out...

IMPORTANT: Also, I want to call ANY other static class from B, not just from the A class...

EDIT2: What I want to achieve is to call static class through another static class, if possible... very similar to calling a method from object variable - but static class (obviously) is not ment to be instantiated.

EDIT3: Also possible solution is to call it as B::CLASSNAME_METHOD_NAME and catch it by __callStatic but I would rather do B::CLASSNAME::METHOD_NAME ...

Another possible solution:

If you don't want to create whole singleton, this could be solution - creating a partial singleton - some kind of singleton-hepler, altough using -> to call a static method could be confusing!

class AA{
    private function __construct(){}
    private static $instance;
    public function getInstance(){ return empty(self::$instance)?(new self()):self::$instance; }
    public function __call($method_name, $args) {
       return AA::$method_name($args);
    }
    public static function test($a, $b){
        echo "TEST: A:".$a." B:".$b; 
    }   
}

class B{
    private function __construct(){}
    public static function A(){
        return AA::getInstance();
    }
}

B::A()->test("one", "two");
jave.web
  • 13,880
  • 12
  • 91
  • 125
  • What would `B::A::test()` do that `A::test()` doesn't...?! – deceze Mar 11 '16 at 08:35
  • 2
    I still don't get what the difference is supposed to be. Let's put it this way: the syntax you show doesn't exist, and therefore has no intrinsic meaning. You're trying to invent some new kind of operation here, or drive at some existing operation with a bad explanation. Please explain in more detail what this is supposed to result in and why just `A::test()` doesn't cut it. – deceze Mar 11 '16 at 08:37
  • Why would you want to call a static class through another static class? isn't that misusing the purpose of a static class? To easier instantiate it in other classes(making it abstract for easy using). – izk Mar 11 '16 at 08:42
  • So would `B::A` always refer to `class A`? Or is your point that a `const` or `static` property of `B` should refer to another class, and you want to call that class' method, dynamically resolving the class? – deceze Mar 11 '16 at 08:42
  • 1
    BTW, at that point you should stop using statics and just instantiate your classes... – deceze Mar 11 '16 at 08:43
  • The latter one - B should have some kind of reference to another class, dynamicly resolving the class call... – jave.web Mar 11 '16 at 08:44
  • @deceze Yes, I know it could be done by instantiating the class, but why would I create singletons, when there would be a pure static approach? (the classes contain API and do not have to be instantiated) – jave.web Mar 11 '16 at 08:45
  • You may be interested in my take on that: [How Not To Kill Your Testability Using Statics](http://kunststube.net/static/) – deceze Mar 11 '16 at 08:46
  • @deceze your article about The Definitive Guide To PHP's isset And empty really helped me out. So I would advise jave.web to read your articles! – izk Mar 11 '16 at 08:51

2 Answers2

1

You would have to use this syntax:

class B {
   const A = 'A';
}

$class = B::A;
$class::test()

This is essentially just the syntax for calling a static method on a variable class name. There's no nicer shortcut for it.

Note that I don't think such a pattern makes a lot of sense, your class design is too static at this point. You should be instantiating your classes and call $b->a->test(), which gives you more flexibility in your application design. Realistically B::A is hardcoded, it's not going to be anything other than 'A', so you may as well write A::test() directly.
If instead of a const you'd use a public static property which may vary at runtime, you now introduce global state into your app, which is also undesirable.

deceze
  • 510,633
  • 85
  • 743
  • 889
  • The `A` can be called itself, but if it's name would be shorter, it could make conflict - but not when calling it through `B` - that way it is clear, what `A` should be called... – jave.web Mar 11 '16 at 08:58
  • At the micro level maybe so, but I'm trying to tell you that maybe at the macro level you should rethink things... But again, suit yourself... :) – deceze Mar 11 '16 at 09:01
  • 1
    As I said, there's no nicer shortcut. – deceze Mar 11 '16 at 09:06
  • Check my possible solution (added to question) - you gave me the idea of having something constantly calling another class + the singleton approach... – jave.web Mar 11 '16 at 09:23
0

calling static function of a class from a static function of an another class

class A{
   private function __construct(){}

   public static function test()
   { 
       echo 'from class A'; 
   }
}

class B{
   private function __construct(){}

    public static function test() 
    {
        return A::test();
    }
}

A::test(); //outputs 'from class A'
B::test(); //outputs 'from class A'
Nonong Re
  • 93
  • 3