2

Here is the scenario.

I am implementing namespaces into my projects.

I have my own custom bridge library that calls other libraries like Zend to do the heavy lifting.

I have no problem using fully qualified namespaces in my custom bridge library but would like to keep the code as terse as possible in my controllers, models and view.

Here is an example of some aliasses i would like to use:

use BridgeLibName\Stdlib\Arrays as arr;
use BridgeLibName\Stdlib\Objects as obj;
use BridgeLibName\Stdlib\Strings as str;
use BridgeLibName\Stdlib\Numbers as num;
use BridgeLibName\Stdlib\File as file;
etc.........

Example usage:

$file = new file('path/to/file.txt');
$file->create();

or

$obj = arr::toObject(['key1'=>'value1']);

is it possible in any way to create an alias or constant that can be globally accessible and not discarded at the end of each file?

Some kind of bootstrap file that can make these aliases stick.

Dieter Gribnitz
  • 5,062
  • 2
  • 41
  • 38
  • No you can not (not in a sane way at least). – PeeHaa Nov 10 '13 at 13:38
  • Works perfectly if referenced with fake class. Must be really careful with implementation though. – Dieter Gribnitz Nov 10 '13 at 13:47
  • Using "fake" classes is a horrible solution to a non problem imho. – PeeHaa Nov 10 '13 at 13:49
  • I agree that it is a horrible solution. But writing out 20+ characters when it can be accomplished with 3 is worse. This makes my code bloated and unreadable. If used carefully i think it can be very useful. As long as you never implement it inside libraries but only keep it inside your app. Writing BridgeLibName\Stdlib\Arrays::inArray() vs arr::inArray() is a problem. If the root namespace changes for some reason this would be hard to fix globally. Aliasing in each controller or model file delivers the same problem. – Dieter Gribnitz Nov 10 '13 at 14:04
  • If you have a better solution, I am willing to discard the post and use it. – Dieter Gribnitz Nov 10 '13 at 14:06
  • If that is how you think about it please go ahead. I just have a strong and different opinion about your "solution". And no I don't have a better solution because I don't see the problem. – PeeHaa Nov 10 '13 at 14:07
  • Thanks for your time. I agree with your viewpoint to a great degree and cringe at the though of using this method myself, but it seems to solve my issue completely and it is the only thing that works. Since my libraries use namespaces correctly I think it should be able to implement this without causing any performance issues or creating conflicts. – Dieter Gribnitz Nov 10 '13 at 14:17
  • 1
    If something works for you in the way you like use it. Don't let some random person on teh intarnet tell you otherwise. If you fail later on in the process or you change you mind later that is progress either way. – PeeHaa Nov 10 '13 at 14:20

1 Answers1

3

As I was writing the question i thought of a solution.

You can fake it by creating classes that extend the namespaced classes.

example:

class arr extends BridgeLibName\Stdlib\Arrays{

}

One important thing to remember:

If you are going to extend the classes the namespaced class will have to be loaded.

This could have performance implications if used too much since aliases and namespaces are only loaded as needed.

Since I am only using it to bridge to other classes there is very little logic inside my bridge files.

These bridge files in turn uses aliases and namespaces correctly thus loading the real files as needed.

I you are not careful with the implementation you can load a lot of unnecessary stuff and cause your app to become slow and bloated.


A nice thing I noticed is that good IDEs like netbeans also seems to be able to do auto completion with this method.


If there is a better way to do this please let me know.


Just thought of an amendment to this method to fix the problem with unnecessary class instantiation.

The core library can work with the normal psr-0 loader.

To have the aliases autoload I created an aditional dir named includes next to my namespaced class.

in composer you describe it like so:

"autoload": {
    "psr-0": {
        "BridgeLibName\\": "."
    },
    "classmap": ["include/"]
}

Now your libraries will load as expected from the correct namespace and your alias classes will autoload as needed.

Classes put into the include dir can now extend the namespaced classes ( as shown above ) and will no longer be loaded prior to being used.

Now you have global aliases without having to sacrifice performance by loading unused classes.

Dieter Gribnitz
  • 5,062
  • 2
  • 41
  • 38
  • 1
    I just though of something. The method as I described can actually be very useful if you need to give legacy support for a library. Extending namespaced classes will allow older systems to use classes as if they were normal classes. For new projects this can easily be turned off by removing the classmap declaration in composer. – Dieter Gribnitz Nov 11 '13 at 13:50