php

「同じ変数なのに触れない!」publicとprivateって何?PHPのアクセス制御を読めるようになろう

AIにPHPを書いてもらった。

コードを見ると、こんなものがありました。

public $name;

別の場所には、

private $password;

public?

private?

英語の意味から考えると、

public = 公開

private = 非公開

という感じでしょうか。

なんとなく意味は分かります。

ところが、実際にコードを触ってみると、

echo $user->name;

は動くのに、

echo $user->password;

はエラーになる。

同じ $user->○○ なのに、なぜ?

今回は、AIが生成したPHPにもよく登場する public と private の正体を調べてみましょう。

難しいオブジェクト指向を全部覚える必要はありません。

今日の目標は、

「なぜこの変数にはアクセスできるのに、こっちにはアクセスできないのか」

をコードから判断できるようになることです。


1. 事件発生!同じように書いたのに片方だけエラー

まずは、こんなクラスを作ってみます。

class User
{
    public $name = 'みのり';

    private $password = 'secret';
}

前回までの記事を読んでいれば、少しコードが読めるようになってきたと思います。

User というクラスがあり、その中に、

$name

と、

$password

があります。

では、実際に使ってみましょう。

$user = new User();

echo $user->name;

結果は、

みのり

です。

ちゃんと表示されました。

では次です。

$user = new User();

echo $user->password;

ところが、こちらは正常に表示されません。

環境によって細かな表示は異なりますが、

Cannot access private property

のようなエラーが出ます。

直訳すれば、

「privateなプロパティにはアクセスできません」

です。

なぜでしょう?


2. publicとprivateの違い

まずは、ものすごく単純に考えてみましょう。

public

は、

「クラスの外からアクセスできる」

もの。

private

は、

「基本的に、そのクラス自身の中からだけアクセスできる」

ものです。

先ほどのコードをもう一度見てみます。

class User
{
    public $name = 'みのり';

    private $password = 'secret';
}

$name には public が付いています。

そのため、

echo $user->name;

と外からアクセスできます。

一方、

private $password = 'secret';

には private が付いています。

そのため、

echo $user->password;

とクラスの外から直接アクセスしようとするとエラーになります。

つまり、

指定クラスの外から
publicアクセスできる
private直接アクセスできない

まずはこれだけ覚えればOKです。


3. privateなら誰も使えないの?

ここで疑問が出てきます。

「外からアクセスできないなら、private にしたデータはどうやって使うの?」

実は、

クラス自身の中からなら使えます。

そこで前回勉強した、

$this

が登場します。

例えば、

class User
{
    private $name = 'みのり';

    public function showName()
    {
        echo $this->name;
    }
}

そして、

$user = new User();

$user->showName();

とすると、

みのり

と表示できます。

ここ、かなり重要です。

外から、

$user->name

と直接触ることはできません。

でもクラス内部の、

$this->name

ならアクセスできます。


4. 前回の$thisとつながった!

前回の記事では、

$this->name

について、

「現在のオブジェクト自身が持つ name」

と説明しました。

今回のコードでも同じです。

class User
{
    private $name = 'みのり';

    public function showName()
    {
        echo $this->name;
    }
}

showName() は User クラス自身のメソッドです。

そのため、

$this->name

として、自分自身が持っている private $name にアクセスできます。

ここまで分かると、

public function showName()

の public も読めますね。

これは、

「showName()というメソッドは外から呼び出せますよ」

という意味です。

だから、

$user->showName();

が実行できるわけです。


5. じゃあ全部publicでよくない?

ここで、かなり自然な疑問が出てきます。

「面倒だから全部 public にすればいいのでは?」

確かに、そうすれば簡単です。

例えば、

class User
{
    public $name;
}

なら、

$user->name = 'みのり';

と自由に変更できます。

でも、

「自由に変更できる」ことが問題になる場合があります。

例えば、ゲームのプレイヤーを考えてみましょう。

class Player
{
    public $hp = 100;
}

外から自由に変更できるので、

$player->hp = -99999;

なんてこともできてしまいます。

そこで、

class Player
{
    private $hp = 100;
}

としておきます。

そしてHPを変更するための処理を用意します。

class Player
{
    private $hp = 100;

    public function damage($amount)
    {
        $this->hp -= $amount;

        if ($this->hp < 0) {
            $this->hp = 0;
        }
    }

    public function getHp()
    {
        return $this->hp;
    }
}

こうすると、

$player->damage(30);

echo $player->getHp();

結果は、

70

になります。

外からHPそのものを直接変更させるのではなく、

「HPを変更するときは、この処理を通してください」

というルールを作れるわけです。

これが private を使う大きな理由のひとつです。


6. privateは「秘密の情報」という意味ではない

ここは初心者が誤解しやすいところです。

private と聞くと、

「パスワードなど秘密のデータを守る機能?」

と思うかもしれません。

しかし、

private $password;

と書いただけで、パスワードが安全に保存されるわけではありません。

private は、

PHPのクラス内で「どこからアクセスできるか」を制御する仕組み

です。

暗号化したり、データベースの情報を外部から見えなくしたりするセキュリティ機能とは別の話です。

ここは分けて考えましょう。


7. 実はもうひとつある「protected」

AIがPHPを書いていると、

protected $name;

というものが出てくることがあります。

PHPでは主に、

public
protected
private

の3種類があります。

ざっくり整理すると、

指定自分のクラス継承したクラスクラスの外
public○○○
protected○○×
private○××

protected では「継承」という新しい言葉が出てきました。

これは別の記事で扱います。

今回は、

protected というものもある

くらいで十分です。


8. AIが書いたコードではどう読む?

例えばAIが、こんなコードを書いたとします。

class User
{
    private $email;

    public function setEmail($email)
    {
        $this->email = $email;
    }

    public function getEmail()
    {
        return $this->email;
    }
}

以前なら、

「なんか難しいコードが出てきた……」

となっていたかもしれません。

でも、ここまで学習するとかなり読めます。

まず、

private $email;

なので、

emailは外から直接アクセスさせない。

次に、

public function setEmail($email)

なので、

外から呼び出せる setEmail() がある。

その中で、

$this->email = $email;

としているので、

自分自身のemailに値を保存している。

さらに、

public function getEmail()

で、

return $this->email;

としている。

つまり、

保存されているemailを取得するための処理

ですね。

実際には、

$user = new User();

$user->setEmail('test@example.com');

echo $user->getEmail();

のように使えます。

AIが書いたコードが、かなり「読めるコード」に変わってきました。


9. AIに修正を頼むときにも役立つ

例えば、

Cannot access private property User::$email

というエラーが出たとします。

意味を知らなければ、

動きません。直してください。

とAIに丸投げすることになります。

もちろん、それでもAIは直してくれるかもしれません。

でも今回の知識があれば、

User::$email がprivateなので外部から直接アクセスできないようです。
publicに変更するのではなく、必要ならgetterを追加する形で修正してください。

といった頼み方もできます。

エラーの意味が分かると、AIへの指示も具体的になる。

これが、AI時代にPHPの基礎を学ぶ大きな意味のひとつです。


今日の合格ライン

今日覚えて帰ることは4つです。

  • public はクラスの外からアクセスできる
  • private は基本的にそのクラス自身からアクセスする
  • $this->name ならクラス内部から自身のプロパティにアクセスできる
  • private は「暗号化」や「秘密にする」という意味ではない

全部暗記する必要はありません。

AIが生成したコードに、

private $name;

があったら、

「あ、これは外から直接触らせないようにしているんだな」

と気付ければ、今回は合格です。


ワンポイント答え合わせ

Q1. クラスの外から直接アクセスできるのは?

A. public

B. private

正解:A

public はクラスの外からアクセスできます。


Q2. 次のコードはそのまま実行できる?

class User
{
    private $name = 'みのり';
}

$user = new User();

echo $user->name;

A. できる

B. できない

正解:B

$name は private なので、クラスの外から直接アクセスできません。


Q3. privateな$nameをクラス自身のメソッドから参照するときは?

class User
{
    private $name = 'みのり';

    public function showName()
    {
        // ここは?
    }
}

A.

echo $this->name;

B.

echo $_POST['name'];

C.

echo public->name;

正解:A

ここで前回学んだ $this-> が登場します。


AI時代だからこそ、磨こう。その腕。

AIなら、

public
private
protected

を正しく使ったクラスを、一瞬で作ることができます。

だからといって、全部を自分で書ける必要はありません。

でも、

「なぜここはprivateなのか」

「なぜ外からアクセスできないのか」

が分かれば、AIが作ったコードを確認し、エラーが起きたときにも原因を追えるようになります。

1から全部書く必要はない。

だが、知る必要はある。

次回は少し方向を変えて、

「$users[0]['name']って何?」PHPの配列を読めるようになろう

に進みます。

AIが生成するコード、データベースの検索結果、APIやJSON――。

この先のWeb制作で大量に登場する**「複数のデータをまとめて扱う」**ための基礎へ進みましょう。

☆ この授業をあとで見返す

学生登録(無料)すると、お気に入りに保存できます。授業は登録しなくても読めます。

☆ この授業をあとで見返す

学生登録(無料)すると、お気に入りに保存できます。授業は登録しなくても読めます。