重构案例1 — ECShop (lib_common.php build_url 函数)

重构案例之 ECShop_V2.7.3_UTF8_release0411/upload/includes/lib_common.php 第1490行的 build_uri 函数。

重构之前的 build_url 函数有大概 400 行左右的代码,而且 switch 的条件分支里还夹杂了 if 的条件。故将 build_uri 函数试着重构成了 UriRewrite 类。

代码1 重构前的 build_url 函数代码

/**
 * 重写 URL 地址
 *
 * @access  public
 * @param   string  $app        执行程序
 * @param   array   $params     参数数组
 * @param   string  $append     附加字串
 * @param   integer $page       页数
 * @param   string  $keywords   搜索关键词字符串
 * @return  void
 */
function build_uri($app, $params, $append = '', $page = 0, $keywords = '', $size = 0)
{
    static $rewrite = NULL;

    if ($rewrite === NULL)
    {
        $rewrite = intval($GLOBALS['_CFG']['rewrite']);
    }

    $args = array('cid'   => 0,
                  'gid'   => 0,
                  'bid'   => 0,
                  'acid'  => 0,
                  'aid'   => 0,
                  'sid'   => 0,
                  'gbid'  => 0,
                  'auid'  => 0,
                  'sort'  => '',
                  'order' => '',
                );

    extract(array_merge($args, $params));

    $uri = '';
    switch ($app)
    {
        case 'category':
            if (empty($cid))
            {
                return false;
            }
            else
            {
                if ($rewrite)
                {
                    $uri = 'category-' . $cid;
                    if (isset($bid))
                    {
                        $uri .= '-b' . $bid;
                    }
                    if (isset($price_min))
                    {
                        $uri .= '-min'.$price_min;
                    }
                    if (isset($price_max))
                    {
                        $uri .= '-max'.$price_max;
                    }
                    if (isset($filter_attr))
                    {
                        $uri .= '-attr' . $filter_attr;
                    }
                    if (!empty($page))
                    {
                        $uri .= '-' . $page;
                    }
                    if (!empty($sort))
                    {
                        $uri .= '-' . $sort;
                    }
                    if (!empty($order))
                    {
                        $uri .= '-' . $order;
                    }
                }
                else
                {
                    $uri = 'category.php?id=' . $cid;
                    if (!empty($bid))
                    {
                        $uri .= '&brand=' . $bid;
                    }
                    if (isset($price_min))
                    {
                        $uri .= '&price_min=' . $price_min;
                    }
                    if (isset($price_max))
                    {
                        $uri .= '&price_max=' . $price_max;
                    }
                    if (!empty($filter_attr))
                    {
                        $uri .='&filter_attr=' . $filter_attr;
                    }

                    if (!empty($page))
                    {
                        $uri .= '&page=' . $page;
                    }
                    if (!empty($sort))
                    {
                        $uri .= '&sort=' . $sort;
                    }
                    if (!empty($order))
                    {
                        $uri .= '&order=' . $order;
                    }
                }
            }

            break;
        case 'goods':
            if (empty($gid))
            {
                return false;
            }
            else
            {
                $uri = $rewrite ? 'goods-' . $gid : 'goods.php?id=' . $gid;
            }

            break;
        case 'brand':
            if (empty($bid))
            {
                return false;
            }
            else
            {
                if ($rewrite)
                {
                    $uri = 'brand-' . $bid;
                    if (isset($cid))
                    {
                        $uri .= '-c' . $cid;
                    }
                    if (!empty($page))
                    {
                        $uri .= '-' . $page;
                    }
                    if (!empty($sort))
                    {
                        $uri .= '-' . $sort;
                    }
                    if (!empty($order))
                    {
                        $uri .= '-' . $order;
                    }
                }
                else
                {
                    $uri = 'brand.php?id=' . $bid;
                    if (!empty($cid))
                    {
                        $uri .= '&cat=' . $cid;
                    }
                    if (!empty($page))
                    {
                        $uri .= '&page=' . $page;
                    }
                    if (!empty($sort))
                    {
                        $uri .= '&sort=' . $sort;
                    }
                    if (!empty($order))
                    {
                        $uri .= '&order=' . $order;
                    }
                }
            }

            break;
        case 'article_cat':
            if (empty($acid))
            {
                return false;
            }
            else
            {
                if ($rewrite)
                {
                    $uri = 'article_cat-' . $acid;
                    if (!empty($page))
                    {
                        $uri .= '-' . $page;
                    }
                    if (!empty($sort))
                    {
                        $uri .= '-' . $sort;
                    }
                    if (!empty($order))
                    {
                        $uri .= '-' . $order;
                    }
                    if (!empty($keywords))
                    {
                        $uri .= '-' . $keywords;
                    }
                }
                else
                {
                    $uri = 'article_cat.php?id=' . $acid;
                    if (!empty($page))
                    {
                        $uri .= '&page=' . $page;
                    }
                    if (!empty($sort))
                    {
                        $uri .= '&sort=' . $sort;
                    }
                    if (!empty($order))
                    {
                        $uri .= '&order=' . $order;
                    }
                    if (!empty($keywords))
                    {
                        $uri .= '&keywords=' . $keywords;
                    }
                }
            }

            break;
        case 'article':
            if (empty($aid))
            {
                return false;
            }
            else
            {
                $uri = $rewrite ? 'article-' . $aid : 'article.php?id=' . $aid;
            }

            break;
        case 'group_buy':
            if (empty($gbid))
            {
                return false;
            }
            else
            {
                $uri = $rewrite ? 'group_buy-' . $gbid : 'group_buy.php?act=view&id=' . $gbid;
            }

            break;
        case 'auction':
            if (empty($auid))
            {
                return false;
            }
            else
            {
                $uri = $rewrite ? 'auction-' . $auid : 'auction.php?act=view&id=' . $auid;
            }

            break;
        case 'snatch':
            if (empty($sid))
            {
                return false;
            }
            else
            {
                $uri = $rewrite ? 'snatch-' . $sid : 'snatch.php?id=' . $sid;
            }

            break;
        case 'search':
            break;
        case 'exchange':
            if ($rewrite)
            {
                $uri = 'exchange-' . $cid;
                if (isset($price_min))
                {
                    $uri .= '-min'.$price_min;
                }
                if (isset($price_max))
                {
                    $uri .= '-max'.$price_max;
                }
                if (!empty($page))
                {
                    $uri .= '-' . $page;
                }
                if (!empty($sort))
                {
                    $uri .= '-' . $sort;
                }
                if (!empty($order))
                {
                    $uri .= '-' . $order;
                }
            }
            else
            {
                $uri = 'exchange.php?cat_id=' . $cid;
                if (isset($price_min))
                {
                    $uri .= '&integral_min=' . $price_min;
                }
                if (isset($price_max))
                {
                    $uri .= '&integral_max=' . $price_max;
                }

                if (!empty($page))
                {
                    $uri .= '&page=' . $page;
                }
                if (!empty($sort))
                {
                    $uri .= '&sort=' . $sort;
                }
                if (!empty($order))
                {
                    $uri .= '&order=' . $order;
                }
            }

            break;
        case 'exchange_goods':
            if (empty($gid))
            {
                return false;
            }
            else
            {
                $uri = $rewrite ? 'exchange-id' . $gid : 'exchange.php?id=' . $gid . '&act=view';
            }

            break;
        default:
            return false;
            break;
    }

    if ($rewrite)
    {
        if ($rewrite == 2 && !empty($append))
        {
            $uri .= '-' . urlencode(preg_replace('/[\.|\/|\?|&|\+|\\\|\'|"|,]+/', '', $append));
        }

        $uri .= '.html';
    }
    if (($rewrite == 2) && (strpos(strtolower(EC_CHARSET), 'utf') !== 0))
    {
        $uri = urlencode($uri);
    }
    return $uri;
}

代码2 重构后的 UriRewrite 类,由于时间关系,类中没有写完所有的代码

<?php

/*
 * URL重写类
 *
 */
class UriRewrite
{
    private $m_app;
    private $m_params;
    private $m_append;
    private $m_page;
    private $m_keywords; 
    private $m_size;

    private $m_rewrite;

    private $m_methodTable = array(
        'category'=>'CreateByCategory',
        'goods'=>'CreateByGoods',
        'brand'=>'CreateByBrand',
        'article_cat'=>'CreateByArticleCat',
        'article'=>'CreateByArticle',
        'group_buy'=>'CreateByGroupBuy',
        'auction'=>'CreateByAuction',
        'snatch'=>'CreateBySnatch',
        'search'=>'CreateBySearch',
        'exchange'=>'CreateByExchange',
        'exchange_goods'=>'CreateByExchangeGoods'
    );

    private $m_result;

    public function __construct($app, $params, $append = '', $page = 0, $keywords = '', $size = 0)
    {
        $this->m_app = $app;
        $this->m_params = $params;
        $this->m_append = $append;
        $this->m_page = $page;
        $this->m_keywords = $keywords;
        $this->m_size = $size;

        $this->m_rewrite = intval($GLOBALS['_CFG']['rewrite']);        
    }

    public function Create() 
    {
        $args = array(
            'cid'   => 0,
            'gid'   => 0,
            'bid'   => 0,
            'acid'  => 0,
            'aid'   => 0,
            'sid'   => 0,
            'gbid'  => 0,
            'auid'  => 0,
            'sort'  => '',
            'order' => ''
        );

        array_merge($args, $this->m_params);

        if(!array_key_exists($this->m_app, $this->m_methodTable))
        {
            return false;
        }

        $uri = $this->{$this->m_methodTable[$this->m_app]}();

        $uri = $this->DoByAppend($uri);

        $uri = $this->DoByCharset($uri);
        
        return $uri;
    }

    protected function CreateByCategory() 
    {
        if (empty($this->m_params['cid']))
        {
            return false;
        }

        $this->m_rewrite = 'category-'.$this->m_params['cid'];

        return $this->AddBID()->AddPriceMin()->AddPriceMax()->AddFilterAttr()->AddPage()->AddSort()->AddOrder()->Result();
    }

    protected function CreateByGoods() {}
    protected function CreateByBrand() {}
    protected function CreateByArticleCat() {}
    protected function CreateByArticle() {}
    protected function CreateByGroupBuy() {}
    protected function CreateByAuction() {}
    protected function CreateBySnatch() {}
    protected function CreateBySearch() {}
    protected function CreateByExchange() {}
    protected function CreateByExchangeGoods() {}

    private function Result()
    {
        return empty($this->m_result)? false : $this->m_result;
    }

    private function DoByAppend($uri)
    {
        if ($this->m_rewrite)
        {
            if ($this->m_rewrite == 2 && !empty($this->m_append))
            {
                $uri .= '-' . urlencode(preg_replace('/[\.|\/|\?|&|\+|\\\|\'|"|,]+/', '', $this->m_append));
            }

            $uri .= '.html';
        }

        return $uri;
    }

    private function DoByCharset($uri)
    {
        if (($this->m_rewrite == 2) && (strpos(strtolower(EC_CHARSET), 'utf') !== 0))
        {
            $uri = urlencode($uri);
        }

        return $uri;
    }

    private function AddCID($uri) 
    {
        if($this->m_rewrite)
        {
            $this->m_rewrite = '';
        }
        else
        {
            $this->m_rewrite = '';
        }
        return $this;
    }

    private function AddGID($uri) {}
    private function AddBID($uri) {}
    private function AddACID($uri) {}
    private function AddAID($uri) {}
    private function AddSID($uri) {}
    private function AddGBID($uri) {}
    private function AddAUID($uri) {}
    private function AddSort($uri) {}
    private function AddOrder($uri) {}
    private function AddPriceMin($uri) {}
    private function AddPriceMax($uri) {}
    private function AddFilterAttr($uri) {}
    private function AddPage($uri) {}    
}

?>

在这次重构中,使用到了一个 方法表 的概念。就是将原本 switch 的条件选择,通过 方法表 定位到对类方法的动态调用。

// 方法表的定义
private $m_methodTable = array(
        'category'=>'CreateByCategory',
        'goods'=>'CreateByGoods',
        'brand'=>'CreateByBrand',
        'article_cat'=>'CreateByArticleCat',
        'article'=>'CreateByArticle',
        'group_buy'=>'CreateByGroupBuy',
        'auction'=>'CreateByAuction',
        'snatch'=>'CreateBySnatch',
        'search'=>'CreateBySearch',
        'exchange'=>'CreateByExchange',
        'exchange_goods'=>'CreateByExchangeGoods'
    );

/*
 * 方法表的调用。还可以使用 call_user_func
 *
 * call_user_func(array($this, $this->m_methodTable[$this->m_app]));
 */

$this->{$this->m_methodTable[$this->m_app]}();
原文地址:https://www.cnblogs.com/bruceleeliya/p/2748270.html