PHP アクセス修飾子についてまとめてみた。(public, private, protected, static)

# はじめに
**・PHPのアクセス修飾子が
　よくわらない方に、おすすめ。**

## アクセス修飾子
**・メンバ変数やメソッドなどが、
　どこからアクセスできるかを定義**するもの。

## public
・スコープに基づき、
　**どこからもでもアクセス可能**

※アクセス修飾子を指定しない場合は
　自動的にpublicとして扱う。

######サンプルコード
```php:access-model.php
<?php

class TestClass {

    // プロパティの定義 (どこからでもアクセス可能)
    public $name;

    // コンストラクタの定義   
    public function __construct($name) { 
        $this->name = $name; // アクセス可能
    }
}
$test = new TestClass('テスト');
echo $test->name; // アクセス可能
// 実行結果: テスト

 ?>
```


## private

・スコープに基づき、
　**同じクラス内のみアクセス可能。**

※継承クラスでもアクセス不可。

######サンプルコード

```php:access-model1.php
<?php

class TestClass {

    // プロパティの定義 (クラス内のみアクセス可能)
    private $name;

    // コンストラクタの定義   
    public function __construct($name) {
        $this->name = $name; // アクセス可能
    }
}
$test = new TestClass('テスト');
echo $test->name; // アクセス不可
// 実行結果:
// Fatal error: Uncaught Error: Cannot access private property TestClass::$name

 ?>
```

## protected

・スコープに基づき、
　**同じクラス内と、
　継承したクラスでのみアクセス可能。**

###### サンプルコード
```php:access-model2.php
<?php

class TestClass {

    // プロパティの定義 (クラス内と、継承したクラス内のみアクセス可能)
    protected $name;
    protected $number;

    // コンストラクタの定義   
    public function __construct($name) {
        $this->name = $name; //アクセス可能
    }
}

// 継承クラス
class SubTestClass extends TestClass {

    // コンストラクタの定義 
    public function __construct($number) {
        $this->number = $number;  // アクセス可能
    }
}
$subTtes = new SubTestClass(1); 
echo $subTtes->number; // アクセス不可

// 実行結果: 
// Fatal error: Uncaught Error: Cannot access protected property SubTestClass::$number

 ?>
```

## static
・スコープに基づき、
　クラスを指定すれば
　**インスタンスを生成せず、アクセス可能。**

※**「static」**を用いることで
　クラスプロパティまたは、
　クラスメソッドとして定義される。

###### サンプルコード

```php:access-model3.php
<?php 

class TestClass {

    // クラスプロパティの定義
    public static $name = 'テスト'; //どこからでもアクセス可能
    private static $number = 1;   // クラス内のみアクセス可能

    // クラスメソッドの定義 (ゲッター)
    public static function getNumber() { // アクセス可能
        return self::$number;
    }
}
echo TestClass::$name.PHP_EOL; // アクセス可能 
echo TestClass::getNumber(); // アクセス可能 (ゲッターを使用しているので「1」、が表示できる)
echo TestClass::$number;// アクセス不可
// 実行結果:
// テスト
// 1
// Fatal error: Uncaught Error: Cannot access private property TestClass::$number   

 ?>
```

## まとめ
**・public**
　どこからでもアクセス可能。
**・private**
　クラス内のみアクセス可能。
**・procted**
　継承クラスでもアクセス可能。
**・static**
　インスタンスを生成せずに、
　アクセス可能。

### おまけ

**・税率計算ができる、
　ソースコードを書いてみた。**

###### サンプルコード


```php:taxrate.php
<?php

class TaxRate {

    // クラスプロパティの定義
    private static $rate = 1.08;

    // クラスメソッドの定義 (ゲッター)
    public static function getRate() {
        return self::$rate;
    }
}

class Item {
    // プロパティの定義
    protected $itemName;
    protected $itemMoney;
    protected $inputData;  

    // コンストラクタの定義
    public function __construct($itemName, $itemMoney) {
        $this->itemName = $itemName;
        $this->itemMoney = $itemMoney;
    }

    // ゲッター
    public function getName() {
        return $this->itemName;
    }

    public function getMoney() {
        return $this->itemMoney;
    }

    // セッター (値の確認) 
    public function setDecision() {
        if (null == $this->inputData[0] || !is_string($this->inputData[0])) {
            throw new LogicException('商品名が入力されていないか、不正な入力値です');
        }
        elseif (null == $this->inputData[1] || !is_numeric($this->inputData[1])) {
            throw new LogicException('金額が入力されていないか、不正な入力値です');
        }
    }
}

class Calcuation extends Item {

    // 親クラスのコンストラクタを呼び出し
    public function __construct() {
        parent:: __construct($itemName, $itemMoney);
    }

    public function inputMethod() {
        echo '欲しい商品を入力してください:';
        $this->itemName = trim(fgets(STDIN));
        echo '金額を入力してください:';
        $this->itemMoney = trim(fgets(STDIN));
        $this->inputData = array($this->itemName, $this->itemMoney);
        return $this->inputData;
    }

    // メソッドの定義
    public function calcuationMethod() {
        $result = '商品名:'.$this->itemName.' '.'金額:'.$this->itemMoney * TaxRate::getRate().'円(税込)';
        echo $result;
    }
}

// インスタの生成
$calcuation = new Calcuation();

// メソッドの実行
$calcuation->inputMethod();
$calcuation->setDecision();
$calcuation->getName();
$calcuation->getMoney();
$calcuation->calcuationMethod();

 ?>
```