2013年2月3日

php 「$this」 , 「self::」について

参考 http://php.net/manual/ja/language.oop5.properties.php


$thisは、自分自身のオブジェクトを指し、
self::は静的アクセスという理解しかないので、ここで一度整理したいと思う。



上記には、静的でないプロパティアクセスにはオブジェクト演算子(->)
               静的なプロパティへのアクセスにはダブルコロン(::)を使う。と記載されている。


では、静的でないプロパティと静的なプロパティの違いについてみていこう。

クラスプロパティもしくはメソッドを static として宣言することで、 クラスのインスタンス化の必要なしにアクセスすることができます。 static なプロパティは、インスタンス化されたクラスオブジェクトから アクセスすることはできません (static なメソッドにはアクセスできます)。static メソッドは、オブジェクトのインスタンスを生成せずに コールすることができます。疑似変数 $this は、 static として宣言されたメソッドの内部から利用することはできません。static プロパティは、矢印演算子 -> によりオブジェクトからアクセス することはできません。

以下サンプルプログラムを作ってみた。
staticプロパティは静的なので、self::でアクセスする。
静的ではなく、オブジェクトの場合は->でアクセスする。
staticメゾットについては、ダブルコロン(::)、アロー演算子(->;)どちらでもアクセス可能。

静的なので、インスタンス化されたオブジェクト空間とは、別にメモリ確保されている事になる。
これを確かめるためにメモリ空間を覗きたかったが、現在の設定ではボタンがDisableであった。
残念。またの機会にでもメモリ空間は見れるようにしておきたい。





class BaseClass
 {
  public $publicVar = 'In Base Class public value';
  protected  $protextedVar = 'In Base Class protected value';
  private $privateVar='In Base Class private value';
 
  public static $public_static_Var = 'In Base Class public static value';
  protected static  $protexted_static_Var = 'In Base Class protected static value';
  private static $private_static_Var='In Base Cla ss private static value';
 
function __construct() 
{
print'In Base Class __constructor';
}

function __destruct()
{
print'In Base Class __destructor';
}

function viewPrint() 
{
var_dump($this);
print'In Base Class viewPrint';

}
function  propertyBaseClassAccess()
{
$this->privateVar;
$this->protextedVar;
$this->publicVar;

//static の為、selfでアクセスOK
self::$public_static_Var;
self::$protexted_static_Var;
self::$private_static_Var;
//static の為、this->ではアクセスNG
// $this->public_static_Var;    //Error Strict standards: Accessing static property BaseClass::$public_static_Var as non static
// $this->protexted_static_Var; //Error Strict standards: Accessing static property BaseClass::$protexted_static_Var as non static
// $this->private_static_Var;   // Error Strict standards: Accessing static property BaseClass::$private_static_Var as non static

}
  public static function  staticpropertyBaseClassAccess()
{
// $this->privateVar;   //Fatal error: Using $this when not in object context
// $this->protextedVar; //Fatal error: Using $this when not in object context
// $this->publicVar;    //Fatal error: Using $this when not in object context

self::$public_static_Var;
self::$protexted_static_Var;
self::$private_static_Var;

}
public function setPublicVar($x){ $this->publicVar=$x; }
  public function setProtextedVar($x){ $this->protextedVar=$x; }
public function setPrivateVar($x){ $this->privateVar=$x; }

public function getPublicVar(){ return $this->publicVar; }
public function getProtextedVar(){ return $this->protextedVar; }
public function getPrivateVar(){ return  $this->privateVar; }

 }

 class SubClass extends BaseClass
 {
// public $publicVar = 'In Sub Class public value';
// protected  $protextedVar = 'In Sub Class protected value';
// private $privateVar='In Sub Class private value';

  function __construct() 
  {
  parent::__construct();
print'In Sub Class __constructor';
  }
 
  function __destruct() 
  {
  parent::__destruct();
  print'In Sub Class __destructor';
  }
  function viewPrint() 
{
var_dump($this);
print'In SubClass viewPrint';

}

//   public function setPublicVar($x){ $this->publicVar=$x; }
//   public function setProtextedVar($x){ $this->protextedVar=$x; }
//   public function setPrivateVar($x){ $this->privateVar=$x; }
 
//   public function getPublicVar(){ return $this->publicVar; }
//   public function getProtextedVar(){ return $this->protextedVar; }
//   public function getPrivateVar(){ return  $this->privateVar; }
 
  }

 $baseClassObj = new BaseClass();
 $baseClassObj->viewPrint();

 //protexted,privateプロパティへのアクセスの為NG
 $baseClassObj->publicVar;
 //$baseClassObj->protextedVar; //Fatal error: Cannot access protected property BaseClass::$protextedVar
 //$baseClassObj->privateVar;   //Fatal error: Cannot access private property BaseClass::$privateVar 

 //静的ではないインスタンスからのstaticプロパティへのアクセスはすべてNG
 //$baseClassObj->public_static_Var;     //Strict standards: Accessing static property BaseClass::$public_static_Var as non static
 //$baseClassObj->protexted_static_Var;  //Fatal error: Cannot access protected property BaseClass::$protexted_static_Var 
 //$baseClassObj->private_static_Var;    //Fatal error: Cannot access private property BaseClass::$private_static_Var

 //下記のようにpublic static プロパティへのアクセスが可能
 BaseClass::$public_static_Var;
 //BaseClass::$protexted_static_Var;    //Fatal error: Cannot access protected property BaseClass::$protexted_static_Var 
 //BaseClass::$private_static_Var;      //Fatal error: Cannot access private property BaseClass::$private_static_Var

 $baseClassObj->propertyBaseClassAccess();
 $baseClassObj->staticpropertyBaseClassAccess();

 BaseClass::staticpropertyBaseClassAccess(); 

 $subClassObj = new SubClass();

 $objArray = array($subClassObj,$baseClassObj);

 print $objArray[1]->publicVar;
 print $objArray[1]::$public_static_Var;

-----------------------------------------------------------------------------

In Base Class __constructor
object(BaseClass)[1]
  public 'publicVar' => string 'In Base Class public value' (length=31)
  protected 'protextedVar' => string 'In Base Class protected value' (length=34)
  private 'privateVar' => string 'In Base Class private value' (length=32)
In Base Class viewPrint
In Base Class __constructor
In Sub Class __constructor
In Base Class public value
In Base Class public static value
In Base Class __destructor
In Base Class __destructor
In Sub Class __destructor




php コンストラクタとデストラクタ




コンストラクタの実行タイミングは分かるけど、
デストラクタの実行タイミングがいまいちよく分かりません。

そこで、下記を参考に


参考:http://php.net/manual/ja/language.oop5.decon.php
引用-----------------------------------------------
デストラクタメソッドは、 
特定のオブジェクトを参照するリファレンスがひとつもなくなったときにコールされます。 
 あるいは、スクリプトの終了時にも順不同でコールされます。


ふむふむ。


class BaseClass
 {
  public $publicVar = 'In Base Class public value';
  protected  $protextedVar = 'In Base Class protected value';
  private $privateVar='In Base Class private value';
  
 function __construct() 
 {
  print'In Base Class __constructor';
 }
 
 function __destruct()
 {
  print'In Base Class __destructor';
 }
 
 function viewPrint() 
 {
  var_dump($this);
  print'In Base Class viewPrint';
  
 }
 
 public function setPublicVar($x){ $this->publicVar=$x; }
  public function setProtextedVar($x){ $this->protextedVar=$x; }
 public function setPrivateVar($x){ $this->privateVar=$x; }
 
 public function getPublicVar(){ return $this->publicVar; }
 public function getProtextedVar(){ return $this->protextedVar; }
 public function getPrivateVar(){ return  $this->privateVar; }
 
 }
 
 class SubClass extends BaseClass
 {
  public $publicVar = 'In Sub Class public value';
  protected  $protextedVar = 'In Sub Class protected value';
  private $privateVar='In Sub Class private value';
  
  function __construct() 
  {
   parent::__construct();
  print'In Sub Class __constructor';
  }
  
  function __destruct() 
  {
   parent::__destruct();
   print'In Sub Class __destructor';
  }
  public function setPublicVar($x){ $this->publicVar=$x; }
  public function setProtextedVar($x){ $this->protextedVar=$x; }
  public function setPrivateVar($x){ $this->privateVar=$x; }
  
  public function getPublicVar(){ return $this->publicVar; }
  public function getProtextedVar(){ return $this->protextedVar; }
  public function getPrivateVar(){ return  $this->privateVar; }
  
  }
 
 $baseClassObj = new BaseClass();
 $baseClassObj->viewPrint();
 
 $subClassObj = new SubClass();
 $subClassObj->viewPrint();




---------------------------------------------------------------------
OutPut

In Base Class __constructor   <------base class="xdebug-var-dump" dir="ltr" pre="">object(BaseClass)[1]
  public 'publicVar' => string 'In Base Class public value' (length=31)
  protected 'protextedVar' => string 'In Base Class protected value' (length=34)
  private 'privateVar' => string 'In Base Class private value' (length=32)

In Base Class viewPrint    <------ ase="" class="" code="">リファレンス
In Base Class __constructor    <------base br="" class="">
In Sub Class __constructor     <------sub ase="" class="xdebug-var-dump" dir="ltr" pre="">
object(SubClass)[2]
  public 'publicVar' => string 'In Sub Class public value' (length=30)
  protected 'protextedVar' => string 'In Sub Class protected value' (length=33)
  private 'privateVar' => string 'In Sub Class private value' (length=31)
  private 'privateVar' (BaseClass) => string 'In Base Class private value' (length=32)

In Base Class viewPrint <-------- br="" class="" sub="">In Base Class __destructor <-------- br="" class="" parent::__destruct="" sub="">In Sub Class __destructor   <-------- br="" class="" sub="">In Base Class __destructor <-------- base="" class="" code="" ub="">
                                         Base Class最後のリファレンスとなり、
                                         最終的にBase Class デストラクタがCallされる

なるほど。
最終的に Sub Classのデストラクタ後に親クラスのBase ClassデストラクタがCallされた。
一つ勉強になった。


 

eclipse PDT Xdebug

Ecilpse DownLoad

http://www.zend.com/en/community/pdt/downloads
ProductVersionFormat/SizeNotes
Zend Eclipse PDTPDT 3.0.2 w/Eclipse Indigo(ZIP) 92.61 MBN/A
Studio Web Debugger20110410(ZIP) 2.16 MBInstallation Guide