第一段yii2 model类,找错与点评


第一段yii2的代码,功能是检测用户是否创建当天日志。如果未创建,立即创建,并且保存。
为了避免大量查询数据库,所以保存到session中(可能不是很好?)。
欢迎指正其中的优缺点(逻辑是否正确):


 #/models/log/DayLog.php
#/models/log/DayLogInterface.php
#/models/log/SystemLog.php
#/models/log/MemberLog.php
#/models/log/VistorLog.php


 php


 #/models/log/DayLog.php
namespace app\models\log;

use yii\db\ActiveRecord;

class DayLog extends ActiveRecord
{

    const SESSION_LOG_ID = 'x_day_id';
    const SESSION_LOG_DATE = 'x_day_date';
    public $allowFields = [];


    /**
     * @description 更新统计日志
     *
     * @param     $id
     * @param     $field
     * @param int $num
     *
     * @return bool
     */
    public function updateLog($id, $field, $num = 1)
    {
        if (in_array($field, $this->allowFields)) {
            $s = self::findOne($id);
            if ($s) {

                return $s->updateCounters([$field => $num]);
            }
        }

        return false;
    }

    public function getLogId()
    {
        return \Yii::$app->session->get($this::SESSION_LOG_ID);
    }

    public function getLogDate()
    {
        return \Yii::$app->session->get($this::SESSION_LOG_DATE);
    }

    public function setLogId($id)
    {
        \Yii::$app->session->set($this::SESSION_LOG_ID, $id);
    }

    public function setLogDate($date)
    {
        \Yii::$app->session->set($this::SESSION_LOG_DATE, $date);
    }

    //退出的时候必须全部删除
    public function clean()
    {
        \Yii::$app->session->remove($this::SESSION_LOG_ID);
        \Yii::$app->session->remove($this::SESSION_LOG_DATE);
    }
}


 php


 #/models/log/DayLogInterface.php
namespace app\models\log;

interface DayLogInterface
{
    public function check();
}


 php


 #/models/log/MemberLog.php
namespace app\models\log;


use yii\base\Event;
use yii\db\ActiveRecord;
use yii\web\User;

class MemberLog extends DayLog implements DayLogInterface
{
    const SESSION_LOG_ID = 'u_day_id'; // 日志的保存ID
    const SESSION_LOG_DATE = 'u_day_date'; //日志中保存的日期 YYYY-MM-dd

    public $allowFields = [];

    public static function tableName()
    {
        return '{{%daylog_member}}';
    }


    public function check()
    {
        //如果不是GUEST检查是否有日志
        if (!\Yii::$app->user->isGuest) {

            $logId = $this->getLogId();
            $logDate = $this->getLogDate();
            $today = date('Y-m-d');

            if ($logId && $logDate == $today) { //当天日志已经创建

            } else {

                $row = self::find()
                    ->where(['uid' => \Yii::$app->user->getId(), 'date' => $today])
                    ->one();

                if ($row) { //数据库中有当天记录

                    $this->setLogId($row->id);
                    $this->setLogDate($row->date);
                } else {

                    $log = new self();
                    $log->date = $today;
                    $log->uid = \Yii::$app->user->getId();
                    if ($log->save() && $log->id) {
                        $this->setLogId($log->id);
                        $this->setLogDate($log->date);
                    }
                }
            }

            //绑定事件 登录前清空原有记录
            Event::on(User::className(), User::EVENT_BEFORE_LOGIN, [ActiveRecord::className(), 'clean']);
        }
    }

}

重构和设计模式 yii2 设计模式 php

‘  陌柏ˇ 10 years ago

免责声明,我没写过yii,只能从OOP的方向说一下问题

我觉得这个代码,依赖关系搞错了,这个逻辑上,应该是$app->user $app->session依赖record,而现在是record依赖user和session

所以如果我来封装,应该大概是这样


 php


 class MemberLog {
    public function __construct($user) {
        // find record by user
        $this->record = findByUser($user);
    }

    public function check() {
        $this->record->doSomething();
    }
}

wagtail answered 10 years ago

Your Answer