Developer

【PHP応用】 プロパティ
2021.03.31
Lv2

【PHP応用】 プロパティ

この記事では、プロパティについて、
以下の3点を説明します。
1.プロパティはオブジェクトのメンバ変数。
2.public,protected,privateのアクセス修飾子を指定する。
3.staticキーワードをつけると、インスタンス化せずに使うことができる。

プロパティとは

オブジェクトのメンバ変数です。
「人間」クラスのプロパティは
「名前」「体重」「身長」などが考えられます。
★他の例も考えてみましょう。

プロパティへのアクセス方法

オブジェクトのプロパティへアクセスする構文
オブジェクト変数->プロパティ名;

ハイフンと大なり記号を組み合わせた
矢印(arrow)のような形をした「アロー演算子」を用いて、
オブジェクト内のプロパティにアクセスできます。
※後に出てきますが、アクセスできることが条件になります。
※JavaやPythonなどと違い、ドット演算子ではアクセスできません。

★以下のサンプルを作って、結果を確認してみましょう。

プロパティの初期設定

class Sample1_3_1{
    public $x=10;
}
$obj = new Sample1_3_1;
echo $obj->x;

プロパティの変更(オブジェクト外から)

class Sample1_3_1{
    //ここでSample1_3_1オブジェクトの属性$xの初期値を定義します
    public $x=10;  
}
$obj = new Sample1_3_1;
$obj->x = 20;
echo $obj->x;

プロパティの変更(オブジェクト内のメソッドから)

class Sample1_3_1{
    public $x=10;
    public function changeX($y){
      $this->x = $y;
    }
}
$obj = new Sample1_3_1;
$obj->changeX(20);
echo $obj->x;

補足:$this

メソッド内で「$this」という変数が呼ばれていることに着目してみましょう。
これは自分自身を指す変数になります。
ここで言う自分自身とは、
「このクラスを元にインスタンス化されたオブジェクト自身」ということです。
「クラス自身」という意味ではないので、注意をしてください。
「$obj->name」と同様、
アロー演算子「->」を用いて、メンバにアクセスできていることがわかります。
このように「$this」は、
インスタンス化された自オブジェクトのメソッドから、
自プロパティや自メソッドを指定したいときに用います。

プロパティに付けるアクセス修飾子

プロパティの定義時に「public」がついていました。
これはアクセス修飾子と言われているものです。
ここでは、アクセス修飾子の意味と使い方を覚えましょう。

プロパティやメソッドといったメンバには
それらにどこからアクセスできるかという
アクセス権(visibility(日本語で「可視性」といったりします))を
指定することができます(指定する必要があります)。
本節では、まずプロパティにおけるアクセス権の指定方法を説明します。

アクセス権の指定構文

アクセス修飾子 変数名;

アクセス修飾子の種類

public
そのプロパティには、どこからでも(別のオブジェクトやオブジェクト外)アクセス可能
protected
そのオブジェクト自身とそのクラスを継承したクラスのオブジェクトからのみアクセス可能
private
そのプロパティを定義しているクラスのオブジェクトからのみアクセス可能

※protectedのところに記述されている「継承」は
後述の節を読んでから確認すると分かりやすいでしょう。
※「そもそもなぜアクセス修飾子を付ける必要があるの?」については、
アクセス修飾子の節で説明します。

補足:private,protectedの例外的なアクセス

同じ型のオブジェクト(同じクラスから生成されたオブジェクト)間では、
同一オブジェクトでなくとも互いのprivateまたはprotectedメンバにアクセスできます。

★では、サンプルを作って、アクセス修飾子の違いを確認してみましょう。

class Sample1_3_2{
    public $x = 10;
    protected $y = 20;
    private $z =30;

    function displayValue(){
        echo $this->x; //OK
        echo $this->y; //OK
        echo $this->z; //OK
    }
}
$obj = new Sample1_3_2();
echo $obj->x; // OK
echo $obj->y; // Fatal エラー
echo $obj->z; // Fatal エラー
$obj->displayValue();

class Sample1_3_2_Sub extends Sample1_3_2{
    public $x = 11;  //OK
    protected $y = 22; //OK
    // private $z = 33; //この行があると26行目OK,32行目Fatalエラー。親クラスでprivateなので継承されない

    function displayValue(){
        echo $this->x; // OK
        echo $this->y; // OK
        echo $this->z; // Undefined
    }
}
$obj2 = new Sample1_3_2_Sub();
echo $obj2->x; // OK
echo $obj2->y; // Fatal エラー
echo $obj2->z; // Undefined
$obj2->displayValue();

コメント部分に記述してあるように、
プロパティの取得が可能なところと、不可能なところがあることがわかります。

プロパティに付ける「static」キーワード

これまでのサンプルでは登場してきていませんが、
プロパティには「static」というキーワードを指定することができます。
プロパティにおけるstaticキーワードの役割を説明します。

staticキーワードの指定構文

static 変数名;

staticキーワードの役割

クラスで定義したプロパティへのアクセスは、
オブジェクトを生成し、
「オブジェクトのプロパティ」という意味で
「オブジェクト名->プロパティ」という指定をする必要があると説明をしました。

しかし、staticキーワードを付与することで、
オブジェクトではなく「クラスのプロパティ」という形で
メンバへアクセスすることができるようになります。

オブジェクトによって値が変わらないようなプロパティについては、
このstaticキーワードを用いることで、
オブジェクトではなくクラスに紐づくメンバとして
定義できることになります。

逆に言うと、staticがついているプロパティは
「オブジェクトの」という指定ができないので、
アロー演算子「->」を使ったアクセスができません。

staticプロパティ呼び出し構文

staticプロパティ呼び出し構文で、
どちらも変数名の頭には$を付けます。
staticプロパティの呼び出し構文(クラス外から指定する場合)

クラス名::変数名

staticプロパティの呼び出し構文(クラス内から指定する場合)

self::変数名

また、staticが付いたプロパティは
アクセス修飾子を付けなくてもエラーにはなりませんが、
暗黙的にpublicになります。

★では、サンプルを作って、staticキーワードの有無による動作の違いを確認してみましょう。

class Sample1_3_3
{
    static $x = 1;
    function f(){
        echo $this->x; //Undefined 
        echo self::$x; //OK
    }
}
echo Sample1_3_3::$x; //OK
$s = new Sample1_3_3();
$s->f();
echo $s->x; //Undefined 

 

補足: 勝手なプロパティ追加の防止法

PHPは既定では、インスタンス作成後に、
プロパティを勝手に追加できます。
これを防ぐために__set()メソッドのオーバーライドをします。
詳細はコラム記事、「プロパティの勝手な追加防止法」をお読みください。

PHPWEBプログラミング講座 連載目次リンク

PHPWEBプログラミング講座 連載目次

関連記事

C# 基礎 第17回 属性(プロパティ)
C#のプロパティについての記事です。
【はじめてのJava】インスタンス変数【オブジェクトとクラス編】
Javaではプロパティではなく、インスタンス変数と呼びますが、基本概念は同じです。