PHP类的隐式类型转换?

时间:2009-06-30 20:53:20

标签: php types

有没有办法告诉php编译器我想从一种类型到另一种类型的特定隐式转换?

一个简单的例子:

class Integer
{
  public $val;
}

function ExampleFunc(Interger $i){...}

ExamFunc(333); // 333 -> Integer object with $val == 333.

[编辑] ...有人问了一个例子。这是c#的一个例子。这是一个布尔类型,在访问一次后更改值。

    /// <summary>
    /// A Heisenberg style boolean that changes after it has been read. Defaults to false.
    /// </summary>
    public class hbool
    {
        private bool value;
        private bool changed = false;

        public hbool()
        {
            value = false;
        }

        public hbool(bool value)
        {
            this.value = value;
        }

        public static implicit operator bool(hbool item)
        {
            return item.Value;
        }

        public static implicit operator hbool(bool item)
        {
            return new hbool(item);
        }

        public bool Value
        {
            get
            {
                if (!changed)
                {
                    value = !value;
                    changed = true;
                    return !value;
                }
                return value;
            }
        }

        public void TouchValue()
        {
            bool value1 = Value;
        }

        public static hbool False
        {
            get { return new hbool(); }
        }

        public static hbool True
        {
            get { return new hbool(true); }
        }
    }

        [Test]
        public void hboolShouldChangeAfterRead()
        {
            hbool b = false;
            Assert.IsFalse(b);
            Assert.IsTrue(b);
            Assert.IsTrue(b);
            hbool b1 = false;
            Assert.IsFalse(b1);
            Assert.IsTrue(b1);
            Assert.IsTrue(b1);
            hbool b2 = true;
            Assert.IsTrue(b2);
            Assert.IsFalse(b2);
            Assert.IsFalse(b2);
            bool b3 = new hbool();
            Assert.IsFalse(b3);
            Assert.IsFalse(b3);
            Assert.IsFalse(b3);
        }

7 个答案:

答案 0 :(得分:3)

PHP5具有类型提示,但有以下限制: http://ca2.php.net/manual/en/language.oop5.typehinting.php

指定的类型必须是对象或数组,因此不允许内置类型,例如 string int

这不是转换,但如果未将指定类型的对象传递给方法或函数,则会抛出错误,如示例所示。

答案 1 :(得分:2)

答案很长:

我认为在这种情况下PHP很难(不可能)进行隐式转换。

请记住:你调用你的类Integer的事实是对代码的人类读者的暗示,PHP不明白它实际上用于保存整数。此外,它有一个名为$ val的属性的事实是一个人类读者提示它应该包含整数的值。 PHP不会理解你的代码,它只会执行它。

在您的代码中的某个时刻,您应该进行显式转换。有可能PHP有一些很好的syntactig糖,但第一次尝试将是这样的:

class Integer
{
  public $val;

  function __construct($val) { $this->val = $val; }
}

function ExampleFunc($i){
    if (is_numeric($i)) { $iObj = new Integer($i); }
    ...
}

ExamFunc(333); // 333 -> Integer object with $val === 333.

这并不像你想要的那么酷,但同样,PHP可能会有一些语法糖,它会或多或少地隐藏显式转换。

简短版:

以这种或那种方式,您需要显式转换

答案 2 :(得分:1)

实际上这可能与SPL_Type extension有关。它定义了原始类型的类,其对象与PHP的原始类型(布尔值,枚举,整数,浮点数和字符串)可互换地操作。

您首先通过简单地从SplIt继承示例,如下所示:

class Integer extends extends \SplInt{}

function ExampleFunc(Interger $i){...}

ExamFunc(333); // 333 -> Integer object with $val == 333.

问题是code of the SplTypes extension自2012年以来一直没有得到维护,到目前为止,它还没有移植到PHP 7,也没有这样的计划。

<强>更新 我发现以下非正式的SPL类型端口到PHP 7.使用风险由您自己承担:https://github.com/esminis/php_pecl_spl_types

基本安装说明:

  1. 克隆代码:https://github.com/esminis/php_pecl_spl_types.git
  2. 生成 configure 文件。在代码目录中输入:phpize
  3. 生成make文件:./configure
  4. 编译代码并安装:make && make install
  5. 将模块添加到PHP配置中。在Ubuntu,输入echo "extension=spl_types.so" > /etc/php7/conf.d/spl_types.ini
  6. 重新启动PHP-FPM(如果使用它):service php7.0-fpm restart

答案 3 :(得分:0)

不,PHP不是强类型语言。

答案 4 :(得分:0)

您是否在询问如何输入演员?你可以这样做:

$ php -r 'var_dump("333");'
string(3) "333"
$ php -r 'var_dump((int)"333");'
int(333)

否则PHP是弱类型的,所以通常你不需要这样做。它隐含在语言中。例如。如果函数采用数字参数,则该数字可以是字符串,整数或浮点数;如果需要,将转换该值。这就是为什么你可以例如echo 33没有错误。

答案 5 :(得分:0)

PHP没有强类型。

每当你将一个hbool实例传递给一个期望bool它会使用你的隐式转换自动转换的函数时,你想要类似的东西。

发生的事情是没有任何功能“期望”一个bool,它都是动态输入的。 您可以通过调用(int)$something强制进行显式转换,但如果是这种情况,则可以通过$something->to_otherthing()代替非自动转换。

PS:我确定我不清楚这里。吃完之后我会尝试编辑这个答案:)

答案 6 :(得分:0)

这个问题很老,但我想提出一个解决方案。 这种行为称为拳击,可以在PHP中完成,但与此相反,取消装箱请参阅:

function a(int $a){...}

a(new Integer(1));
目前无法

。如果你想要一个为你提供此功能的框架,请查看具有此类包装类的BlazeFramework

操作重载在php中无效。实现可能有点太多了,但我给你一个提示! PHP使用set_error_handler()调用回调集,错误级别为E_RECOVERABLE_ERRORdebug_backtrace()提供有关函数/方法调用的信息。

如果你没有这样做,请查看方法blaze\lang\System#systemErrorHandler()的实现,但如果你想要更多这样的功能,最好只使用框架。