dzoocn

第 1048 位会员

会员
个人信息
  • 加入于 2018-02-28 21:39:22
  • 最后登录时间 3年前
个人成就
  • 发表文章次数 3
  • 发布回复次数 6
  • 个人主页浏览次数 40
yii2是否有类似于laravel Api-Resource 资源功能呢?3年前

@forecho [#1楼](#comment1) 另外不知道现在yii3是个什么样的进度呢?完全的composer不下来,不知道yii3能否默认支持这样的api资源需求呢?

yii2是否有类似于laravel Api-Resource 资源功能呢?3年前

@forecho #1楼 我在github提交过相关的问题:https://github.com/yiisoft/yii2/issues/17208 得到的邮件回复是这样的:

This can be done by a trick:
Assume you have a BaseQuery and BaseActiveRecord,
in BaseQuery rewrite all method

    public function all($db = null)
    {
        $records = parent::all($db);
        foreach ($records as &$record) {
            if ($record instanceof ActiveRecord) {
                $record = $record->toArray([], $record->getRelationNames(), 1);
            }
        }unset($record);

        return $records;
    }
in BaseActiveRecord define a method

    public function getRelationNames()
    {
        return array_keys($this->relatedRecords);
    }
Then never ->asArray()->all() which ignore fields(),
instead directly use find()->...->all(), all relations will be expanded recursively.


This is my BaseQuery:

    private static $model;
    private $customSelectColumns = [];
    private $customAsArray = false;
    private $customExtraFields = [];

    public function init()
    {
        parent::init();
        $this->baseSelect();
    }

    /**
     * @param bool $value
     * @return $this|\yii\db\ActiveQuery
     */
    public function asArray($value = true)
    {
        $this->customAsArray = $value;
        parent::asArray(false);

        return $this;
    }

    /**
     * @param null $db
     * @return array|\yii\db\ActiveRecord[]
     */
    public function all($db = null)
    {
        $records = parent::all($db);
        foreach ($records as &$record) {
            if ($record instanceof ActiveRecord && $this->customAsArray) {
                $record = $record->toArray($this->customSelectColumns, $this->customExtraFields);
            }
        }
        unset($record);

        return $records;
    }

    /**
     * @param null $db
     * @return array|\yii\db\ActiveRecord|null
     */
    public function one($db = null)
    {
        $record = parent::one($db);
        if ($this->customAsArray) {
            $record = $record->toArray($this->customSelectColumns, $this->customExtraFields);
        }

        return $record;
    }

    /**
     * @param array|string|\yii\db\ExpressionInterface $columns
     * @param null                                     $option
     * @return \yii\db\ActiveQuery
     */
    public function select($columns, $option = null)
    {
        if (is_array($columns) && ! empty($columns)) {
            $columns = $this->getRealColumns($columns);
        } else {
            $columns = array_intersect($this->getModel()->attributes(),
                $this->getRealColumns(parent::select($columns, $option)->select));
        }

        return parent::select($columns, $option);
    }

    protected function baseSelect()
    {
        return $this->select([]);
    }

    private function getRealColumns(array $columns)
    {
        list($addColumns, $deleteColumns) = $this->devideColumns($columns);
        $this->customSelectColumns = array_merge($this->customSelectColumns, $addColumns);
        if (! $this->customSelectColumns) {
            $this->customSelectColumns = $this->getModel()->attributes();
        }
        $this->customSelectColumns = array_diff($this->customSelectColumns, $deleteColumns);

        return $this->customSelectColumns = array_unique($this->customSelectColumns);
    }

    private function devideColumns(array $columns)
    {
        $addAttributes = $this->getModel()->attributes();
        $deleteAttributes = array_map(function ($v) {
            return '!'.$v;
        }, $addAttributes);
        $addColumns = $deleteColumns = [];
        foreach ($columns as $column) {
            if (in_array($column, $addAttributes)) {
                $addColumns[] = $column;
            } elseif (in_array($column, $deleteAttributes)) {
                $deleteColumns[] = ltrim($column, '!');
            }
        }

        return [$addColumns, $deleteColumns];
    }

    /**
     * @return \common\models\BaseActiveRecord
     */
    private function getModel()
    {
        return (static::$model instanceof $this->modelClass)
            ? static::$model
            : (static::$model = new $this->modelClass);
    }

    /**
     * @param array $extraFields
     * @return $this
     */
    public function extra(array $extraFields)
    {
        $this->customExtraFields = $extraFields;

        return $this;
    }

没能看明白具体怎么继承,怎么使用。老大能否尝试指点下。@forecho

yii2 User个人主页url的生成疑问3年前

@forecho [[#1楼](#comment1)](#comment1) 可能我描述的问题导致理解上有差异;我的意思是 views视图中如何去写这个用户主页的url地址呢?

应该不是

['/user/view', 'username' => $model->username]

也不是

['/user/view', 'id' => $model->id]

因为个人中心设置别名之后,所有的该用户url都自动变更非ID模式了

发帖需要输入验证码了3年前

@forecho #2楼 老大,冒昧问下,为什么你要把一些功能,完全可以用一个控制器代替的,非要变成modules?然后里面就一个默认的DefaultController?是基于什么考量的?这么做有什么好处吗?