PHP 3.x and 4.x About Object Programming

zhaozj2021-02-11  186

PHP 3.x and 4.x About Object Programming

"Object" sounds a very popular vocabulary, it seems that if you have no OOP, it is better to go home. PHP starts supporting object programming from version 3.x, although its Class has accused from the beginning, it has brought us an unexpected surprise. All the way fell and hit it, and it was 4.X, and PHP was quite OOP. Of course, it is still unsatisfactory for the processing of class variables, no private, public, protected, static statement. The availability of PHP-oriented object is not within the scope of this article. With the perfection of object programming in 4.x, PHP Team brings us "trouble": 3.x and 4.x to some game rules for object programming, not compatible. The author discussed a little discussion on the problems encountered by the actual development process. I believe that some problems may have not been encountered, welcome to supplement, and enjoy.

First, the constructor (function) is said in 3.x, the constructor refers to a class function with the same name as the class. It is a bit embarrassing, but it is even more. In 4.x, the constructor refers to a class function that is directly defined in the constructor inside the constructor, that is, the class function that does not include inheritance. For example: 1,

Class ababystudio {function ababystudio () {echo ('call constructor'.chr (13));} // ...}

Note: The effect is the same in 3.x and 4.x.

Class ababy {function ababystudio () {echo ('ababystudio');}} class ababystudio {// ...}

Note: There is a constructor in 3.x in class ABABYSTUDIO, inherited from the parent class Ababy; there is no constructor in 4.x. Readers can try to run such a line of code $ ababystudio = new ababystudio (); "Ababystudio" should be output in version 3.x, and 4.x will not be output.

It is also worth noting that when an object is instantified in 4.x, it can only specify a constant value (or scalar value) as an initial value for class variables. If you want to pass a variable (usually a global variable), object, the expression is set, you should operate in the constructor. For example: 3,

Class ababy {// ...} Class ababystudio {var $ ababy = 'Hello Every One'; // Sentence 1 var $ ababy = 'hello'. 'world'; //sence 2 var $ ababy = new ababy () ; // seencept 3 var $ ababy = array (); //sence 4 var $ ababy = g_hello; // senence 5, g_hello is a constant function ababystudio () {echo ('call constructor'.chr (13)); } // ...}

Note: 5 marked Sentence only 1, 4, 5 can pass at 4.x. However, the author did not understand why the PHP Workgroup allowed Sentence 4, only forced yourself to understand: Array is used as a basic data type, and Array () is not considered a method or expression. 4,

Class ababy {// ...} class ababystudio {var $ ababy; function ababystudio () {$ this-> ababy = 'Hello Every One'; $ this-> Ababy = 'Hello'. 'Every'. 'One' $ This-> Ababy = new ababy (); $ this-> ababy = array (); $ this-> ababy = g_hello; echo ('call constructor'.chr (13));} // ...}

Note: This code can be compiled in 3.x and 4.x, the effect is the same. In 3.x and 4.x, the description of the change of the constructor rule is stopped here. The next article will introduce the incompatibility problem of the delivery parameters in reference.

Second, according to the reference delivery parameters, this section discusses more than the PHP object programming, which is suitable for all aspects of PHP programming. The parameters in the PHP are passed by default, whether the basic data type is still an object. The difference between other object-oriented programming languages ​​is that the default transmission mode of usual objects in other languages ​​is passed by reference. In order to achieve the purpose of the reference transmission parameters, the PHP team introduced a "&" operator to declare that the current variable should be passed according to the reference. It seems a bit weird. The basic data type is not discussed here. 1,

class ABabyStudio {function ABabyStudio () {echo ( 'call constructor'.chr (13));} // ...} $ ABabyStudio1 = new ABabyStudio (); $ ABabyStudio2 = $ ABabyStudio1; $ ABabyStudio3 = & $ ABabyStudio1;

Note: $ AbabyStudio2 gains a $ ababystudio1 replica, not $ ababystudio1 itself, that is, 1 change in the future does not affect 2, and it is also true. $ AbabyStudio3 will get references to the AbabyStudio1, and the change in 1 and 3 is synchronized.

2,

Class ababy {var $ hello; function ababy () {$ this-> hello = 'world';} // ...} Class ababystudio {function ababystudio () {;} function helloeveryone ($ ababy) {$ ababy-> Hello = 'every one';} // ...} $ ababy = new ababy; echo ($ ababy-> hello); $ ababystudio = new ababystudio (); $ ababystudio-> helloeveryone (& $ ababy); echo $ Ababystudio-> hello; Note: You run this code in 3.x, everything is OK. In the 4.X environment, the problem appeared: PHP WARNING: CALL-TIME Pass-by-reference Has Been Deprecated - Argument Passed by Value; if you would like to pass it by reference, modify the declaration of [runtime function name ] (). If you would like to enable call-time pass-by-reference, you can set allow_call_time_pass_reference to True in Your Ini File. However, Future Versions May Not Support this Any Longer.

In 4.x, PHP is close to the general mode. If you want to pass parameters to a function, you should define in a function declaration, the specific form is to add the reference operator "&" in the shape.

Function YourFunction {$ arg ;} $ arg = 7; YourFunction; Echo ($ arg);

Run this code, you will find the value of $ arg to increase to "8". Therefore, the code segment 2 should be modified to: 3,

Class ababy {var $ hello; function ababy () {$ this-> hello = 'world';} // ...} Class ababystudio {function ababystudio () {;} function helloeveryone (& $ ababy) {$ ababy- > hello = 'every one';} // ...} $ ababy = new ababy; echo ($ ababy-> hello); $ ababystudio = new ababystudio (); $ ababystudio-> helloeveryone ($ ababy); echo $ Ababystudio-> hello;

Note: None.

Similarly, if you want a function to return a "reference" instead of "copy", you can also be implemented in a function declaration. This is impossible in 3.x: Function & YourFunction {$ Arg ; return ($ arg); $ myarg = 7; $ argref = & yourfunction ($ myarg); $ argref = 10; Echo ($ myarg);

Running this code will find that the value of $ ARG has become 18. Some people may question this sentence "$ argref = & yourfunction ($ arg);" Since the function has passed back to $ arg by reference, why should I use "&" in this sentence? Ask good! This is because the declaration function returns a parameter $ arg by reference, just tells the function (or PHP parser) Do not copy $ arg when return, and due to the return value of the function (actually a reference) to experience One time I assigned only "=", so "&" will appear again before the function. This ensures that there is only one $ myarg in the memory, and the value of $ myarg will be changed twice. If the $ myarg above is an object, the above statement is equally applicable. The reader can try itself.

Supplementary description, can still force the current 4.x version to support the pass references in 3.x, you can change the following line by modifying php.ini: allow_call_time_pass_reference = OFF to: allow_call_time_pass_reference = ON, not guaranteed in subsequent This approach continues to support this version. Watch and see you, welcome to discuss further. Next introduction to the new magical function in 4.x. Although it is "new", it will also bring you possible surprises trouble.

Third, the magic function says the magical function that appears in 4.x to achieve the "magical" (Magical) that is claimed by the PHP team. The word "Magic Function" in the magic function. This is a class function with retained names. The PHP team has such an expression in the recommendation: User defines their own class functions should not start with two underscores "__", because this may be with the magic function in the current or subsequent versions. A rename conflict will seriously affect the normal operation of the user defined class. So, if you define the method of "__xxx" in the past code, it is highly recommended that you modify them. The magic function automatically triggers when you encounter some events, as if there are triggers in some database software. As of PHP-4.3.2RC4, there are two magical functions: __ Sleep and __wakeup. From the literal, the two functions are triggered when the object is asleep or wake up, but in fact, __sleep triggers when the object is serialize, __ Wakeup When the object is defined (unserialize) trigger. When it comes to it, it may already make people feel boring, because there is no surprise that has no surprises incentives. Take a look at the example below.

1,

Class Ababy {Var $ FileName, $ FileOpen, $ OFFSET, $ Length; Function Ababy () {$ this-> filename = 'Ababy.class.php'; $ this-> fileopen = fopen ($ this-> fileename, ' RB '); $ this-> offset = 0; $ this-> length = 0;} Function getData ($ this-> offset = $ offset; $ this-> length = $ length; fseek ($ THIS-> FileOpen, $ OFFSET); Return ($ this-> fileopen, $ length));} function getlastdata () {Return ($ this-> getData ($ this-> offset, $ this-> Length));}} $ ababy = new ababy (); echo ($ ababy-> getData (7,77)); $ ababybed = serialize ($ ababy); $ ababybed; echo ($ newaby) -> getLastData ()); Note: This class's task is to open a file to read the specified location and byte length data, and can return the data recently read. After instantiation, first read the contents of the specified file to start a total of 77 bytes, then save this class sequence into a string, then the object is previously output from this string. Read the data. This time you don't have to __wakeup. Save the above code into file ababys.class.php and run. Error: Supplied Argument is Not a Valid Stream Resource! This is because the parser returns $ FILEOPEN back to its original face-ITEger, which is no longer the file stream operation handle (RESOUR), the file is still open. One way to "Echo ($ ababy-> getlastdata ());" confirmed. The same situation will also occur on other handles such as database connections, network connections, and readers can test themselves. Let's fix it through the magic function __wakeup. Of course, it is not necessary to use __wakeup, such as you can first reach the object $ Newaba, then save the instance variable $ OFFSET and $ Length to another, then call $ newaby constructor, then call getData () Method, this can meet the desired purpose of the call GetLastData (). So many this then ... Now look at the magic of __wakeup.

2,

Class Ababy {Var $ FileName, $ FileOpen, $ OFFSET, $ Length; Function Ababy () {$ this-> filename = 'Ababy.class.php'; $ this-> fileopen = fopen ($ this-> fileename, ' RB '); $ this-> offset = 0; $ this-> length = 0;} Function getData ($ this-> offset = $ offset; $ this-> length = $ length; fseek ($ THIS-> FileOpen, $ OFFSET); Return ($ this-> fileopen, $ length));} function getlastdata () {Return ($ this-> getData ($ this-> offset, $ this-> Length));} Function __wakeup () {$ this-> fileopen = fopen ($ this-> filename, 'rb');}} $ ababy = new ababy (); echo ($ ababy-> getData (7,77 $ Ababybed = serialize ($ ababy); $ newaby = unserialize ($ ababybed); Echo ($ newaby-> getLastData ()); Note: By adding a magical function __wakeup correcting the above problem. It is normal to run the above script. The last step of the UNSerialize () operation process automatically detects whether the class defines the __wakeup () magic function, and there is an automatic call. In this way, we pass __wakeup () just simple re-open file flow operation handles. "Echo ('Ababy') can be added in __wakeup ();" confirming that it is actually called.

There is a "hidden danger" in the code. After we serialize an object, it usually means that it will not use it immediately, but the above code we did not explicitly close the open file stream operating handle. Although almost every language claims that its garbage collection mechanism can automatically release the unused resources, it is not always like this. Therefore, it is a good habit to release the resources that don't need to be released. Below we tell the parser through the __sleep () magic function Once this object is serialized, it should release the handle of the occupied. 3,

Class Ababy {Var $ FileName, $ FileOpen, $ OFFSET, $ Length; Function Ababy () {$ this-> filename = 'Ababy.class.php'; $ this-> fileopen = fopen ($ this-> fileename, ' RB '); $ this-> offset = 0; $ this-> length = 0;} Function getData ($ this-> offset = $ offset; $ this-> length = $ length; fseek ($ THIS-> FileOpen, $ OFFSET); Return ($ this-> fileopen, $ length));} function getlastdata () {Return ($ this-> getData ($ this-> offset, $ this-> Length);} function __sleep () {fclose ($ this-> fileopen);} function __wakeup () {$ this-> fileopen = fopen ($ this-> filename, 'RB');}} $ ababy = New Ababy (); Echo ($ Ababy-> GetData (7,77)); $ ababybed = serialize ($ ababy); $ newaby = unserialize ($ ababybed); echo ($ newaby-> getlastdata ()); Note: Try Increased __sleep () released after serialization, the forgotten handle. Run the above script. Error: __ sleep () should return an array that contains the name of the instance variable in the class. This is the exquisiteness of __sleep (): You can tell the parser which variables need to be sequenced. This group does not include instance variables (note the actual variable name stored by this array rather than the value) will be abandoned, which can slim in the serialized string, and speed up at the reverse sequence. It seems that __ Sleep () can optimize system performance from two aspects: 1, release resources; 2, have selective serialized instance variables.

Fixed the above code as follows: 4,

Class Ababy {Var $ FileName, $ FileOpen, $ OFFSET, $ Length; Function Ababy () {$ this-> filename = 'Ababy.class.php'; $ this-> fileopen = fopen ($ this-> fileename, ' RB '); $ this-> offset = 0; $ this-> length = 0;} Function getData ($ this-> offset = $ offset; $ this-> length = $ length; fseek ($ THIS-> FileOpen, $ OFFSET); Return ($ this-> fileopen, $ length));} function getlastdata () {Return ($ this-> getData ($ this-> offset, $ this-> Length));} function __sleep () {fclose ($ this-> fileopen; $ arr = array (); array_push ($ arr, 'filename "; array_push ($ arr,' offset '); array_push ($ ARR) , 'Length'); return ($ arr);} function __wakeup () {$ this-> fileopen = fopen ($ this-> filename, 'rb');}} $ ababy = new ababy (); echo ($ Ababy-> GetData (7,77)); $ ababybed = serialize ($ ababy); $ newaby = unserialize ($ ababybed); echo ($ newaby-> getlastdata ()); Note: Fixed __sleep () definitions are normal, and the results are expected.

转载请注明原文地址:https://www.9cbs.com/read-5165.html

New Post(0)