get next & previous id record in database on Yii
我需要yii框架上数据库中的下一个和上一个ID记录来下一个和上一个导航按钮?
我在yii2的模型中添加了以下功能:
1 2 3 4 5 6 7 8 9 | public function getNext() { $next = $this->find()->where(['>', 'id', $this->id])->one(); return $next; } public function getPrev() { $prev = $this->find()->where(['<', 'id', $this->id])->orderBy('id desc')->one(); return $prev; } |
我做了一个函数来获取你要查找的ID。我建议您在模型中声明:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | public static function getNextOrPrevId($currentId, $nextOrPrev) { $records=NULL; if($nextOrPrev =="prev") $order="id DESC"; if($nextOrPrev =="next") $order="id ASC"; $records=YourModel::model()->findAll( array('select'=>'id', 'order'=>$order) ); foreach($records as $i=>$r) if($r->id == $currentId) return isset($records[$i+1]->id) ? $records[$i+1]->id : NULL; return NULL; } |
所以要使用它,你所要做的就是:
1 | YourModel::getNextOrPrevId($id /*(current id)*/,"prev" /*(or"next")*/); |
。
它将返回下一条或上一条记录的对应ID。
我没有测试过,所以试一下,如果出了什么问题,请告诉我。
生成用于将信息传递给其他函数的私有var。
在模型中:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | class Model1 ..... { ... private _prevId = null; private _nextId = null; ... public function afterFind() //this function will be called after your every find call { //find/calculate/set $this->_prevId; //find/calculate/set $this->_nextId; } public function getPrevId() { return $this->prevId; } public function getNextId() { return $this->nextId; } } |
检查在VIEWDETAL链接中生成的代码,并使用修改视图文件中的prev/net链接
1 | $model(or $data)->prevId/nextId |
号
在数组("id"=>)部分中。
我的实现基于SearchModel。
控制器:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | public function actionView($id) { // ... some code before // Get prev and next orders // Setup search model $searchModel = new OrderSearch(); $orderSearch = \yii\helpers\Json::decode(Yii::$app->getRequest()->getCookies()->getValue('s-' . Yii::$app->user->identity->id)); $params = []; if (!empty($orderSearch)){ $params['OrderSearch'] = $orderSearch; } $dataProvider = $searchModel->search($params); $sort = $dataProvider->getSort(); $sort->defaultOrder = ['created' => SORT_DESC]; $dataProvider->setSort($sort); // Get page number by searching current ID key in models $pageNum = array_search($id, array_column($dataProvider->getModels(), 'id')); $count = $dataProvider->getCount(); $dataProvider->pagination->pageSize = 1; $orderPrev = $orderNext = null; if ($pageNum > 0) { $dataProvider->pagination->setPage($pageNum - 1); $dataProvider->refresh(); $orderPrev = $dataProvider->getModels()[0]; } if ($pageNum < $count) { $dataProvider->pagination->setPage($pageNum + 1); $dataProvider->refresh(); $orderNext = $dataProvider->getModels()[0]; } // ... some code after } |
订单搜索:
1 2 3 4 5 6 7 8 9 10 11 | public function search($params) { // Set cookie with search params Yii::$app->response->cookies->add(new \yii\web\Cookie([ 'name' => 's-' . Yii::$app->user->identity->id, 'value' => \yii\helpers\Json::encode($params['OrderSearch']), 'expire' => 2147483647, ])); // ... search model code here ... } |
。
PS:确定是否可以使用
把原来的答案改为yii2,稍微整理一下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | /** * [nextOrPrev description] * @source http://stackoverflow.com/questions/8872101/get-next-previous-id-record-in-database-on-yii * @param integer $currentId [description] * @param string $nextOrPrev [description] * @return integer [description] */ public static function nextOrPrev($currentId, $nextOrPrev = 'next') { $order = ($nextOrPrev == 'next') ? 'id ASC' : 'id DESC'; $records = amespace\path\Model::find()->orderBy($order)->all(); foreach ($records as $i => $r) { if ($r->id == $currentId) { return ($records[$i+1]->id ? $records[$i+1]->id : NULL); } } return false; } |
。
当您得到第一个或最后一个记录,并且它们对数据库进行多个调用时,前面的解决方案是有问题的。下面是我的工作解决方案,它对一个查询进行操作,处理表尾并禁用表尾的按钮:
在模型中:
1 2 3 4 5 6 7 8 9 10 11 12 13 | public static function NextOrPrev($currentId) { $records = <Table>::find()->orderBy('id DESC')->all(); foreach ($records as $i => $record) { if ($record->id == $currentId) { $next = isset($records[$i - 1]->id)?$records[$i - 1]->id:null; $prev = isset($records[$i + 1]->id)?$records[$i + 1]->id:null; break; } } return ['next'=>$next, 'prev'=>$prev]; } |
。
在控制器内:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | public function actionView($id) { $index = <modelName>::nextOrPrev($id); $nextID = $index['next']; $disableNext = ($nextID===null)?'disabled':null; $prevID = $index['prev']; $disablePrev = ($prevID===null)?'disabled':null; // usual detail-view model $model = $this->findModel($id); return $this->render('view', [ 'model' => $model, 'nextID'=>$nextID, 'prevID'=>$prevID, 'disableNext'=>$disableNext, 'disablePrev'=>$disablePrev, ]); } |
在视图中:
1 2 | <?= Html::a('Next', ['view', 'id' => $nextID], ['class' => 'btn btn-primary r-align btn-sm '.$disableNext]) ?> <?= Html::a('Prev', ['view', 'id' => $prevID], ['class' => 'btn btn-primary r-align btn-sm '.$disablePrev]) ?> |
。