(最初は)何がしたい
staticメソッドの集合のクラスで、スクリプトの最後に処理を実行したい。
≒static function __destruct()
を使いたい。
参照元
php - How to emulate __destruct() in a static class? - Stack Overflow
(コード以外ほとんど読んでない…)
class ConfigDestructor
{
public function __destruct()
{
Config::destruct();
}
}
class Config
{
static private $destructorInstance;
static private $autoSave;
static public function get() {} /* set(), save(), load(), etc. */
static public function init($autoSave)
{
if (null === self::$destructorInstance)
self::$destructorInstance = new ConfigDestructor();
self::$autoSave = $autoSave;
}
static public function destruct()
{
if (self::$autoSave)
self::save();
}
}
この方法でやりたいことは満たせた。
# 気になる点
`__destruct()`を呼び出すために一つクラスを新設している点。
話は逸れるが、クラス内で使う(一行継承)例外クラスの記述をそのクラスファイル内でするのは、クラス名とファイル名が対応しているという原則っぽいものに触れないか?という点と似通う。
別ファイルに分けるにも大げさ過ぎるので、指針がほしいが、今回は置く。
# どうしようと思ったか
読んだ当初はPHP7に上げたら無名クラスで代用してやる…と思っていた。
# どうしたのか
PHP7には上がらない。
最近久しぶりに使いたくて見たら、これ自分自身のシングルトンで収まらないか?と気になった。
staticの`__destruct`を別のクラスで呼び出すぐらいなら、自分のインスタンスを作ってもいいのでは?PHPはクラス全体がstaticには出来ないのだし…
```php
<?php
class Config
{
private static $config;
public static function init() {
if (!static::$config) {
static::$config = new self();
}
}
private static function destruct() {
echo "static\n";
}
public function __destruct() {
echo "destruct\n";
self::destruct();
}
}
Config::init();
予期どおり
destruct
static
が出力されるが、何か落とし穴があるのかなーと悩み中。
そもそもどうしてこんなことに…
べた書きと関数のスクリプトファイルに1塊の所々に挟まる処理を追加することになった。
とりあえず新設の処理なので、状態を持つしそのファイル内だけで使うクラスにしてメソッドで処理を書いていたが、使う段になって使いにくいことに気づく。
たくさんの関数の引数にインスタンスを新たに渡さなくてはならないことがまず大変。
また、既存の返り値をインスタンスを含めた配列に変換するのが酷。
(引数で渡したインスタンスの、関数内での変更は呼び出し元でも副作用的に継続するものの、その動きが気に入らない)
仕方ないのでstaticおじさんになり、引数と返り値の悩みから開放されたが、__destruct()
でやる予定の処理の扱いに困り上記の記事へたどり着く。
今回の場合はregister_shutdown_function
でも構わないのだが、クラスを飛び出す感じが嫌だし、条件を満たした場合に終了時処理を登録する都合、
登録済みかどうかのフラグを持つぐらいならシングルトンでいいんじゃないかなと思った次第。