热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

为什么这里的闭包函数无法调用?此外魔术方法也未被调用

我的代码是这样的:{代码...}首先,按道理说,调用一个类中间不存在的成员变量,因该显示的的调用魔术方法_set,但是这里没有显示的声明_set方法;2.为什么我无法调用$obj->getInfo()方法呢?一旦调用就会抛...
我的代码是这样的:

 $value) 
                $this->{$key}=$value;
    }

    public function __call($methodName,$params){
        $params=array_merge(array('stdObject'=>$this),$params);
        if(isset($this->{$methodName})&&is_callable($methodName)){
            //$params就是函数的参数,这里的stdObject就是function中的$stdObject;
            return call_user_func_array($methodName,$params);
        } else {
            throw new Exception("Fatal error: Call to undefined method stdObject::{$methodName}()");
        }
    }

}

echo  phpversion();
$obj = new stdObject();
$obj->name = "Nick";
$obj->surname = "Doe";
$obj->age = 20;
$obj->adresse = null;
$obj->getInfo = function($stdObject) { 
    // $stdObject referred to this object (stdObject).
    echo $stdObject->name . " " . $stdObject->surname . " have " . $stdObject->age . " yrs old. And live in " . $stdObject->adresse;
};

print_r($obj);
$obj->getInfo();
?>

首先,按道理说,调用一个类中间不存在的成员变量,因该显示的的调用魔术方法_set,但是这里没有显示的声明_set方法;
2.为什么我无法调用$obj->getInfo()方法呢?一旦调用就会抛出异常
'Fatal error: Call to undefined method stdObject::getInfo(),就说明这个方法不存在

回复内容:

我的代码是这样的:

 $value) 
                $this->{$key}=$value;
    }

    public function __call($methodName,$params){
        $params=array_merge(array('stdObject'=>$this),$params);
        if(isset($this->{$methodName})&&is_callable($methodName)){
            //$params就是函数的参数,这里的stdObject就是function中的$stdObject;
            return call_user_func_array($methodName,$params);
        } else {
            throw new Exception("Fatal error: Call to undefined method stdObject::{$methodName}()");
        }
    }

}

echo  phpversion();
$obj = new stdObject();
$obj->name = "Nick";
$obj->surname = "Doe";
$obj->age = 20;
$obj->adresse = null;
$obj->getInfo = function($stdObject) { 
    // $stdObject referred to this object (stdObject).
    echo $stdObject->name . " " . $stdObject->surname . " have " . $stdObject->age . " yrs old. And live in " . $stdObject->adresse;
};

print_r($obj);
$obj->getInfo();
?>

首先,按道理说,调用一个类中间不存在的成员变量,因该显示的的调用魔术方法_set,但是这里没有显示的声明_set方法;
2.为什么我无法调用$obj->getInfo()方法呢?一旦调用就会抛出异常
'Fatal error: Call to undefined method stdObject::getInfo(),就说明这个方法不存在

首先,缩进是谁弄的,快站出来,我保证不打死你哦…另外回答你的问题:

  1. 你都知道调用不可访问的成员变量时会调用魔术方法__set(),那你为啥不定义呢!你不定义你怎么让人家工作嘛,就好像你不给工作内容给我但是你希望我每天干的跟狗一样?别逗好么!请自行增加魔术方法定义好么!

    
    class stdObject {
        private function __set($name, $value) {
            $this->$name = $value;
        }
    }
    

  2. PHP中成员属性和成员函数的定义方法是不一样的,我还没见过用$this->method = function() {}这样定义成员函数的,你这是把Javascript的思想代入到PHP中来了吧。所以在调用不可访问成员函数的时触发__call()魔术方法中,你的isset()判断是真,但是is_callable()会返回假(对了这里还要提醒一个笔误,是is_callable($this->$methodName)不是is_callable($methodName),两个完全不一样好么!你以为你把变量名字叫做methodName你不给$this程序就会自动的给你调用成员函数么!坑爹呢!!),然后你的语法会抛出一个异常出来。

公子哥您在逗我。我将is_callable($methodName)变成is_callable($this->{$methodName})成功运行了。我的原因是错在这里。而不是魔术方法。而且达到了我想要的效果。现在代码是这样的:

 $value) {

    $this->{$key}=$value;
    
   }

            
        }
    }

    public function __call($methodName,$params){

      $params=array_merge(array('stdObject'=>$this),$params);
      if(isset($this->{$methodName})&&is_callable($this->{$methodName})){
        //$params就是函数的参数,这里的stdObject就是function中的$stdObject;
        return call_user_func_array($this->{$methodName},$params);
      }
   else{
    throw new Exception("Fatal error: Call to undefined method stdObject::{$methodName}()");
 
    }
    }

};

$obj = new stdObject();
$obj->name = "Nick";
$obj->surname = "Doe";
$obj->age = 20;
$obj->adresse = null;
$obj->getInfo = function($stdObject) { // $stdObject referred to this object (stdObject).
    echo $stdObject->name . " " . $stdObject->surname . " have " . $stdObject->age . " yrs old. And live in " . $stdObject->adresse;
};

$obj->getInfo();
?>

运行的结果是:
Nick Doe have 20 yrs old. And live in
首先,我想说的是,公子哥的基础不太扎实。$this->method = function() {}当然可以这样定义成员函数。此外,调用一个不存在的属性,不一定要显示的指定_set方法。
---------------------------------------------------------------------------------------------------------------知道我为啥会这样做吗?因为php官方手册就是这样写的:
[#1] Ashley Dambra [2014-02-21 06:50:10]
Here a simple class 'stdObject' that give us the possibility to create dynamic classes and the possibility to add and execute methods thing that 'stdClass' don't let us do. Very useful if you extends it to a controller on MVC Design pattern. Let users create own classes.
I have also post this class on http://www.php.net/manual/en/language.types.object.php

 $argument) {
                $this->{$property} = $argument;
            }
        }
    }

    public function __call($method, $arguments) {
        $arguments = array_merge(array("stdObject" => $this), $arguments); // Note: method argument 0 will always referred to the main class ($this).
        if (isset($this->{$method}) && is_callable($this->{$method})) {
            return call_user_func_array($this->{$method}, $arguments);
        } else {
            throw new Exception("Fatal error: Call to undefined method stdObject::{$method}()");
        }
    }
}

// Usage.

$obj = new stdObject();
$obj->name = "Nick";
$obj->surname = "Doe";
$obj->age = 20;
$obj->adresse = null;

$obj->getInfo = function($stdObject) { // $stdObject referred to this object (stdObject).
    echo $stdObject->name . " " . $stdObject->surname . " have " . $stdObject->age . " yrs old. And live in " . $stdObject->adresse;
};

$func = "setAge";
$obj->{$func} = function($stdObject, $age) { // $age is the first parameter passed when calling this method.
    $stdObject->age = $age;
};

$obj->setAge(24); // Parameter value 24 is passing to the $age argument in method 'setAge()'.

// Create dynamic method. Here i'm generating getter and setter dynimically
// Beware: Method name are case sensitive.
foreach ($obj as $func_name => $value) {
    if (!$value instanceOf Closure) {

        $obj->{"set" . ucfirst($func_name)} = function($stdObject, $value) use ($func_name) {  // Note: you can also use keyword 'use' to bind parent variables.
            $stdObject->{$func_name} = $value;
        };

        $obj->{"get" . ucfirst($func_name)} = function($stdObject) use ($func_name) {  // Note: you can also use keyword 'use' to bind parent variables.
            return $stdObject->{$func_name};
        };

    }
}

$obj->setName("John");
$obj->setAdresse("Boston");

$obj->getInfo();
?> 

推荐阅读
  • 在springmvc框架中,前台ajax调用方法,对图片批量下载,如何弹出提示保存位置选框?Controller方法 ... [详细]
  • MVC设计模式的介绍和演化过程
    本文介绍了MVC设计模式的基本概念和原理,以及在实际项目中的演化过程。通过分离视图、模型和控制器,实现了代码的解耦和重用,提高了项目的可维护性和可扩展性。详细讲解了分离视图、分离模型和分离控制器的具体步骤和规则,以及它们在项目中的应用。同时,还介绍了基础模型的封装和控制器的命名规则。该文章适合对MVC设计模式感兴趣的读者阅读和学习。 ... [详细]
  • MySQL中的MVVC多版本并发控制机制的应用及实现
    本文介绍了MySQL中MVCC的应用及实现机制。MVCC是一种提高并发性能的技术,通过对事务内读取的内存进行处理,避免写操作堵塞读操作的并发问题。与其他数据库系统的MVCC实现机制不尽相同,MySQL的MVCC是在undolog中实现的。通过undolog可以找回数据的历史版本,提供给用户读取或在回滚时覆盖数据页上的数据。MySQL的大多数事务型存储引擎都实现了MVCC,但各自的实现机制有所不同。 ... [详细]
  • Todayatworksomeonetriedtoconvincemethat:今天在工作中有人试图说服我:{$obj->getTableInfo()}isfine ... [详细]
  • 数据库锁的分类和应用
    本文介绍了数据库锁的分类和应用,包括并发控制中的读-读、写-写、读-写/写-读操作的问题,以及不同的锁类型和粒度分类。同时还介绍了死锁的产生和避免方法,并详细解释了MVCC的原理以及如何解决幻读的问题。最后,给出了一些使用数据库锁的实际场景和建议。 ... [详细]
  • ps:写的第一个,不足之处,欢迎拍砖---只是想用自己的方法一步步去实现一些框架看似高大上的小功能(比如说模型中的toArraytoJsonsetAtt ... [详细]
  • 今天写一篇blog,已经多长时间没有更了,两个月了吧,没办法,现在银行开发,不能连外网,天天用虚拟机,真烦今天随手写点东西,主要是这两天对于springboot启动的分析,有所领悟 ... [详细]
  • MVC中的自定义控件
    怎么样创建自定义控 ... [详细]
  • 我将SpringMVC升级到Spring3.2.5.我的一些剩余调用即使存在,也会返回无法识别的字段异常.这是错误.Resolvingexceptionfrom ... [详细]
  • 关于extjs开发实战pdf的信息
    本文目录一览:1、extjs实用开发指南2、本 ... [详细]
  • MVC就是model模型control控制view视图把web开发的分工明确各施其职,互不干涉在MVC模式中,三个层各施其职,所以如果一旦哪一层的需求发生了变化,就只需要更改相 ... [详细]
  • SpringMVC接收请求参数的方式总结
    本文总结了在SpringMVC开发中处理控制器参数的各种方式,包括处理使用@RequestParam注解的参数、MultipartFile类型参数和Simple类型参数的RequestParamMethodArgumentResolver,处理@RequestBody注解的参数的RequestResponseBodyMethodProcessor,以及PathVariableMapMethodArgumentResol等子类。 ... [详细]
  • 本文介绍了一种处理AJAX操作授权过期的全局方式,以解决Asp.net MVC中Session过期异常的问题。同时还介绍了基于WebImage的图片上传工具类。详细内容请参考链接:https://www.cnblogs.com/starluck/p/8284949.html ... [详细]
  • Django + Ansible 主机管理(有源码)
    本文给大家介绍如何利用DjangoAnsible进行Web项目管理。Django介绍一个可以使Web开发工作愉快并且高效的Web开发框架,能够以最小的代价构建和维护高 ... [详细]
  • Whyusingstringsaskeysofarray,consoleisshowingthatarraywithoutthesedeclaredvaluesand ... [详细]
author-avatar
gfhhhgh_130
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有