【问题标题】:prevent PHP object from auto-casting防止 PHP 对象自动转换
【发布时间】:2012-12-16 21:49:36
【问题描述】:
 class Foo 
{
    public $var ;

    function __construct($value) 
    {
         $this->var = $value ;
    }
}
$myFoo = new Foo('hello');
echo $myFoo->var . '<br>' ; // output : hello
// Question : how  can I prevent another programer from accidentaly doing the following
$myFoo = 4 ;
echo $myFoo ; // output : 4

我的问题在评论中 // 问题:...

我希望我的同事能够仅使用 $myFoo->var(或 Foo 类中可用的任何公共突变器)为 $myFoo 赋值)

谢谢

编辑: 对于声称不可能的用户,SPL_Types PECL 扩展能够(在一定程度上)实现这一点,例如 http://php.net/manual/en/class.splint.phphttp://blog.felixdv.com/2008/01/09/spl_types-in-php-and-strong-typing/

【问题讨论】:

  • 你不能,但是你可以在需要使用它时检查变量类型,如果它不是你所期望的,则抛出异常/错误。您在示例中并没有真正重铸,而是为变量分配了一个新值。
  • 你做不到。只有使用= 运算符离开时才能完成。
  • 要么编写自己的 IDE,要么确保与聪明人合作。
  • 关于 SPL 设法做到这一点...来自示例:$int = new SplInt(94);。是什么让程序员不写$int = new SplInt(1234); 之后?无论哪种方式,这是一个扩展,它改变了语言的行为以添加诸如类型安全之类的东西。首先,它改变语言,这不能在语言本身内完成。其次,它不提供常量。第三,程序员需要明确地使用这个,你不能强迫他。同样,您不能在创建值时强制分配给变量的值是常量(这适用于所有语言)。
  • SPL_Types 是 PHP 语言的扩展。它是实验性的。如果没有这种疯狂的打字机制,PHP 就已经够糟糕了。如果您想要强类型,请使用 Java/Tomcat 或类似的。

标签: php object casting


【解决方案1】:

你不能在任何弱类型语言中做到这一点。如果你有将这个变量作为参数的函数,你可以在 PHP 中使用类型提示,否则你不能阻止人们重新分配他们的变量。

即使对于强类型语言也是如此。如果程序员创建了一个类的两个实例,则没有机制可以阻止他们将不同的实例分配给相同类型的变量。

发生这种情况的唯一方法是程序员显式使用 constants 而不是 variables(例如在 Java 中使用 final 或在 Java 中使用 val Scala 等),但无论哪种方式,您都无法控制任何语言。

【讨论】:

  • 我接受这个答案是因为它提供了一个相当实用的解决方案,经过大量谷歌搜索后,在我看来更正确的答案是编写我自己的扩展,但这会很好......不太实用: -) 谢谢你
  • @exTrace101,确实如此。这就是语言所提供的。如果您想更改语言以使其成为不同的语言,您可以为此目的编写扩展程序。
【解决方案2】:

您无法阻止更改类中的类型,但如果您将其设为受保护或私有,然后添加一个 setVariable() 方法(其中 Variable 是您的变量名称),您可以控制输入。比如:

class myClass {
    protected $integer = 0;
    public function setInteger($new_value)
    {
        if (!is_int($new_value)) {
             throw new RuntimeException('Cannot assign non-integer value to myClass::$integer');
        }
        $this->integer = $new_value;
    }
    public function getInteger()
    {
        return $this->integer;
    }
}

// Now, outside of the class, the $integer property can only be changed using setInteger()
$class = new myClass;
$class->setInteger('dog'); // Uncaught Runtime exception ...
$class->setInteger(5);
echo $class->getInteger(); // 5

该函数的另一个版本将接受字符串数字并将它们转换为整数:

    public function setInteger($new_value)
    {
        if (!is_numeric($new_value)) {
             throw new RuntimeException('Cannot assign non-integer value to myClass::$integer');
        }
        $this->integer = (int) $new_value;
    }
$class->setInteger('5'); // 5

【讨论】:

  • 如果添加 $class= 'hello' ;在 $class->setInteger(); 之后你的 $class 对象突然变成了一个字符串
  • @exTrace101,适用于所有弱类型语言。 IDE 可能会警告您,但语言不会。您可以将任何值重新分配给变量这一事实是弱类型语言的一个特性,正如强类型语言的一个特性相反。实验性的 SPL_Types 扩展为弱类型语言 PHP 添加了一些强类型特性。
  • @exTrace101 那是 PHP,它不是为强类型设计的
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-22
  • 2020-08-15
  • 1970-01-01
  • 1970-01-01
  • 2018-08-15
  • 1970-01-01
相关资源
最近更新 更多