zoukankan      html  css  js  c++  java
  • PHP中匿名函数和闭包(尚未整理)

    <?php
    /**
     * 匿名函数与闭包学习
     *
     * 首先是匿名函数
     */
    
    /*
     * 一个例子
     * array_map
     * 定义一个函数
     * array_map 回调这个函数
     */
    function addOne($args)
    {
        return $args + 1;
    }
    
    $data = array_map('addOne', array(1, 2, 3, 4));
    print_r($data);
    
    
    /*
     * 变形
     * 直接用闭包huo匿名函数做回调
     * * 上面的做法把回调的实现和使用场所隔离开了,
     * 可见使用闭包实现代码更加简洁。
     */
    $data2 = array_map(function ($args) {
        return $args + 1;
    }, array(1, 2, 3, 4));
    print_r($data2);
    
    /*
     * 闭包是一个对象,所以我们可以在闭包中使用$this关键字获取闭包的内部状态,
     * 闭包对象的默认状态没什么用,需要注意的是其中的__invoke魔术方法和bindTo方法。
     */
    $funName = function ($args) {
        return $args;
    };
    echo "<br>", $funName(1), "<br>", $funName(2);
    
    class Test
    {
        public function __invoke()
        {
            return "对象用方法调用时默认的输出";
        }
    
        public function testA($args)
        {
            return $args;
        }
    
        public function ha()
        {
            return 'hah';
        }
    
    }
    
    $te = new Test();
    echo $te(); //对象用方法调用时默认的输出
    
    /*
     * 让匿名函数绑定对象测试
     */
    $testA = function () {
        $this->testA();
    };
    
    /*
     * 含有参数的匿名函数绑定对象
     *
     */
    $testCl = function ($funcname, $args) {
        return $this->$funcname($args);
    };
    
    $aa = $testA->bindTo(new Test(), 'Test');
    echo $aa('testa');
    $cc = $testCl->bindTo(new Test(), 'Test');
    
    echo '<br>' . $cc('ha', 1);
    //php7中的用法
    echo $testCl('ha', 1)->call(new Test);

     下面是有意思的闭包的例子,他返回的是函数,所以可以这样子。

    <?php
    function operate($operator)
    {
        if ($operator == "-") {
            return function ($a, $b) {
                return $a - $b;
            };
        } else {
            return function ($a, $b) {
                return $a + $b;
            };
        }
    }
    
    $subtraction = operate("-");
    echo $subtraction(4, 3);//1
    $addition = operate("+");
    echo $addition(1, 2);//3
    <?php
    
    
    header("Content-Type:text/html;charset=utf-8");
    
    class Di
    {
        private $_factory;
    
        public function set($id, $value)
        {
            $this->_factory[$id] = $value;
        }
    
        public function get($id)
        {
            $value = $this->_factory[$id];
            return $value();
        }
    }
    
    class User
    {
        private $_username;
    
        function __construct($username = "")
        {
            $this->_username = $username;
        }
    
        function getUserName()
        {
            return $this->_username;
        }
    }
    
    //从这里开始看
    $di = new Di();
    $di->set("zhangsan", function () {
        return new User('张三');
    });
    $di->set("lisi", function () {
        return new User("李四");
    });
    
    echo $di->get("zhangsan")->getUserName();
    echo $di->get("lisi")->getUserName();
    
    /*
     代码中有一个Di容器用来保存对象实例,然后通过set()方法注册服务,通过get()方法获取服务。
    我们看到$di->set()的时候,使用了匿名函数,我们预先注册了zhangsan和lisi两个服务,这两个服务都是User类的实例,
    在$di->set的时候实际上并没有实例化,而是在$di->get()的时候才执行了匿名函数并将对象返回,这就实现了按需实例化,
    不用则不实例化,提高效率。
     经常写js的同学应该知道js的闭包特性,简单的说就是在一个函数里可以定义子函数,父函数中的变量在子函数中可以直接使用,
    那么PHP的闭包怎么用呢?有一点区别。
    */
        function func1($a){
            return function() use ($a){
                echo $a;
            };
        }
        $a = func1("a");
        $a();//输出a
    
    /*
    当你想将外层变量传进内层匿名函数时,使用use (变量)的方式。
    闭包的用途可以用于很多地方,常见于DI模式中,这篇文章的代码只是为了说明,不可以直接使用,谢谢。
    */

    部分资料来源自: http://www.thinkphp.cn/topic/13624.html

  • 相关阅读:
    Linux下的压缩zip,解压缩unzip命令详解及实例
    org.hibernate.type.SerializationException: could not deserialize 反序列化失败
    oracle操作小计
    gradle项目与maven项目互转
    IntelliJ IDEA创建maven web项目(IDEA新手适用)
    数据结构篇——字典树(trie树)
    数据结构篇——并查集
    数据结构篇——优先级队列(堆)
    数据结构篇——平衡二叉树(AVL树)
    数据结构篇——二叉排序(查找,搜索)树
  • 原文地址:https://www.cnblogs.com/cs88/p/6298481.html
Copyright © 2011-2022 走看看