Thinkphp 代码
获取客户端IP地址
?
获取客户端IP地址
$type表示返回类型 0 返回IP地址 1 返回IPV4地址数字
function get_client_ip($type = 0) {
? ? $type ? ? ? = ?$type ? 1 : 0;
? ? static $ip ?= ? NULL;
? ? if ($ip !== NULL) return $ip[$type];
? ? if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
? ? ? ? $arr ? ?= ? explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
? ? ? ? $pos ? ?= ? array_search('unknown',$arr);
? ? ? ? if(false !== $pos) unset($arr[$pos]);
? ? ? ? $ip ? ? = ? trim($arr[0]);
? ? }elseif (isset($_SERVER['HTTP_CLIENT_IP'])) {
? ? ? ? $ip ? ? = ? $_SERVER['HTTP_CLIENT_IP'];
? ? }elseif (isset($_SERVER['REMOTE_ADDR'])) {
? ? ? ? $ip ? ? = ? $_SERVER['REMOTE_ADDR'];
? ? }
? ? // IP地址合法验证
? ? $long = ip2long($ip);
? ? $ip ? = $long ? array($ip, $long) : array('0.0.0.0', 0);
? ? return $ip[$type];
}
?
?
文件字节大小格式化
?
字节格式化 把字节数格式为 B K M G T 描述的大小
function byte_format($size, $dec=2){
? ? $a = array("B", "KB", "MB", "GB", "TB", "PB");
? ? $pos = 0;
? ? while ($size >= 1024) {
? ? ? ? ?$size /= 1024;
? ? ? ? ? ?$pos++;
? ? }
? ? return round($size,$dec)." ".$a[$pos];
}
或者
function get_size($s,$u='B',$p=1){ ?
? ? $us = array('B'=>'K','K'=>'M','M'=>'G','G'=>'T'); ?
? ? return (($u!=='B')&&(!isset($us[$u]))||($s<1024))?(number_format($s,$p)." $u"):(get_size($s/1024,$us[$u],$p)); ?
} ?
?
?
显示彩虹字符串
用于显示彩虹字符串,支持UTF8和中文,效果如下:
function color_txt($str){
? ? $len ? ? ? ?= mb_strlen($str);
? ? $colorTxt ? = '';
? ? for($i=0; $i<$len; $i++) {
? ? ? ? $colorTxt .= ?'<span style="color:'.rand_color().'">'.mb_substr($str,$i,1,'utf-8').'</span>';
? ? }
? ? return $colorTxt;
}
function rand_color(){
? ? return '#'.sprintf("%02X",mt_rand(0,255)).sprintf("%02X",mt_rand(0,255)).sprintf("%02X",mt_rand(0,255));
}
?
?
让PHP更快的提供文件下载
一般来说, 我们可以通过直接让URL指向一个位于Document Root下面的文件, 来引导用户下载文件.
?
但是, 这样做, 就没办法做一些统计, 权限检查, 等等的工作. 于是, 很多时候, 我们采用让PHP来做转发, 为用户提供文件下载.
<?php
$file = "/tmp/dummy.tar.gz";
header("Content-type: application/octet-stream");
header('Content-Disposition: attachment; filename="' . basename($file) . '"');
header("Content-Length: ". filesize($file));
readfile($file);
?
但是这个有一个问题, 就是如果文件是中文名的话, 有的用户可能下载后的文件名是乱码.
?
于是, 我们做一下修改(参考: :
<?php
$file = "/tmp/中文名.tar.gz";
$filename = basename($file);
header("Content-type: application/octet-stream");
//处理中文文件名
$ua = $_SERVER["HTTP_USER_AGENT"];
$encoded_filename = urlencode($filename);
$encoded_filename = str_replace("+", "%20", $encoded_filename);
if (preg_match("/MSIE/", $ua)) {
header('Content-Disposition: attachment; filename="' . $encoded_filename . '"');
} else if (preg_match("/Firefox/", $ua)) {
header("Content-Disposition: attachment; filename*=\"utf8''" . $filename . '"');
} else {
header('Content-Disposition: attachment; filename="' . $filename . '"');
}
header('Content-Disposition: attachment; filename="' . $filename . '"');
header("Content-Length: ". filesize($file));
readfile($file);
?
恩, 现在看起来好多了, 不过还有一个问题, 那就是readfile, 虽然PHP的readfile尝试实现的尽量高效, 不占用PHP本身的内存, 但是实际上它还是需要采用MMAP(如果支持), 或者是一个固定的buffer去循环读取文件, 直接输出.
?
输出的时候, 如果是Apache + PHP mod, 那么还需要发送到Apache的输出缓冲区. 最后才发送给用户. 而对于Nginx + fpm如果他们分开部署的话, 那还会带来额外的网络IO.
?
那么, 能不能不经过PHP这层, 直接让Webserver直接把文件发送给用户呢?
?