在PHP中模拟值类型结构类

在PHP中模拟值类型结构类,php,types,structure,type-safety,Php,Types,Structure,Type Safety,有没有办法在PHP中模拟结构类?ie是一个通过值而不是引用传递的类,所以它仍然可以被类型暗示 如果是这样,可以使用哪些不同的技术?最好的技术是什么 如果这是可能的,您显然可以为PHP创建一个完全类型安全的层,有这样的层吗?有人有过这样的经验吗?我认为最简单的方法是像java那样做——让您的值类不可变,让所有“修改”方法返回一个新对象。我认为只有使用PHP代码才能实现这一目标 您无法控制PHP函数如何处理参数,我也不知道您如何确保一切都按您想要的方式处理,而不必更改PHP二进制和模块中的(低级)代

有没有办法在PHP中模拟结构类?ie是一个通过值而不是引用传递的类,所以它仍然可以被类型暗示

如果是这样,可以使用哪些不同的技术?最好的技术是什么


如果这是可能的,您显然可以为PHP创建一个完全类型安全的层,有这样的层吗?有人有过这样的经验吗?

我认为最简单的方法是像java那样做——让您的值类不可变,让所有“修改”方法返回一个新对象。

我认为只有使用PHP代码才能实现这一目标

您无法控制PHP函数如何处理参数,我也不知道您如何确保一切都按您想要的方式处理,而不必更改PHP二进制和模块中的(低级)代码


不过,这会很酷:)

对象总是通过引用传递的。让它们作为副本传递的唯一方法是显式使用
clone
关键字(是的,无处不在)

我的建议是使用数组,数组是值类型,因此总是被复制的。因为您可以将其用作关联数组(例如字符串->值),所以它也可以是一个对象。当然,缺点是不能使用方法(但这就像一个结构,所以您可能会对此感到满意)。但是,没有办法强制执行类型安全性


但是,老实说,根据您的所有要求,PHP听起来似乎不是您喜欢的语言。

我一直在玩弄anonymous的建议,让对象的任何变化都返回一个新对象,这是可行的,但很尴尬

<?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;
    }
}
它可以工作,但您必须使用一种奇怪的方式来更改对象:

$obj->set($obj, 'foo');
我能想到的唯一其他方法是使用
\uu set()
方法,但那更糟糕。你必须这么做,这让人很困惑

$obj = $obj->blah = 'foo';
最后,可能更容易将变量设置为私有,并且不提供任何变体,因此更改变量“enum”值的唯一方法是创建一个新的变量:

echo $obj; // "banana"
$obj = new FruityEnum("cantaloupe");

如果将其传递给函数,如何确保它传递的是副本而不是引用?或者每次你想传递克隆操作符时都必须使用它吗?它会传递一个引用,但这无关紧要——接收函数无论如何都不能修改它。换句话说,只要对象是不可变的,复制和引用之间的差异就消失了。将其放入数组可能是合理的,但是您不能再提示它了。。。你可以输入一个数组,但那不再是类型安全的了。。。恶性循环。。。我使用php已经有相当长的时间了,越来越多的我开始错过诸如类型安全之类的东西…很好的实验,尽管它产生的开销和使用克隆操作符一样多+1.
echo $obj; // "banana"
$obj = new FruityEnum("cantaloupe");