static修飾子

クラスとオブジェクト

static修飾子とは?

 状態:-  閲覧数:4,622  投稿日:2010-05-10  更新日:2018-01-18  
クラス メンバーが、「クラスのインスタンス」ではなく「クラス」に属していることを宣言する修飾子
・「通常のメンバー」は、「インスタンスメンバー」として「インスタンスオブジェクト」に属している

クラスメンバー」とは?
・「静的メンバー」と同義語
→ クラスそのものに属する「プロパティ」「メソッド」のこと

静的メンバーの対義語
・通常メンバー

static
・スタティック
・静的


書式


定義
・メソッドやプロパティにstatic キーワード をつけるだけ
・プロパティをstaticにする意味はあまりないので普通はstaticにしない
・呼び出しは、クラス外より行なうので、アクセス修飾子は必ず「public」とする

呼出
・インスタンスオブジェクトを生成せず、直接「クラス名::メソッド名()」で呼び出す
クラス名::メソッド名()
・クラス内よりアクセスする場合
self::$プロパティ
self::メソッド()


日本語で例えてみる

 閲覧数:487 投稿日:2016-12-09 更新日:2017-10-10 

「日本人」クラスを設計


class 日本人 {
}


氏名


プロパティ
・日本人なら誰もが持っていて、みな異なる(同じ場合もある)
・個々のインスタンス(例、山田太郎、鈴木花子)で異なる
class 日本人 {
 氏名;
}


生年月日


プロパティ
・日本人なら誰もが持っていて、みな異なる(同じ場合もある)
・個々のインスタンス(例、山田太郎1990-01-01、鈴木花子2000-02-02)で異なる
class 日本人 {
 氏名;
 生年月日;
}


年齢


メソッドより求める
・日本人なら誰もが持っていて、みな異なる(同じ場合もある)
・個々のインスタンス(例、山田太郎27、鈴木花子17)で異なる
・プロパティを利用して算出可能
class 日本人 {
 氏名;
 生年月日;
 年齢計算 function{生年月日プロパティを使用して求める};
}


公用言語


staticプロパティ
・全ての日本人で共通
・すべてのインスタンス(例、山田太郎、鈴木花子)で共通なもの(であるがゆえに1つだけあればよい代物)
class 日本人 {
 static 公用言語;
 氏名;
 生年月日;
 年齢計算 function{生年月日を使用して求める};
}


まとめ1


「氏名」「生年月日」「年齢」
・「日本人」ではなく、個々のインスタンス(例、山田太郎、鈴木花子)に属している
→ staticを付与しない

「公用言語」
・「日本人」に属している
→ staticを付与


まとめ2


インスタンスメソッド内より
・staticプロパティとstaticメソッドは呼出可
山田太郎の公用語を求める

staticメソッド内より
・普通のプロパティと普通のメソッドは呼び出し不可
日本人に共通な氏名を求める
日本人に共通な生年月日を求める
日本人に共通な年齢を求める


「static修飾子」付与 → クラスメソッド

 閲覧数:559 投稿日:2016-12-09 更新日:2017-07-15 

クラスメソッド


クラスで定義されている関数の内、静的(static)なもの
・インスタンス化せずにアクセス可能

=静的メソッド
・インスタンス化せずにアクセス可能


クラスメソッド定義例


class Calculator{
 public static function addition($int1, $int2){
 }
 public static function substraction($int1, $int2){
 }
 public static function getAverage($intVals){
 }
}


クラスメソッド呼び出し例


Calculator::addition(10, 1);
Calculator::substraction(10, 1);
Calculator::getAverage($intVals);


クラスメソッドをメンバーとして持つクラス例


計算処理クラス

class Calculator{
   // 足し算
   public static function addition($int1, $int2){
       return $int1 + $int2;
   }

   // 引き算
   public static function substraction($int1, $int2){
       return $int1 - $int2;
   }

   // 平均値を求める
   public static function getAverage($intVals){
       if (false == is_array($intVals)) {
           return false;
       }
       $cnt = count($intVals);
       $total = 0;
       foreach ($intVals as $int) {
           $total += $int;
       }
       $average = $total / $cnt;
       return $average;
   }
}

$answer = Calculator::addition(10, 1);
var_dump($answer);

$answer = Calculator::substraction(10, 1);
var_dump($answer);

$intVals = array(1, 2, 3, 4, 5, 6, 7);
$answer = Calculator::getAverage($intVals);
var_dump($answer);


▼結果
int(11)
int(9)
int(4)




階層関係 相関イメージ

 閲覧数:516 投稿日:2017-01-17 更新日:2017-02-19 

メンバ(内容別)


メンバ
 |
 +--- プロパティ
 |      |
 |      +--- インスタンスプロパティ
 |      |
 |      +--- クラスプロパティ
 |
 +--- メソッド
        |
        +--- インスタンスメソッド
        |
        +--- クラスメソッド  


メンバへのアクセス方式(書式)


メンバへのアクセス方式
 |
 +--- 「インスタンスオブジェクト経由アクセス」→「->(アロー演算子)」利用。オブジェクト生成必要
 |
 +--- 「クラスアクセス」→「:(スコープ演算子)」利用。オブジェクト生成不要


メンバへのアクセス(プロパティ)


class A
{
 public $p;
 public static $s;
}
$a = new A();
メンバへのアクセス(プロパティ)
 |
 +---  $a->p  ◯「オブジェクト経由アクセス」インスタンスプロパティ
 |
 +---  $a->s  ×「オブジェクト経由アクセス」クラスプロパティ  ※「スタティック」宣言したプロパティは完全に「クラスプロパティ」となるため、「インスタンスプロパティ」としてオブジェクト経由で参照することはできない
 |
 +---  A::$p  ◯「クラスアクセス」インスタンスプロパティ
 |
 +---  A::$s  ◯「クラスアクセス」クラスプロパティ


メンバへのアクセス(メソッド)


class A
{
 public $p();
 public static $s();
}
$a = new A();
メンバへのアクセス(メソッド)  ※メソッド内の記述によっては下記と異なる挙動となる
 |
 +---  $a->p()  ◯「オブジェクト(インスタンスメソッド)経由アクセス」
 |
 +---  $a->s()  △「オブジェクト(クラスメソッド)経由アクセス」  ※可読性の観点から、クラス関数へはアロー演算子でアクセスしない方がよい
 |
 +---  A::p()  △「クラスアクセス(インスタンスメソッド経由)」  ※static でないメソッドを静的呼出ししているので、限りなくまちがいに近い
 |
 +---  A::s()  ◯「クラスアクセス(クラスメソッド経由)」


詳細

 閲覧数:480 投稿日:2017-02-19 更新日:2017-02-23 

一覧表



・可読性を考慮すると、避けた方が無難

一覧表              
メンバの種類 インスタンス経由アクセス「->」 クラス経由アクセス「::」
インスタンスプロパティ
クラスプロパティ ×
インスタンスメソッド △(staticでないメソッドを静的呼出し)
クラスメソッド
クラスメソッド
・staticメソッド内で「$this」使用不可
/*
* 値が異なったら、順位と値を更新するメソッド
* ランキング出力する際に使用
* @param  string $value 順位の基準となる値
* @return int    $rank 順位
*/
class Samerank
{
 public static $rank     = 0; //初期値(実際は最初必ず繰り上がるはずなので「1」小さい)
 public static $lastValue = null;
 
 public static function rankUpdate($value){
   if (Samerank::$lastValue !== $value) {//異なったら
     Samerank::$rank++;                  //順位を更新
     Samerank::$lastValue = $value;      //前のレコードの値を更新
   }
   return Samerank::$rank;
 }
}











メンバへアクセスする方法

 閲覧数:515 投稿日:2017-02-23 更新日:2018-01-18 

アクセス経路2種類


インスタンスオブジェクト経由アクセス
・インスタンスオブジェクト生成が必要
・「->(アロー演算子)」を用い、生成したオブジェクト経由で「インスタンスメンバ」へアクセス

クラス経由アクセス
・オブジェクト生成は不要
・「::(スコープ演算子)」を利用し、「クラスメンバ」へ直接アクセス


メソッド


クラスで定義されている関数
・メンバ関数
・「インスタンスメソッド」と「クラスメソッド」の2種類存在


メソッド分類2種類


インスタンスメソッド
・インスタンスオブジェクトに所属する関数
・クラス定義されている関数の内、静的(static)でないもの
・インスタンス(オブジェクト)を通してアクセスする

クラスメソッド
・クラスに所属する関数
・静的メソッド
・クラス定義されている関数の内、静的(static)なもの
・インスタンス化せず(クラスのインスタンスオブジェクトを生成せず)にアクセス


「$this」の利用可否


利用可
・インスタンスメソッド
→ インスタンスを生成し、そのメソッド内で「self::」または「parent::」を使用してコールした場合

利用不可
・「クラスメソッド」としてコールされた場合
・「インスタンスオブジェクト」は生成されていないため、メソッド内でオブジェクトへのリファレンスを保持する「$this」は利用不可


「self::」「parent::」


「クラスメソッド」がアクセスできるのは?
・「クラスメンバ」のみ
・具体的には、「self::」を用いて「self::$static_public_property」や「self::static_public_method()」のようにアクセスする
・ちなみに、「クラスメソッド」でない「インスタンスメソッド」もこれでコールできる
・しかし、この場合にコールされるのは「インスタンスメソッド」となる(当然、「クラスメソッド」からのアクセスの場合は「クラスメソッド」としてコールされる)

「static修飾子」と「アクセス制限修飾子」の順番
・定義時に指定する「static修飾子」と「アクセス制限修飾子」の順番は任意。ex) 「static public $v」 でも、「public static $v」でも可。

コンストラクタ
・「スタティック」宣言できない

・そもそもスタティックにコールされることを想定していない

<pre>
<?php
   class A{
       public $public_v = "public_vメンバ変数";
       static public $static_public_v = "static_public_vメンバ変数";
       public function public_method(){
           return "public_method()";
       }
       static public function static_public_method(){
           return "static_public_method()";
       }
       public function get_static_public_v(){
           #通常メソッド内でクラスメンバ参照
           return self::$static_public_v;
       }
       static public function get_public_v(){
           #スタティックメソッド内でインスタンスメンバ参照
           return $this->public_v;
       }
   }
   
   /*
   class SKY{
       #①コンストラクタをスタティック宣言しようとすると、Fatal error: Constructor SKY::SKY() cannot be staticとなる。コンストラクタは「スタティック」宣言できない(そもそもスタティックにコールされることを想定しないため)
       static public function SKY(){
           //empty
       }
   }
   */
   
   #②インスタンスオブジェクト生成
   $a = new A;
   
  echo "■③インスタンスオブジェクト経由アクセス\n";
   echo "▼インスタンスプロパティ取得\n";
   echo '$a->public_v              : ', $a->public_v, "\n\n";
   echo "▼クラスプロパティ取得\n";
   echo '$a->static_public_v       : ', $a->static_public_v, "×「スタティック」宣言したプロパティは完全に「クラスプロパティ」となるため、「インスタンスプロパティ」として参照することが出来なくなる。\n\n";
   echo "▼インスタンスメソッド取得\n";
   echo '$a->public_method()       : ', $a->public_method(), "\n\n";
   echo "▼クラスメソッド取得        ※可読性の観点から、クラス関数へはアロー演算子でアクセスしない方がよい\n";
   echo '$a->static_public_method(): ', $a->static_public_method(), "\n\n
";
   
  echo "■④クラスアクセス\n";
   echo "▼インスタンスプロパティ取得\n";
   echo 'A::$public_v              : '/*, A::$public_v*/, "×「インスタンスプロパティ」を「クラスプロパティ」として参照することはできない。【Fatal error:  Access to undeclared static property:  A::$public_v】\n\n";
   echo "▼クラスプロパティ取得\n";  
echo 'A::$static_public_v       : ', A::$static_public_v, "\n\n";
   echo "▼インスタンスメソッド取得  ※static でないメソッドを静的呼出ししているので、限りなくまちがいに近い\n";
   echo 'A::public_method()        : ', A::public_method(), "\n\n";
   echo "▼クラスメソッド取得\n";
   echo 'A::static_public_method() : ', A::static_public_method(), "\n\n
";

  echo "■⑤インスタンスオブジェクト経由アクセス\n";
   echo "▼インスタンスプロパティ更新\n";
   $a->public_v = "public_vメンバ変数更新";
   echo "▼インスタンスプロパティ取得\n";
   echo '$a->public_v              : ', $a->public_v, "\n\n
";

  echo "■⑥クラスアクセス\n";
   echo "▼クラスプロパティ更新\n";
   A::$static_public_v = "static_public_vメンバ変数更新";
   echo "▼クラスプロパティ取得\n";  
echo 'A::$static_public_v       : ', A::$static_public_v, "\n\n
";
 
echo "■⑦新たなオブジェクトb生成\n\n
";
   $b = new A;

  echo "■⑧インスタンスオブジェクト経由アクセス\n";
   echo "▼インスタンスプロパティ取得\n";    
   echo '$b->public_v              : ', $b->public_v, " …「aオブジェクトに対するインスタンスプロパティ」更新は、「bオベジェクトのインスタンスプロパティ」とは関係がない\n\n
";

  echo "■⑨インスタンスオブジェクト(インスタンスメソッド)経由アクセス\n";
   echo "▼クラスプロパティ取得\n";  
   echo '$a->get_static_public_v() : ', $a->get_static_public_v(), " …「クラスに対するプロパティ」更新は、そのクラスから生成される全てのオブジェクトが影響を受ける(クラスプロパティとインスタンスオブジェクトは無関係)\n";
   echo '$b->get_static_public_v() : ', $b->get_static_public_v(), " …「クラスに対するプロパティ」更新は、そのクラスから生成される全てのオブジェクトが影響を受ける(クラスプロパティとインスタンスオブジェクトは無関係)\n\n
";

  echo "■⑩クラスアクセス(クラスメソッド)経由\n";
   echo "▼インスタンスプロパティ取得\n";    
   echo 'A::get_public_v()         : '/*, A::get_public_v()*/, "×【Fatal error:  Using $this when not in object context】「オブジェクトではないから「\$this」は使えない」 \n\n
";
   
  echo "■⑪インスタンスオブジェクト(クラスメソッド)経由アクセス\n";
   echo "▼インスタンスプロパティ取得\n";  
   echo '$a->get_public_v()        : '/*, $a->get_public_v()*/,"×【Fatal error:  Using $this when not in object context】「オブジェクトではないから「\$this」は使えない」 \n";
?>






▼クラス継承時の注意事項

子クラスで親クラスと同名のプロパティを再定義する場合も、メソッドをオーバーライドする場合も、「クラスメンバ」だったものを「インスタンスメンバ」にしたり、「インスタンスメンバ」だったものを「クラスメンバ」に変更することは出来ない。
また、“「パブリック」な「スタティックプロパティ」”に関して、何れの場合も(子クラスで「スタティック」宣言したとしても)子クラスで再定義することができない。





メンバのアクセス制限

クラス定数

コメント投稿(ログインが必要)



類似度ページランキング
順位 ページタイトル抜粋
1 static修飾子 89
2 final修飾子 59
3 switch文 50
4 isset 43
5 $this 43
6 setcookie関数 40
7 include_path 38
8 imagick 38
9 Doctrine 35
10 ob_start 35
11 spliceImageメソッド 33
12 session.hash_function 33
13 session_start() 33
14 session.gc_maxlifetime 32
15 register_globals 32
16 Generators 32
17 preg_match 32
18 define と const の違い 30
19 SessionHandler::gc 30
20 文字列型(string) 29
2025/8/13 12:46 更新
週間人気ページランキング / 8-6 → 8-12
順位 ページタイトル抜粋 アクセス数
1 定数 4
1 Parse error: syntax error, unexpected 'public' (T_PUBLIC) | Parse error(エラーメッセージ) 4
2 PHP用語 3
2 「POSIX正規表現」と「PCRE正規表現」の違い 3
2 結合時の評価と優先順位 | 演算子 3
2 PHPで定数を定義する方法は2種類ある / 配列定数の定義 3
2 ブラウザを閉じたらセッションデータはどうなるの? | セッション 3
3 セッション管理が必要な理由は、HTTPプロトコルには状態を保持する機能がないため | セッション 2
3 コード例 … 「例外処理」はネストすることができる 2
3 ブラウザを閉じたらセッションデータはどうなるの? | セッション 2
3 Fatal error: Uncaught Error: Call to a member function modify() on string | Fatal error(エラーメッセージ) 2
3 Fatal error: require_once(): Failed opening required 'PEAR.php' | Fatal error(エラーメッセージ) 2
3 curl で Cookie を使用する 2
3 ( ! ) Warning: Declaration of xxxx should be compatible with | エラーメッセージ 2
3 http_build_query | URLs(関数) 2
3 and | 演算子 2
3 Cookie | クッキー 2
4 Warning: PDO::query(): LOAD DATA LOCAL INFILE forbidden | Warning(エラーメッセージ) 1
4 You currently have Essential access which includes access to Twitter API v2 endpoints only. If you need access to this endpoint, you’ll need to apply for Elevated access via the Developer Portal. | Twitter API(エラーメッセージ) 1
4 ( ! ) Fatal error: Uncaught PDOException: SQLSTATE[HY093]: Invalid parameter number: parameter was not defined | Fatal error(エラーメッセージ) 1
2025/8/13 1:01 更新