php中类能够调用实例方法不报错的原因

学习php目前是第二天,就是喜欢深入研究这些小细节的秘密。

分别用php 5.2.5和 php 5.4.3测试

<?php
class Person{
	function show(){
         var_dump($this); echo "hello,world"; } function __call($name, $args){ echo "call yes"; } function __callStatic($name, $args){ echo "callStatic yes"; } } Person::show(); ?>

 

1.这里类调用了实例方法,而且还正确的调用到了实例方法,因为没有进入__calll和__callstatic

2.无错误

 按照php的一些书籍资料的说明,应该是类能调用的方法只有类方法,而不是类的实例方法,也就是类只能调用静态方法(static method),但是这里类居然调用了实例方法,百思不得其解。找了一些相关资料,如下:

引用:

-----------------------------------------------------------------

在php文件的任何位置都可以使用 classname::methodname()来直接调用类里面公用的方法。个人觉得出现这个情况是因为
内存的堆区保存的对象仅保存的是对象的属性,对象的方法任然存放在代码区,为类的成员方法,如果使用对象来调用的类的成员方法里面不含$this的话,此时这个方法和静态数据区存放的静态方法并无明显区别。即此时对象的成员方法与该对象的静态方法并无明显区别
都并不随着调用对象的不同,而发生不同的变化。
并且成员方法本身就是在类中定义的,就是老爸和儿子的关系,区别就是一个是自己老婆生的(静态方法),另外一个是和别人老婆生的(成员方法),别人老婆生的那个儿子就管其他人叫老爸了。某一天那个私生的儿子了解情况了(无$this)。便会叫两人叫爸了。
此时便可以使用classname::methodname()

url:http://segmentfault.com/q/1010000000158671

-----------------------------------------------------------------

然后用5.4.3测试果断告警,如下:

还一个牵扯进来的问题是:

<?php
class Person{
	function show(){
		var_dump($this);
		echo "hello,world";
	}
	function __call($name, $args){
		echo "call yes";
	}
	function __callStatic($name, $args){
		echo "callStatic yes";
	}
}
class Child extends Person {
	function tell(){
		self::show();
	}
}
Person::show();
$c = new Child();
$c->tell();
?>

 输出:

Null

object(Child)#1 (0) { }

hello,world

说明:

1.第一次确实没有对象(符合引用的说明)

2.这次却是一个child的对象

 

解释:

其实php中有调用的作用域,这种是看似调用了静态方法的,比如说:上图的$c调用的时候,就是在这个对象的作用域,这个作用域在传递,所以上面的$this是child类的对象,这样做有个例子,如下:

Class A{
	function __construct(){}
}
class B extends A{
	function __construct(){
		parent::__construct();
	}
}

 建议不要用:类调用非静态方法。

 

再看下面的一个例子:

<?php
class Person{
	function __call($name, $args){
		echo "call yes";
	}
	static function __callStatic($name, $args){
		echo "callStatic yes";
	}
}
class Child extends Person {
	function tell(){
		self::show();
	}
}
Person::show();
$c = new Child();
$c->tell();

?>

 

输出:

callStatic yes
call yes

说明:

和我们的理解一样,当第一个person尝试的是调用一个 静态方法,没有调用到,即执行__callStatic();当$c这个作用域的对象把调用作用域传递到父类下之后,调用的是对象方法,所以执行的是__call();

一个大神也做了解释,可以看看,url:http://www.laruence.com/2012/06/14/2628.html

 

 

 

posted @ 2013-04-04 22:53  Anleb  阅读(2472)  评论(2编辑  收藏  举报