php 作为快速迭代项目的语言,其牛逼性质自不必多说。今天咱们要来说说php语言几个魔术方法,当然了,本文主要以setter&getter方法说明为主。

  首先,咱们得知道什么叫魔术方法? 官方定义为:__construct(), __destruct(), __call(), __callStatic(), __get(), __set(), __isset(), __unset(), __sleep(), __wakeup(), __toString(), __invoke(), __set_state(), __clone() 和 __debugInfo() 等方法在 PHP 中被称为"魔术方法"(Magic methods)。在命名自己的类方法时不能使用这些方法名,除非是想使用其魔术功能。

  妈蛋,看了这么长一句,还是不明白什么叫魔术方法?

  换句简单的话就是(片面的),普通方法做不了的事,这个方法能做到,这就是魔术方法! 总之就是,你平时一般不会用到的方法。

  好,现在咱们来说说,哪几个方法是咱们用得最多的呢?当然是 __construct, __destruct 了,创建一个类时,会使用到构造方法(__construct),你可以初始化你的基本数据在里面。销毁一个类时,则会调用析构方法(__destruct),你可以回收一些东西。

  除了这前面两个方法之外,其他的方法就不一定是每个同学都会用得上的功能了。如果说一定要使用的话,那可能还会用到 __call 方法,因为有时候你可能就是要让外面访问你某些变异了的方法,以迷惑对手。

  那么,回到本文话题,php的setter&getter方法,其实就是 __set & __get 方法,为什么说是setter&getter呢,因为在面向对象语言中,就是setXX($value),getXX(); 这两个魔术方法有什么用呢?

  首先,我们还是魔术方法的方针政策上,魔术方法是具有魔术的,是不能随便调用的,它只会在特定的情况下才会生效。

  那么__set 方法呢,就是在你在设置某个类属性变量的时候(如$obj->mm = "c";),如果没有找到这个变量或者该变量不可访问,那么__set就会生效被调用了。

  而 __get 方法,就是在你获取类的某个类属性变量的时候(如$a = $obj->mm),如果访问不到这个属性,那么 __get就会生效被调用了。 举例:

<?php
error_reporting(E_ALL^E_NOTICE);
class SampleMagicTest {
public $a;
private $privVar = "privateVar";
protected $protectedVar = "protectedVar";
public function __construct($a) {
$this->a = $a;
var_dump("in __construct method....", $a);
}
public function __set($name, $value) {
echo "in __set method...\n";
$this->$name = $value; //设置$name属性为该类属性变量,我猜测修饰符应该是 private, 也就是说 外部仍然是访问不到该变量的,但是结果却让我失望了,居然被设置成public,也就是说,你可直接访问到该变量了
//当然了,你还可以做其他没用的事
}
public function __get($name) {
echo "in __get method...\n";
return $this->$name; //返回类属性变量 $name, 该$name通常是私有的变量
//当然了,你还可以做其他没用的事
}
public function __call($name, $arguments) {
var_dump("you called a none defined method,methodName is:", $name, " args is:", $arguments);
}
public function __destruct() {
echo "in __construct method...\n";
return "SampleMagicTest.class.toString\n";
}
public function __toString() {
echo "in __toString method...\n";
}
}
$sample = new SampleMagicTest("1");
$sample->yourName = "jue"; //属性不存在, __set 魔术将生效
echo "yourName:" . $sample->yourName . PHP_EOL; //由于前面的 __set已经将变量放入,此处可以直接调用,没毛病
var_dump($sample->aNoneExistVar); //直接调用一个不存在的变量
$sample->sayHi("hello"); //调用一个不存在的方法,则会触发 __call方法,也就是说,当有了 __call方法之后,php就再也不会报方法未定义之类的错误了,这坑可是不小哦
var_dump($sample);
unset($sample); // 可以主动调用销毁方法,当然了,实际开发中是不建议这么干的
echo "real over...";
?>

  输出结果如下:

$-#: php SampleMagicTest.php
string() "in __construct method...."
string() ""
in __set method...
yourName:jue
in __get method...
NULL
string() "you called a none defined method,methodName is:"
string() "sayHi"
string() " args is:"
array() {
[]=>
string() "hello"
}
in __toString method...
SampleMagicTest.class.toString
object(SampleMagicTest)# () {
["a"]=>
string() ""
["privVar":"SampleMagicTest":private]=>
string() "privateVar"
["protectedVar":protected]=>
string() "protectedVar"
["yourName"]=>
string() "jue"
}
in __construct method...
real over...

  如此,测试完毕。

  说实话,我一点都没感觉到 __set&__get 方法的方便之处在哪里,而__call方法反而作用会大些(有坑自己别往里跳就行),尤其作为反射功能的调用时。

  而我能想到的setter&getter的作用,则更多的是提示你在获取属性时,IDE能给你一个准确的提示,那将是美好的。

  我看过某人写过的代码,将某个配置设值功能作为调用 __set方法的场景(如: public funtion($name, $value) {$this->config[$name] = $value;},这种情况,恕在下不敢苟同。你直接写个易记的方法不就行了吗?

  魔术方法存在自然有其过人之处,但是,并不是每个场景都能使用,大部分情况可能只需要看看就好。

  如果一定要给这些魔术方法的功能重要性排个序的话,我想官方已经把他排出来了。

  你有什么场景在用这些牛逼的魔术方法呢?不访说出来,吓我一跳。。。

周末,说声php的setter&getter(魔术)方法,你们辛苦了的更多相关文章

  1. 说声PHP的setter&getter(魔术)方法,你们辛苦了

    php作为快速迭代项目的语言,其牛逼性质自不必多说.今天咱们要来说说php语言几个魔术方法,当然了,主要以setter&getter方法为主. 首先,咱们得知道什么叫魔术方法? 官方定义为:_ ...

  2. jQuery 3.0 的 setter/getter 模式

    jQuery 的 setter/getter 共用一个函数,通过是否传参来表明它是何种意义.简单说传参它是 setter,不传它是 getter. 一个函数具有多种意义在编程语言中并不罕见,比如函数重 ...

  3. iPhone开发教程之retain/copy/assign/setter/getter

    assign: 简单赋值,不更改索引计数 copy: 建立一个索引计数为1的对象,然后释放旧对象retain:释放旧的对象,将旧对象的值赋予输入对象,再提高输入对象的索引计数为1 1. 接触过C,那么 ...

  4. Writable atomic property '***' cannot pair a synthesized setter/getter with a user defined

    1. warning: Semantic Issue: Writable atomic property 'number' cannot pair a synthesized setter/gette ...

  5. 学习es6 setter/getter研究

    1.背景 在ES6中,我们对类的定义如下 class Person { // 构造函数 constructor (name) { // 属性初始化 this.name = name; } // 成员方 ...

  6. 使用lombok时@Setter @Getter无效

    原文链接 : https://blog.csdn.net/marion158/article/details/87893480 lombok是一个帮助简化代码的工具,通过注解的形式例如@Setter ...

  7. Python的魔术方法详解

    构造和初始化 __init__我们很熟悉了,它在对象初始化的时候调用,我们一般将它理解为"构造函数". 实际上, 当我们调用x = SomeClass()的时候调用,__init_ ...

  8. Python魔术方法-Magic Method

    介绍 在Python中,所有以"__"双下划线包起来的方法,都统称为"Magic Method",例如类的初始化方法 __init__ ,Python中所有的魔 ...

  9. Python 魔术方法指南

    入门 构造和初始化 构造定制类 用于比较的魔术方法 用于数值处理的魔术方法 表现你的类 控制属性访问 创建定制序列 反射 可以调用的对象 会话管理器 创建描述器对象 持久化对象 总结 附录 介绍 此教 ...

随机推荐

  1. 请求不同域的数据方法:requests Jsonp cors

    在需要访问不同域的接口的数据的时候,一般有两种方式: 第一种: 使用requests模块,在业务逻辑中直接访问别的域的接口,获取数据,然后将返回的数据显示到前端页面上; 这个时候,数据访问的流程是: ...

  2. Excel、VBA与MySQL交互

    本文主要涉及: VBA中的MySQL环境配置 VBA连接MySQL数据库 VBA读写MySQL数据 在Excel中连接MySQL数据库及数据读写 系统环境: Windows 10 Excel 2013 ...

  3. Lozad.js 简单使用

    GayHub位置:https://github.com/ApoorvSaxena/lozad.js 导入: <script type="text/javascript" sr ...

  4. [leetcode]34.Find First and Last Position of Element in Sorted Array找区间

    Given an array of integers nums sorted in ascending order, find the starting and ending position of ...

  5. UI动画优化技巧

    知乎上一篇比较好的文章,分享一下: tabs slide 内容过渡动画 好的动画会淡化页面直接的过度. 但更好的做法是使用连续的动画来来过度内容 当我们在设计交互式选项卡或弹出式菜单的时候,尝试将内容 ...

  6. Linux驱动之同步、互斥、阻塞的应用

    同步.互斥.阻塞的概念: 同步:在并发程序设计中,各进程对公共变量的访问必须加以制约,这种制约称为同步. 互斥机制:访问共享资源的代码区叫做临界区,这里的共享资源可能被多个线程需要,但这些共享资源又不 ...

  7. python 数据可视化(matplotlib)

    matpotlib 官网 :https://matplotlib.org/index.html matplotlib 可视化示例:https://matplotlib.org/gallery/inde ...

  8. delphi三层结构常出现的问题和解决方案

    以下问题出现原因有可能多个,暂时将我遇见的记录下来,以后有新的在陆续更新上去,有网友愿意的话也可以共同测试一下. 一,无法更新定位行.一些值可能已在最后一次读取已更改. 错误出现前提: 1, 录数据时 ...

  9. 目录命令(cd)

    cd 命令: // 描述: (Change Directory) 更改当前目录或显示当前目录的名称. 如果仅使用驱动器号(例如,cd C :),则cd将显示指定驱动器中当前目录的名称. 如果不带参数使 ...

  10. Java 8 Lambda 表达式及 Stream 在集合中的用法

    简介 虽然 Java 8 已经发布有一段时间了,但是关于 Java 8 中的 Lambda 表达式最近才开始系统的学习,刚开始就被 Stream 的各种骚操作深深的吸引住了,简直漂亮的不像 Java. ...