親です。

子ども産まれたんで育児とかについて書きます。映画とか心理学とかITとかの趣味についても書きます。

【PHP】PHPとオブジェクト指向(クラスの書き方)について

PHPやってたらオブジェクト指向の工夫的なのが出てきたのでそれをざっとまとめる。 (注:記事内でクラスプロパティの概念がPHPにはないと書いてるけどあるらしい。)

最終的なクラスの書き方

最終的にはこんな感じで書く。コメントで示した3つの点について、この後解説を加える。

<?php
class Menu {
  // ①変数宣言
  // privateでの変数宣言
  private $name;
  private $price;
  private $image;
  // 初期値ありでの宣言
  private $orderCount = 0;
  // クラスプロパティ
  private static $count;

  // ②初期設定 - __constructメソッド  
  public function __construct($name, $price, $image) {
    $this->name = $name;
    $this->price = $price;
    $this->image = $image;
    // クラスプロパティの加算
    self::count++;
  }

  // ③ゲッターとセッター
  // ゲッター
  public function getName() {
    return $this->name;
  }
  // セッター
  public function setOrderCount($orderCount){
    $this->orderCount = $orderCount;
  }

  // ④クラスメソッド
  public static function getCount(){
    return self::$count;
  }
}

?>

基本的なノリの確認

基本的なノリの確認なんだが、
1. クラス名の命名規則
基本的にパスカルケース(先頭大文字)でやる。
2. $thisについて
クラス内で記述される$thisは「このクラスの...」というのを意味する。なので「このクラスのnameプロパティ」とかって感じにクラス内からアクセスするときよく使う。

①変数宣言

class Menu {
  // ①変数宣言
  // privateでの変数宣言
  private $name;
  private $price;
  private $image;
  // 初期値ありでの宣言
  private $orderCount = 0;
  // クラスプロパティ
  private static $count;

プロパティの宣言(変数宣言)はクラスの直下で行う。
通常の変数宣言と違うのは、宣言の前にprivateとかpublicとかがつくことだ。これはこの変数がクラスの外からアクセス可能かどうかを示している。後で説明するゲッターとセッターにも関わってくる内容だが、基本的にはprivateにすれば良い。

また、pythonだとこのクラスから作られたインスタンス全てに共通させたいクラスプロパティについてここで宣言し、インスタンスごとに分けておきたいものは__init__メソッドの中に記載している。
PHPの場合は記載場所を変えるのではなく、宣言の仕方を変えることで、クラスプロパティとインスタンスプロパティの区別をしている。

②__constructed(変数名, 変数名)

  // ②初期設定 - __constructメソッド  
  public function __construct($name, $price, $image) {
    $this->name = $name;
    $this->price = $price;
    $this->image = $image;
  }

インスタンスの作成時に引数をとってプロパティの一括設定できるようにしたメソッド。メソッドだけどメソッドとして呼び出されることはないはず。(メソッド名の前に__をつけるのはpythonでもprivateなメソッドであることを示してたはず。)
ちなみにこんなふうに書く。

$menu1 = new Menu('CURRY', 1900, 'http;//...');

基本的なノリとしてはPython__init__メソッドと同じだ。違うのは、__init__ではプリセットしたいプロパティの設定もここでしてしまうことだ。PHPの場合、プロパティの宣言自体はクラス直下にまとめて書いてしまうため、__construct()ではあくまで「インスタンスの作成時に一括設定する」というのを目的にしているようだ。

③ゲッターとセッター

  // ③ゲッターとセッター
  // ゲッター
  public function getName() {
    return $this->name;
  }
  // セッター
  public function setOrderCount($orderCount){
    $this->orderCount = $orderCount;
  }

①の変数宣言のところでprivateについて説明を加えたが、これは$instance->name = 'CURRY'みたいな直接的な値のセットとか、echo $instance->nameという参照を防ぐために行われている。
その代わりに用意されているのがこのゲッターとセッターというメソッドだ。ゲッターが値の取得・参照で、セッターが値のセットを担う。
publicでそれらを可能にするのではなく、あえてゲッター・セッターを作るメリットは、変数に対するアクセス権限を細かく設定できる点だ。public/privateだとゲットもセットもどちらも可能!不可能!という粗い設定しかできないが、ゲッター/セッターならどこまでは許可、というように細かくできる。
(混乱させると、これファイルごとに権限が設定されてるイメージだけど、ユーザ側にも権限つける発想はないのかな?)

クラスプロパティやクラスメソッド、継承オーバーロードあたりは次の記事にまとめる。

以上!!!