---
# System prepended metadata

title: PHP 魔術方法 __get 與 __set 測試
tags: [PHP]

---

# PHP 魔術方法 __get 與 __set 測試

---
###### tags: `PHP`


在寫Slim時發現
當POST FORM 出去時如果錯誤需要返回原畫面時
沒有Lravel方便用的old方法


--------
-------

## __set __get


[\[PHP\]__set 與 __get](https://blog.johnsonlu.org/php__set-%E8%88%87-__get/)

[PHP 的 __get、__set 魔術方法](https://xyz.cinc.biz/2013/05/php-getset.html)

說明：
public void __set ( string $name , mixed $value )
public mixed __get ( string $name )
__get 執行時機：嘗試取得不存在的屬性或無權訪問的屬性。
__set 執行時機：嘗試設定不存在的屬性或無權訪問的屬性。


### 範例code

```php
class aa{
    private $pri = "private test";
    public $pub = "public test";
     
    public function __get($name){
        echo "執行 __get()=> name: $name";
    }
     
    public function __set($name,$value){
        echo "執行 __set()=> name: $name , value: $value";
    }
}
 
$obj = new aa();
//private 屬性
$obj->pri; //執行 __get()=> name: pri
$obj->pri = "xyz";//執行 __set()=> name: pri , value: xyz
 
//public 屬性
$obj->pub; //不會執行 __get()
$obj->pub = "xyz"; //不會執行 __get()
 
//不存在的屬性
$obj->no; //執行 __get()=> name: no
$obj->no = "xyz"; //執行 __set()=> name: no , value: xyz

```

### 實例應用
若原本有一 class ，有一 public 的屬性，整個系統程式到處直接存取、設定這個屬性。如下。

```php
class aa{
    public $month = 1;
}
$obj = new aa();
echo $obj->month; //1
$obj->month = 13;
echo $obj->month; //13

```

若今天想把 echo $obj->month 的輸出，後面多加一個字 "月" (例：1月)，
且 $obj->month = 13 這種大於12的設定改成 $obj->month = 12。
如果不想修改全部有使用到的地方，
可利用魔術方法 __get、__set 如下修改。

```php=

class aa{
    private $month = 1; // public 改為 private
     
    public function __get($name){
        switch($name){
            case "month";
                return $this->month . "月";
            break;
            default:
                return null;
        }
    }
     
    public function __set($name,$value){
        switch($name){
            case "month";
                if($value < 1){
                    $this->month = 1;
                }else if($value > 12){
                    $this->month = 12;
                }else{
                    $this->month = $value;
                }
            break;
        }
    }
}
$obj = new aa();
echo $obj->month; //1月
$obj->month = 13;
echo $obj->month; //12月

```


### 測試Code

個人在測試時很不錯用
不過還沒實際塞到框架中

```php=
class OldClass
{
    private $old = array();
    public  $check = array();

    public function __get($name)
    {
        return $this->old[$name];
    }

    public function __set($name, $value)
    {
      $this->old[$name] = $value;
      $this->check[$name] = $value;
    }
    
    public function getCheck()
    {
      return $this->check;
    }
}

$old = new OldClass();

$old->name = 'kora';
$old->age = 15;
$old->sex = '女';
$old->name = 'tony';

var_dump($old->name);
var_dump($old->age);
var_dump($old->sex);

echo '--------';
$rs = $old->getcheck();
var_dump($rs);

```

結果

```
string(4) "tony" int(15) string(3) "女"
--------
array(3) { 
    ["name"]=> string(4) "tony" 
    ["age"]=> int(15) 
    ["sex"]=> string(3) "女" 
    }
```



------
------


