魔术方法

魔术方法:系统在特定时机自动调用的方法

常用魔术方法:

1. __get 

        触发时机:对象在外部访问私有成员或者受保护属性时调用

        参数:参数就是属性名

2.__set

        触发时机:对象在外部设置私有成员或者受保护属性值时调用

        参数:属性名和属性值

3.__unset

        触发时机:对象在外部销毁私有成员或者受保护属性时调用

        参数:属性名

4.__isset    

        触发时机:对象在外部判断私有成员或者受保护属性时调用

        参数:属性名

5.__construct

        触发时机:在创建对象时调用

6.__destruct

        触发时机:在销毁对象时调用

7.__toString

        触发时机:echo 一个对象时触发

8.__debugInfo

        触发时机:var_dump一个对象时触发,需返回一个数组

9.__call

        触发时机:调用一个不存在的对象方法时触发

        参数:函数名和参数数组

10.__callStatic

        触发时机:调用一个不存在的静态方法时触发

        参数:函数名和参数数组

11.__sleep

        触发时机:在序列化一个对象时使用

        返回值:数组,数组写想要序列的成员和属性

12.__wakeup

        触发时机:在反序列化一个对象时使用

        反序列化成功以后,想执行一些初始化方法,可以写到这个函数中

13.__clone

        触发时机:在克隆一个对象时使用

        在这里面可以对克隆出来的对象的属性做一些操作

14.__autoload(唯一写在类外的魔术方法)

        触发时机:new一个对象时,当前脚本没有这个类,就会触发这个方法

        参数:该类名的字符串

<?php
	class Person{
		public $name = '小梅';
		protected $sex = '女';
		private $age = 18;
		
		public function __get($pro){
			/*if($pro=='sex'){
				return $this->sex;
			}else if($pro=='age'){
				return $this->age;
			}*/
			return $this->$pro;
		}
		
		public function __set($pro,$val){
			/*if($pro=='sex'){
				$this->sex = $val;
			}else if($pro=='age'){
				$this->age = $val;
			}*/
			$this->$pro = $val;
		}
		
		public function __unset($pro){
			unset($this->$pro);
		}
		
		public function __isset($pro){
			return isset($this->$pro);
		}
		
		public function __toString(){
			return '个人信息,name:'.$this->name;
		}
		
		public function __debugInfo(){
			return ['age','name'];
		}
		
		public function __call($name,$params){
			var_dump($name,$params);
		}
		
		public function __sleep(){
			return ['name','age'];
		}
		
		public function __wakeup(){
			$this->name = 'pan';
		}
		
		public function __clone(){
			echo '<br/>克隆对象中<br/>';
		}
	}
	
	function __autoload($className){
		echo $className.'该类不存在-----';
	}

	$mei = new Person();
	echo $mei->name;
	$mei->age = 20;
	echo $mei->age;
	echo '<br/>';
	echo $mei;
	$mei->demo(2,3,'ui');
	$str = serialize($mei);
	echo $str;
	$obj = unserialize($str);
	echo $obj;
	$mei2 = clone $mei;
	
	$dog = new Dog();
?>


### PHP `__call` 魔术方法的使用说明与示例 #### 定义与功能 在 PHP 中,`__call` 是一种魔术方法,用于捕获并响应对未定义或不可访问的非静态方法的调用。当尝试调用一个类中不存在的方法时,PHP 不会抛出错误而是自动调用 `__call` 方法[^1]。 这种方法的主要用途在于: - 提供默认行为来处理未知方法调用。 - 动态生成方法逻辑,增强代码灵活性。 - 减少因拼写错误或其他原因导致的运行时异常。 #### 参数解释 `__call` 接受两个参数: 1. **$name**: 表示试图调用的未定义方法的名字。 2. **$arguments**: 一个数组,包含了传递给该未定义方法的所有参数。 #### 示例代码 以下是一个典型的 `__call` 使用案例: ```php <?php class ExampleClass { public function __call($name, $arguments) { if (strpos($name, 'get') === 0 && count($arguments) === 1) { return "获取字段 {$arguments[0]} 的值"; } elseif (strpos($name, 'set') === 0 && count($arguments) === 2) { return "设置字段 {$arguments[0]} 的值为 {$arguments[1]}"; } else { return "无法识别的方法:{$name}"; } } } $obj = new ExampleClass(); // 调用未定义的 get 方法 echo $obj->getField('username'); // 输出: 获取字段 username 的值 // 调用未定义的 set 方法 echo "\n" . $obj->setField('password', 'secure123'); // 输出: 设置字段 password 的值为 secure123 // 调用完全不匹配的任意方法 echo "\n" . $obj->randomFunction(); // 输出: 无法识别的方法:randomFunction ?> ``` 在此示例中,通过检测 `$name` 开头是否为 `"get"` 或 `"set"` 并结合传入的参数数量,动态模拟了 getter 和 setter 方法的行为。 #### 应用场景分析 1. **API 设计中的通用处理器** 在构建 RESTful API 或者命令行工具时,可以利用 `__call` 创建灵活的路由机制,使得开发者可以根据请求路径映射到不同的业务逻辑而不需要提前定义所有的方法。 2. **代理模式下的方法转发** 如果有一个对象需要将部分操作委托给另一个对象完成,则可以在中间层实现 `__call` 来拦截所有外部调用并将它们重定向至目标对象。 3. **日志记录与调试辅助** 利用 `__call` 记录每次失败的调用及其上下文信息有助于定位潜在问题所在位置。 --- ### 总结 通过对 `__call` 魔术方法的学习可以看出,它是提高程序扩展性和鲁棒性的有力工具之一。合理运用它可以极大地简化复杂系统的维护成本同时增加其适应能力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值