多くの場合、特定のテーブルの論理タイプのデータを保存する必要があります。 たとえば、ユーザーテーブルなどのデータは、ユーザーアクティベーションフィールド、ユーザーブロックなどです。このようなフィールドでは、すべてのデータがテーブルの1つのフィールドに格納されるビットマスクを使用すると便利です。 最近、Yiiフレームワークを使用しています。 私は彼が好きで、すべてに満足しています。 そのため、いくつかのプロジェクトに取り組んでいる過程で、このフレームワークのビットマスクを使用して作業するための多くの開発がありました。
それらを共有したいです。
そして、ActiveRecordから継承するモデルを作成します。
class BaseActiveRecordClass extends CactiveRecord
フラグを宣言します。 基本クラスには、ほとんどのモデルに使用できるロックフラグを設定します。
const FLAG_MANAGE_BLOCKED=0; //
定数値はビット番号に対応します。 ビットが同じ場合、フラグはほつれます。
次に、フラグを操作するメソッドを作成します。
/* * */ public function setFlag($idBit=0,$bit=1){ $bitFlags=1<<$idBit; if($bit==0){ $this->flags=$this->flags&(~$bitFlags); }else{ $this->flags=$this->flags|$bitFlags; } $this->save(true, array('flags')); } /* * */ public function getFlag($idBit){ $flag=(int)$this->flags; $flag=$flag>>$idBit; if($flag>0) $cBits=log($flag,2); else $cBits=0; $newFlag=$flag|1; if($newFlag==$flag) return 1; else return 0; } /* * * param $flags array */ public function addFlagCriteria($flags=array()){ $criteria=$this->getDbCriteria(); if(!empty($flags)){ foreach($flags as $bit => $flag){ if(is_array($flag)){ $operator=($flag['operator'])?$flag['operator']:"and"; $check=($flag['check'])?(bool)$flag['check']:1; }else{ $operator="and"; $check=(bool)$flag; } $check=$check?"=":"<>"; $criteria->addCondition("(((t.flags>>".$bit.")|1)".$check."(t.flags>>".$bit."))", $operator); } } return $this; } /* * * */ public function noBlock(){ return $this->addFlagCriteria(array(self::FLAG_MANAGE_BLOCKED=>0)); }
フラグで動作するモデルをこのクラスの相続人にし、フラグフィールドをテーブルに追加します。
ここで、たとえば、ニュースがブロックされているかどうかを確認するには、次のようにします。
$model= News::model()->findByPk($id); if($model->getFlag(News::FLAG_MANAGE_BLOCKED)){ die(" "); }
またはニュースをブロックするには:
$model->setFlag(News::FLAG_MANAGE_BLOCKED, 1);
または、たとえば、ブロックされていないニュースを除外するには:
$news=News::model()->noBlock()->findAll();
データベースのフィールドタイプの容量が許す限り、多くのフラグをモデルに追加できます。
資料が有用であることが判明した場合、このトピックの続きを公開し、CgridViewを介した既製のフラグ管理ツールと基本的なカスタマイズツールを使用したアクションについて説明します。