實現一個記錄操作歷史的功能
- 和撤銷,反撤銷功能類似的一個功能。 (實現操作的前進後退)
- 和discuz論壇登入後查看帖子(可以前進後退查看過的帖子,還有帖子查看歷史記錄)
- 邏輯和windows資源管理器網址列前進後退功能一樣。
根據這種需要,實作了一個資料結構。寫了一個通用的類,暫叫歷史記錄類吧。
【原理和時鐘類似。實例化物件時可以建構長度為N(可依需要定長度)個節點的環】
然後整合各種操作。前進、後退、插入、修改插入。
類別可以建構一個陣列。或傳入數組參數建構一個物件。
每次操作之後可以取得操作後的陣列。
操作完的 資料可以依照自己的需求以適當的方式保存。 放在cookie,session裡面,或是序列化,或轉為json資料保存在資料庫裡,或放在檔案裡面都可以。 方便下次使用。 為了方便擴展,存放更多的資料。具體每一筆資料也是一張數組記錄。
例如依需求進行擴充:array('path'=>'D:/www/','sss'=>value)
----------------------------------- -----------------------------------------
順便貼出,自己寫的調試變數用的一個檔案。
- pr()可以格式化並高亮輸出變數。 pr($arr),pr($arr,1)是輸出後退出。
- debug_out() 用來輸出多個變數。預設為退出。
- debug_out($_GET,$_SERVER,$_POST,$arr) ;
-
- include 'debug.php';
- /**
- * 歷史記錄操作類別
-
- * 傳入或建構一個陣列。形如:
- array(
- 'history_num'=>20, //佇列節點總共數
- 'first'=>0, //起始位置,從0開始。陣列索引值
- 'last'=>0, //終點位置,從0開始。 //數組,存放操作佇列。 path'=>'E:/'),
- array('path'=>'/home/')
- ……
- )
- )
- */
-
- class history {
- var $history_num;
- var $first;
- var $last;
- var $back;
- var $history=array();
-
- function __construct($ array=array(),$num=12){
- if (!$array) {//陣列為空.建構一個循環隊列。
- $history=array();
- for ($i=0; $i array_push($history,array('path'=>''));
- }
- $array=array(
- 'history_num'=>$num,
- 'first'=>0,//起始位置
- 'last'=>0,//終點位置
- 'back'=>0,
- 'history'=>$history
- );
- }
- $this->history_num=$array['history_num'];
- $this->first=$array['first'];
- $this->last=$array['last'];
- $this->back=$array['back'];
- $this->history=$array['history'];
- }
-
- function nextNum($i,$n=1){//環路下n一個值。和時鐘環路類似。
- return ($i+$n)history_num ? ($i+$n):($i+$n-$this->history_num);
- }
- function prevNum($i, $n=1){//環路上一個值i。回退N個位置。
- return ($i-$n)>=0 ? ($i-$n) : ($i-$n+$this->history_num);
- }
-
- function minus($ i,$j){//順時針兩點只差,i-j
- return ($i > $j) ? ($i - $j):($i-$j+$this->history_num);
- }
-
-
- function getHistory(){//回傳陣列,用來保存或序列化運算。
- return array(
- 'history_num'=> $this->history_num,
- 'first' => $this->first,
- 'last' => $this->last,
- 'back' => $this->back,
- 'history' => $this->history
- );
- }
-
- function add($path){
- if ($this->back!=0) {//有後退操作記錄的情況下,進行插入。
- $this->goedit($path);
- return;
- }
- if ($this->history[0]['path']=='') {//剛建構,不用加一.第一位不前移
- $this->history[$this->first]['path']=$path;
- return;
- }else{
- $this- >first=$this->nextNum($this->first);//首位前移
- $this->history[$this->first]['path']=$path;
- }
- if ($this->first==$this->last) {//起始位置與終止位置相遇
- $this->last=$this->nextNum($this->last);/ /末端位置前移。
- }
- }
-
- function goback(){//傳回first後退N步驟的位址。
- $this->back+=1;
- //最大後退步數為起點到終點之差(順時針之差)
- $mins=$this->minus($this->first, $this->last);
- if ($this->back >= $mins) {//退到最後點
- $this->back=$mins;
- }
-
- $pos=$this->prevNum($this->first,$this->back);
- return $this->history[$pos]['path'];
- }
-
- function gonext(){//從first後退N步的地方前進一步。
- $this->back-=1;
- if ($this->back $this->back=0;
- }
- return $this->history[$this->prevNum($this->first,$this->back)]['path'];
- }
- function goedit($path){//後退到某個點,沒有前進而是修改。則firs值為最後的值。
- $pos=$this->minus($this->first,$this->back);
- $pos=$this->nextNum($pos);//下一個
- $this ->history[$pos]['path']=$path;
- $this->first=$pos;
- $this->back=0;
- }
-
- / /是否可以後退
- function isback(){
- if ($this->back minus($this->first,$this->last)) {
- return ture;
- }
- return false;
- }
- //是否可以前進
- function isnext(){
- if ($this->back>0) {
- return true;
- }
- return false;
- }
- }
-
-
- //測試程式碼。
- $hi=new history(array(),6);//傳入空數組,則初始化數組構造。
- for ($i=0; $i $hi->add('s'.$i);
- }
- pr($hi->goback ());
- pr($hi->goback());
- pr($hi->goback());
-
- pr($hi->gonext());
- pr($hi->gonext());
- pr($hi->gonext());
- pr($hi->gonext());
- $hi->add( 'asdfasdf');
- $hi->add('asdfasdf2');
- pr($hi->getHistory());
-
-
- $ss=new history($hi ->getHistory());//直接用陣列建構。
- $ss->add('asdfasdf');
- $ss->goback();
- pr($ss->getHistory());
-
-
- ?>
複製程式碼
- /**
- * 取得變數的名字
- * eg hello="123" 取得ss字串
- */
- function get_var_name(&$aVar){
- foreach($GLOBALS as $key =>$var)
- {
- if($aVar==$GLOBALS[$key] && $key!="argc"){
- return $key;
- }
- }
- }
-
- /**
- * 格式化輸出變量,或物件
- * @param mixed $var
- * @param boolean $exit
- */
- function pr($var,$exit = false){
- ob_start();
- $style='';
- if (is_array($var)){
- print_r($var);
- }
- else if(is_object($var)){
- echo get_class($var)." Object";
- }
- else if(is_resource($var)){
- echo (string)$var;
- }
- else{
- echo var_dump($var);
- }
- }
- $out = ob_get_clean();//緩衝輸出給$out 變數
-
- $out=preg_replace('/"(.*)"/','"'. '\1'.'"',$out);//高亮字串變數
- $out=preg_replace('/=>(.*)/','=>'.''.'\1'.'',$out);//高亮=>後面的值
- $out=preg_replace('/[(.*)] /','['.'\1'.'] ',$out);//高亮變數
-
- $from = array(' ','(',')','=>');
- $to = array(' ', '(',')','=>');
- $out=str_replace($from,$to,$out);
-
- $keywords=array('Array','int','string','class','object',' null');//關鍵字高亮
- $keywords_to=$keywords;
- foreach($keywords as $key=>$val)
- {
- $keywords_to[$key] = ''.$val.'
';
- }
- $out=str_replace($keywords,$keywords_to,$out);
- echo $style.''.get_var_name($var).' = '.$out.'';
- if ($exit) exit ;//為真則退出
- }
-
- /**
- * 偵錯輸出變數,物件的值。
- * 參數任一(任意型別的變數)
- * @return echo
- */
- function debug_out(){
- $avg_num = func_num_args();
- $avg_list= func__f ();
- ob_start();
- for($i=0; $i pr($avg_list[$i]);
- }
- $out=ob_get_clean();
- echo $out;
- exit;
- }
-
-
?>
複製程式碼🎜>?>
|
複製程式碼🎜>?>