本文實例講述了php基于雙向循環隊列實現歷史記錄的前進后退等功能。分享給大家供大家參考。具體如下:
為實現一個記錄操作歷史的功能
1. 和撤銷,反撤銷功能類似的一個功能。(實現操作的前進后退)
2. 和discuz論壇登錄后查看帖子(可以前進后退查看過的帖子,還有帖子查看歷史記錄)
3. 邏輯和windows資源管理器地址欄前進后退功能一樣。
根據這種需要,實現了一個數據結構。寫了一個通用的類,暫叫歷史記錄類吧。
【原理和時鐘類似。實例化對象時可以構造長度為N(可以根據需要定長度)個節點的環】
然后整合各種操作。前進、后退、插入、修改插入。
類可以構造一個數組。或者傳入數組參數構造一個對象。 每次操作之后可以取得操作后的數組。 操作完的 數據可以根據自己的需要以合適的方式保存。 放在cookie,session里面,或者序列化,或轉為json數據保存在數據庫里,或者放在文件里面都可以。 方便下一次使用。
為了便于擴展,存放更多的數據。具體每一條數據也是一條數組記錄。
比如根據需要進行擴展:array('path'=>'D:/www/','sss'=>value)
順便貼出,自己寫的調試變量用的一個文件。
1. pr()可以格式化并高亮輸出變量。pr($arr),pr($arr,1)是輸出后退出。
2. debug_out() 用來輸出多個變量。默認為退出。
3. debug_out($_GET,$_SERVER,$_POST,$arr);
history.class.php文件:
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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
|
<?php include 'debug.php' ; /** * 歷史記錄操作類 * 傳入或者構造一個數組。形如: array( 'history_num'=>20, //隊列節點總共個數 'first'=>0, //起始位置,從0開始。數組索引值 'last'=>0, //終點位置,從0開始。 'back'=>0, //從first位置倒退了多少步,差值。 'history'=>array( //數組,存放操作隊列。 array('path'=>'D:/'), array('path'=>'D:/www/'), array('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 < $num ; $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 )< $this ->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<0) { //退到最后點 $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 < $this ->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 <8; $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()); ?> |
debug.php文件:
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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
|
<?php /** * 獲取變量的名字 * 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 ='<style> pre#debug{margin:10px;font-size:13px;color:#222;font-family:Consolas ;line-height:1.2em;background:#f6f6f6;border-left:5px solid #444;padding:5px;width:95%;word- break : break -all;} pre#debug b{font-weight:400;} #debug #debug_str{color:#E75B22;} #debug #debug_keywords{font-weight:800;color:00f;} #debug #debug_tag1{color:#22f;} #debug #debug_tag2{color:#f33;font-weight:800;} #debug #debug_var{color:#33f;} #debug #debug_var_str{color:#f00;} #debug #debug_set{color:#0C9CAE;}</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( '/"(.*)"/' , '<b id="debug_var_str">"' . '\\1' . '"</b>' , $out ); //高亮字符串變量 $out =preg_replace( '/=\>(.*)/' , '=>' . '<b id="debug_str">' . '\\1' . '</b>' , $out ); //高亮=>后面的值 $out =preg_replace( '/\[(.*)\]/' , '<b id="debug_tag1">[</b><b id="debug_var">' . '\\1' . '</b><b id="debug_tag1">]</b>' , $out ); //高亮變量 $from = array ( ' ' , '(' , ')' , '=>' ); $to = array ( ' ' , '<b id="debug_tag2">(</i>' , '<b id="debug_tag2">)</b>' , '<b id="debug_set">=></b>' ); $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 ] = '<b id="debug_keywords">' . $val . '</b>' ; } $out = str_replace ( $keywords , $keywords_to , $out ); echo $style . '<pre id="debug"><b id="debug_keywords">' .get_var_name( $var ). '</b> = ' . $out . '</pre>' ; if ( $exit ) exit ; //為真則退出 } /** * 調試輸出變量,對象的值。 * 參數任意個(任意類型的變量) * @return echo */ function debug_out(){ $avg_num = func_num_args(); $avg_list = func_get_args(); ob_start(); for ( $i =0; $i < $avg_num ; $i ++) { pr( $avg_list [ $i ]); } $out =ob_get_clean(); echo $out ; exit ; } ?> |
希望本文所述對大家的php程序設計有所幫助。