属性:

public function __get($name)              // 这里$name是属性名
{
$getter = 'get' . $name; // getter函数的函数名
if (method_exists($this, $getter)) {
return $this->$getter(); // 调用了getter函数
} elseif (method_exists($this, 'set' . $name)) {
throw new InvalidCallException('Getting write-only property: '
. get_class($this) . '::' . $name);
} else {
throw new UnknownPropertyException('Getting unknown property: '
. get_class($this) . '::' . $name);
}
} // $name是属性名,$value是拟写入的属性值
public function __set($name, $value)
{
$setter = 'set' . $name; // setter函数的函数名
if (method_exists($this, $setter)) {
$this->$setter($value); // 调用setter函数
} elseif (method_exists($this, 'get' . $name)) {
throw new InvalidCallException('Setting read-only property: ' .
get_class($this) . '::' . $name);
} else {
throw new UnknownPropertyException('Setting unknown property: '
. get_class($this) . '::' . $name);
}
}

someObject->foo实际是调用someObject->getFoo()

someObject->foo = $some_value 实际是 someObject->setFoo($some_value)

如下的Post类,实现了可读可写的属性title:

class Post extends yii\base\Object    // 第一步:继承自 yii\base\Object
{
private $_title; // 第二步:声明一个私有成员变量 public function getTitle() // 第三步:提供getter和setter
{
return $this->_title;
} public function setTitle($value)
{
$this->_title = trim($value);
}
}

这样好处多多

Component继承于yii\base\object, 具有以下三个重要特征

  属性

  事件

  行为

事件:

yii\base\Component::on() 就是用来绑定的

$person = new Person;

// 使用PHP全局函数作为handler来进行绑定
$person->on(Person::EVENT_GREET, 'person_say_hello'); // 使用对象$obj的成员函数say_hello来进行绑定
$person->on(Person::EVENT_GREET, [$obj, 'say_hello']); // 使用类Greet的静态成员函数say_hello进行绑定
$person->on(Person::EVENT_GREET, ['app\helper\Greet', 'say_hello']); // 使用匿名函数
$person->on(Person::EVENT_GREET, function ($event) {
echo 'Hello';
});

行为:

行为是把一个类绑定到另一个类, 让第二个类有第一个类的属性和方法. 即:不改变现有类的情况下, 对类的功能进行扩充

使用行为的大致流程

  • 从 yii\base\Component 派生自己的类,以便使用行为;
  • 从 yii\base\Behavior 派生自己的行为类,里面定义行为涉及到的属性、方法;
  • 将Component和Behavior绑定起来;
  • 像使用Component自身的属性和方法一样,尽情使用行为中定义的属性和方法。

YII模式

MVC模式

Model主要是数据, 业务逻辑, 业务规则. 这部分应该比较稳定, 产品成型后不经常改变.

   包括数据, 行为, 方法.

   提供有结构的数据, 原始的数据, 如数组, 队列.

   要和Controller区分开, 好的设计是胖Model, 瘦Controller. Controller只是协调Model和View, 业务相关的放在Model里

View是展示页面, 主要是HTML部分代码, 简单的循环输出, 不会直接调用Model数据.

Controller是负责Model和View之间的桥梁, 负责决定使用哪些Model, 对应哪些View.

   处理用户的请求, 只限于处理用户的请求, 不应该对数据有任何操作和预处理, 这些工作应由Model完成.

    调用Model的读方法, 获取数据, 直接传递给视图, 供显示. 涉及到多个Model时, 有关的逻辑应交给Model来完成.

   调用Model类方法, 进行写操作.

   调用视图渲染函数, 形成对用户Request的Response.

依赖注入

在Web应用中,很常见的是使用各种第三方Web Service实现特定的功能,比如发送邮件、推送微博等。 假设要实现当访客在博客上发表评论后,向博文的作者发送Email的功能,通常代码会是这样:

// 为邮件服务定义抽象层
interface EmailSenderInterface
{
public function send(...);
} // 定义Gmail邮件服务
class GmailSender implements EmailSenderInterface
{
... // 实现发送邮件的类方法
public function send(...)
{
...
}
} // 定义评论类
class Comment extend yii\db\ActiveRecord
{
// 用于引用发送邮件的库
private $_eMailSender; // 初始化时,实例化 $_eMailSender
public function init()
{
...
// 这里假设使用Gmail的邮件服务
$this->_eMailSender = GmailSender::getInstance();
...
} // 当有新的评价,即 save() 方法被调用之后中,会触发以下方法
public function afterInsert()
{
...
//
$this->_eMailSender->send(...);
...
}
}

构造函数注入

构造函数注入通过构造函数的形参,为类内部的抽象单元提供实例化。 具体的构造函数调用代码,由外部代码决定。具体例子如下:

// 这是构造函数注入的例子
class Comment extend yii\db\ActiveRecord
{
// 用于引用发送邮件的库
private $_eMailSender; // 构造函数注入
public function __construct($emailSender)
{
...
$this->_eMailSender = $emailSender;
...
} // 当有新的评价,即 save() 方法被调用之后中,会触发以下方法
public function afterInsert()
{
...
//
$this->_eMailSender->send(...);
...
}
} // 实例化两种不同的邮件服务,当然,他们都实现了EmailSenderInterface
sender1 = new GmailSender();
sender2 = new MyEmailSender(); // 用构造函数将GmailSender注入
$comment1 = new Comment(sender1);
// 使用Gmail发送邮件
$comment1.save(); // 用构造函数将MyEmailSender注入
$comment2 = new Comment(sender2);
// 使用MyEmailSender发送邮件
$comment2.save();

属性注入

与构造函数注入类似,属性注入通过setter或public成员变量,将所依赖的单元注入到类内部。 具体的属性写入,由外部代码决定。具体例子如下:

// 这是属性注入的例子
class Comment extend yii\db\ActiveRecord
{
// 用于引用发送邮件的库
private $_eMailSender; // 定义了一个 setter()
public function setEmailSender($value)
{
$this->_eMailSender = $value;
} // 当有新的评价,即 save() 方法被调用之后中,会触发以下方法
public function afterInsert()
{
...
//
$this->_eMailSender->send(...);
...
}
} // 实例化两种不同的邮件服务,当然,他们都实现了EmailSenderInterface
sender1 = new GmailSender();
sender2 = new MyEmailSender(); $comment1 = new Comment;
// 使用属性注入
$comment1->eMailSender = sender1;
// 使用Gmail发送邮件
$comment1.save(); $comment2 = new Comment;
// 使用属性注入
$comment2->eMailSender = sender2;
// 使用MyEmailSender发送邮件
$comment2.save();

参考自http://www.digpage.com/index.html, 如需学习YII2, 请转自前面链接, <深入理解Yii2.0>, 来获取更多内容.

yii2 学习中的更多相关文章

  1. YII2学习第一天

    YII2学习第一天,之前稍微看了看TP,感觉和自己的理念不是很符合,然后转学YII2了. 使用的文档是https://github.com/yiisoft/yii2/tree/master/docs/ ...

  2. 记录Python学习中的几个小问题

    记录Python学习中的几个小问题,和C#\JAVA的习惯都不太一样. 1.Django模板中比较两个值是否相等 错误的做法 <option value="{{group.id}}&q ...

  3. 深度学习中的Data Augmentation方法(转)基于keras

    在深度学习中,当数据量不够大时候,常常采用下面4中方法: 1. 人工增加训练集的大小. 通过平移, 翻转, 加噪声等方法从已有数据中创造出一批"新"的数据.也就是Data Augm ...

  4. Java 打印金字塔 or 打印带数字的金字塔 (Java 学习中的小记录)

    Java 打印金字塔 or 打印带数字的金字塔 (Java 学习中的小记录) 作者:王可利(Star·星星) 效果图: 代码如下: class Star8 { public static void m ...

  5. Java 需要记得、了解的关键词 (Java 学习中的小记录)

    Java 需要记得.了解的关键词 (Java 学习中的小记录)     作者:王可利(Star·星星) 总结:本次随笔,仅且拿来平时翻阅记忆用

  6. Java学习中,常用的命令管理(Java 学习中的小记录)

    Java学习中,常用的命令管理      作者:王可利(Star·星星) 一.Window中常见的dos命令 在哪里操作dos命令: Win7 ---> 开始  ---->所有程序---& ...

  7. Java基础学习中一些词语和语句的使用

    在Java基础学习中,我们刚接触Java会遇到一些词和语句的使用不清的情况,不能很清楚的理解它的运行效果会是怎么样的,如:break,continue在程序中运行效果及跳转位置, 1.先来看看brea ...

  8. 有关JAVA基础学习中的集合讨论

        很高兴能在这里认识大家,我也是刚刚接触后端开发的学习者,相信很多朋友在学习中都会遇到很多头疼的问题,希望我们都能够把问题分享出来,把自己的学习思路整理出来,我们一起探讨一起成长.    今天我 ...

  9. ubuntu下30天自制操作系统还在继续学习中

    操作系统还在学习中,进度不是非常确定,近期学习到了第13天的中部,由于把ucgui移植上去花了一点时间. 同一时候为了方便代码的兴许管理和分享,也为了学习github的代码管理使用思想, 所以建立了一 ...

随机推荐

  1. Android设置背景图像重复【整理自网络】

    1:在res/drawable文件下新建一个xml文件tool_bar_bg_repeat.xml比如为: <?xml version="1.0" encoding=&quo ...

  2. CLR via C# I/O基元线程同步构造

    1. 分为用户模式构造和内核模式构造 2. 用户模式构造 a.易失构造 在一个简单数据类型的变量上执行原子性读或写操作 VolaileWrite 强制address中的值在调用时写入,除此之外,按照源 ...

  3. ADO.NET的五个主要对象

    优秀文章链接:http://www.cnblogs.com/xianspace/archive/2009/02/21/1395307.html http://www.cnblogs.com/aito/ ...

  4. Python脚本控制的WebDriver 常用操作 <十四> 处理button dropdown 的定位

    测试用例场景 模拟选择下拉菜单中数据的操作 Python脚本 测试用HTML代码: <html> <body> <form> <select name=&qu ...

  5. Microsoft server software support for Microsoft Azure virtual machines

    http://support.microsoft.com/kb/2721672/en-us  Article ID: 2721672 - Last Review: November 22, 2014 ...

  6. SQL随机数的生成

    下面是一个随机函数问题,获取两位数的随机数,且不重复. 但是说明一下,这个函数有点bug,例如:两位数的函数最后能生成89个,如果将数量改成90,那么就无法生成,陷入死循环了. IF object_i ...

  7. SQLserver通过链接服务器连接oracle

    在SQLserver中一直使用的是DTS抽取数据,但是DTS微软只支持到2008,到了2012后就没有这个工具了,现在需要在SQLserver跟Oracle中间建立一个通道,借助这个通道,将Oracl ...

  8. XenServer安装虚拟机---先扩容存放ISO镜像文件

    我们都知道xenserver安装后,不管你的盘有多大,只有4G的空间. 故操作是:新建LV卷,可自定义大小 1.vgdisplay #先查看剩余空间 [root@XenServer /]# vgdis ...

  9. 7zip 命令行

    转自 http://www.cnblogs.com/langlang/archive/2010/12/01/1893866.html 7z.exe 是 7-Zip 的命令行版本.7z.exe 使用 7 ...

  10. 初尝backbone

    backbone的基础知识在此将不再进行介绍.自己后续应该会整理出来,不过今天先把这几天学的成果用一个demo进行展示. 后续可运行demo将会在sinaapp上分享,不过近期在整理sinaapp上d ...