检查方法中的方法是否存在或不为空

Check method in method exists or is not null

有没有更好的方法用更少的代码行检查所有这些?

        if (
            $item->getProduct() !== null
            && $item->getProduct()->getMedia() !== null
            && $item->getProduct()->getMedia()->count()
            && $item->getProduct()->getMedia()->first() !== null
            && $item->getProduct()->getMedia()->first()->getMedia()
        ) {
            $imageUrl = $item->getProduct()->getMedia()->first()->getMedia()->getUrl();

在 PHP 8.0 中,有一个新的“nullsafe 运算符”,拼写为 ?-> 正是为了这个目的:它仅在值不为 null 时调用该方法。

如果不能做的唯一部分是对 ->count() 的额外检查,但只要 ->first() return 为 null 而不是空集上的错误,这可行:

$imageUrl = $item?->getProduct()?->getMedia()?->first()?->getMedia()?->getUrl();

除非并且直到您可以升级到 PHP 8,否则最好的办法是首先寻找改进 API 的方法来避免此问题。根据 Law of Demeter,你可以定义额外的方法,这样你就可以这样写:

$imageUrl = $item->hasProductMedia() ? $item->getProductMedia()->first()->getUrl() : null;

hasProductMedia()getProductMedia() 的实现仍然需要这些检查,但它们被隐藏起来而不是在您每次需要访问它时写入。

另一种方法是“空对象模式”(向 Markus Zeller 致敬,以便在评论中提及这一点)。每个方法 return 不是 return 空值,而是一个满足正确接口的特殊“空对象”。

所以 $item->getProduct() 永远不会 return null,但可能 return 一个 NullProduct;调用 getMedia() 或任何没有任何媒体的产品,将 return 一个 EmptyMediaList;等等。最终,你会在 NullMediaItem 上调用 getUrl(),它会给你一个空值。