PHP で構造体クラスをエミュレートする方法はありますか? つまり、参照渡しではなく値渡しのクラスであるため、タイプヒントを使用できます...
もしそうなら、どのような異なるテクニックを使用できますか? 最高のテクニックは何ですか?
これが可能であれば、明らかに PHP 用の完全にタイプ セーフなレイヤーを作成できますが、そのようなレイヤーはありますか? 誰もこれを経験したことがありますか?
PHP で構造体クラスをエミュレートする方法はありますか? つまり、参照渡しではなく値渡しのクラスであるため、タイプヒントを使用できます...
もしそうなら、どのような異なるテクニックを使用できますか? 最高のテクニックは何ですか?
これが可能であれば、明らかに PHP 用の完全にタイプ セーフなレイヤーを作成できますが、そのようなレイヤーはありますか? 誰もこれを経験したことがありますか?
PHPコードだけで、その目標を達成できるとは思いません。
PHP関数がパラメーターを処理する方法を制御することはできません。また、PHPバイナリおよびモジュールの(下位レベルの)コードを変更せずに、すべてが希望どおりに処理されることを確認する方法がわかりません。
それはかなりクールでしょうが:)
オブジェクトは常に参照によって渡されます。それらをコピーとして渡す唯一の方法は、clone
キーワードを明示的に使用することです(はい、どこでも)。
私の推奨は、値型であるため常にコピーされる配列を使用することです。連想配列(文字列->値など)として使用できるため、オブジェクトである可能性もあります。欠点は、もちろん、メソッドを使用できないことです(ただし、これは構造体のようなものなので、これに満足する可能性があります)。ただし、型安全性を強制する方法はありません。
しかし、すべての要件を考慮すると、正直なところ、PHPはあなたの種類の言語ではないように思えます。
オブジェクトの突然変異が新しいオブジェクトを返すようにするという匿名の提案で遊んでいましたが、これは機能しますが、厄介です。
<?php
class FruityEnum {
private $valid = array("apple", "banana", "cantaloupe");
private $value;
function __construct($val) {
if (in_array($val, $this->valid)) {
$this->value = $val;
} else {
throw new Exception("Invalid value");
}
}
function __set($var, $val) {
throw new Exception("Use set()!!");
}
function set(FruityEnum &$obj, $val) {
$obj = new FruityEnum($val);
}
function __get($var) { //everything returns the value...
return $this->value;
}
function __toString() {
return $this->value;
}
}
そして今それをテストするために:
function mutate(FruityEnum $obj) { // type hinting!
$obj->set($obj, 'banana');
return $obj;
}
$x = new FruityEnum('apple');
echo $x; // "apple"
$y = mutate($x);
echo $x // still "apple"
. $y // "banana"
それは機能しますが、オブジェクトを変更するには奇妙な方法を使用する必要があります。
$obj->set($obj, 'foo');
私がそれを行うと考えることができる他の唯一の方法は、その__set()
方法を使用することでしたが、それはさらにひどいものでした。あなたはこれをしなければなりませんでした、それは血まみれの混乱です。
$obj = $obj->blah = 'foo';
結局、変数をプライベートにし、ミューテーターを提供しない方がおそらく簡単なので、変数の「列挙型」値を変更する唯一の方法は、新しい値を作成することです。
echo $obj; // "banana"
$obj = new FruityEnum("cantaloupe");
最も簡単な方法は、Java のように行うことだと思います。値クラスを不変にし、代わりにすべての「変更」メソッドが新しいオブジェクトを返すようにします。