属性:

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. Summary of Amazon Marketplace Web Service

    Overview Here I want to summarize Amazon marketplace web service (MWS or AMWS) that can be used for ...

  2. [转] shell字符串操作方法,以及实例

    每一种语言都有他独自的字符串操作方法,shell也一样,下面以以例子的方式,简单介绍常用方法. 1,取得字符串长度 string=abc12342341 //等号二边不要有空格 echo ${#str ...

  3. 无法访问Fedora的samba共享

    配置好samba服务后,却发现windows无法访问.经过多次试验与fedora的防火墙有关系. 关闭防火墙: #service iptables stop 或清空规则: #iptables -F w ...

  4. 关于使用视图进行分页时出现当前记录集不支持书签的错误解决方法及原因(asp)

    一般在使用视图进行查询时,视图中意般都关联了两个或者更多个表,一般在这种情况下才会使用视图,但是但我在使用视图来查询数据时没有问题,但是一旦在分页中使用到视图进行查询就会出现错误提示如下: ADODB ...

  5. Redis 四:存储类型之列表类型

    .lpush num 依次从左边推入0 - .rpush num 依次从右边推入0 - .lrnage num - 显示num列表中所有的数据 结果: .lpop num 从左边删除并弹出一个元素 . ...

  6. hbase meta表修复

    meta表修复一 查看hbasemeta情况hbase hbck1.重新修复hbase meta表(根据hdfs上的regioninfo文件,生成meta表)hbase hbck -fixMeta2. ...

  7. VBS基础篇 - 循环

    经常地,当编写代码时,我们希望将一段代码执行若干次,我们可以在代码中使用循环语句来完成这项工作. 循环可分为三类:一类在条件变为 False 之前重复执行语句,一类在条件变为 True 之前重复执行语 ...

  8. select * from table where 1=1

    转自:http://www.dzwebs.net/2418.html 我们先来看看这个语句的结果:select * from table where 1=1,其中where 1=1,由于1=1永远是成 ...

  9. 不借助jquery封装好的ajax,你能用js手写ajax框架吗

    不借助jquery封装好的ajax,你能手写ajax框架吗?最基础的ajax框架,一起来围观吧. .创建XMLHttpRequest对象 var xhr = new XMLHttpRequest(); ...

  10. IntelliJ IDEA的Maven项目在修改时报java.lang.OutOfMemoryError: PermGen space异常

    什么也不说了---内存溢出,遇见太多回了,下面是解决方式: 1.在项目设置中新建Maven,然后设置VM: 2. 在pom.xml添加下面2个插件,一个是jrebel的,一个是jetty的 <b ...