阿江 2017-10-12 11:01:31 75次浏览 0条回复 0 0 0

说明

学习Yii Framework 2(易2框架)的过程是漫长的,也是充满乐趣的,以下是我学习Yii2框架时对官网英文资料(请参见原文网址)的翻译和代码实现,提供了较完整的代码,供你参考。不妥之处,请多多指正!

原文网址:

http://www.yiiframework.com/doc-2.0/guide-concept-properties.html

本文主题:属性(Properties)

在PHP中,类成员变量被称作属性(property),这些变量是类定义的一部分,用于代表类实例的状态(换言之,用于区分类的另一个实例)。在实际应用中,我们常常想要通过一些特殊方法去读取或修改属性值,例如:要把一个字符串赋给label属性时,你可能会去掉它的首尾空格,使用以下代码即可完成:

$object->label=trim($label);

上句代码的缺点是,在你需要设置label属性的地方,你都必须调用trim() 函数,假如,某一天label属性有了一个新需求,要把首字母都变成大写,你可能需要发动label相关的每一处代码。重复修改代码就象平时练习一样难以避免,而且还会产生一些bug。

为了解决这个问题,Yii引入了一个基类:yii\base\Object,它可以使用类方法getter和setter来定义属性,如果一个类需要这些方法,它可以继承yii\base\Object或它的子类即可:

提示:几乎所有的Yii框架核心类都继承自yii\base\Objects或它的子类,也就是说,在一个核心类中无论你是否看到了setter或getter方法,你都可以象一个属性一样使用它。

getter方法是一个名称由get开始的方法;setter方法是由set开始的方法。get或set之后是属性的名称,例如:一个名为getLabel()的getter方法和一个名setLabel()的setter方法定义了一个名为label的属性,定义代码如下:

namespace app\components;
use yii\base\Object;
class Foo extends Object{
	private $_label;
	public function getLabel(){
		return $this->_label;
	}
	public function setLabel($value){
		$this->_label=trim($value);
	}
}

需要清楚一点,getter和setter方法创建了label属性,实际上内部是指向了一个名为'_label'的私有属性。

使用getter和setter定义的属性可以如同一个成员变量一样使用,不同之处在于,当此属性被读取时,实际调用的是getter方法,当属性被赋值时,实际调用的是setter方法,例如:

$label=$object->label;
//等同于调用:
$label=$object->getLabel();

$object->label='abc';
//等同于调用:
$object->setLabel('abc');

当一个属性仅定义了getter而没有定义setter时是只读属性(read only),试图向它赋值会产生InvalidCallException 的异常;类似的一个属性只定义了setter而没有定义getter是只写属性(write-only),尝试云读取此属性也会产生异常,当然,只写属性并不常用。

属性使用getter和setter定义时会有一些特殊的规则和限制:
1、属性是不区分大小写的,例如:$object->label和$object->Label是相同的,这是因为在PHP中方法名是不区分大小写的。
2、如果属性名与类成员变量重名,则仅类成员变量有效,例如,如果Foo类中有一个成员变量名为label,$object->label='abc'赋值,将会影响成员变量label,而并不会调用setLabel()方法。
3、这些属性不支持可见性,也就是说getter或setter方法设置的属性没有public、protected或private的区别。
4、属性只能被非静态(non-static)的getter和setter方法定义,静态方法将不会按此方式处理。
5、调用property_exists()方法无法判断此种属性的存在与否,因为此种属性是通过魔术方法创建的,可以使用canGetProperty()或canSetProperty()方法来实现判断,hasProperty()。

回到前述的问题,不用到处修改label值去添加trim()方法,只需要在setLabel()添加一处trim()即可,当一个新需要要将label的首字母大小时,setLabel()方法可以被很快的修改而无需修改其他的代码,此处的变化将影响到所有使用label的地方。

实例1:getter、setter应用实例:

D:\phpwork\advanced\frontend\controllers\PostController.php

public function actionLabel(){
        $object=new \frontend\models\Label();
        $object->label=' abc11 ';
//		$object->Label=' abc11 ';//与上句等效,不区分大小写
        echo "<br>label:".$object->label;
//		echo "<br>label:".$object->Label;//与上句等效,不区分大小写

		$object->setlabel(' abc23 ');
//      $object->setLabel(' abc23 ');//与上句等效,不区分大小写
   		echo "<br>label:".$object->getlabel();
//		echo "<br>label:".$object->getLabel();//与上句等效,不区分大小写
    }

测试结果:

/*
label:abc11
label:abc23
*/

D:\phpwork\advanced\frontend\models\Label.php

<?php
namespace frontend\models;
use Yii;
use yii\base\Object;
class Label extends Object{
    private $_label;
    public function getLabel(){
        return $this->_label;
    }
    public function setLabel($value){
        $this->_label=trim($value);
    }
}

实例2:属性是否存在的判断方法canGetProperty()

D:\phpwork\advanced\frontend\controllers\PostController.php

    public function actionLabel(){
        $object=new \frontend\models\Label();
        $have=property_exists($object,'name');
        echo "<br>have name(var):".var_export($have,true);
        $have=property_exists($object,'label');
        echo "<br>have label(var):".var_export($have,true);
        $have=$object->canGetProperty('name');
        echo "<br>have name(var):".var_export($have,true);
        $have=$object->canGetProperty('name',false);
        echo "<br>have name(property):".var_export($have,true);
        $have=$object->canGetProperty('label');
        echo "<br>have label(property):".var_export($have,true);
    }

测试结果:

/*
have name(var):true
have label(var):false
have name(var):true
have name(property):false
have label(property):true
*/

D:\phpwork\advanced\frontend\models\Label.php

<?php
namespace frontend\models;
use Yii;
use yii\base\Object;
class Label extends Object{
    public $name;
    private $_label;
    public function getLabel(){
        return $this->_label;
    }
    public function setLabel($value){
        $this->_label=trim($value);
    }
}

(全文完)

    没有找到数据。
您需要登录后才可以回复。登录 | 立即注册