PHP learning book-Chapter 8 (II)

Source: Internet
Author: User
Tags function examples modulus
Now let's take a look at some of the more magical properties of the form, including the method for using the number of variable parameters and allowing the form to modify the method for passing in variables, and make the form a method for data use. The content of this section is the most advanced writing skills in this chapter.

Now let's take a look at some of the more magical attributes of the function, including the method of using the number of variable parameters, allowing the function to modify the method of incoming variables, and making the function the method used by the data.

This section is the most challenging section in this Chapter. it is only suitable for programmers who are adventurous, curious, or experienced.

Variable parameter count

It is useful to know the actual number of parameters when calling the passed function based on the actual situation. There are three possible methods for processing in PHP, one of which can only be used in PHP4:

1. define a function with preset parameters. when a function misses any parameter in a call, it will be replaced by a preset value without warning information.

2. use array parameters to store these values. the program code of the call is responsible for packaging the array. the correspondence ontology must properly separate the data.

3. use the variable parameter functions (func_num_args (), func_get_arg (), and func_get_args () in PHP4 ()).

Preset parameters

To define a function with preset parameters, you only need to change the formal parameters to the specified formula. If the actual call parameters are less than the defined formal parameters, PHP compares the formal parameters with the actual parameters until they are used up, then fill in the remaining parameters with the preset settings.

For example, all variables in the following function are defined by default values:

Function tour_guide ($ city = "Gotham City ",

$ Desc = "vast metropolis ",

$ How_ens = "dozens ",

$ Of_what = "costumed villains ")

{

Print ("$ city is a $ desc filled

$ How_many of $ of_what. <BR> ");

}

Tour_guide ();

Tour_guide ("Chicago ");

Tour_guide ("Chicago", "wonderful city ");

Tour_guide ("Chicago", "wonderful city ",

"Teeming millions ");

Tour_guide ("Chicago", "wonderful city ",

"Teeming millions ",

"Gruff people with hearts

Gold and hard-luck stories to tell ");

The browser will output a result similar to the following. The line feed symbol in the sentence is determined by the browser used:

Gotham City is a great metropolis filled with dozens of costumed villains.

Chicago is a great metropolis filled with dozens of costumed villains.

Chicago is a wonderful city filled with dozens of costumed villains.

Chicago is a wonderful city filled with teeming millions of costumed villains.

Chicago is a wonderful city filled with teeming millions of gruff people whit hearts of gold and hard-luck stories to tell.

The main limitation of the preset parameters is that the matching of the actual parameters to the formal parameters is determined by the sequential comparison between the two, first served. Therefore, you cannot use the preset parameter settings without knowing the last pile of problems.

Replace multiple parameters with arrays

If you are not satisfied with the elasticity of multiple parameters, you can use arrays as a means of communication to bypass the entire parameter count problem.

The following example uses this policy and also uses several tips, such as ternary operators (introduced in chapter 7) and correlated arrays (not regularly mentioned in chapter 6, in chapter 2, I will explain it comprehensively ):

Function tour_brochure ($ info_array)

{

$ City =

IsSet ($ info_array [? City?])?

$ Info_array [? City?] : "Gotham City ";

$ Desc =

IsSet ($ info_array [? City?])?

$ Info_array [? Desc?] : "Great metroprlis ";

$ How_many =

IsSet ($ info_array [? How_many?])?

$ Info_array [? How_many?] : "Dozens ";

$ Of_what

IsSet ($ info_array [? Of_what?])?

$ Info_array [? Of_what?] : "Costumed villains ";

Print ("$ city is a $ desc filled

$ How_many of $ of_what. <BR> ");

}

This function checks to compare the input array parameters with four different values separated by a specific string, and uses the ternary conditional operator 「?」, The region variable is specified as the input value (if it is already stored in the array). Otherwise, it is specified as the preset value. Now, we try to call this function using two different arrays:

Tur_brochure (array (); // empty array

$ Tour_info =

Aray (? City? =>? Cozumel ?,

? Desc? =>? Destination getaway ?,

'Of _ wh' => 'Sandy beaches ');

Tur_brochure ($ tour_info );

In this example, we first call tour_brochure with an empty array (corresponding to no parameter) and then call it with an array, which stores three of the four possible associated values. Its browser output is:

Gotham City is a great metropolis filled with dozens of costumed villains.

Cozumel is a destination getaway filled with dozens of sandy beaches.

In both cases, the number of "dozens" is preset because neither array has any content stored in the "how_modules" associated part.

Use multiple parameters in PHP4

Finally, PHP4 provides some functions to obtain the number and value of parameters in the function body. these functions are:

Fnc_num_args () does not contain parameters. it returns the number of parameters passed in when calling this function.

Fnc_get_arg () carries an integer parameter n and returns the nth parameter of the call. The parameter count starts from 0.

Fnc_get_args () returns an array without a parameter, which contains all the parameters of the call. the array index starts from 0.

If you call them outside the function ontology, all these three functions will throw a warning message. if the index used during the call is higher than the passed final parameter index, func_get_arg () will also throw a warning.

If the user's function uses these functions to decode parameters, you can make full use of the call method mentioned here. PHP will not complain because the actual number of parameters is more than the number of formal parameters in the definition. You can define a function without parameters, and then use this function to compare and match any actually passed-in function.

For example, consider the following two function examples, which return an input parameter array:

Fnction args_as_array_1 ()

{

$ Arg_count = func_num_args ();

$ Counter = 0;

$ Local_array = array ();

Wile ($ counter <$ arg_count)

{

$ Local_array [$ counter] =

Fnc_get_arg ($ ary_counter );

$ Counter = $ counter + 1;

}

Rturn ($ local_array );

}

Fnction args_as_array_2 ()

{

Rtun (func_get_args ());

}

The first cumbersome function uses func_get_arg () to retrieve each individual parameter, and uses the result of func_num_args () to define a boundary for the loop, therefore, no more parameters are Retrieved than actually passed in. Each parameter is stored in the array and then transmitted back to the array. The packaging of such parameters is actually completed by func_get_arps (), so the second version of this function is very short.

Here is another example. we rewrite the previous tour_guide () function, which uses multiple parameter functions to replace the preset parameters:

Fnction tour_guide_2 ()

{

$ Num_args = func_num_args ();

$ City = $ num_args> 0?

Fnc_get_arg (0): "Gotham City ";

$ Desc = $ num_args> 1?

$ Desc = $ num_args> 1?

Fnc_get_arg (1): "great metropolis ";

$ How_gs = $ num_args> 2?

Fnc_get_arg (2): "dozens ";

$ Of_what = $ num_args> 3?

Fnc_get_arg (3): "costumed villains ";

Pint ("$ city is a $ desc filled

$ How_many of $ of_what. <BR> ");

}

Tur_guide2 ();

The above code has the same effect and effect as the preset parameter code, and is subject to the same restrictions. The parameter is passed in according to the location, so there is no way to replace "costumed villains" with other content, and only use "Gotham City" as the default value.

Call-by-value vs. call-by-reference)

The default action defined by the user in PHP is "call-by-value transfer value call", which means that when a variable is passed to the call function, PHP creates a copy of the variable value and sends it to the function. Therefore, no matter what the function is, it cannot change the actual variable that appears in the function call. Although such behavior has advantages, it also has disadvantages. When we only want to use the return value of the function, this is of course a good way, but if we modify the input variable as the actual target, it will hinder.

The following example shows an example of less efficient subtraction for value-based calling:

Fnction my_subtract ($ numl, $ num2)

{

I ($ numl <$ num2)

De ("Negative numbers are imaginary ");

$ Return_result = 0;

Wile ($ numl> $ num2)

{

$ Numl = $ numl-1;

$ Return_result = $ return_result + 1;

}

Rturn ($ return_result );

}

$ First_op = 493;

$ Second_op = 355;

$ Result1 = my_subtract ($ first_op, $ second_op );

Pint ("result1 is $ result1 <BR> ");

$ Result2 = my_subtract ($ first_op, $ second_op );

Print ("result2 is $ result2 <BR> ");

Good, we can see that the result of executing the same subtraction twice will be the same:

Rsult1 is 138

Rsult2 is 138

Even if my_subtract changes the value of $ numl, this result is returned. The $ numl variable only stores copies of the values of the actual parameter $ first_op, therefore, $ first_op will not be affected.

Call-by-reference)

PHP provides two different methods for the function to be defined, or in a function call, it is more capable of modifying parameters, also known as an address transfer call.

If you want to define a function to operate the input variable directly, you can add the "&" symbol before the formal parameter in the definition, as shown below:

Fnction my_subtract_ref (& $ numl, & $ num2)

{

I ($ numl-<$ num2)

De ("Negative numbers are imaginary ");

$ Return_result = 0;

Wile ($ num1> $ num2)

{

$ Numl = $ num1-1;

$ Return_result = $ return_result + 1;

}

Rturn ($ return_result );

}

$ First_op = 493;

$ Second_op = 355;

$ Result1 = my _ subtract_ref ($ first_op, $ second_op );

Pint ("result1 is $ result1 <BR> ");

$ Result2 = my_subtract_ref ($ first_op, $ second_op );

Pint ("result2 is $ result2 <BR> ");

Now, if you execute the same subtraction call as before, you will get the following output:

Rsult1 is 138

Rsult1 is 0

This is because the format parameter $ numl and the actual parameter $ first_op refer to the same content. modifying one is equivalent to modifying the other.
You can also add the "&" symbol before the actual parameter to force a function to pass the parameter according to the parameter (this is a progressive elimination function, and may be removed in future PHP versions ). That is to say, you can use the initial value-based call function to obtain the parameter-based action, as shown below:

$ First_op = 493;

$ Second_op = 355;

$ Result1 = my_subtract (& $ first_op, & $ second_op );

Print ("result1 is $ result1 <BR> ");

$ Result2 = my_subtract (& $ first_op, & $ second_op );

Print ("result2 is $ result2 <BR> ");

This time, the following results are obtained:

Rsult1 is 138

Rsult1 is 0

For PHP4, variable parameters can also be used outside the form call. Generally, specifying a variable parameter (& $ varname) to a variable will make the two variables become aliases of each other,
Instead of two variables with the same value. For example:

$ Name_1 = "Manfred von Richtofen ";

$ Name_2 = "Percy Blakeney ";

$ Alias_1 = $ name_1; // The variable has the same value

$ Alias_2 = & $ name_2; // The variable is the same

$ Alias_1 = "The Red Baron"; // The actual name is not changed.

$ Alias_2 = "The Scarlet Pimpernel"; // no matter what it is, it is irrelevant.

Prnt ("$ alias_1 is $ name_1 <BR> ");

Prnt ("$ alias_2 is $ name_2 <BR> ");

The above code will get the output of the browser:

The Red Baron is Manfred von Richtofen

The Scarlet Pimpernel is The Scarlet Pimpernel

Variable function name

A very flexible technique in PHP is to replace the user-defined location with variables. In other words, you do not need to enter a literal name in the program code, but you can enter a variable starting, the actual call function depends on the string specified for the variable. In a sense, this allows the function to be used as data. This technique may be very familiar to Price C language programmers, as well as for beginners of any type of Lisp language (such as Scheme or Common Lisp.

For example, the following two function calls are completely equal:

Function customized_greeting ()

{

Print ("You are being greeted in a customized way! <BR> ");

}

Customized_greeting ();

$ My_greeting = 'mizmized _ greeting ';

$ My_greeting ();

The above code generates the same output:

You are being greeted in a customized way!

You are being greeted in a customized way!

Because the function name is a string, it can also be used as a function parameter or as a function result.

Extended extension example +

Let's take a look at the troubles of using a more advanced feature of the function, including using the function name as the function parameter.

Example 8-1 this example shows an extended extension example of the function. this function completes the password replacement function, which is the most primitive password system, replace another letter with one letter in the alphabet to confuse the information displayed.

The program code below is long and advanced in any program code demonstrated so far in this book. For those who do not want to know the details, skip this code.

Example 8-1 password replacement

/* Part 1: password calculation and tool letter */

Function add 1 ($ num)

{

Return ($ num + 1) % 26 );

}

Function sub_1 ($ num)

{

Return ($ num + 25) % 26 );

}

Function swap 2 ($ num)

{

If ($ num % 2 = 0)

Return ($ num + 1 );

Else

Return ($ num-1 );

}

Function swap 26 ($ num)


{

Return (25-$ num );

}

Function lower letter ($ char string)

{

Return (ord ($ char string)> = ord ('A '))&&

(Ord (& char string) <= ord ('Z ')));

}

Function upper letter ($ char string)

{

Return (ord ($ char string)> = ord ('A '))&&

(Ord ($ char string) <= ord ('Z ')));

}

/* Part 2: letter cipher function */

Function letter cipher ($ char string, $ code func)

{

If! (Upper letter ($ char string) |

Lower letter ($ char string )))

Return ($ char string );

If (upper leter ($ char string ))

$ Base num = ord ('A ');

Else

$ Base num = ord ($ char string )-

$ Base num );

Return (chr ($ base num +

($ Code func ($ char num)

% 26 )));

}

/* Part 3: main string cipher function */

Function string cipher ($ message, $ cipher func)

{

$ Coded message = "";

$ Message length = strlen ($ message );

For ($ index = 0;

$ Index <$ message length;

$ Index ++)

$ Coded message. =

Letter cipher ($ message [$ index], $ cipher func );

Return ($ coded message );

}

Example 8-1 consists of three parts. In the first part, we defined several formulas for performing simple numeric operations on numbers 0-25. these numbers represent the letters A-Z in the cryptographic program. Add_1 adds 1 to the number, with "26" as the modulus (meaning that only the number 26 and more than 26 will be "rolled back" to start with "0. 0 to 1, 1 to 2 ,... And 25 to 0. Sub_1 converts numbers in the other direction. by adding 25 (in this modulus algorithm, it is equal to minus 1), 25 is changed to 24, 24 is changed to 23 ,... , 0 to 25. Swap_2 replaces the positions of numbers in pairs (0 to 1, 1 to 0, 2 to 3, 3 to 2... And so on) swap_26 is to replace the higher and lower numbers (25 to 0, 0 to 25, 24 to 1, 1 to 24... And so on ).

All these functions are the basis of this simple password program. There are also two utility functions to test whether the characters are uppercase or lowercase letters.

The second part is a letter_cipher () function. the function of this function is to obtain an arithmetic function in the first part, and then use it to encode simple letters. This function first tests whether the string it processes (only one character in it) is a letter. if not, it is returned as is. If the character is a letter, you can use it. The function of Ord () is to convert it to a number, and then deduct the appropriate letter (A or a) to limit the number to 0 to 25. Once it is within this range, you can apply its name to the password function passed in as a string, convert the number to a letter, and return it back.

Finally, the third part is the string_cipher () function, which carries a string message and a password function, which returns a new string value, the value is the content encoded through the function. Here we use one or two features that we didn't see before (including the character string connection operator 「. = ", as mentioned in chapter 10). This function processes the letters of the message string one by one and constructs a new string, use the new letters to indicate that the results obtained by $ cipher_func are applied to the numbers of the old letters. here you probably know enough about this.

Below, we will write some code to test string_cipher ();

$ Originak = "My secret message is ABCDEFG ";

Print ("Original message is: $ orginal <BR> ");

$ Coding_array = array ('add _ 1 ',

'Sub _ 1,

'Swap _ 2 ',

'Swap _ 26 ');

For ($ count = 0;

$ Count <sizeof ($ coding_array );

$ Coded_message =

String_cipher ($ original, $ code );

Print ("$ code encoding is: $ coded_message <BR> ");

}

These test code uses a pre-defined four-letter code form to hide them in an array and then repeat the array to encode the $ original message, the encoded version is displayed. The browser output is as follows:

Original message is: My secret message is ABCDEFG

Add_1 encoding is: Nz tfdsfu nfttbhf jt BCDEFGH

Sub_1 encoding is: Lx rdbqfs nfttbhf jt BADCFRH

Swap_2 encoding is: Nz tfdqfs nfttbhf jt BADCFEH

Swap_26 encoding is: Nb hvxivg nvhhztv rh ZYXWVUT

We can take this form as a method for data further, and write a letter ratio that applies multiple passwords to messages in the sequence. This function also uses the variable parameter type of PHP4:

Function chained_code ($ message)

{

/* Obtain the reflected message first, and then find any number of edited code correspondence names.

Apply each encoding form to the previous result and return the result. */

$ Argc = func_num_args ();

$ Coded = $ message;

For ($ count = 1; $ count <$ argc; $ count ++)

{

$ Function_name = func_get_arg ($ count );

$ Coded =

String_cipher ($ coded,

$ Function_name );

}

Return ($ coded );

}

The first parameter of Chained_code () should be a message string followed by any number of names corresponding to the password function. The encoded message is the result of applying the first encoding form to the message, and then applying the second encoding form to the result, and so on. We can test it by using a combination of pre-defined letter-encoding methods.

$ Tricky =

Chained_code ($ original,

'Add _ 1' swap _ 26 ',

'Add _ 1' swap _ 2 ');

Print ("Tricky encoded version is $ tricky <BR> ");

$ Easy =

Chained_code ($ original,

'Add _ 1', 'swap _ 26 ',

'Swap _ ', 'sub _ 1 ',

'Add _ 1', 'swap _ 2 ,'

'Swap _ 26, ''sub _ 1 ,');

Print ("Easy encoded version is $ easy <BR> ");

The result is:

Tricky encoded version is Ma guww.muggysu qg YXWXUVS

Easy encoded version is My secret message is ABCDEFG

As you may see, the editor of the "tricky" message is in the combination of the pre-code, but does not exactly correspond to any separate encoding form. The "easy" encoding is a more complex combination of these functions. The result is the initial message ...... No changes! (This is not because the key code is invalid. we just want readers to understand why such a specific edited correspondence sequence can return to the original message .)

The scope shown in this small password script is intended to help you understand that, although the password program is a little more complex, PHP supports using a function name as a function parameter, this makes it quite simple.

Summary

Most PHP functions exist in a large number of built-in functions, which are provided by the PHP open source code development team. Each form should be documented in the online manual of the http://www.php.net (although a little short ).

You can also write your own function, which can be used in the same way as the built-in function. The function is written in a simple C-language syntax, as shown below:

Function my_function ($ argl, $ arg2 ,...)

{

Statement1;

Statement2;

...

Return ($ value );

}

User-defined functions can be used with any PHP-type parameters, and can also return any type value. Parameter and return value types are not required.

In PHP4, the number of calls to a function is no different from that to a function, as long as each function of a call has been defined. It is not required for independent function declaration or prototype design. The variables specified in the function are restricted to the function area unless the global declaration is used. Region variables can be declared as static, which means they can retain their own values between function calls.

The default action of the user-defined function is "call by value (call_by_reference)", which means that the function uses a copy of the parameter during operation, therefore, you cannot modify the original variable in the form call. By adding "&" to the parameter, you can force "call-by-reference", either on the caller or on the caller. PHP provides multiple ways to change the number of parameters included in the function. Finally, the form to be called can be determined during the execution period, and a string variable can be used to replace the user-defined form name, so that the form can be treated as material, and transfer it back and forth between other functions.

The above is the content of Chapter 8 (II) of the PHP Learning Guide. For more information, see PHP Chinese website (www.php1.cn )!

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.