PHP脚本批量清除nginx缓存的方法

我写了一个程序能够实现

1.提交一批url进行清除对应的cache

2.提交一批url目录可以清除包含这些目录的url,若是提交域名可以清除整站

3.查看某个目录下的缓存文件是否缓存上

4.可以添加多个站点

需要县安装ngx_cache_purge

代码如下

 1 <?php
 2 /*
 3  * 作者:yifangyou
 4    日期:2012-07-21 14:43:00
 5    功能:按照多个目录或者多个URL的方式,清除nginx的cache,或者查看nginx cache 缓存
 6    要求:nginx + ngx_cache_purge
 7  */
 8    //代理服务器的ip
 9   $proxyIp="127.0.0.1";
10   //代理服务器端口
11     $proxyPort=80;
12     //代理服务器的缓存目录
13     $cacheDir="/opt/proxy_cache_dir/";
14     $proxySites=array(
15     //用户访问的域名 => 被代理的实际网站的域名,若是都是80的话就是一样即可
16      "http://www.test.com"=>"http://www.test.com"
17     );
18 //输出文件
19 $output="";    
20 $result=array();
21 $filedirs = array();
22 //只查看缓存文件,不清除
23 if($_POST["view"]){
24          $accessSite=$_POST["accessSite"];
25      $proxySite=$proxySites[$accessSite];
26          $clearUrls=array();
27          $clearUrls=explode ("\n",$_POST["dirs"]);
28          if($$proxySite){
29                  foreach($ds as $d){
30                          $d=str_replace($accessSite, $proxySite,$d);
31                          $clearUrls[]=$d;
32                  }
33          }
34          scan_dir($cacheDir);
35          $cacheurls = array();
36          foreach($filedirs as $filename){
37                 if(!is_file($filename)){
38                         continue;
39                 }
40                 $cacheUrl=getUrlFromCacheFile($filename);
41                                 if(count($clearUrls)){
42                                     $cacheurls[]=$cacheUrl;
43                                     continue;
44                                 }
45                 foreach($clearUrls as $clearUrl){
46                   $clearUrl=str_replace($accessSite, $proxySite,$clearUrl);
47                   $pos=strpos($cacheUrl,$clearUrl);
48                   // echo "$cacheUrl,$clearUrl,$pos<br/>";
49                   //比较http://www.b.com/a/b.jpg和http://www.b.com/a
50                   if($pos===0){
51                      $cacheurls[]=$cacheUrl;
52                      break;
53                    }
54                 }
55         }
56 
57 }else //清除一批URL
58 if($_POST["urls"]){
59     $accessSite=$_POST["accessSite"];
60     $proxySite=$proxySites[$accessSite];
61     $output.="<div >执行结果
  1 \n<pre>\n";
  2     $urls=explode ("\n",$_POST["urls"]);
  3     foreach($urls as $url2){
  4         $url=trim($url2);
  5         $output.="------------------------$url start-----------------------------\n";
  6         $pos = strpos($url, $accessSite);
  7         if ($pos !== false && $pos==0) {
  8             $url=str_replace($accessSite, $proxySite,$url);
  9             if(purge($proxyIp,$proxyPort,$url)==0){
 10                 $result[$url2]=0;
 11             }else{
 12                 $result[$url2]=1;
 13             }
 14         }else{
 15             $output.="skip $url\n";
 16             $result[$url2]=-1;
 17         }
 18         $output.="------------------------$url end -----------------------------\n";
 19     }
 20     $output.="</pre>\n";
 21 }else//清除某个目录下的所有文件
 22 if($_POST["dirs"]){
 23     $accessSite=$_POST["accessSite"];
 24     $proxySite=$proxySites[$accessSite];
 25     $clearUrls=array();
 26     $clearUrls=explode ("\n",$_POST["dirs"]);
 27     if($$proxySite){
 28         foreach($ds as $d){
 29             $d=str_replace($accessSite, $proxySite,$d);
 30             $clearUrls[]=$d;
 31         }
 32     }
 33     scan_dir($cacheDir);
 34     $cacheurls = array();
 35     foreach($filedirs as $filename){
 36         if(!is_file($filename)){
 37             continue;
 38         }
 39         $cacheUrl=getUrlFromCacheFile($filename);
 40 
 41         foreach($clearUrls as $clearUrl){
 42          $clearUrl=str_replace($accessSite, $proxySite,$clearUrl);
 43             $pos=strpos($cacheUrl,$clearUrl);
 44             // echo "$cacheUrl,$clearUrl,$pos<br/>";
 45             //比较http://www.b.com/a/b.jpg和http://www.b.com/a
 46             if($pos===0){
 47                     $cacheurls[]=$cacheUrl;
 48                     break;
 49             }
 50         }
 51     }
 52     if(count($cacheurls) > 0){
 53         $accessSite=$_POST["accessSite"];
 54         $proxySite=$proxySites[$accessSite];
 55         $output.="<div >执行结果
 56 \n<pre>\n";
 57         foreach($cacheurls as $url2){
 58 
 59             $url=trim($url2);
 60             $output.="------------------------$url start-----------------------------\n";
 61             $pos = strpos($url, $accessSite);
 62             if(purge($proxyIp,$proxyPort,$url)==0){
 63                     $result[$url2]=0;
 64             }else{
 65                     $result[$url2]=1;
 66             }
 67             $output.="------------------------$url end -----------------------------\n";
 68         }
 69         $output.="</pre>\n";
 70     }else{
 71         foreach($clearUrls as $u){
 72             $result[$u]=-1;
 73         }
 74     }
 75 }
 76 ?>
 77 
 78 <!DOCTYPE html>
 79 <html xmlns="http://www.w3.org/1999/xhtml">
 80 <head>
 81 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 82 <title>刷新squid</title>
 83 <body>
 84 <?php
 85     if($result){
 86         echo "<table ><tr><td>URL</td><td>结果</td></tr>\n";
 87         foreach($result as $url=>$isOk){
 88             switch($isOk){
 89                 case 0://成功
 90                 $r="<font >成功</font>";
 91                 break;
 92                 case 1://成功
 93                 $r="<font color='red'>失败</font>";
 94                 break;
 95                 case -1://跳过
 96                 $r="<font color='Yellow'>跳过</font>";
 97                 break;
 98             }
 99             if($$proxySite){
100                 $url=str_replace($proxySite, $accessSite, $url);
101             }
102             echo "<tr><td>$url</td><td>$r</td></tr>\n";
103         }
104         echo "</table>\n";
105     }
106 ?>
107 
108 <form action="" method="post">
109 <table >
110 <tr><td>选择站点:</td></tr>
111 <tr><td>
112 <select name="accessSite" >
113     <?php
114         foreach($proxySites as $accessSite => $proxySite){
115         $isSelected=$_POST["accessSite"]==$accessSite?"selected":"";
116             echo "<option value='$accessSite' $isSelected>$accessSite</option>\n";
117         }
118     ?>
119 </select>
120 <script>
121     function view(){
122         location="?accessSite="+document.getElementById("accessSite").value+"&view=1";    
123     }    
124 </script>
125 <input type="checkbox" name="view" value="1" <?php echo $_POST["view"]?"checked":"";?>/><label for="view">只查看</label>
126 </td></tr>
127 <tr><td>输入一组URL(一个一行):</td></tr>
128 <tr><td><textarea name="urls" ><?php if($_POST["view"])foreach($cacheurls as $cacheurl){echo "$cacheurl\n";}?></textarea></td></tr>
129 <tr><td>刷新目录(一个一行):</td></tr>
130 <tr><td><textarea name="dirs" ></textarea></td></tr>
131 <tr><td><input type="submit" value="提交" /></td></tr>
132 </table>
133 </form>
134 <?php
135     echo $output;
136 ?>
137 </body></html>
138 <?php
139 //清除某个url
140 function purge($proxyIp,$proxyPort,$url)
141 {
142     global $output;
143     $host = parse_url($url);
144     $host = $host['host'];
145     $purge_url=str_replace("http://".$host,"/purge",$url);
146     if (empty($proxyIp)) {
147         $proxyIp = gethostbyname($host);
148     }
149     if (empty($proxyPort)) {
150         $proxyPort = "80";
151     }
152     $output.="正在从服务器".$proxyIp."更新".$url."\n";
153     $errstr = '';
154     $errno = '';
155     $fp = fsockopen ($proxyIp, $proxyPort, $errno, $errstr, 2);
156     if (!$fp)
157     {
158          $output.="连接失败!";
159          return -1;
160     }
161     else
162     {
163         $out = "GET ".$purge_url." HTTP/1.1\r\n";
164         $out .= "Host:".$host."\r\n";
165         $out .= "Connection: close\r\n\r\n";
166         $output.="***********request start**************\n";
167         $output.=$out;
168         $output.="***********request end **************\n";
169         fputs ($fp, $out);
170         $output.="***********response start**************\n";
171         //是否更新成功
172         $isOk=false;
173         while($out = fgets($fp , 4096)){
174             if(strpos($out,"200 OK\r\n")!==FALSE){
175                 //更新成功
176                 $isOk=true;
177             }
178             $output.=$out;
179             if($out=="\r\n"){
180                 break;
181             }
182         }
183         fclose ($fp);
184         $output.="***********response end **************\n";        
185         flush();
186         if($isOk){
187             return 0;
188         }else{
189             return 1;
190         }
191     }
192 }
193 
194 //递归扫描cache目录下所有文件路径
195 function scan_dir($dir) {
196         global $filedirs;
197         if (!is_dir($dir)) return false;
198         if ($dh = opendir($dir)) {
199             while (($file = readdir($dh)) !== false) {
200                 if ($file[0] == '.') continue;
201                 if($file=='swap.state')continue;
202                 $fullpath = "$dir/$file";
203                 $filedirs[] = $fullpath;
204                 if (is_dir($fullpath)) 
205                     scan_dir($fullpath); 
206             }
207             closedir($dh);
208         }
209         return $filedirs;
210 }
211 //从cache文件中提取真实的URL
212 function getUrlFromCacheFile($filename){
213         //cache文件头长度
214         $headerLen=0x1E;
215         $handle = fopen($filename, "rb");
216         if(!$handle){
217             return -1; 
218         }
219         //读取文件的前1k字节
220         $contents = fread($handle, 1024);
221         fclose($handle);
222         if(strlen($contents)<=$headerLen){
223             return -2; 
224         }
225         //截掉文件头
226         $contents=substr($contents,$headerLen);
227         
228         //cache文件的分隔符为\A
229         $pos=strpos($contents, chr(0x0A));
230         if($pos===FALSE){
231             return -3; 
232         }
233         //获取分隔符前的字符串
234         $contents="http://".substr($contents,0,$pos);
235         return $contents;
236 }
237 ?>