阿江 2017-10-12 11:01:31 2262次浏览 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);
    }
}

(全文完)

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