Anonymous function (closure function)
Anonymous function, also called closure function, allows temporary creation of a function without a specified name, commonly used The value of the callback function parameter can also be used as the value of a variable. For specific usage, see the following example code:
/* 示例一:声明一个简单匿名函数,并赋值给一个变量,通过变量名调用这个匿名函数 */ $anonFunc = function($param){ echo $param; }; $anonFunc('这里是一个匿名函数'); // 通过变量名调用匿名函数,和普通函数没什么区别 /* 示例二:通过在函数内部使用匿名函数动态创建函数 */ function operate($operator){ if($operator == '+'){ return function($a, $b){ return $a + $b; } } if($operator == '-'){ return function($a, $b){ return $a - $b; } } } $add = operate('+'); echo $add(4, 3); // 7 $sub = operate('-'); echo $sub(4, 3); // 1 /* 示例三:匿名函数作为回调函数参数传入 */ function callback($callback){ $callback(); } function callback(){ // 闭包测试函数 echo '这里是闭包测试函数体'; }
In the three examples in the above code, the anonymous function does not pass parameters. We know that anonymous functions are used frequently in JavaScript, and the parameters in the parent function Variables can be used directly in sub-functions, but the PHP language does not allow this. You need to use the use ($var) keyword (pay attention to how it is used in the code) to achieve the same purpose. Make the following modifications to Example 3 in the above code:
/* 示例三修改:匿名函数作为参数传入,并且携带参数 */ function callback($callback) use ($content){ $callback($content); } $content = '这里是闭包函数的输出内容'; function callback($content){ // 闭包函数 echo $content; }
In Example 2 in the above code, you can also use the use keyword to realize the reference of the anonymous function to the outer variable of the parent function. The use of anonymous functions and closure features in these sample codes is just for understanding the concepts and does not have much practical significance. Closures have many uses, and they are most commonly used in dependency injection (DI) of the container mode in the PHP framework.
PHP Object-Oriented Container Pattern
As the name suggests, a container is used to store things. In fact, it is to declare a class specifically used to access object instances. In this case , then there must be at least two core methods in the container to bind dependencies to the container and obtain dependencies from the container. A container can be said to be a dependency management tool, sometimes also called a service container.
/* 声明一个简单的容器类 */ class Container{ private $_diList = array(); // 用于存放依赖 /* 核心方法之一,用于绑定服务 * @param string $className 类名称 * @param mixed $concrete 依赖在容器中的存储方式,可以是类名字符串,数组,一个实例化对象,或者是一个匿名函数 */ puclic function set($className, $concrete){ $this->_diList[$className] = $concrete; } /* * 核心方法之二,用于获取服务对象 * @param string $className 将要获取的依赖的名称 * @return object 返回一个依赖的实例化对象 */ public function get($className){ if(isset($this->_diList[$className])){ return $this->diList[$className]; } return null; } }
The above code is a simple container pattern, in which the set method is used to register dependencies, and the get method is used to obtain dependencies. There are many ways for containers to store dependencies. The following example code uses anonymous functions as an illustration.
/* 数据库连接类 */ class Connection{ public function __construct($dbParams){ // connect the database... } public someDbTask(){ // code... } } /* 会话控制类 */ class Session{ public function openSession(){ session_start(); } // code... } $container->set('session', function(){ return new Session(); }); $container = new Container(); // 使用容器注册数据库连接服务 $container->set('db', function(){ return new Connetion(array( "host" => "localhost", "username" => "root", "password" => "root", "dbname" => "dbname" )); }); // 使用容器注册会话控制服务 $container->set('session', function(){ return new Session(); }); // 获取之前注册到容器中的服务,并进行业务的处理 $container->get('db')->someDbTask(); $container->get('session')->openSession();
The above code is how to use the container, in which two services, db and session, are registered. Here, anonymous functions are used as dependent storage methods, and the $container->set() method is called to register the service. It is not actually instantiated at the time, but the anonymous function is executed when the $container->get() method is called to obtain the dependency, and the instantiated object is returned. This achieves on-demand instantiation, and does not instantiate if not used. ization, improving the operating efficiency of the program.
The above is the detailed content of From anonymous function (closure feature) to PHP design pattern container pattern. For more information, please follow other related articles on the PHP Chinese website!