Summary of closure instance tutorial in php-php Tutorial

Source: Internet
Author: User
This article describes how to use closure in php. For more information, see this article.

Closure, an Anonymous function, was introduced in php5.3, also known as Anonymous functions. That is, a function with no name defined. For example, the following code (the file name is do. php)


 

Here, A () can never be used as the parameter of B, because A is not an "anonymous" function.

So we should change it to this:


 

Implement closures

Passing in an anonymous function as a parameter in a common function can also be returned. This implements a simple closure.

Here are three examples:


  ';}; CallFunc ($ printStrFunc); // You can also pass anonymous functions directly. If you know about js, you may be familiar with callFunc (function ($ str) {echo $ str; // output no! I hate you });

Keyword for connecting closure and external variables: USE

The closure can save some variables and values in the context of the code block. By default, an anonymous function cannot call the context variable of the code block, but must use the use keyword.

Let's look at another example (well, I am short of money, I am vulgar ):


  

As you can see, dollar is not declared in the use keyword and cannot be obtained in this anonymous function. therefore, pay attention to this issue during development.

Some people may think about whether the context variables can be changed in anonymous functions, but I find it is not possible:


   '; // Add the $ RMB value to 1 $ RMB ++;}; $ func (); echo $ RMB;} getMoney (); // output: // 1 // 1

The original use references only a copy of the variable clone. But what if I want to completely reference the variable instead of copying it? To achieve this effect, you can add an & symbol before the variable:


   '; // Add the $ RMB value to 1 $ RMB ++;}; $ func (); echo $ RMB;} getMoney (); // output: // 1 // 2

Okay, so that the anonymous function can reference the context variable. If an anonymous function is returned to the outside world, the anonymous function will save the variables referenced by use, and the outside world will not be able to get these variables, so that the concept of 'closures 'may be clearer.

Based on the description, let's change the above example:


   '; // Add the $ RMB value to 1 $ RMB ++;}; return $ func;} $ getMoney = getMoneyFunc (); $ getMoney (); $ getMoney (); // output: // 1 // 2 // 3

Okay, so what if we want to call an anonymous function in a class? Go directly to demo


   

Among them, A: testA () returns an unknown funciton.

Concept of binding

The Closure in the above example is only a global anonymous function. well, now we want to specify a class with an anonymous function. It can also be understood that the access range of this anonymous function is no longer global, but the access range of a class.

Then we need to bind an anonymous function to a class ".


    Base + 3 ;}; $ a = Closure: bind ($ f, new A); print_r ($ a (); // Output 103 echo PHP_EOL; $ B = Closure: bind ($ f, new B, 'B'); print_r ($ B (); // output 1003

In the above example, the anonymous function f contains this inexplicably. this keyword indicates that the anonymous function needs to be bound to the class.

After binding, it is like A has such A function, but the function is public or private. the last parameter of bind shows the callable range of the function.

We have seen bindTo above. let's take a look at the introduction on the official website.


(PHP 5 >= 5.4.0, PHP 7)

Closure: bind-copy a Closure and bind it to the specified $ this object and class scope.

Description

Public static Closure: bind (Closure $ closure, object $ newthis [, mixed $ newscope = 'static '])
This method is the static version of Closure: bindTo. View its documentation for more information.

Parameters

Closure

The anonymous function to be bound.

Newthis

The object to be bound to an anonymous function, or NULL creates an unbound closure.

Newscope

The class scope that you want to bind to the closure, or 'static 'indicates that it will not change. If an object is input, the type name of the object is used. The class scope is used to determine the visibility of the $ this object in the closure and the protection method. (Note: you can input an instance of the class name or class. the default value is 'static ', indicating that the instance will not be changed .)

Return value:

Returns a new Closure object or FALSE if the object fails.


    Ifoo;}; $ bcl1 = Closure: bind ($ cl1, null, 'A'); $ bcl2 = Closure: bind ($ cl2, new (), 'A'); echo $ bcl1 (), "\ n"; // output 1 echo $ bcl2 (), "\ n"; // output 2

Let's take a look at an example to further understand:


    Base + 3 ;}; $ sf = static function () {return self: $ base + 3 ;}; $ a = Closure: bind ($ f, new ); print_r ($ a (); // Output 103, bound to echo PHP_EOL of Class A; $ B = Closure: bind ($ f, new B, 'B '); print_r ($ B (); // output 1003, bound to echo PHP_EOL of Class B; $ c = $ sf-> bindTo (null, 'C '); // Note: Use Variable # sf to bind to class C. The first parameter is nullprint_r ($ c () by default. // output 10003 here.

Let's look at another demo:


    Dog ;};/** get the attributes of public members of an Animal instance */$ pig = function () {return $ this-> pig ;}; $ bindCat = Closure :: bind ($ cat, null, new Animal (); // bind the Animal instance scope to the Closure, but not to the Closure $ this object $ bindDog = Closure :: bind ($ dog, new Animal (), 'Animal '); // bind the Animal class scope to the closure, bind the Animal instance object as the $ this object to the Closure $ bindPig = Closure: bind ($ pig, new Animal ()); // bind the Animal instance object to the closure as the $ this object, and keep the echo $ bindCat (),'
'; // Output: Garfield. according to the binding rules, the closure is allowed to obtain the Animal static private member attribute echo $ bindDog (),' through the scope limitation operator (),'
'; // Output: Wang, according to the binding rules, allows the closure to obtain the private member attribute echo $ bindPig () of the Animal instance through the bound $ this object (Animal instance object (),'
'; // Output: PIG. according to the binding rules, the closure is allowed to obtain the public member attribute of the Animal instance through the bound $ this object.

Through the above examples, it is not difficult to understand anonymous binding... we are looking at an extended demo (introducing the trait feature)


    $ Name) {return call_user_func ($ this-> $ name, $ args );} else {throw new \ RuntimeException ("Method {$ name} does not exist") ;}}/*** ADD Method */public function _ set ($ name, $ value) {$ this-> $ name = is_callable ($ value )? $ Value-> bindTo ($ this, $ this): $ value ;}} /*** only attributes without method Animal classes ** @ author fantasy */class animal {use DynamicTrait; private $ dog = 'wangwang team';} $ Animal = new Animal; // add a method to the animal instance to obtain the private attribute of the instance $ dog $ animal-> getdog = function () {return $ this-> dog ;}; echo $ animal-> getdog (); // output Wangwang

For example, now we use the current shopping environment


    Products [$ item] = $ quantity;}/*** obtain the quantity of a single item ** @ access public * @ param string item name */public function getQuantity ($ item) {return isset ($ this-> products [$ item])? $ This-> products [$ item]: FALSE;}/*** get the total price ** @ access public * @ param string tax rate */public function getTotal ($ tax) {$ total = 0.00; $ callback = function ($ quantity, $ item) use ($ tax, & $ total) {$ pricePerItem = constant (_ CLASS __. ": PRICE _". strtoupper ($ item); // call the above constant $ total + = ($ pricePerItem * $ quantity) * ($ tax + 1.0 );}; array_walk ($ this-> products, $ callback); return round ($ total, 2) ;}$ my_cart = new Cart; // add the product and quantity to the shopping cart $ my_cart-> add ('butter ', 10); $ my_cart-> add ('milk', 3 ); $ my_cart-> add ('eggs', 12); // you can obtain the total price, with a sales tax of 3%. echo $ my_cart-> getTotal (0.03); // output 1196.4

Note: the closure can USE the USE key to connect external variables.

Summary: The features of PHP closures can actually implement similar or even more powerful functions using CLASS. it cannot be compared with the closure of js. we can only look forward to improving the closure support of PHP in the future. However, anonymous functions are quite useful. for example, if you use functions such as preg_replace_callback, you do not need to declare callback functions externally. The rational use of closures makes the code more concise and refined.

The above is a summary of the details of the closure instance tutorial in php. For more information, see other related articles in the first PHP community!

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.