PHP强制转换到我的类

fslejnso  于 2022-12-17  发布在  PHP
关注(0)|答案(7)|浏览(116)

为什么这是不可能的:

$user = (User) $u[0];

但这是可能的

$bool = (boolean) $res['success'];

我使用PHP 7.0.

olmpazwi

olmpazwi1#

据我所知,在PHP中只能强制转换为某些类型:

(int), (integer) - cast to integer
(bool), (boolean) - cast to boolean
(float), (double), (real) - cast to float  (real deprecated in PHP 8.0)
(string) - cast to string
(binary) - cast to binary string (PHP 6)
(array) - cast to array
(object) - cast to object
(unset) - cast to NULL (PHP 5) (depracted in PHP 7.2) (removed in 8.0)

(see Type Casting
相反,您可以使用instanceof来检查特定类型:

if($yourvar instanceof YourClass) {
    //DO something
} else {
    throw new Exception('Var is not of type YourClass');
}

编辑

正如Szabolcs Páll在他的回答中提到的,也可以声明一个return typeparameter type,但在这种情况下,如果类型不匹配,将抛出异常(TypeError)。

function test(): string
{
    return 'test';
}

function test(string $test){
    return "test" . $test;
}

从PHP 7.2开始,也可以通过在类型前面添加?来使类型可以为空:

function test(): ?string
{
    return null;
}
v6ylcynt

v6ylcynt2#

您可以使用PHPDoc

/** @var User $user */
$user = $u[0];
46scxncf

46scxncf3#

如果你只是想确保一个变量是YourClass的示例,并让异常处理交给类型系统,你可以使用下面的函数:

function implicitFakeCast($myClass): YourClass
{
    return $myClass;
}

**注意:**这实际上不会执行任何类型转换,而是在类不匹配的情况下抛出异常,并让intellisense将其视为目标类的示例。

col17t5w

col17t5w4#

对于那些确实希望能够转换为类类型的人,我发现了@borzilleri的一个要点,它使用序列化和反序列化来实现这一点:https://gist.github.com/borzilleri/960035 .

TL;DR:

// make sure to include the namespace when casting
$className = "Some\\NameSpace\\SomeClassName";
$classNameLength = strlen( $className );
$castedItem = unserialize(
    preg_replace(
        '/^O:\d+:"[^"]++"/',
        "O:$classNameLength:\"$className\"",
        serialize( $item )
    )
)
uemypmqf

uemypmqf5#

在php8中这非常简单:

$item = (fn($item):YourClass=>$item)($item);
wvmv3b1j

wvmv3b1j6#

对象和基元类型是不同的,既然叫基元类型,其实很简单,可能只有1个字节,2个字节,4个字节,最多8个字节。
当我们谈论对象时,这个对象可能与其他对象有不同的属性。那么PHP的问题将是,“这个对象真的来自我的类吗?”“如何将这个对象转换为我的类?"因此,你不能立即使用

$myObject = (ClassName) $variable

那怎么投呢?不知道,一般是这样投的:
1.创建类的构造函数
1.在类中,创建一个专门接受某些参数(可能是数组)的方法
下面是示例:

public class MyAwesomeClass{

     function __construct($thisIsArray){
         $this->attributeA = $thisIsArray["A"];
         $this->attributeB = $thisIsArray["B"];
         ......
     }

     static function fromArray($thisIsArray){
         return MyAwesomeClass($thisIsArray);
     }

}

$obj = MyAwesomeClass::fromArray($attributes);
js5cn81o

js5cn81o7#

除了回答为什么这是不可能的之外,我建议您编写一个构建器函数,它基于您的输入创建一个对象。

$user = User::buildFromSomeArrayInput($u[0]);

然后让一个构建器创建一个新的User对象,分配正确的属性,等等。当然,你可以就地完成所有这些工作,但是有一个构建器函数可以确保你不会在几个位置上做这些工作,而且你可以设置私有属性,因为它是一个类成员函数。这比让它神奇地工作要多一点工作,但不会太多,唯一的问题是当你有一个不同的对象,它没有暴露你需要的所有内部组件,但这是有原因的,因为内部组件可能会改变-〉你不想依赖它。
有一些黑客建议用序列化来做这个,我建议避开他们,因为他们是黑客,就我而言,不是很清楚。

相关问题