Important knowledge points in PHP object-oriented (iii.)
Source: Internet
Author: User
1. Namespace: and C + + namespaces are similar, and function equally, to avoid the problem of naming conflicts that can be caused by referencing more third-party libraries. By namespace, even the names of two classes are the same, but because they are located in different namespaces, they can still be precisely positioned and differentiated. The first time I saw PHP's name space syntax, the feeling and C + + in the syntax is very very similar, but in writing a little example to do the experiment when found that their differences are still very large, in order to avoid later forget, so here particularly recorded it down. See the following code: Copy Code <?php//in test2.php namespace Nstest\test2; class Test2 { public static function Printme () { print ' This is Nstest\te St2\test2::p rintself. '. ' \ n "; }} <?php//in test1.php namespace Nstest\test1; class Test1 { public static function Printme () { print ' This is Nstest\te St1\test1::p rintself. '. ' \ n "; }} require "test2.php"; Nstest\test2\test2::p rintme (); Copy code Run results are as follows: bogon:testphp$ php test1.php php Fatal Error: class ' nstest\test1\nstest\tes T2\test2 ' not found in/users/liulei/phpstormprojects/testphp/test1.php in line Is this result more unexpected, and why? HOHO, the original PHP in the name space reference, when theIf the first character of the namespace is not a leading slash (\), it is automatically recognized as the relative namespace, in which the Test1 's own namespace is namespace Nstest\test1, so nstest\test2\test2: When the Printme () method calls Test2::p rintme (), PHP automatically resolves to nstest\test1\nstest\test2\test2::p rintme (), which means that the nstest\test2 is inside the current namespace. Fixing the problem is simple, just add a leading slash (\) to the reference, and see the following repaired code: Copy Code <?php//test2.php namespace Nstest\test2; class Test2 { public static function Printme () { print ' This is Nstest\te St2\test2::p rintself. '. ' \ n "; }} <?php//test1.php namespace Nstest\test1; class Test1 { public static function Printme () { print ' This is Nstest\te St1\test1::p rintself. '. ' \ n "; }} require "test2.php"; \nstest\test2\test2::p rintme (); The copy code Run results are as follows: bogon:testphp$ PHP test1.php This is nstest\test2\test2::p rintself. There's also a way to change the relative reference in the name space in PHP. Here we can change the Test1 namespace to namespace Nstest, and the other changes see the red highlights in the following code: Copy Code <? php//test2.php namespace Nstest\test2; class Test2 { public static function Printme () { print ' This is Nstest\te St2\test2::p rintself. '. ' \ n "; }} <?php//test1.php namespace Nstest; class Test1 { public static function Printme () { print ' This is Nstest\te St1\test1::p rintself. '. ' \ n "; } require "test2.php"; Test2\test2::p rintme (); copy code Run result is equal to the correct result above. The most important difference is that the example uses the relative positioning in the PHP namespace. I'm sure developers familiar with C + + will think of the Use keyword, PHP also provides this keyword, and their functionality is consistent, both to avoid the need to refer to classes in other namespaces in the subsequent code without having to pass the full qualifier (prefix of the class name). As for the specific grammar rules, take a look at the specific code and key comments below. Copy Code <?php//test2.php namespace Nstest\test2; class Test2 { public static function Printme () { print ' This is Nstest\te St2\test2::p rintself. '. ' \ n "; }} <?php//test1.php namespace Nstest\test1; class Test1 { public static functiOn Printme () { print ' This is nstest\test1\test1::p rintself. '. ' \ n "; } require "test2.php"; The special note here is that NSTEST\TEST2 has already indicated that the namespace absolute path is positioned without the need to add a leading slash (\). In addition, there is an implicit rule that test2 represents the default alias for that namespace, and requires a test2 prefix when referencing objects in its namespace. Use Nstest\test2; Test2\test2::p rintme (); //Here we can also explicitly specify the alias name space, such as: Use Nstest\test2 as Test2_alias; Test2_alias\test2::p rintme (); replication code Run results are as follows: bogon:testphp$ PHP test1.php this is nstest\t Est2\test2::p rintself. This is nstest\test2\test2::p rintself. Finally, introduction to the global namespace in PHP reference way, see the following code and key comments: Replication Code <?php class Test { public static function PR Intme () { print ' This is Global namespace Test::p rintself. '. ' \ n "; } //The following two lines of code represent the same object, that is, the test class under the global namespace, but if the first method cannot be properly identified by the PHP//compiler because of a namespace conflict, then you can explicitly notify PHP using the second method. What you want to refer to is the test class in the global namespace. Test::p rintme (); \test::p rintme (); Copy code Run results are as follows: bogon:testphp$ PHP test1.php This is Global namespace Test::p rintself. This is Global namespace Test::p rintself. 2. Reflection: PHP reflection and functionality provided in Java Java.lang.reflect Package, more interestingly, even many methods of naming and calling are very similar. They are all made up of PHP built-in classes that can analyze classes, class methods, and method parameters. Our main introduction Here is the following several commonly used built-in classes: (Reflection, Relectionclass, Reflectionmethod, Reflectionparameter, and Reflectionproperty). Now we're going to take it one step at a time, starting with Reflectionclass to show example code and critical annotations: Copy code <?php class TestClass { public $ publicvariable; Function Publicmethod () { -print "This is publicmethod.\n"; } Function ClassInfo (Reflectionclass $c) { $details = ""; //getname will return the actual class name. $name = $c->getname (); if ($c->isuserdefined ()) { $details. = "$name is User defined.\n"; &NB Sp } if ($c->isinternal ()) { $details. = "$name is built-in.\n"; } if ($c->isabstract ()) { $details. = "$name is abstract class.\n"; } I F ($c->isfinal ()) { $details. = "$name is final class.\n"; } IF ($c->isinstantiable ()) { $details. = "$name can be instantiated.\n"; } else { &NBS P $details. = "$name cannot be instantiated.\n"; } return $details; } function Classsource (Reflectionclass $c) { $path = $c->getfilename () $lines = @fi Le ($path); //Get the starting and ending lines 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 copy code Run results are as follows: Copy code 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 () { &NBSP ; print "This is publicmethod.\n"; } to copy code Let's continue our Reflectionmethod learning journey with code samples and critical annotations. Copy code <?php class TestClass { public $publicVariable function __construct () { } Private function Privatemethod () { } function pub Licmethod () { print "This is publicmethod.\n"; } function publicme THOD2 (string $arg 1, int $arg 2) { }} //The methods in Reflectionmethod used in this function are very straightforward and are not too much to repeat. function MethodInfo (Reflectionmethod $m) { $name = $m->getname (); $details = ""; if ($m->isuserdefined ()) { $details. = "$name is User defined.\n"; &NB Sp } 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"; } &N Bsp if ($m->isstatic ()) { $details. = "$name is static.\n"; } if ($ M->isfinal ()) {&NBSp $details. = "$name is final.\n"; } if ($m->isconstructor ()) { $details. = "$name is constructor. \ n "; } if ($m->returnsreference ()) { $details. = "$name Returns a re Ference.\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::p UBLICMethod] source.\n "; Print Methodsource ($RC->getmethod (' Publicmethod ')); The copy code Run results are as follows: Copy code 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::p Ublicmethod] source. Function Publicmethod () { print "This is publicmethod.\n"; } copy Code Let's go on with the Reflectionparameter, he represents the parameter information of the member function. Keep looking at the code. Copy code <?php class Paramclass { } class TestClass { function Publicmethod () { & nbsp Print "This is publicmethod.\n"; } &NBSp function PublicMethod2 (paramclass $arg 1, & $arg 2, $arg 3 = null) { }} function Paraminfo (Re Flectionparameter $p) { $details = ""; /The $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 (); &N Bsp $details. = "\$ $name must be a $classname object\n"; } if ($p->ispassedbyreference ()) { $details. = "\$ $name are pass Ed by reference.\n "; } if ($p->isdefaultvalueavailable ()) { $def = $p->getdefault Value (); $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 results of the copy code run are as follows: Copy code bogon:testphp$ PHP reflection_test.php $arg 1 has position 0. $arg 1 must be a Paramclass object $arg 2 has position 1. $arg 2 is passed by reference. $ARG 3 has position 2. $arg 3 has default: copy code above are the reflection APIs provided through PHP to traverse the specific information of any class, in fact, like the reflection function provided in other languages such as Java, PHP also supports the method of invoking the actual object through the reflection class, which will be applied primarily to two methods, Reflectionclass::newinstance () to create the object instance, and the other is Reflectionmethod::invoke (), Executes the method based on the object instance and method name. See following code: Copy Code <?php class TestClass { private $privateArg function __construct ($arg) { $this->privatearg = $arg; } function Publicmethod () { print ' $PRIvatearg = '. $this->privatearg. " \ n "; } function publicMethod2 ($arg 1, $arg 2) { , print ' $arg 1 = '. $ Arg1. ' $arg 2 = '. $arg 2. ' \ n "; }} $RC = new Reflectionclass (' TestClass '); $TESTOBJ = $RC->newinstanceargs Array (' This is private argument. '); $method = $RC->getmethod (' Publicmethod '); $method->invoke ($TESTOBJ); $method 2 = $RC->getmethod (' publicMethod2 '); $method 2->invoke ($TESTOBJ, "Hello", "World"); The copy code Run results are as follows: bogon:testphp$ php reflection_test.php $PRIVATEARG = This is private argument. $arg 1 = Hello $arg 2 = 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 more intuitively and understand the PHP Reflection API. After reading the following code example, we will be more clear, if you need to use the class-related functions, from the Reflectionclass, and the member function of the information must come from the Reflectionmethod, The method parameter information is derived from the Reflectionparameter. Note: The blog recorded in the Knowledge Point, is in the process of learning PHP, I encountered some of the PHP and other object-oriented language than the more unique place, or for me I really need a book to write downTo prepare for the post-search knowledge points. Although there is no depth, but still hope to share with you.
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