gallu’s blog

エンジニアでゲーマーで講師で占い師なおいちゃんのブログです。

「知らないものはもらわない」っていう安全のために

ん…うん知ってはいたのですが、以下のコードは、大変に憂慮すべき動作をします。PHP君は。

<?php

// エラー出力制御
ini_set('display_errors', 'on');
error_reporting(E_ALL);

class hoge {
};

$obj = new hoge();
$obj->aaa = 10;
var_dump($obj);

$ php t.php
object(hoge)#1 (1) {
["aaa"]=>
int(10)
}

なんだろうねぇ普通に考えたら「エラー」とか、せめても「警告」とか出てくれりゃよいのですが。


まぁこれがあるので「そもそも、プロパティは雪駄下駄以外では触らない」という流儀を「鉄の掟」としているのですが。
とはいえ、な状況で、これを防ぐ事は果たしてできるのだろうか? と、ちょいと思案したです。


初手に考えたのは__setマジックメソッド…なんだけど、嫌な予感。
早速確認。
http://www.php.net/manual/ja/language.oop5.overloading.php#object.set

__set() は、 アクセス不能プロパティへデータを書き込む際に実行されます。

だ〜よ〜ね〜。「存在しない」であって「アクセス不能」じゃないんだよねぇ…とか思いつつ、念のため実験コード。

<?php

// エラー出力制御
ini_set('display_errors', 'on');
error_reporting(E_ALL);

class hoge {

public function __set($name, $val) {
  echo "set {$name} -> {$val}\n";
}

};

$obj = new hoge();
$obj->aaa = 10;
var_dump($obj);

$ php t.php
set aaa -> 10
object(hoge)#1 (0) {
}

あ、いけた。


むぅ…これかなぁ。
単純に処理潰すなら__set書くだけ書いて空っぽ、でもいいし。
もうちょっと「ゴリっと」したければ、throwぶん投げてもいいし。


少し、この辺の「安全に書けるナレッジ」を、今年は貯めていきたいなぁ、って思う。