各种编程语言中获取与转换Unix时间戳(Unix timestamp)

如何在不同编程语言中获取现在的Unix时间戳(Unix timestamp)?

Java time
JavaScript Math.round(new Date().getTime()/1000)
getTime()返回数值的单位是毫秒
Microsoft .NET / C# epoch = (DateTime.Now.ToUniversalTime().Ticks – 621355968000000000) / 10000000
MySQL SELECT unix_timestamp(now())
Perl time
PHP time()
PostgreSQL SELECT extract(epoch FROM now())
Python 先 import time 然后 time.time()
Ruby 获取Unix时间戳:Time.now 或 Time.new
显示Unix时间戳:Time.now.to_i
SQL Server SELECT DATEDIFF(s, ‘1970-01-01 00:00:00’, GETUTCDATE())
Unix / Linux date +%s
VBScript / ASP DateDiff(“s”, “01/01/1970 00:00:00”, Now())
其他操作系统
(如果Perl被安装在系统中)
命令行状态:perl -e “print time”

如何在不同编程语言中实现Unix时间戳(Unix timestamp) → 普通时间?

Java String date = new java.text.SimpleDateFormat(“dd/MM/yyyy HH:mm:ss”).format(new java.util.Date(Unix timestamp * 1000))
JavaScript 先 var unixTimestamp = new Date(Unix timestamp * 1000) 然后 commonTime = unixTimestamp.toLocaleString()
Linux date -d @Unix timestamp
MySQL from_unixtime(Unix timestamp)
Perl 先 my $time = Unix timestamp 然后 my ($sec, $min, $hour, $day, $month, $year) = (localtime($time))[0,1,2,3,4,5,6]
PHP date(‘r’, Unix timestamp)
PostgreSQL SELECT TIMESTAMP WITH TIME ZONE ‘epoch’ + Unix timestamp) * INTERVAL ‘1 second’;
Python 先 import time 然后 time.gmtime(Unix timestamp)
Ruby Time.at(Unix timestamp)
SQL Server DATEADD(s, Unix timestamp, ‘1970-01-01 00:00:00’)
VBScript / ASP DateAdd(“s”, Unix timestamp, “01/01/1970 00:00:00”)
其他操作系统
(如果Perl被安装在系统中)
命令行状态:perl -e “print scalar(localtime(Unix timestamp))”

PHP大括号的妙用

一、不管什么程序,function name(){}, for(){}, ….太多了,不说也知道做什么用了。
二、$str{4}在字符串的变量的后面跟上{}刚大括号和中括号一样都是把某个字符串变量当成数组处理。
三、{$val}这时候大括号起的作用就是,告诉PHP,括起来的要当成变量处理。
复制代码 代码如下:
$arr=array(0=>123, ‘name’=>’你好’);
foreach($array as $k=>$v){
echo “select * from blog_blogs where blog_tags like ‘%{$arr[$k]}%’ order by blog_id”; //加一个大括号只是将作为变量的标志符
}
echo ‘<br/ ><br/ ><br/ ><br/ ><br/ ><br/ ><br/ >’;
foreach($array as $k=>$v){
echo “select * from blog_blogs where blog_tags like ‘%{{$arr[$k]}}%’ order by blog_id”; //加两个大括号,外层的将作为普通的字符
}
//用大括号来区分变量
//echo “$arr[‘name’]”; //用此句会报语法错误
echo “{$arr[‘name’]}”; //此句正常,大括号内的字符将作为变量来处理
//$str{4} 在字符串的变量的后面跟上{} 大括号和中括号一样都是把某个字符串变量当成数组处理
$str = ‘abcdefg’;
echo $str{4};
{}大括号在php中的作用(PHP变量放在大括号里面的含义)

如:$sql = “insert into article (`channel_id`,`title`,`detail`,`pub_time`) values (‘{$cid}’,'{$title}’,'{$detail}’,'{$time}’);”;
不加似乎也可以,加{}是什么意思呢?
还有字段名 为什么要以“包括呢?

==============================================

至少便于阅读嘛~~~”是insert into语句要求的,因为字符串要成对出现嘛
加{}有时候是为了防止变量名和后面的字符串连在一起嘛
例如
{$cid}dd
如果cid=aa
那么{$cid}dd=aadd
不加的话你自己看看了$ciddd,岂不变成了ciddd变量了~~

PHP 变量后面加上一个大括号{},里面填上数字,就是指 PHP 变量相应序号的字符。
例如:
$str = ‘hello’;
echo $str{0}; // 输出为 h
echo $str{1}; // 输出为 e
如果要检查某个字符串是否满足多少长度,可以考虑用这种大括号(花括号)加 isset 的方式替代 strlen 函数,因为 isset 是语言结构,strlen 是函数,所以使用 isset 比使用 strlen 效率更高。
比如判断一个字符串的长度是否小于 5:
if ( !isset ( $str{5} ) ) 就比 if ( strlen ( $str ) < 5 ) 好。
下面几个比较能说明原因的解释是:

表示{}里面的是一个变量 ,执行时按照变量来处理 在字符串中引用变量使用的特殊包括方式,这样就可以不使用.运算符,从而减少代码的输入量了。

其实输出那块是等同于print “hello “.$arr[‘fruit’];

一、使用大括号的变量
前一篇日志提到了,PHP Notice警告的是下面一句:

switch (${action}.’_’.${child}) {
初看并没有什么问题。我也查询了PHP手册上关于变量的定义:这里。
1、可变变量的情况
可见,与大部分资料一样,变量使用大括号的情况,在于“可变变量”(Variable variables)。其中提到:
引用
In order to use variable variables with arrays, you have to resolve an ambiguity problem. That is, if you write $$a[1] then the parser needs to know if you meant to use $a[1] as a variable, or if you wanted $$a as the variable and then the [1] index from that variable. The syntax for resolving this ambiguity is: ${$a[1]} for the first case and ${$a}[1] for the second.
也就是说,为了在数组环境中也可以使用可变变量,因此,需要根据不同的情况,恰当的使用大括号{}限制变量的范围。${$a[1]} 与${$a}[1] 是完全不同的:
引用
${$a[1]} 这里$a[1]是一个变量;
${$a}[1] 这里$a是一个变量;
2、定界、避免歧义
实际上,这情况与可变变量时类似。例如,若使用“.”连接符,连接一个字符串,可能是这样:

echo $str.’_2010′;
用大括号来写,可能更简单:

echo “${str}_2010”;
可见,如果没有大括号,则可能把$str_2010整个作为一个变量来处理。当然,这样的写法,只能用在双引号中,单引号里面是不会执行变量替换的。

3、字符串变量中的单个字符
例如:
复制代码 代码如下:
<?php
$str=’000′;
$str{0}=’1′;
echo $str; //输出为100
?>

这不难理解,与中括号[]的作用是一致的,有点类似Python中把字符串看成对象的情况。所以,下面的语句功能相同:
复制代码 代码如下:
<?php
$str=’000′;
$str[0]=’1′;
echo $str; //也是输出100
?>

不过,这些都不是我想说明的内容,真正想描述的情况,请见下面。

二、变量使用大括号的异同 
首先,把PHP的错误信息输出全部打开,即/etc/php.ini 为:
引用
error_reporting = E_ALL
display_errors = On
然后,打开测试页面,其中代码为:
复制代码 代码如下:
<?php
$test=’123′;
echo $test;
echo “${test}”;
echo “{$test}”;
echo ${test}.’_’;
echo ${test};
?>

你会看到如下的结果:
引用
123123123
Notice: Use of undefined constant test – assumed ‘test’ in /var/www/html/phpcrm/testpages/variables.php on line 6
123_
Notice: Use of undefined constant test – assumed ‘test’ in /var/www/html/phpcrm/testpages/variables.php on line 7
123
这说明什么?
1、可接受的写法
从输出结果中“123123123”,表明前面三行的echo语句都是正常的:
复制代码 代码如下:
echo $test;
echo “${test}”;
echo “{$test}”;

2、不建议的写法
后面的两行都有Notice警告,也就是曾把test变量看成常量,只是后来才假设为变量来处理的。因此,为了避免歧义和冲突,不建议这样写:
复制代码 代码如下:
echo ${test}.’_’;
echo ${test};

不过,可以有一种变通的写法
复制代码 代码如下:
echo ${‘test’}.’_’;
echo ${‘test’};

这样写的话就不会报错了
3、不正确的写法
网上不少资料介绍,${var}与{$var}的作用是一样的。但是,如果你再加入一句:

echo {$test};
那么,你将会得到以下错误信息:
引用
Parse error: syntax error, unexpected ‘{‘ in /var/www/html/phpcrm/testpages/variables.php on line 8
这可不是Notice警告,是错误,因解析问题,程序将不能正常运行。

三、总结
结合前面两部分的内容,我相信,对于变量引用时使用大括号,应遵循以下原则:
引用
1、正确的写法为:${var} 的形式;
2、与双引号一同使用;
3、根据需表达的意思进行定界。
所以,最后我把switch一行改为:

switch (“${action}_${child}”) {
即不再出现Notice警告。

让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 = rawurlencode($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-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直接发送这个文件给用户:

<?php
    $file = "/tmp/中文名.tar.gz";
 
    $filename = basename($file);
 
    header("Content-type: application/octet-stream");
 
    //处理中文文件名
    $ua = $_SERVER["HTTP_USER_AGENT"];
    $encoded_filename = rawurlencode($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 . '"');
    }
 
    //让Xsendfile发送文件
    header("X-Sendfile: $file");

X-Sendfile头将被Apache处理, 并且把响应的文件直接发送给Client.

Lighttpd和Nginx也有类似的模块, 大家有兴趣的可以去找找看

PHP十六进制和ASCII互转

//ASCII 转 十六进制
function asc2hex($str) {
	return '\x'.substr(chunk_split(bin2hex($str), 2, '\x'),0,-2);
}
//十六进制 转 ASCII
function hex2asc($str) {
	$str = join('',explode('\x',$str));
	$len = strlen($str);
	for ($i=0;$i<$len;$i+=2) $data.=chr(hexdec(substr($str,$i,2)));
	return $data;
}

Linux下安装PHP Tidy扩展

一、进入PHP安装目录下的TIDY扩展目录,如:
cd /setup/php-5.2.17/ext/tidy

二、执行phpize生成编译文件,如:
/usr/local/php/bin/phpize

三、编译并生成扩展,如:
./configure –with-php-config=/usr/local/php/bin/php-config –enable-tidy
make
make install

若编译过程中提示错误 configure: WARNING: You will need re2c 0.13.4 or later if you want to regenerate PHP parsers ,先执行如下命令后再重新返回第三步操作:
wget http://sourceforge.net/projects/re2c/files/re2c/0.13.5/re2c-0.13.5.tar.gz/download
tar -zxvf re2c-0.13.5.tar.gz
cd re2c-0.13.5
./configure && make && make install

若编译过程中提示错误 configure: error: Cannot find libtidy ,先执行如下命令后再重新返回第三步操作:
yum install libtidy-devel
yum install libtidy

四、修改PHP.INI配置
vi /usr/local/php/etc/php.ini
插入扩展配置:extension = “tidy.so”

五、重启WEB服务器,完成

关于处理GET方式提交的含有特殊字符的参数

曾经有一位朋友遇到这样一个问题,一产品名称为A&T Plastic,在产品列表中就产生了这样的一个联接<a href=”product.asp?name=A&T Plastic”>A&T Plastic</a>,在服务器端接收此参数的时候怎么也无法接收到准确的产品名。
当时就问我,如何解决,也许是当时忙吧,随口告诉他用HTMLENCODE方法,对方试告诉并没有能解决这个问题。我当时没有再给予回答,偶尔想起实在是对不起,我讲错了。今日闲暇就整理了一下如何处理GET方式提交的含有特殊字符的参数,以表内心的愧疚。

特殊特殊字符的含义
————————————————————————————
字符 特殊字符的含义 URL编码
# 用来标志特定的文档位置 %23
% 对特殊字符进行编码 %25
& 分隔不同的变量值对 %26
+ 在变量值中表示空格 %2B
\ 表示目录路径 %2F
= 用来连接键和值 %3D
? 表示查询字符串的开始 %3F

当键值中含有以上列表中的一些字符时就无法准确的接收其中的值。
<!–文件名为01.asp–>
< %
‘定义含有特殊字符的字符串
str=”parameter=#%&+\=?value</html>”
‘用URLEncode方法进行编码
strurlencode=server.URLEncode(str)
‘用HTMLEncode方法进行编码
strhtmlencode=server.HTMLEncode (str)
‘显示所有的querysting字符
Response.Write “<b>QueryString:</b><b>”
Response.Write Request.QueryString
‘显示传递的参数
Response.Write “<br /></b><b>Parameter is:</b>” & str &”<br />”
Response.Write “<b>QueryParameter=</b>”
Response.Write Request.QueryString (“str”)

%>
<html>
<head>
<meta NAME=”GENERATOR” Content=”Microsoft Visual Studio 6.0″>
<title></title>
</meta></head>
<body>

<p><a href=”01.asp?str=<%=strurlencode%>”>Str UrlEncode Method</a></p>
<p> </p>
<p><a href=”01.asp?str=<%=strhtmlencode%>”>Str HtmlEncode Method</a></p>
</body>
</html>
显示结果
QueryString:
Parameter is:parameter=#%&+\=?value
QueryParameter=
Str UrlEncode Method
Str HtmlEncode Method
点击连接1,结果
QueryString:str=parameter%3D%23%25%26%2B%5C%3D%3Fvalue%3C%2Fhtml%3E
Parameter is:parameter=#%&+\=?value
QueryParameter=parameter=#%&+\=?value
Str UrlEncode Method
Str HtmlEncode Method
此时我们发现好象参数值中的没有能正确接收到,当我们查看原代码的时候就会发现其实已经准确的接收到了,原因是“”是标准html tag ,经过浏览器解释后就不会显示出来了。
点击连接2,结果
QueryString:str=parameter=
Parameter is:parameter=#%&+\=?value
QueryParameter=parameter=
Str UrlEncode Method
Str HtmlEncode Method
此时就会发现在#后面没有能正确接收到,而是被解释为锚点的开始,在”#”后面的为锚的名称。

结论:在含有以上列表中具有特殊功能的特殊字符的字符串,作为参数用GET方式传递时,只需要用URLENCODE方法处理一下就可以拉。如果不想让浏览者看到含后HTML TAG的字符串的具体值值是,我们可以用HTMLENCODE处理一下。

PHP中用函数urlencode()就可以拉,这里就不在举例了。

PHP常用服务器环境变量

//第一部分:魔术常量
echo (__LINE__).' //当前文件的行号'.'</br>';  // 文件中的当前行号。  
echo (__FILE__).' //文件的完整路径和文件名'.'</br>';  // 文件的完整路径和文件名。如果用在被包含文件中,则返回被包含的文件名。自 PHP 4.0.2 起,__FILE__ 总是包含一个绝对路径(如果是符号连接,则是解析后的绝对路径),而在此之前的版本有时会包含一个相对路径。  
echo (__DIR__).' //文件所在的完整目录'.'</br>';  //文件所在的目录。如果用在被包括文件中,则返回被包括的文件所在的目录。它等价于 dirname(__FILE__)。除非是根目录,否则目录中名不包括末尾的斜杠。(PHP 5.3.0中新增) =  
//__FUNCTION__    //函数名称(PHP 4.3.0 新加)。自 PHP 5 起本常量返回该函数被定义时的名字(区分大小写)。在 PHP 4 中该值总是小写字母的。  
//__CLASS__     类的名称(PHP 4.3.0 新加)。自 PHP 5 起本常量返回该类被定义时的名字(区分大小写)。在 PHP 4 中该值总是小写字母的。  
//__METHOD__    类的方法名(PHP 5.0.0 新加)。返回该方法被定义时的名字(区分大小写)。  
//__NAMESPACE__ 当前命名空间的名称(大小写敏感)。这个常量是在编译时定义的(PHP 5.3.0 新增)  

//第二部分:服务器环境变量 $_SERVER 注:并非所有服务器都支持,以下参数在不同的服务器解析下会有差别

echo $_SERVER['PHP_SELF'].' //当前执行脚本的文件名'.'</br>';  // 当前执行脚本的文件名,从根目录开始包含路径
//echo $_SERVER['GATEWAY_INTERFACE'] .'</br>';   服务器使用的 CGI 规范的版本;例如,"CGI/1.1"
echo $_SERVER['SERVER_ADDR'].' //当前运行脚本所在的服务器的 IP 地址'.'</br>';    //当前运行脚本所在的服务器的 IP 地址
echo $_SERVER['SERVER_NAME'] .' //当前运行脚本所在的服务器的主机名'.'</br>';  // 当前运行脚本所在的服务器的主机名。如果脚本运行于虚拟主机中,该名称是由那个虚拟主机所设置的值决定。
echo $_SERVER['SERVER_SOFTWARE'] .' //服务器标识字符串'.'</br>';  // 服务器标识字符串,在响应请求时的头信息中给出。
//echo $_SERVER['SERVER_PROTOCOL'].'</br>';    请求页面时通信协议的名称和版本。例如,"HTTP/1.0"。 
 
echo $_SERVER['REQUEST_METHOD'] .' //访问页面使用的请求方法'.'</br>';  // 访问页面使用的请求方法;例如,"GET", "HEAD","POST","PUT"。 
echo $_SERVER['REQUEST_TIME'].' //请求开始时的时间戳'.'</br>';    //请求开始时的时间戳。从 PHP 5.1.0 起可用
echo $_SERVER['QUERY_STRING'].' //查询字符串'.'</br>';  // query string(查询字符串),如果有的话,通过它进行页面访问。
echo $_SERVER['HTTP_HOST'].' //当前请求头中Host项内容'.'</br>';    //当前请求头中 Host: 项的内容,如果存在的话。

echo $_SERVER['REMOTE_ADDR'] .' //浏览当前页面的用户的 IP 地址'.'</br>';  // 浏览当前页面的用户的 IP 地址。 
//echo $_SERVER['REMOTE_HOST'] .'</br>';   浏览当前页面的用户的主机名。DNS 反向解析不依赖于用户的 REMOTE_ADDR。Note: 你的服务器必须被配置以便产生这个变量。例如在 Apache 中,你需要在 httpd.conf 中设置 HostnameLookups On 来产生它。 
echo $_SERVER['REMOTE_PORT'] .' //用户机器上连接到 Web 服务器所使用的端口号'.'</br>';  // 用户机器上连接到 Web 服务器所使用的端口号 
echo $_SERVER['SCRIPT_FILENAME'] .' //当前执行脚本的绝对路径'.'</br>';    // 当前执行脚本的绝对路径。
echo $_SERVER['SERVER_ADMIN'] .' //该值指明了 Apache 服务器配置文件中的 SERVER_ADMIN 参数'.'</br>';  // 该值指明了 Apache 服务器配置文件中的 SERVER_ADMIN 参数。如果脚本运行在一个虚拟主机上,则该值是那个虚拟主机的值号 
echo $_SERVER['SERVER_PORT'] .' //Web 服务器使用的端口'.'</br>';  // Web 服务器使用的端口。默认值为 "80"。如果使用 SSL 安全连接,则这个值为用户设置的 HTTP 端口。 
echo $_SERVER['SCRIPT_NAME'] .' //包含当前脚本的路径'.'</br>';  // 包含当前脚本的路径。这在页面需要指向自己时非常有用。__FILE__ 常量包含当前脚本(例如包含文件)的完整路径和文件名。 

echo $_SERVER['REQUEST_URI'] .' //URI 用来指定要访问的页面'.'</br>';  // URI 用来指定要访问的页面。例如 "/index.html"。

PHP判断访客是否搜索引擎蜘蛛

/**  
 * 判断访客是否搜索引擎蜘蛛  
 *  
 * @access  public  
 * @return  string  
 */  
function is_spider($record = true)  
{  
    static $spider = NULL;  
  
    if ($spider !== NULL)  
    {  
        return $spider;  
    }  
  
    if (empty($_SERVER['HTTP_USER_AGENT']))  
    {  
        $spider = '';  
  
        return '';  
    }  
  
    $searchengine_bot = array(  
        'googlebot',  
        'mediapartners-google',  
        'baiduspider+',  
        'msnbot',  
        'yodaobot',  
        'yahoo! slurp;',  
        'yahoo! slurp china;',  
        'iaskspider',  
        'sogou web spider',  
        'sogou push spider'  
    );  
  
    $searchengine_name = array(  
        'GOOGLE',  
        'GOOGLE ADSENSE',  
        'BAIDU',  
        'MSN',  
        'YODAO',  
        'YAHOO',  
        'Yahoo China',  
        'IASK',  
        'SOGOU',  
        'SOGOU'  
    );  
  
    $spider = strtolower($_SERVER['HTTP_USER_AGENT']);  
  
    foreach ($searchengine_bot AS $key => $value)  
    {  
        if (strpos($spider, $value) !== false)  
        {  
            $spider = $searchengine_name[$key];  
  
            if ($record === true)  
            {  
                $GLOBALS['db']->autoReplace($GLOBALS['ecs']->table('searchengine'), array('date' => local_date('Y-m-d'), 'searchengine' => $spider, 'count' => 1), array('count' => 1));  
            }  
  
            return $spider;  
        }  
    }  
  
    $spider = '';  
  
    return '';  
}

迅雷、快车、QQ旋风链接加解密

<?php
/**
*专用链接加解密
* 本程序适用于迅雷、快车和QQ旋风专用链接加解密,其他的暂未支持。程序较简单,有PHP基础的一看就明白。
*/

function encrypt($url = null, $type = "thunder"){
	$types = array("thunder", "flashget", "qqdl");
	$type = strtolower($type);
	$url = trim($url);
	if ($url == null) return null;
	if (false == array_search($type, $types)) $type = "thunder";
	
	switch ($type){
		case "thunder":
			$url = "thunder://" . base64_encode("AA".$url."ZZ");
			break;
		case "flashget":
			$url = "flashget://" . base64_encode("[FLASHGET]".$url."[FLASHGET]") . "&bao";
			break;
		case "qqdl":
			$url = "qqdl://" . base64_encode($url);
			break;
	}
	return $url;
}

function decrypt($url_origin = null){
	$url = trim($url_origin);
	if ($url == null) return null;
	$count = preg_match("/(\w+):\/\//i", $url, $matches);
	if($count == 0 || $count == false){
		return $url_origin;
	}else{
		$type = strtolower($matches[1]);
	}

	$count = preg_match("/:\/\/([a-zA-Z0-9+\/]+={0,2})/i", $url, $matches);
	if($count == 0 || $count == false){
		return $url_origin;
	}else{
		$url = $matches[1];
	}
	switch ($type){
		case "thunder":
			$url = substr(base64_decode($url), 2, -2);
			break;
		case "flashget":
			$url = substr(base64_decode($url), 10, -10);
			break;
		case "qqdl":
			$url = base64_decode($url);
			break;
		default:
			return $url_origin;
	}
	return $url;
}
?>

<html>
<head>
<title>专用链接加解密</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<style type="text/css">
#tb{
	background-color:green;
	margin:10px auto;
}
#result{
	width:60%;
	margin:10px auto;
}
</style>
</head>
<body>
	<div id="link">
		<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="POST" >
			<table id="tb">
			<tr><td>链接</td><td colspan=2><textarea rows=3 name="url"></textarea></td></tr>
			<tr><td ><input type="radio" name="endecode" value="decode" id="decode" checked><label for="decode">解密</label></td><td><input type="radio" name="endecode" value="encode" id="encode"><label for="encode">加密</label></td><td></td></tr>
			<tr><td><input type="radio" name="type" value="thunder" checked>迅雷</td><td><input type="radio" name="type" value="flashget">快车</td><td><input type="radio" name="type" value="qqdl">QQ旋风</td></tr>
			<tr><td><input type="submit" name="submit" value="确定"></td><td><input type="reset" name="reset"></td><td></td></tr>
			</table>
		</form>
	</div>
	<div id = "result">
	<?php
	if(isset($_POST['endecode']) && isset($_POST['type']) && isset($_POST['url'])){
		$url = $_POST['url'];
		$type = $_POST['type'];
		$endecode = $_POST['endecode'];
		if($endecode == "decode"){
			$url2 = decrypt($url);
			echo "<p>解密前的地址: $url </p>";
			echo "<p>解密后的地址: $url2 </p>";
		}elseif($endecode == "encode"){
			$url2 = encrypt($url,$type);
			echo "<p>加密前的地址: $url </p>";
			echo "<p>加密后的地址: $url2 </p>";
		}
	}
	?>
	</div>
</body>
</html>

关于这个不知道从哪里来的Loper主题QapTcha插件导致无法回复的修复

由于小奠爱的强烈要求和众多蓝盟兄弟都跟我一起盗版再盗版,没办法,被逼着要修复……

答案很简单:这个不知道从哪里来的主题缺少文件。盗版就是这样的喽!I like Free!

修复方法:
1. wp-content/Qaptcha.jquery.php 增加一个这样的文件(不要用记事本,用UE等编辑器,因为记事本有BOM)

<?php
session_start();

$aResponse['error'] = false;
$_SESSION['iQaptcha'] = false;

if(isset($_POST['action']))
{
	if(htmlentities($_POST['action'], ENT_QUOTES, 'UTF-8') == 'qaptcha')
	{
		$_SESSION['iQaptcha'] = true;
		if($_SESSION['iQaptcha'])
			echo json_encode($aResponse);
		else
		{
			$aResponse['error'] = true;
			echo json_encode($aResponse);
		}
	}
	else
	{
		$aResponse['error'] = true;
		echo json_encode($aResponse);
	}
}
else
{
	$aResponse['error'] = true;
	echo json_encode($aResponse);
}

2. 到你们的林大爷这个文章下面回复试一下!

3. 完事!

忽然发现LUC有不少懒得没得救的人,于是…:Qaptcha.jquery.php

另外,如果博客程序放在二级目录里的话(如blog),还需要修改一个地方:

文件位置 wp-content/themes/loper1.2/qaptcha/jquery/QapTcha.jquery.js

在文件的第56行左右找到

$js.post("/wp-content/Qaptcha.jquery.php",{
	action : 'qaptcha'
},

把/wp-content/Qaptcha.jquery.php的路径修改为你的博客真实路径,如:

$js.post("/blog/wp-content/Qaptcha.jquery.php",{

	action : 'qaptcha'
},

利用PHP将MYSQL数据输入成EXCEL格式

<?php 
$DB_Server = “localhost”;   
$DB_Username = “put your user name here”;   
$DB_Password = “put your password here”;   
$DB_DBName = “put your database name here”;   
$DB_TBLName = “put your table name here”;   
  
$savename = date(“YmjHis”);  // excel file name
$Connect = @mysql_connect($DB_Server, $DB_Username, $DB_Password) or die(“Couldn’t connect.”);   
mysql_query(“Set Names ‘utf-8′”);
$file_type = “vnd.ms-excel”;   
$file_ending = “xls”;
header(“Content-Type: application/$file_type;charset=utf-8″);
header(“Content-Disposition: attachment; filename=”.$savename.”.$file_ending”);   
//header(“Pragma: no-cache”);      
  
$now_date = date(“Y-m-j H:i:s”);    
$title = “User Email”;    
  
$sql = “SELECT entity_id, email from $DB_TBLName WHERE entity_id >’0′ AND entity_id<10001″;    //export entity_id from 1 to 1000
$ALT_Db = @mysql_select_db($DB_DBName, $Connect) or die(“Couldn’t select database”);   
$result = @mysql_query($sql,$Connect) or die(mysql_error()); 
  
echo(“$title\n”);    
$sep = “\t”;    
for ($i = 0; $i < mysql_num_fields($result); $i++) {
    echo mysql_field_name($result,$i) . “\t”;    
}    
print(“\n”);    
$i = 0;    
while($row = mysql_fetch_row($result)) {    
    $schema_insert = “”;
    for($j=0; $j<mysql_num_fields($result);$j++) {    
        if(!isset($row[$j]))    
            $schema_insert .= “NULL”.$sep;    
        elseif ($row[$j] != “”)    
            $schema_insert .= “$row[$j]“.$sep;
        else    
            $schema_insert .= “”.$sep;    
    }    
    $schema_insert = str_replace($sep.”$”, “”, $schema_insert);    
    $schema_insert .= “\t”;    
    print(trim($schema_insert));    
    print “\n”;    
    $i++;    
}    
return (true); 
?>

php下防止Webshell浏览目录

php的Webshell能够实现浏览网站目录、修改网站文件、数据库查询、修改、下载等等,做为个人工具可谓功能完善且强大,做为黑客工具可谓功能恐怖,危害极大!做网站需要在各个方面做好安全防御。
在Linux下进行目录的安全设置可参阅:《Linux下Web目录和文件安全权限设置》
在PHP支撑层次,可以通过如下方法阻止Webshell对目录的浏览:
首先,修改PHP源码后重新编译PHP环境

tar zxvf php-5.2.14.tar.gz
gzip -cd php-5.2.14-fpm-0.5.14.diff.gz | patch -d php-5.2.14 -p1
cd php-5.2.14/

然后编辑文件main/fopen_wrappers.c,找到 php_check_open_basedir_ex 函数的定义部分,大约在 220行。在如下代码之后插入修改代码

PHPAPI int php_check_open_basedir_ex(const char *path, int warn TSRMLS_DC)
{
	/* Only check when open_basedir is available */
	if (PG(open_basedir) && *PG(open_basedir)) {
		char *pathbuf;
		char *ptr;
		char *end;
		//从此处开始插入修改代码

插入的修改代码为:

char *env_doc_root;
if(PG(doc_root)){
        env_doc_root = estrdup(PG(doc_root));
}else{
        env_doc_root = sapi_getenv("DOCUMENT_ROOT", sizeof("DOCUMENT_ROOT")-1 TSRMLS_CC);
}
if(env_doc_root){
        int res_root = php_check_specific_open_basedir(env_doc_root, path TSRMLS_CC);
        efree(env_doc_root);
        if (res_root == 0) {
                return 0;
        }
        if (res_root == -2) {
                errno = EPERM;
                return -1;
        }
}

修改完成的样子:

PHPAPI int php_check_open_basedir_ex(const char *path, int warn TSRMLS_DC)
{
	/* Only check when open_basedir is available */
	if (PG(open_basedir) && *PG(open_basedir)) {
		char *pathbuf;
		char *ptr;
		char *end;
		//增加代码.开始
                char *env_doc_root;
                if(PG(doc_root)){
                        env_doc_root = estrdup(PG(doc_root));
                }else{
                        env_doc_root = sapi_getenv("DOCUMENT_ROOT", sizeof("DOCUMENT_ROOT")-1 TSRMLS_CC);
                }
                if(env_doc_root){
                        int res_root = php_check_specific_open_basedir(env_doc_root, path TSRMLS_CC);
                        efree(env_doc_root);
                        if (res_root == 0) {
                                return 0;
                        }
                        if (res_root == -2) {
                                errno = EPERM;
                                return -1;
                        }
                }
		//增加代码.结束
		//原文件其他代码...

保存退出后,继续编译、安装即可

然后修改php.ini中 open_basedir配置

open_basedir = "/tmp/:/var/tmp/"

以上,修改编译php和修改php.ini配置的目的在于,将php脚本的允许操作区域限制于自身目录和/tmp+/var/tmp之下,不允许它随意对其他目录进行操作。这样Webshell的活动区域就受限了,也就无法修改其他目录文件或挂马,无法继续找到数据库配置文件进而对数据库进行操作。

Nginx+PHP优化提速

Nginx+PHP是高效、高速、高性能的完美组合,但是要发挥其性能极致还是需要一些手段进行优化,使得这个组合结合更加紧密。在Nginx中启用fastcgi cache就可以有效提高PHP网站的访问速度。

配置参数:
http里:

fastcgi_cache_path /www/php_cache levels=1:2 keys_zone=cache_php:30m inactive=1d max_size=10g;

server里:

location ~ .*\.php?$
{
      #fastcgi_pass  unix:/tmp/php-cgi.sock;
      fastcgi_pass  127.0.0.1:9000;
      fastcgi_index index.php;
      include fcgi.conf;
      #以下是fastcgi_cache的配置
      fastcgi_cache   cache_php;
      fastcgi_cache_valid   200 302  1h;
      fastcgi_cache_min_uses  1;
      fastcgi_cache_use_stale error  timeout invalid_header http_500;
      fastcgi_cache_key $host$request_uri;
}

配置说明
fastcgi_cache_path:fastcgi_cache缓存目录,可以设置目录层级,比如1:2会生成16*256个字目录,cache_php是这个缓存空间的名字,cache是用多少内存(nginx直接放内存,提高访问速度),inactive表示默认失效时间,max_size表示最多用多少硬盘空间。

fastcgi_cache_valid:定义哪些http头要缓存
fastcgi_cache_min_uses:URL经过多少次请求将被缓存
fastcgi_cache_use_stale:定义哪些情况下用过期缓存
fastcgi_cache_key:定义fastcgi_cache的key,示例中就以请求的URI作为缓存的key,Nginx会取这个key的md5作为缓存文件,如果设置了缓存哈希目录,Nginx会从后往前取相应的位数做为目录<br>fastcgi_cache:用哪个缓存空间

清除缓存
指定删除某一URL的php文件的缓存的PHP程序
主要代码如下:

$md5 = md5($url);
    $cacheFile = '/www/php_cache/' . substr($md5, -1, 1) . '/' . substr($md5, -3, 2) . '/' . $md5;
    if (!file_exists($cacheFile)) {
        exit('缓存不存在。');
    }
    if (@unlink($cacheFile)) {
        echo '清除缓存成功。';
    } else {
        echo '清除缓存失败。';
    }

深入了解 register_globals

从 PHP4.2.0版本开始,php.ini中的设置选项 register_globals 默认值变成了 off。所以,最好从现在就开始用Off的风格开始编程!

register_globals的值可以设置为:On或者Off,我们举一段代码来分别描述它们的不同。

代码:

<form name=”frmTest” id=”frmTest” action=”URL”>
<input type=”text” name=”user_name” id=”user_name”>
<input type=”password” name=”user_pass” id=”user_pass”>
<input type=”submit” value=”login”>
</form>

当register_globals=Off的时候,下一个程序接收的时候应该用$_GET[‘user_name’]和$_GET[‘user_pass’]来接受传递过来的值。(注:当<form>的method属性为post的时候应该用$_POST[‘user_name’]和$_POST[‘user_pass’])

当register_globals=On的时候,下一个程序可以直接使用$user_name 和$user_pass来接受值。

顾名思义,register_globals的意思就是注册为全局变量,所以当On的时候,传递过来的值会被直接的注册为全局变量直接使用,而Off的时候,我们需要到特定的数组里去得到它。所以,碰到上边那些无法得到值的问题的朋

友应该首先检查一下你的register_globals的设置和你获取值的方法是否匹配。(查看可以用phpinfo()函数或者直接查看php.ini)

下面来看看这里有什么错误?

看看下面的这段PHP脚本,它用来在输入的用户名及口令正确时授权访问一个Web页面:
<?php
// 检查用户名及口令
if ($username == ‘kevin’ and $password == ‘secret’)
$authorized = true;
?>
<?php if (!$authorized): ?>
<!– 未授权的用户将在这里给予提示 –>
<p>Please enter your username and password:</p>
<form action=”<?=$PHP_SELF?>” method=”POST”>
<p>Username: <input type=”text” name=”username” /><br />
Password: <input type=”password” name=”password” /><br />
<input type=”submit” /></p>
</form>
<?php else: ?>
<!– 有安全要求的HTML内容 –>
<?php endif; ?>
上面的代码中存在的问题是你可以很容易地获得访问的权力,而不需要提供正确的用户名和口令。只在要你的浏览器的地址栏的最后添加?authorized=1。因为PHP会自动地为每一个提交的值创建一个变量 — 不论是来自动一

个提交的表单、URL查询字符串还是一个cookie — 这会将$authorized设置为1,这样一个未授权的用户也可以突破安全限制。

PHP PDO属性列表

PDO::PARAM_BOOL
表示一个布尔类型
PDO::PARAM_NULL
表示一个SQL中的NULL类型
PDO::PARAM_INT
表示一个SQL中的INTEGER类型
PDO::PARAM_STR
表示一个SQL中的SQL CHAR,VARCHAR类型
PDO::PARAM_LOB
表示一个SQL中的large object类型
PDO::PARAM_STMT
表示一个SQL中的recordset类型,还没有被支持
PDO::PARAM_INPUT_OUTPUT
Specifies that the parameter is an INOUT parameter for a stored procedure. You must bitwise-OR this value with an explicit PDO::PARAM_* data type.
PDO::FETCH_LAZY
将每一行结果作为一个对象返回
PDO::FETCH_ASSOC
仅仅返回以键值作为下标的查询的结果集,名称相同的数据只返回一个
PDO::FETCH_NAMED
仅仅返回以键值作为下标的查询的结果集,名称相同的数据以数组形式返回
PDO::FETCH_NUM
仅仅返回以数字作为下标的查询的结果集
PDO::FETCH_BOTH
同时返回以键值和数字作为下标的查询的结果集
PDO::FETCH_OBJ
以对象的形式返回结果集
PDO::FETCH_BOUND
将PDOStatement::bindParam()和PDOStatement::bindColumn()所绑定的值作为变量名赋值后返回
PDO::FETCH_COLUMN
表示仅仅返回结果集中的某一列
PDO::FETCH_CLASS
表示以类的形式返回结果集
PDO::FETCH_INTO
表示将数据合并入一个存在的类中进行返回
PDO::FETCH_FUNC
PDO::FETCH_GROUP
PDO::FETCH_UNIQUE
PDO::FETCH_KEY_PAIR
以首个键值下表,后面数字下表的形式返回结果集
PDO::FETCH_CLASSTYPE
PDO::FETCH_SERIALIZE
表示将数据合并入一个存在的类中并序列化返回
PDO::FETCH_PROPS_LATE
Available since PHP 5.2.0
PDO::ATTR_AUTOCOMMIT
在设置成true的时候,PDO会自动尝试停止接受委托,开始执行
PDO::ATTR_PREFETCH
设置应用程序提前获取的数据大小,并非所有的数据库哦度支持
PDO::ATTR_TIMEOUT
设置连接数据库超时的值
PDO::ATTR_ERRMODE
设置Error处理的模式
PDO::ATTR_SERVER_VERSION
只读属性,表示PDO连接的服务器端数据库版本
PDO::ATTR_CLIENT_VERSION
只读属性,表示PDO连接的客户端PDO驱动版本
PDO::ATTR_SERVER_INFO
只读属性,表示PDO连接的服务器的meta信息
PDO::ATTR_CONNECTION_STATUS
PDO::ATTR_CASE
通过PDO::CASE_*中的内容对列的形式进行操作
PDO::ATTR_CURSOR_NAME
获取或者设定指针的名称
PDO::ATTR_CURSOR
设置指针的类型,PDO现在支持PDO::CURSOR_FWDONLY和PDO::CURSOR_FWDONLY
PDO::ATTR_DRIVER_NAME
返回使用的PDO驱动的名称
PDO::ATTR_ORACLE_NULLS
将返回的空字符串转换为SQL的NULL
PDO::ATTR_PERSISTENT
获取一个存在的连接
PDO::ATTR_STATEMENT_CLASS
PDO::ATTR_FETCH_CATALOG_NAMES
在返回的结果集中,使用自定义目录名称来代替字段名。
PDO::ATTR_FETCH_TABLE_NAMES
在返回的结果集中,使用自定义表格名称来代替字段名。
PDO::ATTR_STRINGIFY_FETCHES
PDO::ATTR_MAX_COLUMN_LEN
PDO::ATTR_DEFAULT_FETCH_MODE
Available since PHP 5.2.0
PDO::ATTR_EMULATE_PREPARES
Available since PHP 5.1.3.
PDO::ERRMODE_SILENT
发生错误时不汇报任何的错误信息,是默认值
PDO::ERRMODE_WARNING
发生错误时发出一条php的E_WARNING的信息
PDO::ERRMODE_EXCEPTION
发生错误时抛出一个PDOException
PDO::CASE_NATURAL
回复列的默认显示格式
PDO::CASE_LOWER
强制列的名字小写
PDO::CASE_UPPER
强制列的名字大写
PDO::NULL_NATURAL
PDO::NULL_EMPTY_STRING
PDO::NULL_TO_STRING
PDO::FETCH_ORI_NEXT
获取结果集中的下一行数据,仅在有指针功能时有效
PDO::FETCH_ORI_PRIOR
获取结果集中的上一行数据,仅在有指针功能时有效
PDO::FETCH_ORI_FIRST
获取结果集中的第一行数据,仅在有指针功能时有效
PDO::FETCH_ORI_LAST
获取结果集中的最后一行数据,仅在有指针功能时有效
PDO::FETCH_ORI_ABS
获取结果集中的某一行数据,仅在有指针功能时有效
PDO::FETCH_ORI_REL
获取结果集中当前行后某行的数据,仅在有指针功能时有效
PDO::CURSOR_FWDONLY
建立一个只能向后的指针操作对象
PDO::CURSOR_SCROLL
建立一个指针操作对象,传递PDO::FETCH_ORI_*中的内容来控制结果集
PDO::ERR_NONE (string)
设定没有错误时候的错误信息
PDO::PARAM_EVT_ALLOC
Allocation event
PDO::PARAM_EVT_FREE
Deallocation event
PDO::PARAM_EVT_EXEC_PRE
Event triggered prior to execution of a prepared statement.
PDO::PARAM_EVT_EXEC_POST
Event triggered subsequent to execution of a prepared statement.
PDO::PARAM_EVT_FETCH_PRE
Event triggered prior to fetching a result from a resultset.
PDO::PARAM_EVT_FETCH_POST
Event triggered subsequent to fetching a result from a resultset.
PDO::PARAM_EVT_NORMALIZE
Event triggered during bound parameter registration allowing the driver to normalize the parameter name.