作者归档:admin

使用PHP取远程文件的大小的3种方法

1、【最傻最天真的方法】
将文件使用file_get_contents取回后,strlen
或者存为文件后使用filesize 嘿嘿

2、【使用get_headers】
如果没有打开allow_url_fopen
会显示waring
Warning: get_headers() [function.get-headers]: URL file-access is disabled in the server configuration
示例代码如下:

1
2
3
4
5
<?PHP
$a_array = get_headers($url, true);
$size = $a_array['Content-Length'];
Echo $size;
?>

3、【使用fsockopen,然后正则匹配出文件大小】
使用fsockopen向目标地址发送http request,然后根据服务器的response使用正则匹配

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
<?PHP
function get_file_size($url) {
    $url = parse_url($url);
 
    if (empty($url['host'])) {
        return false;
    }
 
    $url['port'] = empty($url['post']) ? 80 : $url['post'];
    $url['path'] = empty($url['path']) ? '/' : $url['path'];
 
    $fp = fsockopen($url['host'], $url['port'], $error);
 
    if($fp) {
        fputs($fp, "GET " . $url['path'] . " HTTP/1.1\r\n");
        fputs($fp, "Host:" . $url['host']. "\r\n\r\n");
 
        while (!feof($fp)) {
            $str = fgets($fp);
            if (trim($str) == '') {
                break;
            }elseif(preg_match('/Content-Length:(.*)/si', $str, $arr)) {
                return trim($arr[1]);
            }
        }
        fclose ( $fp);
        return false;
    }else {
        return false;
    }
}
 
?>

通过IP定位经纬度

由于需要给客户端提交数据接口并且数据中包括经纬度,然而数据库中只存储了IP,于是需要通过IP定位经纬度。

一开始查找是否存在Google API直接将IP转化成经纬度,没有,只有将地址转化成经纬度,开始其它查找,得到方案一和方案二:
【方案一】
使用闭关纪要21.地图人站点的IP查询经纬度和经纬度查询行政区划的服务
地址为:
http://dituren-service.appspot.com/services/ip_lookup?c=onIpLookupLoaded&ip=24.24.24.24
其实现思路为:采用IP库实现了通过IP得到一个地址的文字描述之后,再通过Google的地址解析服务去匹配经纬度,调用代码如下:

1
2
3
4
5
6
7
8
9
10
11
<?PHP
$url = "http://dituren-service.appspot.com/services/ip_lookup?c=onIpLookupLoaded&ip=24.24.24.24";
$content = @file_get_contents($url);
$result = array();
if (!empty($content)) {
    preg_match("/\((.*)\)/i", $content, $matches);
    $result = json_decode($matches[1], true);
}
print_r($result);
 
?>

【方案二】
使用http://www.blueforge.net/map/ 提供的IP地址查询服务
取数据代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?PHP
$arr = explode(" ", microtime());
$rst = $arr[1] . substr($arr[0], strpos($arr[0], '.') + 1, 3);
 
$url = "http://www.blueforge.net/map/?rs=get_ip_info&rst=&rsrnd=" . $rst . "&rsargs[]=" . $ip;
$rs = @file_get_contents($url);
preg_match("/{(.*)}/", $rs, $matches);
 
$str = '$arr=array(' . str_replace(':', '=>', $matches[1]) . ');';
$str = str_replace('parseFloat', 'floatVal', $str);
eval($str);
print_r($arr);
 
?>

由于作者是直接给JS用的,所以源地址返回的数据是JS代码,我在这里做了一个替换,将其变为PHP代码。
以上两种方法都是基于Google API,并且在速度和稳定性方面存在极大的隐患

【方案三】
比较好的方案是在本地有一个数据库存储了相关信息,直接取出来,
http://www.maxmind.com/ 这个网站提供了这样一个数据库,在其城市级的数据中,我们可以找到经纬度信息,网站提供了各种语言的程序实现,这里就不再多说了。
数据库下载地址:
http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz
PHP程序下载地址:
http://geolite.maxmind.com/download/geoip/api/php/

方案三存在两个问题:

1、一些数据不全
2、存在一些乱码,特别是城市相关信息

迎春舞会之集体舞

【问题描述】
背景 Background
  HNSDFZ的同学们为了庆祝春节,准备排练一场舞会。
【描述 Description 】
  表演者排成n排,构成一个向前的正三角形(在屏幕上,即向下)。而就每个人,他有可能正面朝前(小的向前正三角形)、或向后三角形(小的向后正三角形)。
  然而这些人在服装上有明显区别——一部分穿冬季校服,其他的穿夏季校服。
  现在给出每个人的着衣情况,请你求穿夏季校服的同学所构成的最大正三角形,输出所含人数。

输入格式 Input Format
  第一排为n。
  接下来n排,第i排有2*i-1个有效字符(‘#’或‘-’,分别表示此同学穿冬季校服或穿夏季校服)。输入文件中出现空格,且空格只是为了保持整个三角形的形状。

【输出格式 Output Format】
  输出人数。

【样例输入 Sample Input】
5
#-##—-#
—–#-
—#-
-#-
-

样例输出 Sample Output
9

注释 Hint
n<=100 【算法分析】 对于三角形有两种情况: 尖向下时: f1[i][j]+=min(f1[i-1][j-1],f1[i-1][j],f1[i-1][j+1]) 尖向上时: f2[i][j]+=min(f2[i+1][j-1],f2[i+1][j],f2[i+1][j-1]) 而且一定要仔细看题目给的三角形   “他有可能正面朝前(小的向前正三角形)、或向后三角形(小的向后正三角形)” 注意几点: 1.尖向上的情况,只能是一行中的偶数个 2.尖向下的情况,只能是一行中的奇数个 代码

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
#include <stdio.h>
#include <string.h>
 
#define min(a,b) a<b?a:b
 
int main()
{
       char ch[300][300];
       int f[300][300];
       int n, i, j, k, flag, max = 1, len;
 
       scanf("%d", &n);
       getchar();
 
       for (i = 0; i < n; i++)
       {
              gets(ch[i]);
       }
 
       memset(f, 0, sizeof(f));
       j = 0;
 
       while (ch[0][j] == ' ')
              j++;
 
       k = 1;
 
       while (j < strlen(ch[0]))
       {
              if (ch[0][j] == '#')
                     f[0][k++] = 0;
              else if (ch[0][j] == '-')
                     f[0][k++] = 1;
              j++;
       }
       for (i = 1; i < n; i++)
       {
              j = 0;
              while (ch[i][j] == ' ')
                     j++;
 
              k = i;
              flag = 0;
 
              while (ch[i][j] != '\0')
              {
                     if (ch[i][j] != ' ')
                     {
                            flag++;
                            k++;
 
                            if (ch[i][j] == '-')
                            {
                                   f[i][k] = 1;
                                   if (flag % 2 == 1)  //向下的三角形
                                   {
                                          if (f[i - 1][k] != 0 && f[i - 1][k - 1] != 0 && f[i - 1][k + 1] != 0)
                                          {
                                                 f[i][k] += min(f[i - 1][k - 1], f[i - 1][k + 1]);
                                          }
                                   }
                                   else  //向上的三角形
                                   {
                                          if (f[i][k - 1] != 0 && f[i][k - 2] != 0 && f[i - 1][k - 1] != 0)
                                          {
                                                 f[i][k] += min(f[i][k - 2], f[i - 1][k - 1]);
                                          }                                 
                                   }
 
                                   if (f[i][k] > max)
                                          max = f[i][k];
                            }
                     }
                     j++;
              }
       }
 
       printf("%d\n", max * (max * 2 -1 + 1) / 2);
       return 0;
}