Php 更优雅的方式写这些条件?

Php 更优雅的方式写这些条件?,php,Php,出于好奇,我想知道是否有更优雅的方式来写下面的条件句?我看不到一个较短的写作方式,但它感觉相当笨拙,所以欢迎任何建议 // Check whether this page has any visuals if (count($this->page->pagevisuals->find_all()) > 0) { // Ok to go ahead and assign $vis

出于好奇,我想知道是否有更优雅的方式来写下面的条件句?我看不到一个较短的写作方式,但它感觉相当笨拙,所以欢迎任何建议

        // Check whether this page has any visuals
        if (count($this->page->pagevisuals->find_all()) > 0)
        {
            // Ok to go ahead and assign
            $visual = $this->page->pagevisuals->find_all();
        }
        // If this is a sub page, parent page may have visuals we can use
        elseif (count($this->page->parent->pagevisuals->find_all()) > 0)
        {
             $visual = $this->page->parent->pagevisuals->find_all();
        }
        // If two levels deep, grandparent page might have visuals
        elseif (count($this->page->parent->parent->pagevisuals->find_all()) > 0)
        {
            $visual = $this->page->parent->parent->pagevisuals->find_all();
        }
如果它们都不匹配,你怎么办?在这段代码中,它将被设置为最后一个,这与您所做的不同。(在您的代码中,如果不匹配,则未触及$visual,在此代码中,它将设置为零。您可以添加
或$visual=-1
或类似内容。)

如果你想避免所有的->父项,你可以做一个循环,但是你需要一些终止符

$el = $this->page;
while(!$visual = $el->pagevisuals->find_all()) {
  $el = $el->parent;
}

如果它不匹配,这可能会永远运行,但我对您的应用程序了解不够,无法建议终止条件-您可以添加计数器或其他内容。

您可以将
$This->page
分配给一个变量,并以该变量开始语句,以获得非常轻微的改进


或者,您可以创建嵌套的三元语句来分配
$visual
,但这肯定不是推荐的做法。

您可以编写一个循环:

$page = $this->page;
$visual = null;
while (!$visual && $page) {
    $visual = $page->pagevisuals->find_all();
    $page = $page->parent;
}
我相信这是等效的,并且无论您有多少级别的父级/嵌套,它都会起作用。

递归方法:

function getVisuals($root) {
    $visuals = $root->pagevisuals->find_all();
    if(count($visuals) === 0 && isset($root->parent)) {
        $visuals = getVisuals($root->parent);
    }
    return $visuals;
}

$visuals = getVisuals($this->page);

如果您可以控制任何类
$this->page
是的实例,那么您可以将其作为一个实例方法。

您可以创建一个递归方法来摆脱这些讨厌的条件。此外,您还为每个条件分支调用了两次find_all()方法,这将使处理时间加倍

下面是一个递归函数的尝试(虽然可能不起作用,但递归函数总是有点棘手!)。小心无限循环

<?php
$visual = $this->page->find_all_visuals();

class Page {
    function find_all_visuals()
    {
        $found = $this->pagevisuals->find_all();

        if (count($found) > 0) {
            return $found;
        } else if ($this->parent == null) {
            return null;
        } else {
            return $this->parent->find_all_visuals();
        }
    }
}
?>

您可能需要对代码进行两项更改:

  • 如果没有视觉效果,请确保getVisuals()返回空数组,而不是null
  • 考虑创建一个空对象—一个没有视觉效果且自身作为父对象的单例页面实例。它可能有一个类似isNull()的方法,因此您可以轻松地测试给定页面是否为null页面
  • 如果您进行了这两项调整,那么大多数与视觉效果相关的代码将更易于编写和调试

    获取两个级别的所有视觉效果(我假设您不希望递归):

    获取页面、父级或父级的视觉效果:

       ($visuals = $this->page->pagevisuals->find_all()) ||
       ($visuals = $this->page->parent->pagevisuals->find_all()) ||
       ($visuals = $this->page->parent->parent->pagevisuals->find_all());
    
    递归函数也会简单得多(这是一种添加到页面对象的方法):


    这不是更具可读性,它主要只是一个压缩版本。
    $visuals = array_merge(
        $this->page->pagevisuals->find_all(),
        $this->page->parent->pagevisuals->find_all(),
        $this->page->parent->parent->pagevisuals->find_all(),
    );
    
       ($visuals = $this->page->pagevisuals->find_all()) ||
       ($visuals = $this->page->parent->pagevisuals->find_all()) ||
       ($visuals = $this->page->parent->parent->pagevisuals->find_all());
    
    public function findRecursive(){
        $my_visuals = $this->pagevisuals->find_all()
        return $this->parent->isNull()?
                   $my_visuals
                   : array_merge($my_visuals, $this->parent->findRecursive());
    }