周梦康 发表于 2019-01-23 255 次浏览

最近一直在做代码重构的工作,用到了 xunsearch 的功能,由于 xunsearch 都是网络调用,每个方法都可能出现网络故障,所以之前的写法是这样

class SearchService
{
    /**
     * @var \XS[]
     */
    protected $xsList = array();

    protected $app;

    public function __construct($app)
    {
        $this->app = $app;

        try {
            if (!isset($this->xsList[$app]) || is_null($this->xsList[$app])) {
                $this->xsList[$app] = new \XS($app . '_' . ENV_TAG);
            }
        } catch (\Exception $e) {
            error_log($e->getMessage());
            return null;
        }

        $this->xsList[$app]->search->setTimeout(0.5);
    }

    public function _search($query, $fuzzy = false, $limit = 10, $offset = 0)
    {
        try {
            return $this->xsList[$this->app]->search->setFuzzy($fuzzy)->setLimit($limit, $offset)->search($query);
        } catch (\Exception $e) {
            error_log($e->getMessage());
            return array();
        }
    }

    public function searchWithCount($query, $fuzzy = false, $limit = 10, $offset = 0)
    {
        try {

            $list = $this->xsList[$this->app]->search->setFuzzy($fuzzy)->setLimit($limit, $offset)->search($query);
            $count = $this->xsList[$this->app]->search->lastCount;
            return ["total" => $count, "list" => $list];
        } catch (\Exception $e) {
            error_log($e->getMessage());
            return array();
        }
    }

    public function updateIndex($data)
    {
        try {
            $doc = new \XSDocument;
            $doc->setFields($data);
            return $this->xsList[$this->app]->index->update($doc);
        } catch (\Exception $e) {
            error_log($e->getMessage());
            return false;
        }
    }

    public function delIndex($data)
    {
        try {
            return $this->xsList[$this->app]->index->del($data);
        } catch (\Exception $e) {
            error_log($e->getMessage());
            return false;
        }
    }
}

这些代码有个共性,就是都要 try catch,比如我们页面相关文章搜索,找不到,不能抛异常,页面应该继续打开,所以要用 try catch。

那怎么把这些重复代码收拢下呢?

http://manual.phpdoc.org/HTMLframesConverter/default/ 里面有个注释叫 @method

@method shows a "magic" method that is found inside the class.

所以我们代码可以这么玩

/**
 * Class SearchService
 *
 * @package Service\Xunsearch
 *
 * @method searchProxy($query, $fuzzy = false, $limit = 10, $offset = 0)
 * @method searchWithCountProxy($query, $fuzzy = false, $limit = 10, $offset = 0)
 * @method updateIndexProxy(array $data)
 * @method delIndexProxy($data)
 *
 */
class SearchService
{
    /**
     * @var \XS[]
     */
    protected $xsList = array();

    protected $app;

    /**
     * SearchService constructor.
     *
     * @param $app
     */
    public function __construct($app)
    {
        $this->app = $app;

        if (!isset($this->xsList[$app]) || is_null($this->xsList[$app])) {
            $this->xsList[$app] = new \XS($app . '_' . ENV_TAG);
        }

        $this->xsList[$app]->search->setTimeout(0.5);
    }

    /**
     * @param string $query 文档:http://www.xunsearch.com/doc/php/guide/search.query
     * @param bool   $fuzzy 是否开启模糊搜索
     * @param int    $limit 本次查找的数量
     * @param int    $offset 查找的起始位置
     *
     * @return \XSDocument[]
     * @throws \XSException
     */
    private function search(string $query, $fuzzy = false, $limit = 10, $offset = 0)
    {
        return $this->xsList[$this->app]->search->setFuzzy($fuzzy)->setLimit($limit, $offset)->search($query);
    }

    /**
     * @param      $query
     * @param bool $fuzzy
     * @param int  $limit
     * @param int  $offset
     *
     * @return array
     * @throws \XSException
     */
    private function searchWithCount($query, $fuzzy = false, $limit = 10, $offset = 0)
    {
        $list = $this->xsList[$this->app]->search->setFuzzy($fuzzy)->setLimit($limit, $offset)->search($query);
        $count = $this->xsList[$this->app]->search->lastCount;
        return ["total" => $count, "list" => $list];
    }

    /**
     * @param array $data
     *
     * @return \XSIndex
     * @throws \XSException
     */
    private function updateIndex(array $data)
    {
        $doc = new \XSDocument;
        $doc->setFields($data);
        return $this->xsList[$this->app]->index->update($doc);
    }
    

    /**
     * 删除某个或多个id的索引
     *
     * @param mixed $data 单个id或者id的数组
     *
     * @return \XSIndex
     */
    private function delIndex($data)
    {
        return $this->xsList[$this->app]->index->del($data);
    }

    public function __call($name, $arguments)
    {
        $method = str_replace("Proxy", "", $name);
        if (!method_exists($this, $method)) {
            throw new \LogicException(__CLASS__ . "::" . $method . " not found");
        }

        try {
            $data = call_user_func_array([$this, $name], $arguments);
        } catch (\Exception $e) {
            error_log($e->getMessage());
            return false;
        }

        return $data;
    }
}

靠,发现没少几行,而且返回值不明确,对业务也不透明,还是不这么玩了,不过可以记录下@method

嗨,老铁,欢迎来到我的博客!

如果觉得我的内容还不错的话,可以关注下我在 segmentfault.com 上的直播。我主要从事 PHP 和 Java 方面的开发,《深入 PHP 内核》作者之一。

[视频直播] PHP 进阶之路 - 亿级 pv 网站架构的技术细节与套路 直播中我将毫无保留的分享我这六年的全部工作经验和踩坑的故事,以及会穿插着一些面试中的 考点难点加分点

评论列表