PHP投射到我的班级

Sex*_*yMF 8 php casting

为什么这是不可能的:

$user = (User) $u[0];
Run Code Online (Sandbox Code Playgroud)

但这是可能的

$bool = (boolean) $res['success'];
Run Code Online (Sandbox Code Playgroud)

我使用PHP 7.0.

Sza*_*áll 12

如果您只想确保变量是 YourClass 的实例并让异常处理到类型系统,您可以使用以下函数:

function implicitFakeCast($myClass): YourClass
{
    return $myClass;
}
Run Code Online (Sandbox Code Playgroud)

注意:这实际上不会进行任何转换,而是在类不匹配的情况下抛出异常,并让智能感知将其视为目标类的实例。

  • 完全同意,实际上,将意外的类作为函数/方法的返回值可能与尝试强制转换不可强制转换一样异常。 (4认同)
  • 异常应该用于处理在**异常**情况下发生的**异常**,而不是作为程序逻辑或执行测试的常规方法。 (3认同)
  • 具有类型错误的代码当然应该被视为“异常”。 (2认同)

Jar*_*sto 9

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

(int), (integer) - cast to integer
(bool), (boolean) - cast to boolean
(float), (double), (real) - cast to float
(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)
Run Code Online (Sandbox Code Playgroud)

(参见类型转换)

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

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


小智 9

您可以使用 PHPDoc

/** @var User $user */
$user = $u[0];
Run Code Online (Sandbox Code Playgroud)

  • 是的,在 PHP 中转换为类仅在用于 IDE 自动完成/建议时才具有其目的。所以 PHPDoc 是正确的选择。您甚至可以通过仅编写 /** @var User */ 而不使用变量名来简化它。 (3认同)
  • 这是假设您只是尝试添加静态分析的类型提示。运行时强制转换/断言对于防止错误更有用,如果您使用的是半途而废的静态分析工具,则运行时强制转换/断言本质上会带来“编译时”信息。 (2认同)

Ger*_*rci 8

在 php8 中这非常简单:

 $item = (fn($item):YourClass=>$item)($item);
Run Code Online (Sandbox Code Playgroud)

  • 是的,这就是重点!但是,它确保您的实例是“YourClass”,并且作为副作用,IDE(phpstorm)会知道它......(没有任何丑陋的注释......)。这与上面 @szabolcs-páll 提供的解决方案几乎相同,但使用 php8 箭头函数,作为内联解决方案...... (3认同)
  • 如果 `$item` 是 `YourClass` 的实例,此代码不执行任何操作,否则将引发类型错误。 (2认同)

Ken*_*Ken 6

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

特尔;博士:

// 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 )
    )
)
Run Code Online (Sandbox Code Playgroud)

  • 多么肮脏的黑客啊!喜欢这个 :) (4认同)