Important knowledge points in PHP object-oriented (III) _ PHP Tutorial

Source: Internet
Author: User
Important knowledge points in PHP object-oriented (3 ). 1. namespace: it is similar to the namespace in C ++ and serves the same purpose. it is used to avoid name conflicts when many third-party libraries are referenced. Through namespace, even if two cl 1. namespace:

It is similar to the namespace in C ++ and serves the same purpose. it is used to avoid name conflicts when many third-party libraries are referenced. Through namespace, even if the names of the two classes are the same, they can still be precisely located and differentiated because they are in different namespace. The first time I saw the PHP namespace syntax, I felt very similar to C ++ in terms of syntax. However, I found it only when I wrote some small examples for experiment, they are quite different. in order to avoid future forgetting, they are recorded here. See the following code:

// In Test2.php

Namespace nstest \ test2;

Class Test2 {

Public static function printMe (){

Print 'this is nstest \ test2 \ Test2: printSelf. '. "\ n ";

}

}

// In Test1.php

Namespace nstest \ test1;

Class Test1 {

Public static function printMe (){

Print 'this is nstest \ test1 \ Test1: printSelf. '. "\ n ";

}

}

Require "Test2.php ";

Nstest \ test2 \ Test2: printMe ();

The running result is as follows:

Bogon: TestPhp $ php Test1.php

PHP Fatal error: Class 'nstest \ test1 \ nstest \ test2 \ test2' not found in/Users/liulei/PhpstormProjects/TestPhp/Test1.php on line 13

Is this result unexpected? why? HOHO: When PHP referenced a namespace, if the first character in the namespace is not a leading slash (\), it is automatically recognized as a relative namespace, in the above code, the namespace of Test1 itself is namespace nstest \ test1. Therefore, when test2: printMe () is called in the nstest \ Test2 \ Test2: printMe () method, PHP will automatically resolve it to nstest \ test1 \ nstest \ test2 \ Test2: printMe (), that is, the nstest \ test2 is in the current namespace. To fix this problem, you only need to add the leading slash (\) to the reference. See the following fixed code:

// Test2.php

Namespace nstest \ test2;

Class Test2 {

Public static function printMe (){

Print 'this is nstest \ test2 \ Test2: printSelf. '. "\ n ";

}

}

// Test1.php

Namespace nstest \ test1;

Class Test1 {

Public static function printMe (){

Print 'this is nstest \ test1 \ Test1: printSelf. '. "\ n ";

}

}

Require "Test2.php ";

\ Nstest \ test2 \ Test2: printMe ();

The running result is as follows:

Bogon: TestPhp $ php Test1.php

This is nstest \ test2 \ Test2: printSelf.

There is also a way to change it. you can refer to the relative reference in the namespace in PHP. Here we can change the Test1 namespace to namespace nstest. for other modifications, see The Red highlighted section in the following code:

// Test2.php

Namespace nstest \ test2;

Class Test2 {

Public static function printMe (){

Print 'this is nstest \ test2 \ Test2: printSelf. '. "\ n ";

}

}

// Test1.php

Namespace nstest;

Class Test1 {

Public static function printMe (){

Print 'this is nstest \ test1 \ Test1: printSelf. '. "\ n ";

}

}

Require "Test2.php ";

Test2 \ Test2: printMe ();

The running result is equal to the above correct result. The most important difference is that this example uses relative location in the PHP namespace. I believe that developers familiar with C ++ will surely think of the use keyword. PHP also provides this keyword, and their functions are consistent to avoid the following code, you do not need to reference classes in other namespaces by using the full-definition delimiter (prefix of the namespace before the class name. For specific syntax rules, let's take a look at the specific code and key notes below.

// Test2.php

Namespace nstest \ test2;

Class Test2 {

Public static function printMe (){

Print 'this is nstest \ test2 \ Test2: printSelf. '. "\ n ";

}

}

// Test1.php

Namespace nstest \ test1;

Class Test1 {

Public static function printMe (){

Print 'this is nstest \ test1 \ Test1: printSelf. '. "\ n ";

}

}

Require "Test2.php ";

// Note that nstest \ test2 indicates that the absolute path of the namespace is located, and the leading slash (\) is not required.

// Another implicit rule is test2, which indicates the default alias of the namespace. The test2 prefix must be added to reference objects in the namespace.

Use nstest \ test2;

Test2 \ Test2: printMe ();

// Here we can also explicitly specify an alias for the namespace, for example:

Use nstest \ test2 as test2_alias;

Test2_alias \ Test2: printMe ();

The running result is as follows:

Bogon: TestPhp $ php Test1.php

This is nstest \ test2 \ Test2: printSelf.

This is nstest \ test2 \ Test2: printSelf.

Finally, we will introduce the reference method of global namespace in PHP. See the following code and Key notes:

Class Test {

Public static function printMe (){

Print 'this is Global namespace Test: printSelf. '. "\ n ";

}

}

// The following two lines of code indicate the same object, that is, the Test class in the global namespace. However, if a namespace conflict occurs, the first method cannot be

// If the compiler can recognize PHP normally, you can use the second method to explicitly notify PHP. you must reference the Test class in the global namespace.

Test: printMe ();

\ Test: printMe ();

The running result is as follows:

Bogon: TestPhp $ php Test1.php

This is Global namespace Test: printSelf.

This is Global namespace Test: printSelf.

2. Reflection:

The reflection in PHP is the same as the function provided by the Java. lang. reflect package in java. What's more interesting is that many methods have the same naming and calling methods. They are composed of PHP built-in classes that can analyze classes, class methods, and method parameters in some columns. Here we mainly introduce the following common built-in classes: (Reflection, RelectionClass, ReflectionMethod, ReflectionParameter, and ReflectionProperty ). Now let's take a step-by-step understanding, that is, the sample code and key comments are given from ReflectionClass:

Class TestClass {

Public $ publicVariable;

Function publicMethod (){

Print "This is publicMethod. \ n ";

}

}

Function classInfo (ReflectionClass $ c ){

$ Details = "";

// GetName returns the actual class name.

$ Name = $ c-> getName ();

If ($ c-> isUserDefined ()){

$ Details. = "$ name is user defined. \ n ";

}

If ($ c-> isInternal ()){

$ Details. = "$ name is built-in. \ n ";

}

If ($ c-> isAbstract ()){

$ Details. = "$ name is abstract class. \ n ";

}

If ($ c-> isFinal ()){

$ Details. = "$ name is final class. \ n ";

}

If ($ c-> isInstantiable ()){

$ Details. = "$ name can be instantiated. \ n ";

} Else {

$ Details. = "$ name cannot be instantiated. \ n ";

}

Return $ details;

}

Function classSource (ReflectionClass $ c ){

$ Path = $ c-> getFileName ();

$ Lines = @ file ($ path );

// Obtain the start line and end line of the class definition code.

$ From = $ c-> getStartLine ();

$ To = $ c-> getEndLine ();

$ Len = $ to-$ from + 1;

Return implode (array_slice ($ lines, $ from-1, $ len ));

}

Print "The following is Class Information. \ n ";

Print classInfo (new ReflectionClass ('testclass '));

Print "\ nThe following is Class Source. \ n ";

Print classSource (new ReflectionClass ('testclass '));

The running result is as follows:

Bogon: TestPhp $ php reflection_test.php

The following is Class Information.

TestClass is user defined.

TestClass can be instantiated.

The following is Class Source.

Class TestClass {

Public $ publicVariable;

Function publicMethod (){

Print "This is publicMethod. \ n ";

}

}

Next let's continue learning ReflectionMethod with code examples and key comments.

Class TestClass {

Public $ publicVariable;

Function _ construct (){

}

Private function privateMethod (){

}

Function publicMethod (){

Print "This is publicMethod. \ n ";

}

Function publicMethod2 (string $ arg1, int $ arg2 ){

}

}

// The methods in the ReflectionMethod used in this function are very simple and intuitive, so we will not repeat them too much.

Function methodInfo (ReflectionMethod $ m ){

$ Name = $ m-> getName ();

$ Details = "";

If ($ m-> isUserDefined ()){

$ Details. = "$ name is user defined. \ n ";

}

If ($ m-> isInternal ()){

$ Details. = "$ name is built-in. \ n ";

}

If ($ m-> isAbstract ()){

$ Details. = "$ name is abstract. \ n ";

}

If ($ m-> isPublic ()){

$ Details. = "$ name is public. \ n ";

}

If ($ m-> isProtected ()){

$ Details. = "$ name is protected. \ n ";

}

If ($ m-> isPrivate ()){

$ Details. = "$ name is private. \ n ";

}

If ($ m-> isStatic ()){

$ Details. = "$ name is static. \ n ";

}

If ($ m-> isFinal ()){

$ Details. = "$ name is final. \ n ";

}

If ($ m-> isConstructor ()){

$ Details. = "$ name is constructor. \ n ";

}

If ($ m-> returnsReference ()){

$ Details. = "$ name returns a reference. \ n ";

}

Return $ details;

}

Function methodSource (ReflectionMethod $ m ){

$ Path = $ m-> getFileName ();

$ Lines = @ file ($ path );

$ From = $ m-> getStartLine ();

$ To = $ m-> getEndLine ();

$ Len = $ to-$ from + 1;

Return implode (array_slice ($ lines, $ from-1, $ len ));

}

$ Rc = new ReflectionClass ('testclass ');

$ Methods = $ rc-> getMethods ();

Print "The following is method information. \ n ";

Foreach ($ methods as $ method ){

Print methodInfo ($ method );

Print "\ n ------------------ \ n ";

}

Print "The following is Method [TestClass: publicMethod] source. \ n ";

Print methodSource ($ rc-> getMethod ('publicmethod '));

The running result is as follows:

Bogon: TestPhp $ php reflection_test.php

The following is method information.

_ Construct is user defined.

_ Construct is public.

_ Construct is constructor.

--------------------

PrivateMethod is user defined.

PrivateMethod is private.

--------------------

PublicMethod is user defined.

PublicMethod is public.

--------------------

PublicMethod2 is user defined.

PublicMethod2 is public.

--------------------

The following is Method [TestClass: publicMethod] source.

Function publicMethod (){

Print "This is publicMethod. \ n ";

}

Let's continue with ReflectionParameter, which indicates the parameter information of the member function. Continue to read the code.

Class ParamClass {

}

Class TestClass {

Function publicMethod (){

Print "This is publicMethod. \ n ";

}

Function publicMethod2 (ParamClass $ arg1, & $ arg2, $ arg3 = null ){

}

}

Function paramInfo (ReflectionParameter $ p ){

$ Details = "";

// $ DeclaringClass here will be equal to TestClass.

$ DeclaringClass = $ p-> getDeclaringClass ();

$ Name = $ p-> getName ();

$ Class = $ p-> getClass ();

$ Position = $ p-> getPosition ();

$ Details. = "\ $ name has position $ position. \ n ";

If (! Empty ($ class )){

$ Classname = $ class-> getName ();

$ Details. = "\ $ name must be a $ classname object \ n ";

}

If ($ p-> isPassedByReference ()){

$ Details. = "\ $ name is passed by reference. \ n ";

}

If ($ p-> isdefavaluvalueavailable ()){

$ Def = $ p-> getDefaultValue ();

$ Details. = "\ $ name has default: $ def \ n ";

}

Return $ details;

}

$ Rc = new ReflectionClass ('testclass ');

$ Method = $ rc-> getMethod ('publicmethod2 ');

$ Params = $ method-> getParameters ();

Foreach ($ params as $ p ){

Print paramInfo ($ p). "\ n ";

}

The running result is as follows:

Bogon: TestPhp $ php reflection_test.php

$ Arg1 has position 0.

$ Arg1 must be a ParamClass object

$ Arg2 has position 1.

$ Arg2 is passed by reference.

$ Arg3 has position 2.

$ Arg3 has default:

The above section uses the Reflection API provided by PHP to traverse the specific information of any class. In fact, it is the same as the Reflection function provided by other languages such as Java, PHP also supports calling the actual object method through the reflection class. here we will mainly apply two methods: ReflectionClass: newInstance () to create an object instance, and ReflectionMethod :: invoke (), which is executed based on the object instance and method name. See the following code:

Class TestClass {

Private $ privateArg;

Function _ construct ($ arg ){

$ This-> privateArg = $ arg;

}

Function publicMethod (){

Print '$ privateArg ='. $ this-> privateArg. "\ n ";

}

Function publicMethod2 ($ arg1, $ arg2 ){

Print '$ arg1 ='. $ arg1. '$ arg2 ='. $ arg2. "\ n ";

}

}

$ Rc = new ReflectionClass ('testclass ');

$ TestObj = $ rc-> newInstanceArgs (array ('this is private argument .'));

$ Method = $ rc-> getMethod ('publicmethod ');

$ Method-> invoke ($ testObj );

$ Method2 = $ rc-> getMethod ('publicmethod2 ');

$ Method2-> invoke ($ testObj, "hello", "world ");

The running result is as follows:

Bogon: TestPhp $ php reflection_test.php

$ PrivateArg = This is private argument.

$ Arg1 = hello $ arg2 = world

In fact, ReflectionClass, ReflectionMethod, and ReflectionParameter provide us with more available methods. Here are just a few of the most typical methods, so that we can learn and understand PHP Reflection API more intuitively. I believe that after reading the code examples, we will be clear that if we need to use the class-related functions in the future, we will find them from ReflectionClass, and the member function information must come from ReflectionMethod, the method parameter information comes from ReflectionParameter.

Note: The points recorded in this Blog are some of the more unique PHP skills compared with other object-oriented languages, or, for me, I really need to write down the knowledge points for future reference. I hope to share it with you.

Http://www.bkjia.com/PHPjc/664271.htmlwww.bkjia.comtruehttp://www.bkjia.com/PHPjc/664271.htmlTechArticle1. namespace: very similar to the namespace in C ++, it also works to avoid name conflicts when many third-party libraries are referenced. Through namespace, even if two cl...

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.