【很变态】PHP类实例化对象竟然可以访问类的“静态(static)方法”!!!

之前发现一个PHP的变态问题:PHP中静态(static)调用非静态方法详解

这次看了下 ThinkPHP 的源码 function.inc.php ,里面有个函数:

/**
 * 取得对象实例 支持调用类的静态方法
 *
 * @param string $name 类名
 * @param string $method 方法
 * @param string $args 参数
 * @return object 对象实例
 */
function get_instance_of($name, $method = ‘‘, $args = array()) {
	static $_instance = array();
	$identify = empty($args) ? $name . $method : $name . $method . to_guid_string($args);
	if (!isset($_instance[$identify])) {
		if (class_exists($name)) {
			$o = new $name();
			if (method_exists($o, $method)) {
				if (!empty($args)) {
					$_instance[$identify] = call_user_func_array(array(&$o, $method), $args);
				} else {
					$_instance[$identify] = $o->$method();
				}
			} else {
				$_instance[$identify] = $o;
			}
		} else {
			halt(L(‘_CLASS_NOT_EXIST_‘) . ‘:‘ . $name);
		}
	}

	return $_instance[$identify];
}

该函数注释说可以 支持调用类的静态方法,从源码表面看,按理说类实例是不能调用类的静态方法。可是呢,PHP偏偏就支持 类实例化对象可以访问静态(static)方法,但是不能访问静态属性。

<?php
ini_set(‘display_error‘, true);
error_reporting(E_ALL);

class Dog {

	public static $name = ‘wangwang‘;

	static function say($data) {
		echo $data;
	}
}
$myDog = new Dog();

$myDog->say(‘123456‘); // 输出 123456

echo $myDog->name; // 发出Notice信息: Undefined property: Dog::$name in ...

?>

参考资料:http://php.net/manual/zh/language.oop5.static.php

时间: 2024-10-24 03:51:25

【很变态】PHP类实例化对象竟然可以访问类的“静态(static)方法”!!!的相关文章

JavaSE-子类实例化对象的过程

package com.btp.t1; //子类对象实例化的全过程 /*1.当最底层子类实例化对象时,它的父类,父类的父类...到Object类的所有类的构造器都会被调用,只不过当一个类拥有多个构造器时,调用的是其中一个. *2.子类构造器内,默认调用父类构造器:super();当有this关键字时,就不调用父类构造器了,就会调用同一个类内的其他构造器,所以一个类当有n个构造器时,仅允许最多有n-1个构造器内使用this关键字,最少有一个构造器去调用上层父类的构造器. *3.当父类重载一个构造器

如果使用实例化对象,来为类动态的添加一个 字符串形式的 方法。

import types class MyClass: @staticmethod def extends(self_name, method_name, method_str, ): ''' 使用实例化对象 动态的为 类添加一个 字符串形式的 方法. :param self_name: 调用该方法的对象 的名字 :param method_name: 要添加的方法的名字 :param method_str: 这个方法的 具体代码 ''' method_str = method_str + '\

PHP类的静态(static)方法和静态(static)变量使用介绍

PHP类的静态(static)方法和静态(static)变量使用介绍,学习php的朋友可以看下 在php中,访问类的方法/变量有两种方法: 1. 创建对象$object = new Class(),然后使用”->”调用:$object->attribute/function,前提是该变量/方法可访问. 2. 直接调用类方法/变量:class::attribute/function,无论是静态/非静态都可以.但是有前提条件: A. 如果是变量,需要该变量可访问. B. 如果是方法,除了该方法可访

[C#] 常用工具类——应用程序属性信息访问类

using System; using System.Collections.Generic; using System.Text; using System.Reflection; namespace Utils { /// <summary> /// <para> </para> /// 常用工具类——应用程序属性信息访问类 /// <para> -------------------------------------------</para&g

常用工具类——应用程序属性信息访问类

using System; using System.Collections.Generic; using System.Text; using System.Reflection; namespace Utils { /// <summary> /// <para> </para> /// 常用工具类——应用程序属性信息访问类 /// <para> -------------------------------------------</para&g

2016/3/21 面向对象: ①定义类 ②实例化对象 ③$this关键字 ④构造函数 ⑤析构函数 ⑥封装 ⑦继承

一:定义类   二:实例化对象 1 //定义类 2 class Ren 3 { 4 var $name; 5 var $sex; 6 var $age; 7 8 function Say() 9 { 10 echo "{$this->name}在说话"; 11 } 12 } 13 //实例化对象 14 $Ren = new Ren(); 15 //调用对象的成员: 16 $Ren->name = "张三"; 17 $Ren->Say(); 显示结果

Scala中包、类、对象、成员访问权限理解

本文通过下面一个程序简单分析下包.类.对象访问权限的情况: package spark {   package navigation {     private[spark] class Navigator {       protected[navigation] def useStartChar() = println("navigation")       class LegOfJourney {         private[Navigator] val distance =

C++类与对象(2)——类的组合

当我们创建一个类时,我们总是习惯用C++的基本数据类型作为类的组成部件.但实际上类的成员数据既可以是基本类型也可以是自定义类型,当然也可以是类的对象.这就是类的组合,它描述的就是一个类内嵌其他类的对象作为成员的情况,它们之间的关系是一种包含于被包含的关系. 当创建类的对象时,如果这个类具有内嵌对象成员,那么各个内嵌对象将首先被自动创建, 组合构造函数定义的一般形式: 类名::类名(形参表):内嵌对象1(形参表),内前对象2(形参表)...... {类的初始化} 其中"内嵌对象1(形参表),内前对

第二章、创建和销毁对象。ITEM1:考虑用静态工厂方法代替构造器

除了使用构造器来获取类的一个实例,还可以使用静态工厂方法(static factory method). 下面的方法是将boolean基本类型转成一个Boolean对象引用: 1 public final class Boolean implements java.io.Serializable, 2 Comparable<Boolean> 3 { 4 //与基本类型boolean=true匹配 5 public static final Boolean TRUE = new Boolean(