This time I will bring you a detailed explanation of php namespace usage, what are the precautions when using php namespace, the following is a practical case, let’s take a look.
Problems solved by namespaces (the manual is also very clear, and the following is simplified according to my own understanding):
1: Solve the problems of classes, constants, functions and There is a name conflict within PHP or a third party.
2: Create aliases to help solve the problem of too long names of classes, constants, and functions, and to help improve the readability of the code. In addition, too long names are usually caused by mitigating the first type of problem.
1: The namespace is declared with the keyword namespace. At the same time, the namespace must be located before other code, including any non-php code and whitespace characters (php's declare key words), otherwise a fatal error will be thrown.
For example:
<?php namespace Index; ?>
Note 1: If there is no code or whitespace before the namespace, but a fatal error still occurs, this should be caused by the bom header, remove the bom Just head on.
Note 2: Although all legal PHP code can be placed under the namespace, the only classes (abstract classesand traits), interfaces, constants and functions that are affected by the namespace are affected.
2: Much like the relationship between directories and files, PHP namespaces also allow you to specify hierarchical namespace names. Therefore, namespace names can be defined in a hierarchical manner, separated by \.
For example:
<?php namespace Index\Col\File; define('MESSAGE','hello world'); ?>
3: Multiple namespaces can be defined in one file. There are two definition syntaxes, one is simple combination syntax, and the other is curly bracket syntax. The use of another file defining multiple namespaces is generally a scenario where multiple files are merged into one file, but it is best not to do this unless it is absolutely necessary, because it increases the complexity of the code and reduces the readability. Generally There is no need for such use.
Simple combination syntax:
<?php namespace Index; const INSTANCE=1; namespace Col; const INSTANCE=2; ?>
Braces syntax, one file has multiple namespaces, if you need to write non-namespace code, you can only use braces syntax, and it is not named The space code uses namespace to declare a namespace without a name, and then uses curly brackets:
<?php /*命名空间Index*/ namespace Index{ const INSTANCE=1; } /*命名空间Col*/ namespace Col{ const INSTANCE=2; } /*全局非命名空间代码*/ namespace { const INSTANCE=3; } ?>
4: Multiple different files can define the same namespace, which means that the contents of the same namespace can Stored in multiple different files respectively, I won’t give an example here.
There are three situations in which the namespace is used. The manual actually explains it in detail, but it may cause some confusion due to translation problems. Here I will simplify it and use my own Let’s sort through the examples:
1: There is no qualified name, that is, the name of the class, constant, function, and interface to be read is directly used. In this case, the class, constant, and interface name of the namespace to which the content belongs will be read. Function and interface names, but if there is no relevant data in the namespace, a fatal error will be returned if it is a class or interface name. If it is a function or constant, global functions and constants will be automatically read. If there is no global function or constant, a fatal error will be reported. fatal error.
The following example:
<?php /*全局非命名空间代码*/ namespace { const INSTANCE=1; function test(){ echo 1; } class foo{ static function fool(){ echo 1; } } var_dump(INSTANCE); //打印出来的是1 test(); //输出1 foo::fool(); //输出1 } /*命名空间Index*/ namespace Index{ const INSTANCE=2; function test(){ echo 2; } class foo{ static function fool(){ echo 2; } } var_dump(INSTANCE); //打印出来的是2 test(); //输出2 foo::fool(); //输出2 } /*命名空间Col*/ namespace Col{ const INSTANCE=3; function test(){ echo 3; } class foo{ static function fool(){ echo 3; } } var_dump(INSTANCE); //打印出来的是3 test(); //输出2 foo::fool(); //输出2 } ?>
In the above example, each namespace output does not have a qualified name, so the corresponding data value set in the current namespace will be obtained.
If the current namespace is not set, functions and constants will read the corresponding data values set globally. Fatal errors will be reported only if there is no corresponding global setting. Classes and interfaces will directly report fatal errors, as shown in the following code. Show.
<?php /*全局非命名空间代码*/ namespace { const INSTANCE=1; function test(){ echo 1; } class foo{ static function fool(){ echo 1; } } var_dump(INSTANCE); //打印出来的是1 test(); //输出1 foo::fool(); //输出1 } /*命名空间Index*/ namespace Index{ var_dump(INSTANCE); //打印出来的是1 test(); //输出1 foo::fool(); //fatal error } ?>
2: Qualified names are divided into two situations, one is the case of qualified names containing prefixes, and the other is the case of containing globally qualified names. The manual separates these two types separately, but I think these two can be combined together. They both have qualified names, but the former does not have global qualifications, while the latter has global qualifications.
① A qualified name that contains a prefix. This prefix can have multiple or one level, but the leftmost cannot be a \global qualifier. In this case, the namespace where the code is located will be read and the prefix will be added. The data corresponding to the qualified name, that is:
所处命名空间\前缀限定\名称来读取,如果该代码是全局没有命名空间的,则直接用前缀限定名称来读取,也就是:前缀限定\名称来读取。
实例代码:
<?php /*命名空间Col\Index*/ namespace Col\Index{ const INSTANCE=1; } /*命名空间Index*/ namespace Index{ const INSTANCE=2; } /*命名空间Col*/ namespace Col{ const INSTANCE=3; var_dump(Index\INSTANCE); //打印出来的是1 读取的是Col\Index\INSTANCE } /*全局非命名空间代码*/ namespace { const INSTANCE=4; var_dump(Index\INSTANCE); //打印出来的是2 读取的是Index\INSTANCE } ?>
②全局限定前缀名称:也就是在最左侧有全局操作符\进行修饰的前缀限定名称,当然也可以没有前缀限定直接全局操作符\加上名称也是可以的。但加上全局操作符后就跟目录里的绝对路径一样,只会按照全局限定后的所设置的进行读取。
具体实例如下:
<?php /*命名空间Col\Index*/ namespace Col\Index{ const INSTANCE=1; } /*命名空间Index*/ namespace Index{ const INSTANCE=2; } /*命名空间Col*/ namespace Col{ const INSTANCE=3; var_dump(\Index\INSTANCE); //打印出来的是2 读取的是Index\INSTANCE } /*全局非命名空间代码*/ namespace { const INSTANCE=4; var_dump(\Index\INSTANCE); //打印出来的是2 读取的是Index\INSTANCE } namespace Lin{ const INSTANCE=5; var_dump(\INSTANCE); //打印出来的是4 读取的是INSTANCE,是全局非命名空间里的INSTANCE,如果没有全局操作符\,读取的会是当前命名空间的Lin\INSTANCE=5 } ?>
有时候命名空间会放在字符串中使用,如果是单引号不会通过编译器解释,所以没有任何问题,但是如果是双引号,那么就会有些意外情况了,要知道双引号里的内容是需要经过编译器进行解释然后再进行输出的,而\在编译器里的解释容易造成歧义。
例如"index\name"这里就有\n会被解释成换行,除此之外还有很多这种造成意外的情况。
因此一般我们推荐命名空间如果要放在字符串中使用,最好使用单引号,一是效率,二是安全,如果使用双引号,则必须增加一个\进行转义避免歧义,例如"index\\name"这样就没有问题了。
随手双引号的举个例子:
<?php /*全局非命名空间代码*/ namespace Index\Name{ class foo{ function construct(){ echo 2; } } } namespace{ $a= "Index\\Name\\foo"; //用\转义了\所以可以正常运行,但是如果去掉转义的话会报错Class 'Index\Nameoo',因为/f被解释成了换页符 $obj=new $a; }
相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!
推荐阅读:
The above is the detailed content of Detailed explanation of php namespace usage. For more information, please follow other related articles on the PHP Chinese website!