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
} ?
?
?
显示彩虹字符串
用于显示彩虹字符串,支持UTF8和中文,效果如下:
function color_txt($str){
? ? $len ? ? ? ?= mb_strlen($str);
? ? $colorTxt ? = '';
? ? for($i=0; $i
? ? ? ? $colorTxt .= ?''.mb_substr($str,$i,1,'utf-8').'';
? ? }
? ? 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来做转发, 为用户提供文件下载.
$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);
?
但是这个有一个问题, 就是如果文件是中文名的话, 有的用户可能下载后的文件名是乱码.
?
于是, 我们做一下修改(参考: :
$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直接把文件发送给用户呢?
?
今天, 我看到了一个有意思的文章: How I PHP: X-SendFile.
?
我们可以使用Apache的module mod_xsendfile, 让Apache直接发送这个文件给用户:
$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="' . basename($file) . '"');
//让Xsendfile发送文件
header("X-Sendfile: $file");
?
X-Sendfile头将被Apache处理, 并且把响应的文件直接发送给Client.
Lighttpd和Nginx也有类似的模块, 大家有兴趣的可以去找找看
?
?
配置htaccess文件隐藏index.php
用于在apache环境下面隐藏URL地址中的index.php
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L]
?
?
去除PHP代码中的空白和注释
PHP内置了一个php_strip_whitespace方法用于读取php文件并去除代码中的空白和注释,但不支持直接读取内容去除空白和注释,下面的方法则可以支持读取字符串内容,并且ThinkPHP框架内置了该方法。
/**
?* 去除代码中的空白和注释
?* @param string $content 代码内容
?* @return string
?*/
function strip_whitespace($content) {
? ? $stripStr ? = '';
? ? //分析php源码
? ? $tokens ? ? = token_get_all($content);
? ? $last_space = false;
? ? for ($i = 0, $j = count($tokens); $i
? ? ? ? if (is_string($tokens[$i])) {
? ? ? ? ? ? $last_space = false;
? ? ? ? ? ? $stripStr ?.= $tokens[$i];
? ? ? ? } else {
? ? ? ? ? ? switch ($tokens[$i][0]) {
? ? ? ? ? ? ? ? //过滤各种PHP注释
? ? ? ? ? ? ? ? case T_COMMENT:
? ? ? ? ? ? ? ? case T_DOC_COMMENT:
? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? //过滤空格
? ? ? ? ? ? ? ? case T_WHITESPACE:
? ? ? ? ? ? ? ? ? ? if (!$last_space) {
? ? ? ? ? ? ? ? ? ? ? ? $stripStr ?.= ' ';
? ? ? ? ? ? ? ? ? ? ? ? $last_space = true;
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? case T_START_HEREDOC:
? ? ? ? ? ? ? ? ? ? $stripStr .= "
? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? case T_END_HEREDOC:
? ? ? ? ? ? ? ? ? ? $stripStr .= "THINK;\n";
? ? ? ? ? ? ? ? ? ? for($k = $i+1; $k
? ? ? ? ? ? ? ? ? ? ? ? if(is_string($tokens[$k]) && $tokens[$k] == ';') {
? ? ? ? ? ? ? ? ? ? ? ? ? ? $i = $k;
? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? ? ? ? ? } else if($tokens[$k][0] == T_CLOSE_TAG) {
? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? default:
? ? ? ? ? ? ? ? ? ? $last_space = false;
? ? ? ? ? ? ? ? ? ? $stripStr ?.= $tokens[$i][1];
? ? ? ? ? ? }
? ? ? ? }
? ? }
? ? return $stripStr;
}
?
?
检查字符串是否是UTF8编码
用于判断某个字符串是否采用UTF8编码
function is_utf8($string){
? ? return preg_match('%^(?:
? ? ? ? ?[\x09\x0A\x0D\x20-\x7E] ? ? ? ? ? ?# ASCII
? ? ? ?| [\xC2-\xDF][\x80-\xBF] ? ? ? ? ? ? # non-overlong 2-byte
? ? ? ?| ?\xE0[\xA0-\xBF][\x80-\xBF] ? ? ? ?# excluding overlongs
? ? ? ?| [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} ?# straight 3-byte
? ? ? ?| ?\xED[\x80-\x9F][\x80-\xBF] ? ? ? ?# excluding surrogates
? ? ? ?| ?\xF0[\x90-\xBF][\x80-\xBF]{2} ? ? # planes 1-3
? ? ? ?| [\xF1-\xF3][\x80-\xBF]{3} ? ? ? ? ?# planes 4-15
? ? ? ?| ?\xF4[\x80-\x8F][\x80-\xBF]{2} ? ? # plane 16
? ?)*$%xs', $string);
}
?
?
XSS安全过滤
来源于网络,用于对字符串进行XSS安全过滤。
function remove_xss($val) {
? ?// remove all non-printable characters. CR(0a) and LF(0b) and TAB(9) are allowed
? ?// this prevents some character re-spacing such as
? ?// note that you have to handle splits with \n, \r, and \t later since they *are* allowed in some inputs
? ?$val = preg_replace('/([\x00-\x08,\x0b-\x0c,\x0e-\x19])/', '', $val);
? ?// straight replacements, the user should never need these since they're normal characters
? ?// this prevents like
? ?$search = 'abcdefghijklmnopqrstuvwxyz';
? ?$search .= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
? ?$search .= '1234567890!@#$%^&*()';
? ?$search .= '~`";:?+/={}[]-_|\'\\';
? ?for ($i = 0; $i
? ? ? // ;? matches the ;, which is optional
? ? ? // 0{0,7} matches any padded zeros, which are optional and go up to 8 chars
? ? ? // @ @ search for the hex values
? ? ? $val = preg_replace('/([xX]0{0,8}'.dechex(ord($search[$i])).';?)/i', $search[$i], $val); // with a ;
? ? ? // @ @ 0{0,7} matches '0' zero to seven times
? ? ? $val = preg_replace('/(?{0,8}'.ord($search[$i]).';?)/', $search[$i], $val); // with a ;
? ?}
? ?// now the only remaining whitespace attacks are \t, \n, and \r
? ?$ra1 = array('javascript', 'vbscript', 'expression', 'applet', 'meta', 'xml', 'blink', 'link', 'style', 'script', 'embed', 'object', 'iframe', 'frame', 'frameset', 'ilayer', 'layer', 'bgsound', 'title', 'base');
? ?$ra2 = array('onabort', 'onactivate', 'onafterprint', 'onafterupdate', 'onbeforeactivate', 'onbeforecopy', 'onbeforecut', 'onbeforedeactivate', 'onbeforeeditfocus', 'onbeforepaste', 'onbeforeprint', 'onbeforeunload', 'onbeforeupdate', 'onblur', 'onbounce', 'oncellchange', 'onchange', 'onclick', 'oncontextmenu', 'oncontrolselect', 'oncopy', 'oncut', 'ondataavailable', 'ondatasetchanged', 'ondatasetcomplete', 'ondblclick', 'ondeactivate', 'ondrag', 'ondragend', 'ondragenter', 'ondragleave', 'ondragover', 'ondragstart', 'ondrop', 'onerror', 'onerrorupdate', 'onfilterchange', 'onfinish', 'onfocus', 'onfocusin', 'onfocusout', 'onhelp', 'onkeydown', 'onkeypress', 'onkeyup', 'onlayoutcomplete', 'onload', 'onlosecapture', 'onmousedown', 'onmouseenter', 'onmouseleave', 'onmousemove', 'onmouseout', 'onmouseover', 'onmouseup', 'onmousewheel', 'onmove', 'onmoveend', 'onmovestart', 'onpaste', 'onpropertychange', 'onreadystatechange', 'onreset', 'onresize', 'onresizeend', 'onresizestart', 'onrowenter', 'onrowexit', 'onrowsdelete', 'onrowsinserted', 'onscroll', 'onselect', 'onselectionchange', 'onselectstart', 'onstart', 'onstop', 'onsubmit', 'onunload');
? ?$ra = array_merge($ra1, $ra2);
? ?$found = true; // keep replacing as long as the previous round replaced something
? ?while ($found == true) {
? ? ? $val_before = $val;
? ? ? for ($i = 0; $i
? ? ? ? ?$pattern = '/';
? ? ? ? ?for ($j = 0; $j
? ? ? ? ? ? if ($j > 0) {
? ? ? ? ? ? ? ?$pattern .= '(';
? ? ? ? ? ? ? ?$pattern .= '([xX]0{0,8}([9ab]);)';
? ? ? ? ? ? ? ?$pattern .= '|';
? ? ? ? ? ? ? ?$pattern .= '|(?{0,8}([9|10|13]);)';
? ? ? ? ? ? ? ?$pattern .= ')*';
? ? ? ? ? ? }
? ? ? ? ? ? $pattern .= $ra[$i][$j];
? ? ? ? ?}
? ? ? ? ?$pattern .= '/i';
? ? ? ? ?$replacement = substr($ra[$i], 0, 2).'
? ? ? ? ?$val = preg_replace($pattern, $replacement, $val); // filter out the hex tags
? ? ? ? ?if ($val_before == $val) {
? ? ? ? ? ? // no replacements were made, so exit the loop
? ? ? ? ? ? $found = false;
? ? ? ? ?}
? ? ? }
? ?}
? ?return $val;
}
?
?
COOKIE用法示例
cookie方法是ThinkPHP内置的函数,用于完成cookie的设置、获取和删除操作。
设置
cookie('name','value'); ?//设置cookie
cookie('name','value',3600); // 指定cookie保存时间为1小时
?
高级设置
cookie('name','value',array('expire'=>3600,'prefix'=>'think_')); // 指定有效期和前缀
// 下面的代码和上面等效
cookie('name','value','expire=3600&prefix=think_')
?
获取
$value = cookie('name');
?
无论是否设置了前缀参数,cookie方法会自动判断。
删除
删除某个cookie值,可以用:
cookie('name',null);
?
如果需要清空cookie,可以用:
cookie(null); // 清空当前设定前缀的所有cookie值
cookie(null,'think_'); // ?清空指定前缀的所有cookie值
?
?
验证码不能显示?通常都是BOM信息惹的祸此代码能解决验证码不能显示问题.(批量去除BOM信息的代码)
有时,我们在本地测试环境中需要显示验证码的地方没有问题,一旦布置到服务器上去的时候.需要显示验证码的地方无法显示?如果你也碰到同样问题,请往下看.
问题的原因大部分是BOM头信息造成的,通常thinkphp的配置文件都要去除BOM头信息.什么是BOM头信息?百度一下就知道啦.
我通常的解决办法是,布置到服务器上去之后,新建一个去除所有文件的BOM头信息的代码文件.然后运行之即可.
比如:我在服务器根目录新建一个delBom.php文件.运行http://www.xxx.com/delBom.php即可.代码如下:
if (isset($_GET['dir'])){ //设置文件目录 ?
$basedir=$_GET['dir']; ?
}else{ ?
$basedir = '.'; ?
} ?
$auto = 1; ?
checkdir($basedir); ?
function checkdir($basedir){ ?
if ($dh = opendir($basedir)) { ?
? while (($file = readdir($dh)) !== false) { ?
? ?if ($file != '.' && $file != '..'){ ?
? ? if (!is_dir($basedir."/".$file)) { ?
? ? ?echo "filename: $basedir/$file ".checkBOM("$basedir/$file")."
"; ?
? ? }else{ ?
? ? ?$dirname = $basedir."/".$file; ?
? ? ?checkdir($dirname); ?
? ? } ?
? ?} ?
? } ?
closedir($dh); ?
} ?
} ?
function checkBOM ($filename) { ?
global $auto; ?
$contents = file_get_contents($filename); ?
$charset[1] = substr($contents, 0, 1); ?
$charset[2] = substr($contents, 1, 1); ?
$charset[3] = substr($contents, 2, 1); ?
if (ord($charset[1]) == 239 && ord($charset[2]) == 187 && ord($charset[3]) == 191) { ?
? if ($auto == 1) { ?
? ?$rest = substr($contents, 3); ?
? ?rewrite ($filename, $rest); ?
? ?return ("BOM found, automatically removed._http://www.k686.com"); ?
? } else { ?
? ?return ("BOM found."); ?
? } ?
} ?
else return ("BOM Not Found."); ?
} ?
function rewrite ($filename, $data) { ?
$filenum = fopen($filename, "w"); ?
flock($filenum, LOCK_EX); ?
fwrite($filenum, $data); ?
fclose($filenum); ?
} ?
?> ?
?
?
U方法使用示例,地址方法,在模型或模板中都可以使用
U方法是ThinkPHP中用于自动生成URL地址的方法,能够帮助你因为不同的环境和配置而自动生成对应的URL地址。
特点如下:
1、自动识别当前的URL模式
2、自动识别当前的PATH_INFO分隔符
3、域名和二级域名支持
4、伪静态和锚点支持
5、路由地址支持
因此,在使用U方法的时候,你基本上不需要关注当前使用的是什么URL模式和什么配置参数,按照U方法统一的规则调用即可,在实际生成URL地址的时候U方法会自动识别。
下面是一些基本的用法:
// 当前模块的read操作地址,传入参数id为5
U('read','id=5');
?
如果要传入变量,则用:
U('read','id='.$vo['id']);
?
如果你的U方法是在模板调用,一般需要写成:
?
生成Blog模块的index操作地址,并传入更多的参数:
U('blog/index','cate_id=5&type=1');
?
当然,也可以使用数组传参:
U('blog/index',array('cate_id'=>5,'type'=>1));
?
如果参数比较少,也可以直接在第一个参数中传入:
U('Blog/read?id=5');?
U('Blog/cate?cate_id=1&status=1')
?
支持分组生成:
U('Home/Blog/read?id=5'); // Home分组下面的blog模块的read操作地址?
U('Admin/Blog/cate?cate_id=1&status=1');// Admin分组
?
表示
U方法会自动加上当前配置的伪静态后缀,如果你配置了多个伪静态后缀,则默认会加上第一个,如果需要指定伪静态后缀,也可以使用:
U('Blog/read','id=1','xml');
?
表示输出伪静态后缀为.xml的URL地址
?
如果要使用U方法输出路由地址,则需要在第一个参数前加上"/",例如:
U('/news/1');
?
则表示要生成的URL地址是 news/1 这样的路由地址。
?
如果需要生成带域名的URL地址,可以使用:
U('Blog/read@blog.thinkphp.cn','id=1');
?
或者
U('Blog/read@blog','id=1');
?
表示采用当前域名的blog二级域名地址。
?
支持锚点生成(注意需要更新最新的Git版本才能支持)
U('Blog/read#review','id=5');
?
生成的URL地址最后会带上 #review 锚点,便于跳转到评论部分。
?
?
设置图片的HTTP缓存,也可以设置JS和CSS的
如果是Apache环境下面,可以在.htaccess文件中添加下面的代码,用于设置图片的HTTP缓存和有效期(需要开启apache的headers模块支持),减少网站的图片资源请求压力,提高访问速度和你的pagespeed值^_^。
Header set Cache-Control "max-age=604800"
?
上面的代码设置了网站的图片使用为期一周的HTTP缓存,当然,你一样可以给js或者css文件加上http缓存哦。
?
?
检查字符串中是否有外链
/**
?* all_external_link 检测字符串是否包含外链
?* @param ?string ?$text 文字
?* @param ?string ?$host 域名
?* @return boolean ? ? ? false 有外链 true 无外链
?*/
function all_external_link($text = '', $host = '') {
? ? if (empty($host)) $host = $_SERVER['HTTP_HOST'];
? ? $reg = '/http(?:s?):\/\/((?:[A-za-z0-9-]+\.)+[A-za-z]{2,4})/';
? ? preg_match_all($reg, $text, $data);
? ? $math = $data[1];
? ? foreach ($math as $value) {
? ? ? ? if($value != $host) return false;
? ? }
? ? return true;
}
?
?
在htaccess中设置域名重定向
仅用于Apache环境下面,可以在htaccess文件中添加下面的代码,当访问abc.com的时候会重定向到www.abc.com,当然你也可以设置重定向到其它的域名。
RewriteEngine on
RewriteCond %{HTTP_HOST} ^abc.com$ [NC]
RewriteRule ^(.*)$ http://www.abc.com/$1 [R=301,L]
?
?
PHP获取客户端的IP、地理信息、浏览器信息、本地真实IP
?// 作用取得客户端的ip、地理信息、浏览器、本地真实IP
?class get_gust_info {?
??
? ////获得访客浏览器类型
? function GetBrowser(){
? ?if(!empty($_SERVER['HTTP_USER_AGENT'])){
? ? $br = $_SERVER['HTTP_USER_AGENT'];
? ? if (preg_match('/MSIE/i',$br)) { ? ?
? ? ? ? ? ? ? ?$br = 'MSIE';
? ? ? ? ? ? ?}elseif (preg_match('/Firefox/i',$br)) {
? ? ?$br = 'Firefox';
? ? }elseif (preg_match('/Chrome/i',$br)) {
? ? ?$br = 'Chrome';
? ? ? ?}elseif (preg_match('/Safari/i',$br)) {
? ? ?$br = 'Safari';
? ? }elseif (preg_match('/Opera/i',$br)) {
? ? ? ? $br = 'Opera';
? ? }else {
? ? ? ? $br = 'Other';
? ? }
? ? return $br;
? ?}else{return "获取浏览器信息失败!";}?
? }
??
? ////获得访客浏览器语言
? function GetLang(){
? ?if(!empty($_SERVER['HTTP_ACCEPT_LANGUAGE'])){
? ? $lang = $_SERVER['HTTP_ACCEPT_LANGUAGE'];
? ? $lang = substr($lang,0,5);
? ? if(preg_match("/zh-cn/i",$lang)){
? ? ?$lang = "简体中文";
? ? }elseif(preg_match("/zh/i",$lang)){
? ? ?$lang = "繁体中文";
? ? }else{
? ? ? ? $lang = "English";
? ? }
? ? return $lang;
? ??
? ?}else{return "获取浏览器语言失败!";}
? }
??
? ?////获取访客操作系统
? function GetOs(){
? ?if(!empty($_SERVER['HTTP_USER_AGENT'])){
? ? $OS = $_SERVER['HTTP_USER_AGENT'];
? ? ? if (preg_match('/win/i',$OS)) {
? ? ?$OS = 'Windows';
? ? }elseif (preg_match('/mac/i',$OS)) {
? ? ?$OS = 'MAC';
? ? }elseif (preg_match('/linux/i',$OS)) {
? ? ?$OS = 'Linux';
? ? }elseif (preg_match('/unix/i',$OS)) {
? ? ?$OS = 'Unix';
? ? }elseif (preg_match('/bsd/i',$OS)) {
? ? ?$OS = 'BSD';
? ? }else {
? ? ?$OS = 'Other';
? ? }
? ? ? ? ? return $OS; ?
? ?}else{return "获取访客操作系统信息失败!";} ??
? }
??
? ////获得访客真实ip
? function Getip(){
? ?if(!empty($_SERVER["HTTP_CLIENT_IP"])){ ??
? ? ? $ip = $_SERVER["HTTP_CLIENT_IP"];
? ?}
? ?if(!empty($_SERVER['HTTP_X_FORWARDED_FOR'])){ //获取代理ip
? ? $ips = explode(',',$_SERVER['HTTP_X_FORWARDED_FOR']);
? ?}
? ?if($ip){
? ? ? $ips = array_unshift($ips,$ip);?
? ?}
? ?
? ?$count = count($ips);
? ?for($i=0;$i
? ? ?if(!preg_match("/^(10|172\.16|192\.168)\./i",$ips[$i])){//排除局域网ip
? ? ? $ip = $ips[$i];
? ? ? break; ? ?
? ? ? } ?
? ?} ?
? ?$tip = empty($_SERVER['REMOTE_ADDR']) ? $ip : $_SERVER['REMOTE_ADDR'];?
? ?if($tip=="127.0.0.1"){ //获得本地真实IP
? ? ? return $this->get_onlineip(); ??
? ?}else{
? ? ? return $tip;?
? ?}
? }
??
? ////获得本地真实IP
? function get_onlineip() {
? ? ? $mip = file_get_contents("http://city.ip138.com/city0.asp");
? ? ? ?if($mip){
? ? ? ? ? ?preg_match("/\[.*\]/",$mip,$sip);
? ? ? ? ? ?$p = array("/\[/","/\]/");
? ? ? ? ? ?return preg_replace($p,"",$sip[0]);
? ? ? ?}else{return "获取本地IP失败!";}
? ?}
??
? ////根据ip获得访客所在地地名
? function Getaddress($ip=''){
? ?if(empty($ip)){
? ? ? ?$ip = $this->Getip(); ? ?
? ?}
? ?$ipadd = file_get_contents("http://int.dpool.sina.com.cn/iplookup/iplookup.php?ip=".$ip);//根据新浪api接口获取
? ?if($ipadd){
? ? $charset = iconv("gbk","utf-8",$ipadd); ??
? ? preg_match_all("/[\x{4e00}-\x{9fa5}]+/u",$charset,$ipadds);
? ??
? ? return $ipadds; ? //返回一个二维数组
? ?}else{return "addree is none";} ?
? }?
?}
?$gifo = new get_gust_info();
?echo "你的ip:".$gifo->Getip();
?echo "
所在地:";
?$ipadds = $gifo->Getaddress();
?foreach($ipadds[0] as $value){
? ? ?echo "\r\n ? ?".iconv("utf-8","gbk",$value); ? ?
?}
?
?echo "
浏览器类型:".$gifo->GetBrowser();
?echo "
浏览器语言:".$gifo->GetLang();
?echo "
操作系统:".$gifo->GetOs();
??
?
??>
?
?
URL安全的字符串base64编码和解码
如果直接使用base64_encode和base64_decode方法的话,生成的字符串可能不适用URL地址。下面的方法可以解决该问题: URL安全的字符串编码:
function urlsafe_b64encode($string) {
? ?$data = base64_encode($string);
? ?$data = str_replace(array('+','/','='),array('-','_',''),$data);
? ?return $data;
}
?
URL安全的字符串解码:
function urlsafe_b64decode($string) {
? ?$data = str_replace(array('-','_'),array('+','/'),$string);
? ?$mod4 = strlen($data) % 4;
? ?if ($mod4) {
? ? ? ?$data .= substr('====', $mod4);
? ?}
? ?return base64_decode($data);
}
?
?
获取客户端浏览器信息
/**
?* 获取客户端浏览器类型
?* @param ?string $glue 浏览器类型和版本号之间的连接符
?* @return string|array 传递连接符则连接浏览器类型和版本号返回字符串否则直接返回数组 false为未知浏览器类型
?*/
function get_client_browser($glue = null) {
? ? $browser = array();
? ? $agent = $_SERVER['HTTP_USER_AGENT']; //获取客户端信息
? ??
? ? /* 定义浏览器特性正则表达式 */
? ? $regex = array(
? ? ? ? 'ie' ? ? ?=> '/(MSIE) (\d+\.\d)/',
? ? ? ? 'chrome' ?=> '/(Chrome)\/(\d+\.\d+)/',
? ? ? ? 'firefox' => '/(Firefox)\/(\d+\.\d+)/',
? ? ? ? 'opera' ? => '/(Opera)\/(\d+\.\d+)/',
? ? ? ? 'safari' ?=> '/Version\/(\d+\.\d+\.\d) (Safari)/',
? ? );
? ? foreach($regex as $type => $reg) {
? ? ? ? preg_match($reg, $agent, $data);
? ? ? ? if(!empty($data) && is_array($data)){
? ? ? ? ? ? $browser = $type === 'safari' ? array($data[2], $data[1]) : array($data[1], $data[2]);
? ? ? ? ? ? break;
? ? ? ? }
? ? }
? ? return empty($browser) ? false : (is_null($glue) ? $browser : implode($glue, $browser));
}
?
?
时间戳友好化格式化函数 显示刚刚,几秒前
在一些微博系统中经常要将时间于现在时间相比显示为多久以前发布的,如显示为:刚刚、5秒前、5小时前、5天前..这种
/**
?*
?+--------------------------------
?* Description 友好显示时间
?+--------------------------------
?* @param int $time 要格式化的时间戳 默认为当前时间
?+--------------------------------
?* @return string $text 格式化后的时间戳
?+--------------------------------
?* @author yijianqing
?+--------------------------------
?*/
function mdate($time = NULL) {
? ? $text = '';
? ? $time = $time === NULL || $time > time() ? time() : intval($time);
? ? $t = time() - $time; //时间差 (秒)
? ? if ($t == 0)
? ? ? ? $text = '刚刚';
? ? elseif ($t
? ? ? ? $text = $t . '秒前'; // 一分钟内
? ? elseif ($t
? ? ? ? $text = floor($t / 60) . '分钟前'; //一小时内
? ? elseif ($t
? ? ? ? $text = floor($t / (60 * 60)) . '小时前'; // 一天内
? ? elseif ($t
? ? ? ? $text = floor($time/(60*60*24)) ==1 ?'昨天 ' . date('H:i', $time) : '前天 ' . date('H:i', $time) ; //昨天和前天
? ? elseif ($t
? ? ? ? $text = date('m月d日 H:i', $time); //一个月内
? ? elseif ($t
? ? ? ? $text = date('m月d日', $time); //一年内
? ? else
? ? ? ? $text = date('Y年m月d日', $time); //一年以前
? ? return $text;
}
?
使用此函数,我们只需在前台用
{$vo.time|mdate}
?
实现时间友好化显示了
?
?
将返回的数据集转换成树结构
/**
?* 将返回的数据集转换成树
?* @param ?array ? $list ?数据集
?* @param ?string ?$pk ? ?主键
?* @param ?string ?$pid ? 父节点名称
?* @param ?string ?$child 子节点名称
?* @param ?integer $root ?根节点ID
?* @return array ? ? ? ? ?转换后的树
?*/
function list_to_tree($list, $pk = 'id', $pid = 'pid', $child = '_child', $root=0) {
? ? $tree = array();// 创建Tree
? ? if(is_array($list)) {
? ? ? ? // 创建基于主键的数组引用
? ? ? ? $refer = array();
? ? ? ? foreach ($list as $key => $data) {
? ? ? ? ? ? $refer[$data[$pk]] =& $list[$key];
? ? ? ? }
? ? ? ??
? ? ? ? foreach ($list as $key => $data) {
? ? ? ? ? ? // 判断是否存在parent
? ? ? ? ? ? $parentId = $data[$pid];
? ? ? ? ? ? if ($root == $parentId) {
? ? ? ? ? ? ? ? $tree[$data[$pk]] =& $list[$key];
? ? ? ? ? ? }else{
? ? ? ? ? ? ? ? if (isset($refer[$parentId])) {
? ? ? ? ? ? ? ? ? ? $parent =& $refer[$parentId];
? ? ? ? ? ? ? ? ? ? $parent[$child][] =& $list[$key];
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? }
? ? }
? ? return $tree;
}
?
?
头像编辑-当不改变头像时
目前是这么做的 将上传判断代码段
?/* ?if(!$upload->upload()) {// 上传错误提示错误信息
? ? $this->error($upload->getErrorMsg());
?}else{// 上传成功 获取上传文件信息?
? ? $info = ?$upload->getUploadFileInfo();
?} ?*/
?
改为:
$upload->upload();
$info = ?$upload->getUploadFileInfo();
?
这样即使不上传图片也不提示错误, 然后在上传页面 添加
?
?
在update()方法中做如下判断:
if(is_null($info[0]["savename"])){
? ? $data['face']=$_POST['face'];
}else{
? ? $data['face']=$info[0]["savename"];
}
?
?
合并数组函数
调用PHP原生的array_merge时,如果第一个参数为空,则会导致返回结果为空。这个函数做了相应处理。
function MergeArray($list1,$list2)
{
? ? if(!isEmpty($list1) && !isEmpty($list2))?
? ? {
? ? ? ? return array_merge($list1,$list2);
? ? }
? ? else return (isEmpty($list1)?(isEmpty($list2)?null:$list2):$list1);
}
function isEmpty($data)
{
? ? return null == $data || false == $data || "" == $data;
}
?
?
Google翻译插件调用,采用CURL调取
调用Google翻译的接口,需要开启curl支持。
? ? /*
? ? ? ? Google翻译函数 by QQ366958903
? ? ? ? $text ? ?要翻译的文本
? ? ? ? $tl ? ? ? ?目标语言
? ? ? ? $sl ? ? ? ?原语言
? ? ? ? $ie ? ? ? ?字符编码
? ? */
? ??
? ? function translate($text='',$tl='zh-CN',$sl='auto',$ie='UTF-8'){
? ? ? ? $ch = curl_init('http://translate.google.cn/');
? ? ? ? curl_setopt($ch,CURLOPT_RETURNTRANSFER, 1);
? ? ? ? curl_setopt($ch, CURLOPT_POSTFIELDS,"&hl=zh-CN&sl={$sl}&ie={$ie}&tl={$tl}&text=".urlencode($text));?
? ? ? ? $html = curl_exec($ch);
? ? ? ? preg_match('#(.*?)