Examples of using namespace in php. Namespaces in PHP, explained. Namespaces: Multiple scopes of description

I recently encapsulated my project in a namespace and ran into the problem of lack of proper documentation. Everything that we managed to find dates back to approximately 2009, and it’s almost 2012... In the material found, there are a lot of non-working places that use something that is not in the current version of php. In this regard, I would like to shed some light on this issue.
So, what is a Namespace or namespace? The great wikipedia defines them like this:

Namespace is a set, which means a model, abstract storage or environment created for the logical grouping of unique identifiers (that is, names). An identifier defined in a namespace is associated with that namespace. The same identifier can be independently defined in multiple spaces. Thus, a value associated with an identifier defined in one namespace may (or may not) have the same (or rather different) meaning as the same identifier defined in another namespace. Namespace-aware languages ​​define rules that indicate which namespace an identifier belongs to (that is, its definition).wiki

All clear? It's actually simple. Before version 5.3, there were only two spaces in php - global (in which your main code was executed) and local (in which function variables were defined).

Since version 5.3 everything has changed. Now you can define your namespace in which your classes, methods, etc. will exist.


I hope it became a little clearer.

I specifically named the classes the same. Since they are defined in different spaces, they are two different classes, despite the same names. The main script still functions in the global space, nothing has changed here and classes and functions can still be defined in it. So what are spaces for then? First of all, to make sure that when you include a file with some framework or library, your classes will not override the framework's classes or vice versa.

In order to use classes defined in your namespace, you need to import the space you define into the global one in the right place (I usually prefer to do this at the beginning of the file). To do this, use the use keyword

Attention: for some reason php does not allow the use of the keyword use in condition blocks and loops

Let's take the example from the pictures and implement it in code:

Attention: the namespace keyword must be located at the very beginning of the file, immediately after
file A.php
B.php file
An alternative syntax is possible:
It is recommended to declare each namespace in a separate file. Although it is possible in one, it is strictly not recommended!
Now let's move to the third file, in which our main script will function
index.php
It would seem that this is an advantage, only more code is added, but this is not entirely true, a little further I will give an example of an autoload class, with which the lines connecting files with classes will be unnecessary.
Now let's look at our classes.

Attention: using the scope resolution operator (::) in php namespaces not allowed! The only thing it is suitable for is accessing static class methods and constants. At first they wanted to use it for the namespace, but then they decided against it due to problems that arose. Therefore, a construction like A::A::say(); is invalid and will result in an error.

For namespaces, you must use the backslash character "\"
Attention: To avoid misunderstandings, it is necessary to escape this character when used in strings: "\\"

Namespaces can be nested inside each other, let's add to our A.php file:
and in the index we will write the following:

An important point is to use aliases for imported spaces. You could write A\subA::say(); You will agree that it is difficult to write full paths to spaces every time; in order to avoid this, aliases were introduced. When compiling, the following will happen: instead of the alias sub, A\subA will be substituted, so we will get the call A\subA::say();

What then happens when calling functions defined in the global space? PHP first looks for a function within the space where you are currently working, and if it doesn’t find it, it goes to the global scope. In order to immediately indicate that you are using a global function, you must precede it with a backslash.

In order to avoid problems with autoloading classes from spaces, the file system must be organized similarly to the organization of spaces. For example, we have a root folder classes, where our classes will be stored, then our spaces can be organized as follows
classes\A\A.php
classes\A\sub\A.php (sub subspace will be placed in a separate file)
classes\B\B.php

PHP has a magic constant __NAMESPACE__ which contains the name of the current space.

And now about autoloading.

The class below is not mine, I just made it work and improved it a little, taken from here.
Attention: In order for your classes to be loaded, the class name must match the file name!

" .$file ." in " .$filepath)); if (file_exists($filepath)) ( if(Autoloader::debug) Autoloader::StPutFile(("connected " .$filepath)); $flag = FALSE; require_once($filepath); break; ) Autoloader::recursive_autoload($file, $path2, &$flag); ) ) closedir($handle); ) ) private static function StPutFile($data) ( $dir = $_SERVER["DOCUMENT_ROOT"] ." /Log/Log.html"; $file = fopen($dir, "a"); flock($file, LOCK_EX); fwrite($file, ("║" .$data ."=>" .date(" d.m.Y H:i:s") ."

" .PHP_EOL)); flock($file, LOCK_UN); fclose ($file); ) ) \spl_autoload_register("yourNameSpace\Autoloader::autoload"); )
If you look at the names of the classes that come in for loading, you will see that each class is preceded by a prefix from the namespace that is specified in use. This is why I recommend using the location of files in directories similar to the namespace; this speeds up the search to one or two iterations.

Now our index can be written like this:
Now all the classes and interfaces that you will use will be loaded automatically.

To demonstrate some of the dynamic capabilities of the language with spaces, let’s declare another class:
test.php

Index.php
sayName("test"); //or you can do this test\sayName("test2"); //or like this $obj::sayName("test"); //or you can do this test::sayName("test2");

I hope that my article will be useful to someone.

PHP, starting with version 5.3, gave us namespaces. Since then, there has been some sluggish and some heated discussion about how to use this namespace?
Some frameworks, such as Symphony, Laravel, and, of course, Zend, have adopted this technology.
All this more or less fit into the MVC scheme. There remains one, probably eternal, debate: what should be the main marriage pair of the application - Model and Controller?
Some tell us that the Model should be stout and fat and with her a slender and thin Controller. In a word - matriarchy.
Others, on the contrary, believe that the Controller must manage and command everything, so he turns out to be solid and well-fed. And with him is a thin, slender Model, whose task boils down to give and bring. This is patriarchy.
So which is better in MVC scheme? Patriarchy or matriarchy?
Let's look at this from the perspective of building a family unit based on democracy. And let Namespace help us with this.

We don't like thick, clunky Controllers that, like a bull in a china shop, can crush the entire application if you're careless.
We don't like fat Models either. Well, who likes them? They must be worthy of the podium!
Let's try, with the help of Namespace, like with a good matchmaker, to create a harmonious family.

First, let's create the application framework. As banal as it may be, let it be a blog.

We have created a basic structure where:

  • Blog is our application's storage;
  • Views and Templates - storage of views and templates;
  • Utility - repository of shared libraries;
  • index.php - bootstrap script;
  • Post - this is where the family idyll of the Controller and the Model should take place.

With index.php everything is simple:

run(); /* * end of index.php */

We determine the necessary paths and create an autoloader.
The autoloader loads the required classes, which are located in a folder hierarchy according to the class namespace. For example, the BlogPostServicesView class would be searched for in Blog/Post/Services.
And here is the first meeting with Namespace.
When we start index.php, we create an instance of the Blog application, the class of which is loaded from Blog/Blog.php.
Let's look at him.

post = new Post(); ) public function run() ( $this->post->view->all(); ) )//end class Blog

When creating the Blog class, we inject a Post class into it with Namespace BlogPost and the autoloader loads it from Blog/Post/Post.php.
Probably this class can be called a Controller,

view = new View(); ) )//end class Post

The Post entity includes:
- the structure of the data record itself - BlogPostEntitiesPostEntity.php

Services serving Controller requests - BlogPostServicesView.php (one of the services, for example)

db = new DB(); )//end __construct public function all() ( $posts = $this->db->survey(); Contemplate::compose(array("header" => "header", "main" => "main", "footer" => "footer",), array("posts" => $posts, "title" => "Viper site",)); ) )//end class PostView

The database interaction system - BlogPostRepositoriesDB.php - here it is, our thin, elegant Model,
Just give it, bring it, and nothing more!

dbh = new PDO("mysql:host=localhost;dbname=test", $user, $pass, array(PDO::ATTR_PERSISTENT => true)); ) catch (PDOException $e) ( echo "Error!: " . $e->getMessage() . "
"; die(); ) )//end __construct public function survey() ( $query_view = $this->dbh->prepare("SELECT * from posts"); $query_view->execute(); return $query_view- >fetchAll(PDO::FETCH_CLASS, "BlogPostEntitiesPostEntity"); )//end survey )//end class Db

As a result, we were able to create an application structure where all components are well connected, while we achieved a clear separation of classes, where each class performs its own task. Our controller is thin and at the same time powerful. The model matches him. Perfect family!
And all thanks to Namespace.

I don’t argue, in many cases the framework is convenient. But look, Namespace doesn’t remind you of anything?
A clear division into classes, a strict and at the same time flexible hierarchy of directories and classes, completely subordinate to the developer.
Sometimes there is no such significant add-on in the form of hundreds of files and classes in the form of a framework.
The absence of a Procrustean bed of rules for the interaction of classes and components.

The article was inspired by thoughts on this topic by Taylor Otwell, the author of the Laravel framework, for which many thanks to him.
Address of the example source code on GitHub.

Hello. In today's article we will look at, what are namespaces in PHP.

If you have been using it for a long time OOP, then you’ve probably encountered a situation where, when connecting a third-party library, you experienced a failure due to the fact that you are already using the same class names in your code as in the library. This can especially happen if you use common names like "model", "db" and so on. I’ll tell you now how to fix this.

Namespace- this is some kind of storage created for the abstract grouping of unique identifiers (names).

Those. if you use namespaces, then you can safely connect third-party libraries and not be afraid that they will have the same names as in your code. Let's finish with the theory and let's move on to practice.

Let's create a file myclass.php with this content

namespace my\oneProject;
class MyClass ( )
?>

Here we have created a class in the namespace my\oneProject. By the way, you need to write exactly the backslash. Don't get confused!

Now in file index.php let's write the following

require_once("myclass.php");
$mc = new MyClass(); // Error: class not found
$mc = new my\oneProject\MyClass(); // everything is working
?>

As you can see, now it’s not possible to create a class just like that, you must specify in which namespace he is lying down.

We can specify several at once namespaces in one file

namespace Project;

Const CONNECT_OK = 1;
class Connection ( )
function connect() ( )

NamespaceAnotherProject;

Const CONNECT_OK = 1;
class Connection ( )
function connect() ( )
?>

Despite the fact that we have absolutely identical names of classes, functions and constants, we will not have a name conflict, because they lie in different spaces.

We can also use bracket syntax.

namespace Project (

Const CONNECT_OK = 1;
class Connection ( )
function connect() ( )
}

Namespace AnotherProject (

Const CONNECT_OK = 1;
class Connection ( )
function connect() ( )
}
?>

If you combine the code into global namespace with code in other spaces, then only the syntax with brackets is used.

namespace Project (

Const CONNECT_OK = 1;
class Connection ( )
function connect() ( )
}

Namespace ( // global code
session_start();
$a = Project\connect();
echo Project\Connection::start();
}
?>

Also, don't forget that defining a namespace should always be the first line of code. If you write like this there will be an error

To find out which namespace you are currently in, you can use the constant __NAMESPACE__

namespace Project;
echo """, __NAMESPACE__, """; // will print "Project"
?>

Using this constant you can, for example, dynamically construct names

namespace Project;

Function incl($classname) (
$a = __NAMESPACE__ . "\\" . $classname;
return new $a;
}
?>

So that's all for today. You can get more information and practical knowledge by taking the course

I recently encapsulated my project in a namespace and ran into the problem of lack of proper documentation. Everything that we managed to find dates back to approximately 2009, and it’s almost 2012... In the material found, there are a lot of non-working places that use something that is not in the current version of php. In this regard, I would like to shed some light on this issue.
So, what is a Namespace or namespace? The great wikipedia defines them like this:

Namespace is a set, which means a model, abstract storage or environment created for the logical grouping of unique identifiers (that is, names). An identifier defined in a namespace is associated with that namespace. The same identifier can be independently defined in multiple spaces. Thus, a value associated with an identifier defined in one namespace may (or may not) have the same (or rather different) meaning as the same identifier defined in another namespace. Namespace-aware languages ​​define rules that indicate which namespace an identifier belongs to (that is, its definition).wiki

All clear? It's actually simple. Before version 5.3, there were only two spaces in php - global (in which your main code was executed) and local (in which function variables were defined).

Since version 5.3 everything has changed. Now you can define your namespace in which your classes, methods, etc. will exist.


I hope it became a little clearer.

I specifically named the classes the same. Since they are defined in different spaces, they are two different classes, despite the same names. The main script still functions in the global space, nothing has changed here and classes and functions can still be defined in it. So what are spaces for then? First of all, to make sure that when you include a file with some framework or library, your classes will not override the framework's classes or vice versa.

In order to use classes defined in your namespace, you need to import the space you define into the global one in the right place (I usually prefer to do this at the beginning of the file). To do this, use the use keyword

Attention: for some reason php does not allow the use of the keyword use in condition blocks and loops

Let's take the example from the pictures and implement it in code:

Attention: the namespace keyword must be located at the very beginning of the file, immediately after
file A.php
B.php file
An alternative syntax is possible:
It is recommended to declare each namespace in a separate file. Although it is possible in one, it is strictly not recommended!
Now let's move to the third file, in which our main script will function
index.php
It would seem that this is an advantage, only more code is added, but this is not entirely true, a little further I will give an example of an autoload class, with which the lines connecting files with classes will be unnecessary.
Now let's look at our classes.

Attention: using the scope resolution operator (::) in php namespaces not allowed! The only thing it is suitable for is accessing static class methods and constants. At first they wanted to use it for the namespace, but then they decided against it due to problems that arose. Therefore, a construction like A::A::say(); is invalid and will result in an error.

For namespaces, you must use the backslash character "\"
Attention: To avoid misunderstandings, it is necessary to escape this character when used in strings: "\\"

Namespaces can be nested inside each other, let's add to our A.php file:
and in the index we will write the following:

An important point is to use aliases for imported spaces. You could write A\subA::say(); You will agree that it is difficult to write full paths to spaces every time; in order to avoid this, aliases were introduced. When compiling, the following will happen: instead of the alias sub, A\subA will be substituted, so we will get the call A\subA::say();

What then happens when calling functions defined in the global space? PHP first looks for a function within the space where you are currently working, and if it doesn’t find it, it goes to the global scope. In order to immediately indicate that you are using a global function, you must precede it with a backslash.

In order to avoid problems with autoloading classes from spaces, the file system must be organized similarly to the organization of spaces. For example, we have a root folder classes, where our classes will be stored, then our spaces can be organized as follows
classes\A\A.php
classes\A\sub\A.php (sub subspace will be placed in a separate file)
classes\B\B.php

PHP has a magic constant __NAMESPACE__ which contains the name of the current space.

And now about autoloading.

The class below is not mine, I just made it work and improved it a little, taken from here.
Attention: In order for your classes to be loaded, the class name must match the file name!

" .$file ." in " .$filepath)); if (file_exists($filepath)) ( if(Autoloader::debug) Autoloader::StPutFile(("connected " .$filepath)); $flag = FALSE; require_once($filepath); break; ) Autoloader::recursive_autoload($file, $path2, &$flag); ) ) closedir($handle); ) ) private static function StPutFile($data) ( $dir = $_SERVER["DOCUMENT_ROOT"] ." /Log/Log.html"; $file = fopen($dir, "a"); flock($file, LOCK_EX); fwrite($file, ("║" .$data ."=>" .date(" d.m.Y H:i:s") ."

" .PHP_EOL)); flock($file, LOCK_UN); fclose ($file); ) ) \spl_autoload_register("yourNameSpace\Autoloader::autoload"); )
If you look at the names of the classes that come in for loading, you will see that each class is preceded by a prefix from the namespace that is specified in use. This is why I recommend using the location of files in directories similar to the namespace; this speeds up the search to one or two iterations.

Now our index can be written like this:
Now all the classes and interfaces that you will use will be loaded automatically.

To demonstrate some of the dynamic capabilities of the language with spaces, let’s declare another class:
test.php

Index.php
sayName("test"); //or you can do this test\sayName("test2"); //or like this $obj::sayName("test"); //or you can do this test::sayName("test2");

I hope that my article will be useful to someone.

(PHP 5 >= 5.3.0, PHP 7)

Before discussing the use of namespaces, it is important to understand how PHP knows which namespaced element your code is requesting. A simple analogy can be made between PHP namespaces and a filesystem. There are three ways to access a file in a file system:

  1. Relative file name like foo.txt. This resolves to currentdirectory/foo.txt where currentdirectory is the directory currently occupied. So if the current directory is /home/foo, the name resolves to /home/foo/foo.txt.
  2. Relative path name like subdirectory/foo.txt. This resolves to currentdirectory/subdirectory/foo.txt.
  3. Absolute path name like /main/foo.txt. This resolves to /main/foo.txt.
The same principle can be applied to namespaced elements in PHP. For example, a class name can be referred to in three ways:
  1. Unqualified name, or an unprefixed class name like $a = new foo(); or foo::staticmethod(); currentnamespace, this resolves to currentnamespace\foo foo. One caveat: unqualified names for functions and constants will resolve to global functions and constants if the namespaced function or constant is not defined. See Using namespaces: fallback to global function/constant for details.
  2. Qualified name, or a prefixed class name like $a = new subnamespace\foo(); or subnamespace\foo::staticmethod();. If the current namespace is currentnamespace, this resolves to currentnamespace\subnamespace\foo. If the code is global, non-namespaced code, this resolves to subnamespace\foo.
  3. Fully qualified name, or a prefixed name with global prefix operator like $a = new \currentnamespace\foo(); or \currentnamespace\foo::staticmethod();. This always resolves to the literal name specified in the code, currentnamespace\foo.

Here is an example of the three kinds of syntax in actual code:

namespace Foo\Bar\subnamespace;

const FOO = 1 ;
function foo()()
class foo
{
}
?>

namespace Foo\Bar;
include "file1.php" ;

const FOO = 2;
function foo()()
class foo
{
static function staticmethod()()
}

/* Unqualified name */
foo(); foo::staticmethod(); echo FOO ;

/* Qualified name */
subnamespace\foo(); // resolves to function Foo\Bar\subnamespace\foo
subnamespace\foo::staticmethod(); // resolves to class Foo\Bar\subnamespace\foo,
// method staticmethod
echo subnamespace\FOO; // resolves to constant Foo\Bar\subnamespace\FOO

/* Fully qualified name */
\foo\bar\foo(); // resolves to function Foo\Bar\foo
\foo\bar\foo::staticmethod(); // resolves to class Foo\Bar\foo, method staticmethod
echo\Foo\Bar\FOO; // resolves to constant Foo\Bar\FOO
?>

Note that to access any global class, function or constant, a fully qualified name can be used, such as \strlen() or \Exception or \INI_ALL. ?>