PHPのclassで外部アクセスを禁止するようなセキュアな構造を作って、脆弱性対応を行う場合は、非常にしっかりした構造をしなければいけませんが、基本的にpublicでOKというような構成の場合は、できるだけアクセスしやすいような構造にする必要があります。
同じclass内で変数参照したい場合、$thisを使う時とself::とする場合で、制限が違うようなので、少し調べてみました。
また、別classや、classの外部から参照する場合などの設計時に気をつけなければいけない点を調査しておきました。
wordpressやPHPの独自フレームワーク構築の際に役立ててください。
Class内部での変数参照
<?php
class Foo{
public $val1 = "OK";
static $val2 = "OK";
public static $val3 = "OK";
var $val4 = "OK";
function __construct(){
echo "this / puclic : ".$this->val1.PHP_EOL;
echo "this / static : ".$this->val2.PHP_EOL;
echo "this / public static : ".$this->val3.PHP_EOL;
echo "this / var : ".$this->val4.PHP_EOL;
echo "--".PHP_EOL;
//echo "self / puclic : ".self::$val1.PHP_EOL;
echo "self / static : ".self::$val2.PHP_EOL;
echo "self / public static : ".self::$val3.PHP_EOL;
//echo "self / var : ".self::$val4.PHP_EOL;
echo "--".PHP_EOL;
}
}
new Foo;
【注意!】self::でstatic以外にアクセスすると、PHPがErrorで停止してしまうので、コメントアウトしてます。
$thisの場合は、アクセスできなくてもwarningレベルみたいです。
結果
this / puclic : OK
this / static :
this / public static :
this / var : OK
--
self / static : OK
self / public static : OK
--
class内でself::アクセスする場合は、staticがついていないとダメなんですね。
逆に$thisアクセスはstaticがついているとダメという非常に面倒くさい感じです。
以下のようにマトリクスにしておきます。
Class内の変数アクセス |
| $this | self:: |
public | ◯ | |
static | | ◯ |
public static | | ◯ |
var | ◯ | |
Class外部からのアクセス(変数)
<?php
class Foo{
public $val1 = "OK";
static $val2 = "OK";
public static $val3 = "OK";
var $val4 = "OK";
}
$foo = new Foo;
echo "foo -> puclic : ".$foo->val1.PHP_EOL;
echo "foo -> static : ".$foo->val2.PHP_EOL;
echo "foo -> public static : ".$foo->val3.PHP_EOL;
echo "foo -> var : ".$foo->val4.PHP_EOL;
echo "--".PHP_EOL;
//echo "foo :: puclic : ".$foo::$val1.PHP_EOL;
echo "foo :: static : ".$foo::$val2.PHP_EOL;
echo "foo :: public static : ".$foo::$val3.PHP_EOL;
//echo "foo :: var : ".$foo::$val4.PHP_EOL;
echo "--".PHP_EOL;
//echo "Foo / puclic : ".$foo::$val1.PHP_EOL;
echo "Foo / static : ".Foo::$val2.PHP_EOL;
echo "Foo / public static : ".Foo::$val3.PHP_EOL;
//echo "Foo / var : ".$foo::$val4.PHP_EOL;
echo "--".PHP_EOL;
結果
foo -> puclic : OK
foo -> static :
foo -> public static :
foo -> var : OK
--
foo :: static : OK
foo :: public static : OK
--
Foo / static : OK
Foo / public static : OK
--
内部と同じなので想定通りの結果ですね。
new宣言するしないのパターンを追加してみましたが、ここでの差分はなさそうです。
Class外からの変数アクセス |
| $foo-> | $foo:: | Foo:: |
public | ◯ | | |
static | | ◯ | ◯ |
public static | | ◯ | ◯ |
var | ◯ | | |
Class外部からのアクセス(関数)
<?php
class Foo{
function res1(){
return "OK";
}
public function res2(){
return "OK";
}
static function res3(){
return "OK";
}
public static function res4(){
return "OK";
}
}
$foo = new Foo;
echo "foo -> function : ".$foo->res1().PHP_EOL;
echo "foo -> public : ".$foo->res2().PHP_EOL;
echo "foo -> static : ".$foo->res3().PHP_EOL;
echo "foo -> public static : ".$foo->res4().PHP_EOL;
echo "--".PHP_EOL;
echo "foo :: function : ".$foo::res1().PHP_EOL;
echo "foo :: public : ".$foo::res2().PHP_EOL;
echo "foo :: static : ".$foo::res3().PHP_EOL;
echo "foo :: public static : ".$foo::res4().PHP_EOL;
echo "--".PHP_EOL;
echo "Foo / function : ".Foo::res1().PHP_EOL;
echo "Foo / public : ".Foo::res2().PHP_EOL;
echo "Foo / static : ".Foo::res3().PHP_EOL;
echo "Foo / public static : ".Foo::res4().PHP_EOL;
echo "--".PHP_EOL;
結果
foo -> function : OK
foo -> public : OK
foo -> static : OK
foo -> public static : OK
--
foo :: function : OK
foo :: public : OK
foo :: static : OK
foo :: public static : OK
--
Foo / function : OK
Foo / public : OK
Foo / static : OK
Foo / public static : OK
--
外部からのアクセスは、どのパターンにもアクセスできるようです。
変数と同じになるようにイメージしてたんですが、扱いが違うのが少し戸惑いますね。
Class外からの関数アクセス |
| $foo-> | $foo:: | Foo:: |
function | ◯ | ◯ | ◯ |
public | ◯ | ◯ | ◯ |
static | ◯ | ◯ | ◯ |
public static | ◯ | ◯ | ◯ |
Class外部からの関数アクセスして、変数を返す
<?php
class Foo{
public $val1 = "OK";
static $val2 = "OK";
public static $val3 = "OK";
var $val4 = "OK";
function res1(){
$data = "";
$data.= "public : ". (isset($this->val1) ? $this->val1 : "NG") ."\n";
$data.= "static : ". (isset($this->val2) ? $this->val2 : "NG") ."\n";
$data.= "public static : ". (isset($this->val3) ? $this->val3 : "NG") ."\n";
$data.= "var : ". (isset($this->val4) ? $this->val4 : "NG") ."\n";
return $data;
}
public function res2(){
$data = "";
$data.= "public : ". (isset($this->val1) ? $this->val1 : "NG") ."\n";
$data.= "static : ". (isset($this->val2) ? $this->val2 : "NG") ."\n";
$data.= "public static : ". (isset($this->val3) ? $this->val3 : "NG") ."\n";
$data.= "var : ". (isset($this->val4) ? $this->val4 : "NG") ."\n";
return $data;
}
static function res3(){
$data = "";
$data.= "public : ". (isset($this->val1) ? $this->val1 : "NG") ."\n";
$data.= "static : ". (isset($this->val2) ? $this->val2 : "NG") ."\n";
$data.= "public static : ". (isset($this->val3) ? $this->val3 : "NG") ."\n";
$data.= "var : ". (isset($this->val4) ? $this->val4 : "NG") ."\n";
return $data;
}
public static function res4(){
$data = "";
$data.= "public : ". (isset($this->val1) ? $this->val1 : "NG") ."\n";
$data.= "static : ". (isset($this->val2) ? $this->val2 : "NG") ."\n";
$data.= "public static : ". (isset($this->val3) ? $this->val3 : "NG") ."\n";
$data.= "var : ". (isset($this->val4) ? $this->val4 : "NG") ."\n";
return $data;
}
}
$foo = new Foo;
echo "-- foo -> res1() --".PHP_EOL;
echo (method_exists($foo,"res1") ? $foo->res1() : "").PHP_EOL;
echo "-- foo -> res2() --".PHP_EOL;
echo (method_exists($foo,"res2") ? $foo->res2() : "").PHP_EOL;
echo "-- foo -> res3() --".PHP_EOL;
echo (method_exists($foo->res3) ? $foo->res3() : "").PHP_EOL;
echo "-- foo -> res4() --".PHP_EOL;
echo (method_exists($foo->res4) ? $foo->res4() : "").PHP_EOL;
結果
-- foo -> res1() --
public : OK
static : NG
public static : NG
var : OK
-- foo -> res2() --
public : OK
static : NG
public static : NG
var : OK
-- foo -> res3() --
-- foo -> res4() --
function事態のアクセスは上記検証で問題ないはずなのですが、内部変数にアクセスする箇所でトラブルが発生するようだ。
問題なくアクセスできたのは、結果の通りなので、内部変数へのアクセスは不具合の元になる可能性が高いですね。
Class外からの関数経由での変数アクセス ($foo->**) |
変数 / 関数 | function | public | static | public static |
public | ◯ | ◯ | -- | -- |
static | ☓ | ☓ | -- | -- |
public static | ☓ | ☓ | -- | -- |
var | ◯ | ◯ | -- | -- |
今後もう少し調べてみたいと思います。
今回はこの辺まで。
0 件のコメント:
コメントを投稿