global code should be enclosed in global namespace declaration php
PHP Global namespace aliases
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:
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.
1 Answer 1
As I was writing the question i thought of a solution.
You can fake it by creating classes that extend the namespaced classes.
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:
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.
Global code should be enclosed in global namespace declaration php
(PHP 5 >= 5.3.0, PHP 7, PHP 8)
Multiple namespaces may also be declared in the same file. There are two allowed syntaxes.
Example #1 Declaring multiple namespaces, simple combination syntax
This syntax is not recommended for combining namespaces into a single file. Instead it is recommended to use the alternate bracketed syntax.
Example #2 Declaring multiple namespaces, bracketed syntax
It is strongly discouraged as a coding practice to combine multiple namespaces into the same file. The primary use case is to combine multiple PHP scripts into the same file.
To combine global non-namespaced code with namespaced code, only bracketed syntax is supported. Global code should be encased in a namespace statement with no namespace name as in:
Example #3 Declaring multiple namespaces and unnamespaced code
namespace < // global code
session_start ();
$a = MyProject \ connect ();
echo MyProject \ Connection :: start ();
>
?>
No PHP code may exist outside of the namespace brackets except for an opening declare statement.
Example #4 Declaring multiple namespaces and unnamespaced code
declare( encoding = ‘UTF-8’ );
namespace MyProject <
namespace < // global code
session_start ();
$a = MyProject \ connect ();
echo MyProject \ Connection :: start ();
>
?>
User Contributed Notes 6 notes
echo «I belong to namespace a» ;
namespace b <
echo «I’m from namespace b» ;
>
//Namespace can be used in this way also
namespace MyProject <
function connect () < echo "ONE" ; >
Sub \ Level \ connect ();
>
namespace MyProject \ Sub <
function connect () < echo "TWO" ; >
Level \ connect ();
>
namespace MyProject \ Sub \ Level <
function connect () < echo "THREE" ; >
\ MyProject \ Sub \ Level \ connect (); // OR we can use this as below
connect ();
>
//call same named function using namespace
require ( ‘Apple.php’ );
require( ‘Orange.php’ );
use Apples ;
use Oranges ;
Apples \ eat ();
Oranges \ eat ();
?>
//Apple.php
namespace Apples ;
function eat ()
<
echo «eat apple» ;
>
?>
//Orange.php
namespace Oranges ;
There are rational examples of where the ability to blend multiple namespaces into a single file is not only desirable but also absolutely necessary. An example of where this ability is useful is over in the very popular phpseclib library where they are PSR-4 compliant but, in order to be compliant, they have to read a directory of files to know what classes are available so that the autoloader can load the correct files. If they, instead, just bundled the defaults into one file using this mechanism already supported by PHP core, there would be no need to do extraneous scanning of the file system.
That’s just one legitimate use-case where strict compliance with PSRs gets in the way of good software development.
What does it mean global namespace would be polluted?
What does it mean global namespace would be polluted?
I don’t really understand what global namespace getting polluted means.
3 Answers 3
Quick Note On Garbage Collection
As variables lose scope, they will be eligible for garbage collection. If they are scoped globally, then they will not be eligible for collection until the global namespace loses scope.
Here is an example:
Adding this to your global namespace (at least for me) should ad 10,000 kb of memory usage (win7 firefox) which will not be collected. Other browsers may handle this differently.
Whereas having that same code in a scope which goes out of scope like this:
Will allow arra to lose scope after the closure executes and be eligible for garbage collection.
Global Namespace Is Your Friend
Despite the many claims against using the global namespace, it is your friend. And like a good friend, you should not abuse your relationship.
Be Gentle
This is going to create 11 global variables which could possibly be overwritten or misconstrued somewhere.
Be Resourceful
A more resourceful approach, which does not pollute the global namespace, would be to wrap this all in the module pattern and only use one global variable while exposing multiple variables.
Here is an example: (Please note this is simple and there is no error handling)
Generated code in autoload_real.php should be namespaced #5231
Comments
Firehed commented Apr 22, 2016
While collisions are effectively impossible due to the random (hashed?) class and function names, having the class and function in the global namespace is slightly annoying when doing work that involves get_defined_functions or get_declared_classes if any filtering of the resulting array is required, especially when using the namespace support in the Reflection APIs.
Unless there’s a reason not to do this (which I’d be very interested in hearing), I’m more than happy to do the work and send a PR. I expect the file output would change from, roughly:
and the related call sites would be updated.
The only question I have is whether Composer\Autoload (that ClassLoader uses) or Composer\Autoloader (based on the generated class name) would be preferable, or something else entirely.
The text was updated successfully, but these errors were encountered:
We are unable to convert the task to an issue at this time. Please try again.
The issue was successfully created but we are unable to update the comment at this time.
alcohol commented Apr 22, 2016
Seldaek commented Apr 22, 2016
I think there is nothing speaking against it no. Sounds harmless enough but then again you never know what you’re gonna break when changing such things. Since we allow setting the autoload suffix then people might rely on the class name for some reason. I don’t see your use case as really warranting a BC break.
If anything you could also use https://getcomposer.org/doc/06-config.md#autoloader-suffix to set the suffix to a known value so that it gets easier to filter out?
Firehed commented Apr 22, 2016 •
Unfortunately I can’t since I’m building a standalone library, and the project root could override that value. There’s really no great way that I’ve found to get at the whole project’s metadata from the loaded Composer classes without manually re-parsing the json files (which is really my root issue). In any case the difficulty is the same in filtering by prefix, namespace, or suffux. What I hope to address is not needing to handle more than one, since I already need to filter out Composer\Autoload\ClassLoader so I’m already looking for the Composer\ namespace (it’s not a show-stopper by any means)
But I’m also keenly aware that the unlikely BC break this introduces would somewhat ironically most likely cause issues with my own use case 😉 If there are future versions with BC breaks planned, would you consider making (or merging) this change?
Seldaek commented Apr 22, 2016
Well.. even if we make a breaking release, the amount of breakage should only be as great as needed ideally. Breaking things for the sake of breaking things isn’t great 🙂 And in this case really I am not sure the benefit is that great. You have one prefix or two to filter, doesn’t seem like it’s worth inflicting pain on anyone else 🙂
Firehed commented Apr 22, 2016
Of course, it’s totally reasonable to avoid adding any unnecessary BC breaks, even during a release that allows for them. I wasn’t trying to suggest doing it just to do it, even if my specific use-case may come across as that way.
As an end-user, I would still expect a project using namespaces to not put code in the global namespace, even if that code is automatically generated. Composer is obviously pretty special both within the PHP community and in its specific needs, but I’d still consider the current behavior both unexpected and undesirable.
But ultimately it’s your call and I respect the decision either way.
Seldaek commented Apr 22, 2016
I tend to agree in general, which is why it’s prefixed with composer* (and hence namespaced in a way). I guess we could do this in 2.0 and if anyone complains before we release a stable 2.0 we can always revert.
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
PHP Namespace
Summary: in this tutorial, you’ll learn about PHP namespaces, how to define classes that belong to a namespace, and how to use namespaces.
Why namespaces
When your project grows in complexity, you’ll need to integrate the code from others. Sooner or later, you’ll find that your code has different classes with the same name. This problem is known as name collision.
To resolve it, you can use namespaces. PHP supported namespaces since version 5.3.
What is a namespace
It’s easier to understand namespaces by analogy to the directory structure in a filesystem.
A directory stores related files, which is similar to a namespace that groups related classes.
A directory doesn’t allow you to have two files with the same name. However, you can have files with the same names in different directories. Likewise, namespaces mimic the same principle.
By definition, namespaces provide you with a way to group related classes and help you avoid any potential name collisions.
Namespaces are not limited to group classes. They can group other identifiers, including functions, constants, variables, etc.
Set up a directory structure
First, create a project directory, e.g., store and create a new index.php file in the directory.
Second, create src directory in the project directory and Model directory in the src directory.
Third, create a new file called Customer.php in the Model directory with the following code:
The directory looks like the following:
Define a namespace
To define a namespace, you place the namespace keyword followed by a name at the very top of the page. The following example gives the Customer class with a namespace Store\Model :
Use a class that belongs to a namespace
Since the Customer class now is namespaced, you need to use the fully qualified name that includes the namespace like this:
Now, it should work properly.
Import a namespace
To avoid using the fully qualified names from a namespace, you can import the namespace with the use operator like this:
Import a class from a namespace
PHP allows you to import a class from a namespace instead of importing the namespace. For example:
In this example, we use the use operator to import the Customer class from the Store\Model namespace. Therefore, we don’t have to prefix the class name with the namespace.
Import multiple classes from a namespace
First, create a new file called Product.php in the src/Model directory:
For demonstration purposes, the Product class is empty. Now, the directory structure looks like the following:
When the number of imported classes grows, your code will become more verbose. So instead of importing each individual class, you can import all the classes using a single statement:
Alias classes from a namespace
First, create a new directory called Database under the project directory and place a new file Logger.php in the Database directory with the following code:
Second, create a new directory Utils under the project directory and create a new Logger.php in the Utils directory.
Now, you have two classes with the same name in different namespaces:
Third, import Logger classes from both namespaces Store\Utils and Database\Logger into the index.php file:
PHP raises the following error:
To avoid this, you can just import the namespaces:
Or you can give a class an alias when importing it:
The following example assigns the DatabaseLogger class an alias to the Store\Database\Logger class:
Use classes from the global namespace
To use global classes such as built-in classes or user-defined classes without a namespace, you need to precede the name of such classes with a backslash ( \ ).
The following example shows how to use the built-in DateTime class in the App namespace: