星期一, 十二月 25, 2006

摘录:有用的表格(一)MYSQL Cheat Sheets

MYSQL Cheat Sheets
http://www.nparikh.org/unix/mysql.php

Selecting a database:
mysql> USE database;
Listing databases:
mysql> SHOW DATABASES;
Listing tables in a db:
mysql> SHOW TABLES;
Describing the format of a table:
mysql> DESCRIBE table;
Creating a database:
mysql> CREATE DATABASE db_name;
Creating a table:
mysql> CREATE TABLE table_name (field1_name TYPE(SIZE), field2_name TYPE(SIZE));
Ex: mysql> CREATE TABLE pet (name VARCHAR(20), sex CHAR(1), birth DATE);
Load tab-delimited data into a table:
mysql> LOAD DATA LOCAL INFILE "infile.txt" INTO TABLE table_name; (Use n for NULL)
Inserting one row at a time:
mysql> INSERT INTO table_name VALUES ('MyName', 'MyOwner', '2002-08-31'); (Use NULL for NULL)
Retrieving information (general):
mysql> SELECT from_columns FROM table WHERE conditions;
All values: SELECT * FROM table;
Some values: SELECT * FROM table WHERE rec_name = "value";
Multiple critera: SELECT * FROM TABLE WHERE rec1 = "value1" AND rec2 = "value2";
Reloading a new data set into existing table:
mysql> SET AUTOCOMMIT=1;
# used for quick recreation of table
mysql> DELETE FROM pet;
mysql> LOAD DATA LOCAL INFILE "infile.txt" INTO TABLE table;
Fixing all records with a certain value:
mysql> UPDATE table SET column_name = "new_value" WHERE record_name = "value";
Selecting specific columns:
mysql> SELECT column_name FROM table;
Retrieving unique output records:
mysql> SELECT DISTINCT column_name FROM table;
Sorting:
mysql> SELECT col1, col2 FROM table ORDER BY col2;
Backwards: SELECT col1, col2 FROM table ORDER BY col2 DESC;
Date calculations:
mysql> SELECT CURRENT_DATE, (YEAR(CURRENT_DATE)-YEAR(date_col)) AS time_diff [FROM table];
MONTH(some_date) extracts the month value and DAYOFMONTH() extracts day.
Pattern Matching:
mysql> SELECT * FROM table WHERE rec LIKE "blah%";
(% is wildcard - arbitrary # of chars)
Find 5-char values: SELECT * FROM table WHERE rec like "_____"; (_ is any single character)
Extended Regular Expression Matching:
mysql> SELECT * FROM table WHERE rec RLIKE "^b$";
(. for char, [...] for char class, * for 0 or more instances ^ for beginning,
{n} for repeat n times, and $ for end)
(RLIKE or REGEXP) To force case-sensitivity, use "REGEXP BINARY"
Counting Rows:
mysql> SELECT COUNT(*) FROM table;
Grouping with Counting:
mysql> SELECT owner, COUNT(*) FROM table GROUP BY owner;
(GROUP BY groups together all records for each 'owner')
Selecting from multiple tables:
(Example) mysql> SELECT pet.name, comment FROM pet, event WHERE pet.name = event.name;
(You can join a table to itself to compare by using 'AS')
Currently selected database:
mysql> SELECT DATABASE();
Maximum value:
mysql> SELECT MAX(col_name) AS label FROM table;
Auto-incrementing rows:
mysql> CREATE TABLE table (number INT NOT NULL AUTO_INCREMENT, name CHAR(10) NOT NULL);
mysql> INSERT INTO table (name) VALUES ("tom"),("dick"),("harry");
Adding a column to an already-created table:
mysql> ALTER TABLE tbl ADD COLUMN [column_create syntax] AFTER col_name;
Removing a column:
mysql> ALTER TABLE tbl DROP COLUMN col;
(Full ALTER TABLE syntax available at mysql.com.)
Batch mode (feeding in a script):
# mysql -u user -p source batch_file;
Backing up a database with mysqldump:
# mysqldump --opt -u username -p database > database_backup.sql
(Use 'mysqldump --opt --all-databases > all_backup.sql' to backup everything.)
(More info at MySQL's docs.)
 

星期四, 十二月 14, 2006

构思:Parser 调度流程

构思:Parser 调度流程
tags:构思,简单的调度,调度,shell
PS:下面是自己的一段构思,伪代码,很伪... 呵呵 希望你能看得懂
目的是实现一个可以被监控的任务处理

程序
Worker 执行parser任务
Fairy 检测worker 是否正常运行中
数据
Lastupdate-yyyy-mm-dd.hh 任务流,即时追加中(url)

kill_worker.tmp 当前任务的id
Last_line.tmp 最后处理的行数
Logs/[job].err_lines.err 处理失败的数据

[raw_base]/[mpath].raw 数据源
[out_base]/[mpath].path 对应数据原始路径(url)
[out_base]/[mpath].rss 结果数据
Logs/[job].worker.err 错误日志
Logs/[job].worker.log 处理日志

Fairy 每10分钟启动一次
Max_pause_time=5min
If (!-f last_line.tmp) or (last_line.tmp’s change time -lt current time-$Max_pause_time) # 如果任务标记文件不存在或的最后更新时间 超过了限定的间隔
Then
cat kill_worker.tmp|sh # 假定工作进程宕机,将当前的工作进程杀掉
err_line=`cat last_line.tmp`; # 获取宕机时刻的任务
if `tail -1 logs/[jobs].err_lines.err`==$err_line # 如果同上一次宕机的任务相同
then
echo $err_line|awk ‘{sub(“.*”,$2++,$2);print}’> cat last_line.tmp; # 重置当前任务为下一个任务
echo $err_line >> logs/[jobs].err_lines.err # 记录当前出错的任务
worker [job] & # 启动下一次任务
fi

Worker 由Fairy 自动启动
$job=$1; # 获取任务
Pid=$$; # 获取当前进程的id
Echo kill $pid > worker_pid.tmp; # 设置kill操作
Start_line=`cat last_line.tmp|awk ‘{if(/$job/){print $2}else{print 1}` # 获取开始的行号
Line=1;
While read $line
If($line –gt $start_line)
Then
Continue;
Fi

Echo $job $Line > last_line.tmp; # 设置最后行号
Echo $line |php stream-parser.php ; # 开始单次任务
$Line++; # 递增
Done<$job # 设定任务流 > Logs/$job.worker.$pid.log # 记录日志
2> Logs/$job.worker.$pid.err # 记录错误日志


星期三, 十二月 13, 2006

code:管理shell中的子任务

管理shell中的子任务
tags:shell,kill,awk
---------------------------------------------------------------
PS:好久之前的代码了 不过正好用到 就找来发到这里了
---------------------------------------------------------------

http://fallseir.livejournal.com/58926.html
ps #打印运行的进程列表
kill #杀掉指定的进程
awk #操作字符数据
$$ #当前进程的PID
tmp_sh.sh # 测试shell脚本 在shell中 定时kill到超时的子进程


获取父进程的pid
$ ps lx|awk '/ps lx$/{print $4}' # 查看当前进程的父PID
ppid=`ps lx|awk '/ps lx$/{print $4}'`
$(date -u;sleep 120m;date -u;)& #创建一后台运行的任务
$ ps lx #查看当前运行的进程
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
0 503 8500 8499 16 0 4492 1408 wait Ss pts/1 0:00 -bash
1 503 8556 8500 16 0 4492 1408 wait S pts/1 0:00 -bash
0 503 8558 8556 16 0 3904 556 - S pts/1 0:00 sleep 120
0 503 8561 8500 17 0 4420 708 - R+ pts/1 0:00 ps lx
#查看根任务的子任务列表
$ ps lx |awk 'BEGIN{ps[8500]="root";}{if($4 in ps){ps[$3]=$13;}}END{for(i in ps){print i ":" ps[i];}}'

tmp_sh.sh # 测试shell脚本 在shell中 定时kill到超时的子进程
-----------------------------------------------------------------------------------------------
# fallseir.lee (fallseir@gmail.com ,http://feed.feedsky.com/fallseir)
# -20060620 17:08
# 获取当前的进程PID
ppid=$$;
##
# 将满足条件的子进程kill掉
##
function kill_subs(){
# 打印所有进程并输出满足条件的进程ID
ps lx|awk '
BEGIN{
ps['$ppid']="root";#设置父进程ID
}
##
# 判断当前进程是否为kill的进程
# pid 进程ID
# w 进程启动的shell命令名称
# t 进程执行的时间 hh:mm
##
function is_kill(pid,w,t){
split(t,arr_t); # 分离hh:mm时间的时间格式以便用于计算
# 测试规则 将所有存在的wget进程标记为kill进程
if(w=="wget" && (arr_t[0]>0 || arr_t[1]>=0)){
return 1;
}else{
return -1;
}
}
{
# 设定使用的参数
ppid=$4; # 当前行的父进程ID
pid=$3; # 当前行的进程ID
w=$13; # 当前行的shell命令
t=$12; # 当前行的shell命令执行时间

if(ppid in ps){ # 如果父进程ID在ps列队里,只有子进程别操作
ps[pid]=t; # 将当前进程id添加到ps列队
if(is_kill(pid,w,t)>0){ # 如果当前进程满足kill条件
ks[pid]=w " " t; # 加入到ks列队
}
}
}
END{
# 输出kill名令,kill掉ks列队里的PID
for(i in ks){
print "kill " i;
}
}'
}
##
# 判断是否有worker在工作
##
function is_working(){
# 打印当前进程列队并查看是否有当前进程的子进程中的worker数量
ps lx|awk '
BEGIN{
ps['$ppid']="root";
}
function is_work(w){
# 假设 worker 的 shel l命令为 wget 和 awk 命令
if(w == "wget" || w=="awk"){
return 1;
}else{
return -1;
}
}
{
ppid=$4;
pid=$3;
w=$13;
t=$12;
if(ppid in ps){
ps[pid]=t;
if(is_work(w)>0){ # 将 worker 放入 ws 列队
ws[pid]=w " " t;
}
}
}
END{
c=0;
for(i in ws){ #计算worker数量
c++;
}
print c; #打印worker数量
}'
}

## --- work ---
# -- 创建 worker 的工位
mkfifo $$.test # 以当前进程ID构建管道
exec 3<>$$.test # 将管道已读写方式连接到3号流
rm $$.test # 删除构建的管道,当需要的流建立后 之前建立的管道已无用
# 建立5个工作者的位置
for((i=0;i<5;i++))
do
echo i>&3;
done
# 在后台进行100个数量的wget任务
(for((i=0;i<=100;i++))
do
read t; # 获取一个工作的位置
(r=$(wget "http://feed.feedsky.com/fallseir" --timeout=3000 --spider 2>&1 |cat);
# 判断wget的执行结果是否成功
r=$(echo $r|awk 'BEGIN {r=-1;} {if(/200/){r=1;}} END{print r;}') ;
if( [ "$r" == "1" ] )
then
echo "# $t $i";
else
echo "- $t $i";
fi;
# 任务完成后归还工作位置
echo $t >&3;)& # 任务在后台进行
# 设定 for 范围中默认从3号流读取数据
done <&3)&
while [ "1"="1" ] # 建立 killer 监听进程
do
kills=`kill_subs`;
echo $kills; #输出要被kill的进程
$kills # 执行kill 操作 #kill_subs|sh;
if([ "`is_working`" -gt 0 ]) # 如果还有worker在工作 sleep 5 秒钟
then
#echo `is_working`
echo "killer sleep 5 s";
sleep 5s;
else # 如果没有 worker 在工作 退出killer 监听
#is_working;
echo "killer end `date -u`";
break;
fi
done

echo "wait sh end `date -u`";
wait; # 等待所有自进程结束
exec 3<&- # 关闭 3 号流
echo "end `date -u`";




--
[:p] --飞扬.轻狂 [fallseir.lee]
http://fallseir.livejournal.com
http://feed.feedsky.com/fallseir

星期一, 十一月 27, 2006

Code:简单的服务器端发送http请求

Tag:php,rpc,socket,post

因为手里需要所以简单的写了点点,但没有对后期数据进行处理,也没有加异常处理
先用之,再改进...

$remove_url="http://localhost/worktest/test_server.php";
// Create the client object
$client = new SRPC_Client($remove_url);
$client->debug=true;
// Run a query for PHP
if (!$client->call("http://feed.feedsky.com/fallseir")) {
die('Something went wrong - '.$client->getErrorCode().' : '.$client->getErrorMessage());
}

// Display the result
echo '
';
print_r($client->headers);
print_r($client->contents);
echo '
';

class SRPC_Client{
var $server;
var $port;
var $path;
var $useragent;
var $debug;
var $error;

var $contents;
var $headers;
function SRPC_Client($server, $path = false, $port = 80) {
if (!$path) {
// Assume we have been given a URL instead
$bits = parse_url($server);
$this->server = $bits['host'];
$this->port = isset($bits['port']) ? $bits['port'] : 80;
$this->path = isset($bits['path']) ? $bits['path'] : '/';
// Make absolutely sure we have a path
if (!$this->path) {
$this->path = '/';
}
} else {
$this->server = $server;
$this->path = $path;
$this->port = $port;
}
$this->useragent = 'The simple RPC PHP Library';
}
function Call($content){
$r="\r\n";
$length=strlen($content);
$request = "POST {$this->path} HTTP/1.0$r";
$request .= "Host: {$this->server}$r";
$request .= "Content-Type: text/xml charset=utf-8$r";
$request .= "User-Agent: {$this->useragent}$r";
$request .= "Content-length: {$length}$r$r";
$request .= $content;
// Now send the request
if ($this->debug) {
echo '
'.htmlspecialchars($request)."\n
\n\n";
}
$fp = @fsockopen($this->server, $this->port);
if (!$fp) {
$this->error = array(-32300, 'transport error - could not open socket');
return false;
}
fputs($fp, $request);
$contents = '';
$gotFirstLine = false;
$gettingHeaders = true;
$headers = '';
while (!feof($fp)) {
$line = fgets($fp, 4096);
if (!$gotFirstLine) {
// Check line for '200'
if (strstr($line, '200') === false) {
$this->error = array(-32300, 'transport error - HTTP status code was not 200');
return false;
}
$gotFirstLine = true;
}
if (trim($line) == '') {
$gettingHeaders = false;
}
if (!$gettingHeaders) {
$contents .= trim($line).$r;
}else{
$rawheaders .= trim($line).$r;
}
}
fclose($fp);
if ($this->debug) {
echo '
'.htmlspecialchars($contents)."\n
\n\n";
}

preg_match_all('/(.*?): (.*)\r/', $rawheaders, $matches);
$count = count($matches[1]);
for ( $i = 0; $i < $count; $i++) {
$key = strtolower($matches[1][$i]);
$headers["$key"] = $matches[2][$i];
}
preg_match('/.*([0-9]{3}).*/', $rawheaders, $return);
$headers['response'] = $return[1]; // HTTP response code eg 204, 200, 404
$code = $headers['response'];
/** if ( ('302' == $code || '301' == $code) && isset($headers['location']) ) **/
$this->rawheaders=$rawheaders;
$this->headers=$headers;
$this->contents=$contents;
return true;
}
}

星期五, 十月 27, 2006

摘录:Bash中对变量的操作&特殊字符

Bash中对变量的操作 原文
本文出自:http://www.ytht.org 作者:chenhao (2001-10-29 07:00:00)

1.条件变量替换:
Bash Shell可以进行变量的条件替换,既只有某种条件发生时才进行替换,替换
条件放在{}中.
(1) ${value:-word}
当变量未定义或者值为空时,返回值为word的内容,否则返回变量的值.
(2) ${value:=word}
与前者类似,只是若变量未定义或者值为空时,在返回word的值的同时将
word赋值给value
(3) ${value:?message}
若变量以赋值的话,正常替换.否则将消息message送到标准错误输出(若
此替换出现在Shell程序中,那么该程序将终止运行)
(4) ${value:+word}
若变量以赋值的话,其值才用word替换,否则不进行任何替换
(5) ${value:offset}
${value:offset:length}
从变量中提取子串,这里offset和length可以是算术表达式.
(6) ${#value}
变量的字符个数
(7) ${value#pattern}
${value##pattern}
去掉value中与pattern相匹配的部分,条件是value的开头与pattern相匹配
#与##的区别在于一个是最短匹配模式,一个是最长匹配模式.
(8) ${value%pattern}
${value%%pattern}
于(7)类似,只是是从value的尾部于pattern相匹配,%与%%的区别与#与##一样
(9) ${value/pattern/string}
${value//pattern/string}
进行变量内容的替换,把与pattern匹配的部分替换为string的内容,/与//的区
别与上同

注意:上述条件变量替换中,除(2)外,其余均不影响变量本身的值


2.变量的算术运算
在Bash Shell中,只能进行两个整数间的运算,其结果仍为整数.要进行算术
运算,需要使用let命令,语法为:
let expr
expr是一个包含项和操作符的表达式,项可以是一个变量或是一个整数常数,
当使用整数常数时,其默认为十进制整数,用户可以用radio#number来指定其它
形式的整数,其中radio定义了整数是几进制表示的,number是该整数的值.若
radio>10,那么数字字符可从0-9和A-Z.
在表达式中支持的操作符及其含义为:
+,-,*,/,% 加,减,乘,除,取模
>>,<<,&,^,| 左移,右移,位与,位异或,位或
?: 三元运算符.与C语言中的定义一致
~ 取补码
!,>=,<=,>,<,==,!=,&&,||
=,+=,-=,*=,/=,%=,<<=,>>=,&=,^=,|=
表达式式中也可以使用括号.括号或运算优先级的定义与一般计算机语言中的
相同.
let命令具有返回值.当计算结果(若有多个表达式时,以最后一个为准)为0时,
返回值为1,否则为0.
当表达式中含有shell的特殊字符(如|)时,需要用引用符('或")将其引用起来.
使用let时还需要注意的时,对于let x+y这样的式子,shell虽然计算了x+y的值
但却将结果丢弃,若不想这样,可以使用let sum=x+y将x+y的结果保存在变量sum中
另外还可以使用((和))操作符取代let命令,而且这样的话,还可以省去对算术
表达式的引用,如果想返回表达式的值,则需用$(())的格式.

Bash中的特殊字符

Bash中的特殊字符 本文出自:http://www.ytht.org 作者:chenhao (2001-10-28 13:05:01)
1.通配符
* 匹配任何长度的任何串
? 匹配单个字符
[...] 匹配单个括号内的字符,[]中的-,!具有特殊含义,如:
$ echo [a-z]*
显示首字母在a-z范围内的文件或目录名
$ echo [a,b]*
显示首字母为a或b的文件或目录名
$ echo [!a]*
显示首字母不为a的文件或目录名(使用!时,!必须是[后的第一个字符)
!还可与-和,一起使用

在Bash 2.0以后的版本中,若用shopt打开了extglob选项(shopt -s extglob),
那么还可以扩展的模式表达式(模式表达式是指那些包含了一个或多个shell通配
符的字):
*(pattern [|pattern] ...) 匹配模式的零次或多次出现
+(pattern [|pattern] ...) 匹配模式的一次或多次出现
@(pattern [|pattern] ...) 匹配模式的一次出现
?(pattern [|pattern] ...) 匹配任何一个模式.与*不同的是它不匹配
多个模式或模式的重复出现
!(pattern [|pattern] ...) 与?类似,不过是不包括指定模式的串
应该注意到,模式表达式的定义是递归的,每个表达式都可以包含一个或多个
模式,而且模式表达式也是可以嵌套的.

2.数据或程序控制使用的特殊字符:
主要有:
< (file) 输出重定向到文件
>> (file) 输出重定向到文件,内容加到已存在的文件尾部
< (file) 输入重定向到文件
; 命令分隔符
| 管道符,把一条命令的输出重定向为另一命令的输入
& 放在命令之后强迫命令在后台执行
`` 命令替换,重定向一条命令的输出为另一命令的参数

3.用于引用和逃逸的特殊字符:
逃逸符\ 表示以后的字符不具有特殊的含义或不是Shell的函数,
除此之外,Bash还可以识别一些C语言中的转义序列,如:
\a 响伶
\b 回退
\e Escape
\n 换行
\r 回车
\t 制表
\v 制表
\\ 反斜线
\nnn 八进制的ASCII编码
\xnnn 十六进制的ASCII编码
但必须以如下方式进行引用:
$'string'
引用符'和" 将特殊字符或由空白分隔的字引用起来组成一个简单字符串
两者区别在与,双引号内的内容可以进行参数和变量替换

怎样通过shell解析文件中的变量
原文
[xyb@linux xyb]$ echo name=xyb > id.txt
[xyb@linux xyb]$ echo age=xx >> id.txt
[xyb@linux xyb]$ eval $(cat id.txt | grep name=)
[xyb@linux xyb]$ eval $(cat id.txt | grep age=)
[xyb@linux xyb]$ echo $name
xyb
[xyb@linux xyb]$ echo $age
xx
[xyb@linux xyb]$

#! /bin/sh
name=`grep -e '^name=' YOURFILE | sed -e 's/^name=//g'`

星期四, 十月 26, 2006

摘录:shell常用指令收集

shell常用指令收集

awk 是一种方便的面向行的文本处理语言。
cat 将指定为参数的文件内容打印到终端。作为管道的第一个命令,这是很方便的,例如,cat foo.txt | blah。
cut 从输入文件或流的每个行上抽取出由字符限定的字段。
expand 将输入制表符转换为空格。使用 -t 选项来指定制表符停止位。
fmt 对段落重新格式化以便在其边缘处进行换行。这个能力被构建到大多数文本编辑器中,但是应知道它仍是一个好工具。
head 打印出文件或流的前十行。使用 -n 选项来指定应显示的行数。
join 与 paste 类似,但它在每个输入行中使用一个字段(缺省情况下是第一个字段)来匹配一在单行上合并的字段。
nl 将行号添加到输入的每个行上。这对于打印输出很有用。
od 将输入流转换为八进制或十六进制的“转储”格式。
paste 获取两个或更多文件作为输入,连接输入文件上的每个后续行,并输出结果行。它对于创建文本的表或列是很有用的。
pr 将文件分解为多个页面的输出;通常用于打印。
sed 是一个功能强大的面向流的文本编辑器。
sort 按字母次序打印在命令行上指定的文件内容。当然,sort 也接受用管道传送的输入。输入 man sort 来熟悉控制排序行为的各种选项。
split 将较大的文件拆分成许多较小、更易处理的块。
csplit 也是拆分文件,和split不同的是,新文件的名字可以用pattern来控制
cat 可以将这些小文件合并为分割前的文件
tac 与 cat 类似,但它以逆向顺序打印所有行,换句话说,先打印最后一行。
tail 打印出文件或流的最后十行。使用 -n 选项来指定应显示的行数。
tee 将它的输入打印到文件和屏幕。当您想创建某些日志记录,但还想在屏幕上看时,这很有用。
tr 是字符转换工具;它用来将输入流中的某些字符映射成输出流中的某些其它字符。
unexpand 将输入空格转换为制表符。使用 -t 选项来指定制表符停止位。
uniq 获取已排序的文件或数据流(通过管道)并除去重复行。
wc 打印出指定文件或输入流(来自管道)中的行、字和字节的数量。输入 man wc 来学习如何精调显示的内容。
cmp -- 判断两个文件内容是否一样。
diff -- 详细输出两个不同文件的差别。
diff3,可以比较三个文件

comm 比较两个排好序的文件
fold 按指定的宽度把文本文件换行
basename 去处前导的目录后的文件或目录名
echo 打印字符串
env 打印环境变量
expr 数学表达式计算
expr 还可以在指定的字符串中查找特定的子串
false 设置返回值为1
true 设置返回值为0
pwd 打印当前目录名
seq 打印指定步进值的数字序列,整数浮点数都可以
sleep 让当前进程休息一会儿
uname 打印一些重要的内核信息
yes 不停打印指定字符串,缺省为y

grep is a very powerful search tool.
find / -name 'linux*' | grep -E 'linux'

echo "" > filename # 创建文件,文件中包含一个空行 echo默认输出一个换行符
echo -n "" >filename # 创建空文件
touch filename # 创建空文件 'touch' changes the timestamp of a file and creates one if it doesn't exist.
cat /dev/null >filename # 创建空文件
> file #创建空文件
cp /dev/null filename #创建空文件



--原文

摘录:在 echo 中控制输出颜色

使用 echo 来向控制台输出指定的颜色

echo -e '\e[44;33;1m colors \e[0m'
在echo输出时使用ESC序列来控制输出的颜色和样式
-e 用来开启echo中的转义
\e 或 \033 来输出Esc符号
设置颜色 \e[4背景色;3前景色;高亮m
Esc[background;foreground;1m
恢复默认 \e[0m
Esc[0m
Foreground colors: 30=black, 31=red, 32=green, 33=yellow, 34=blue 35=purple, 36=turquoise, 37=white
Background colors: 0=transparent, 40=back, 41=red, 42=green, 43=yellow, 44=blue 45=purple, 46=turquoise, 47=white

原文
-- http://www.linuxforum.net/forum/showflat.php?Cat=&Board=vrml&amp;Number=624453&page=0&view=collapsed&sb=5&o=31&fpart=
-- http://www.linuxforum.net/forum/files/345507-colors.txt
如果需要在shell脚本里打印不同颜色的字符,可以使用ESC序列。

echo -e '\e[44;33;1m colors \e[0m'

echo -e表示启用\字符转义;\e即打印ESC控制符;[固定格式;44设置

背景为蓝色;33设置前景为白色;1设置加亮显示;m固定格式;colors

要打印的字符串;\e[0m设回开始的shell环境颜色设置。

连起来就是打印背景蓝色、前景高亮白色的字符串colors。
#! /bin/bash
# show colors (version 2)

FG='30 31 32 33 34 35 36 37'
BG='40 41 42 43 44 45 46 47'

NORMALSTR=' Normal '
BOLDSTR=' Bold '

echo

# Row Title
echo -n " "
for i in $FG ; do
echo -n " ${i} "
done
echo

# Row Title Line
echo -n "== "
for i in $FG ; do
echo -n " ========"
done
echo

# Color Map
for i in $BG ; do
echo -n "${i} "
for j in $FG ; do
echo -ne "\e[${j};${i}m${NORMALSTR}"
done
echo -e '\e[0m'

echo -ne " "
for j in $FG ; do
echo -ne "\e[${j};${i};1m${BOLDSTR}"
done
echo -e '\e[0m'
done

echo

星期日, 十月 22, 2006

转载:Code-flash播放器

Code-flash播放器
转载自穷困潦倒的阿威 http://my.opera.com/shui1220/blog/show.dml/316714

基于Flash的音乐播放器收集

1. Audio Player(官方地址)

名字很直接,就叫音频播放器,呵呵。
2. Dew Player(官方地址)
很漂亮的东东,作者本人就是设计师。
3. Odeo(官方地址)
Odeo本身提供的就是Podcast的服务,这是它们的重要工具之一。另外,你可以不下载这个swf,直接引用该网站上的这个播放器使用。
4. XSPF Web Music Player (官方地址)
这个播放器最大的特点就是支持XSPF格式(有空我会介绍下,Webjay, Yahoo! Music Engine都用它)的音乐播放列表,也就是说,通过它你可以播放多首歌曲。
它还提供多种播放器样式,最小的是Button(播放按钮),其次是Slim(单条),以及Extended(多功能模式)。除了界面一般外,功能上,它算非常的强了,比前面几个都厉害。
5.FMP256 Flash MP3 Player (官方地址)
这个播放器也支持 XSPF格式的播放列表,可以放多首歌。另外,它还有更强大的商业版本,3美元。
6. Easy musicplayer for Flash (EMFF) (官方地址)
非常简洁的作品,出自德国人之手。
7. Mini Mp3 Flash Player(相关链接)
Dew Player很像,但看上去更丑些。
8.爱播播放器(官方地址)
很强大的玩意儿,由爱播网推出。

星期三, 十月 18, 2006

podcasting 展望

podcasting 展望
作者:飞扬轻狂 fallseir.lee (fallseir at gmail.com)
一、什么是podcasting
技术角度认为什么是podcasting
Podcast是为了用户更方便的获取数据,作者更容易的发布数据而产生的。
狭义的说 Podcast 简单的说就是blogger创作的音频列表。
更广一点的说 Podcast 就是经常被更新的专人维护的媒体数据列表(可以包含语音视频图片等格式的数据)。

上图是一幅描述广播、blog和podcast关系的草图
其实应该加上网站和读者,
下面来叙述一下他们的关系,
首先,
听众通过收音机来获取广播的内容
读者通过Feed阅读器来定于作者发布在FEED上的blog内容
podcasting的出现使得听众可以使用Podcast订阅器来订阅作者提供在支持podcast的网站上的音频数据了。
其次,
不论是广播的信息源还是blog之前网站的信息源都是少数人发布的,而由多数人来获取;
podcasting的出现使得人人都可以成为信息发布者。

可以设想,如果我们的任意款mp3可以连接电脑后就方便的获取和筛选我们需要的数据,而这些数据有是分门别类的排列好供我们挑选,如此网络该是多么享受的事情。
podcasting及应用其上的服务就可以为我们营造这个方便的未来,
1、作者将数据提交到网络
2、由扮演再发布者的角色进行筛选整合和归类
3、由网络中的读者和听众进行评论,归类和digg等大众参与的评估
4、最后听众和读者就可以得到他们想要的内容了
这一切都需要podcasting这样的通用格式来将数据流连接起来来保证更有效的发布,更实用的评估,更方便得获取。



下面是摘录的两篇关于podcasting的说明

Podcast,中文译名尚未统一,但最多的是将其翻译为“播客”。它是数字广播技术的一 种,出现初期借助一个叫“iPodder”的软件与一些便携播放器相结合而实现。Podcasting录制的是网络广播或类似的网络声讯节目,网友可将网 上的广播节目下载到自己的iPod、MP3播放器或其它便携式数码声讯播放器中随身收听,不必端坐电脑前,也不必实时收听,享受随时随地的自由。更有意义 的是,你还可以自己制作声音节目,并将其上传到网上与广大网友分享。
就像博客颠覆了被动接受文字信息的方式一样,播客颠覆了被动收听广播的方式,使听众成为主动参与者。有人说,播客可能会像博客(Blog)一样,带来大众传媒的又一场革命。

一.Podcast的推动者Doc Searls给出的定义:
PODcasting,Personal Optional Digital casting。PODcasting是自助广播,是全新的广播形式。收听传统广播时我们是被动收听我们可能想听的节目,而PODcasting则是我们 选择收听的内容、收听的时间以及以何种方式让其他人也有机会收听。 戴维·温纳(Dave Winer)的Morning Coffee Notes:人各有所专,所以理论上人人播客是可能的。

 二.Dave Shusher在其“Podcasting的定义”一文中的定义:

他提出Podcasting必须具备三个要件:

1.必须是一个独立的、可下载的媒体文件;

2.该文件的发布格式为RSS2.0 enclosure feed;

3.接收端能自动接收、下载并将文件转至需要的地方,放置于播放器的节目单中。

  他认为可下载MP3 不是波刻(Podcast)――这是充分但不是必要条件。“能下载固然不错,但能自动出现供你播放而无需你关照才是关键。这才是Podcasting。”

三.Wikipedia的定义:

像WIKI这样的定义是开放、动态的,到2004年12月13日为止,其定义为: Podcasting源于iPod,兼具broadcasting和webcasting 之意。Podcasting 与TiVo相似, 只是Podcasting是用于声讯节目而且目前免费。但是应该注意,该技术能把任何文件“拉”过来,包括软件更新、照片和视频。

摘自:什么是Podcast? http://tech.bokee.com/140/2005-04-14/364318.html
( 作者:郑雅钦 | 2005年04月14日 20:04 | 原始出处: 博客中国)


Podcast是以数字方式存储在网络上的音频广播。传统广播特点是直播的,有一定的时效性、一次性,播完就可能消失,而且只能是“你播啥我听啥”。Podcast就不同了,它更自由:播者自由,听者也自由。做为播客,你可以自己建立个Podcast网站自己做Podcast,播你喜欢的。做为听众,因为可以下载,那么你就可以存下来慢慢听,不喜欢听这段就换下一段,“想听啥就听啥,想啥时听就啥时听”。
摘自:iPodder初级教程 http://blog.terac.com/andy/e_206.html

php中的逻辑输出信息缓存处理

php中的逻辑输出信息缓存处理
tags: php, cache,out
-- fallseir.lee (fallseir at gmail.com) 20061018
doc in google http://docs.google.com/View?docid=dg4t629m_43f75qzq
/* ---- 事例代码 ---- */

/** 将输出缓存到内存 **/
$out_headers[]='<meta http-equiv="refresh" content="3;url='.$return_url.'">';
add_error_cache("您已经登陆,请退出后再进行登录操作!"); # 添加错误消息
add_cache_out("将在3秒后自动跳转到$return_url"); # 添加输出消息
add_cache_out("如果没有自动跳转请单击<a href=\"$return_url\">这里</a>!");
cache_clear() # 清除前边设置的缓存
$out_headers[]='<meta http-equiv="refresh" content="3;url='.$return_url.'">';
add_success_cache("退出成功!"); # 添加成功消息
add_cache_out("将在3秒后自动跳转到$return_url");
add_cache_out("如果没有自动跳转请单击<a href=\"$return_url\">这里</a>!");

/** 将缓存的内容输出 **/
out_cache(); # 输出内建样式的全部缓存信息
join("<br/>",get_error_cache()); # 输出指定的信息
join("<br/>",get_success_cache()); # 输出指定的信息
join("<br/>",get_out_cache()); # 输出指定的信息

/* ---- 页面缓存封装 ---- */
/** 设定输出缓存 **/
if(!is_array($cache_outs)){
$cache_outs=array();
}
if(!is_array($cache_keyouts)){
$cache_keyouts=array();
}
/** 输出缓存信息 **/
function out_cache($br=true,$out_str=false){
$errs=get_error_cache();
$sucs=get_success_cache();
$infos=get_out_cache();
$outstr="";
if(count($errs)>1||(is_array($errs) && $errs[0])){
$outstr.= '<p class="errbox">';
$outstr.= join("<br/>",$errs);
$outstr.= '</p>';
}
if(count($sucs)>1||(is_array($sucs) && $sucs[0])){
$outstr.= '<p class="sucbox">';
$outstr.= join("<br/>",$sucs);
$outstr.= '</p>';
}
if(count($infos)>1||(is_array($infos) && $infos[0])){
$outstr.= '<p class="infobox">';
$outstr.= join("<br/>",$infos);
$outstr.= '</p>';
}
if($br)$outstr=str_replace("\n","<br/>\n",$outstr);
if($out_str){
return $outstr;
}else{
echo $outstr;
return 1;
}
}
/**
* 清除输出缓存
*/
function cache_clear(){
global $cache_outs;
$cache_outs=array();
global $cache_keyouts;
$cache_keyouts=array();
}
/**
* 添加错误信息到缓存
*/
function add_error_cache($msg){
add_cache_out("ERROR",$msg);
}
/**
* 输出缓存的错误消息
*/
function get_error_cache($format="× {out}"){
return get_out_cache("ERROR",$format);
}
/**
* 添加正确信息到缓存
*/
function add_success_cache($msg){
add_cache_out("SUCCESS",$msg);
}
/**
* 输出缓存的正确消息
*/
function get_success_cache($format="√ {out}"){
return get_out_cache("SUCCESS",$format);
}
/**
* 将消息加入输出缓存
* cout($msg);
* cout($key,$msg);
* cout($keys,$msg);
*/
function add_cache_out($msg,$msg2=false){
if($msg2===false){
global $cache_outs;
if(!is_array($cache_outs)){
$cache_outs=array();
}
return add_array_cache($cache_outs,$msg,$msg2);
}else{
$key=$msg;
$msg=$msg2;
global $cache_keyouts;
if(!is_array($cache_keyouts)){
$cache_keyouts=array();
}
return add_array_cache($cache_keyouts,$msg,$key);
}
}
/**
* 输出缓存的消息
*/
function get_out_cache($key=false,$format=false){
print_r($cache_outs);
if($key===false){
global $cache_outs;
$os=$cache_outs;
}else{
global $cache_keyouts;
$os=$cache_keyouts;
}
return get_array_cache($os,$format,$key);
}
/* ---- 底层逻辑封装 ---- */
/** -- 使用数组进行缓存输出 -- **/
/**
* 添加输出信息到缓存数组中,可以使用key进行填充 使用get_array_cache获取添加到缓存数组的输出信息
* add_array_cache($os) 输出空行
* add_array_cache($os,$msg) 输出信息
* add_array_cache($os,$msg,$key:string) 将信息输出到指定的位置
* add_array_cache($os,$msg,$keys:array) 将信息输出的分层的位置
* -- fallseir.lee 20061018
*/
function add_array_cache(&$os,$msg="",$key=false){
if($key===false){
if(!is_array($os)){
$os=array();
}
array_push($os,$msg);
}else if(is_array($key)&&count($key)>0){
if(!is_array($os)){
$os=array();
}
$t=&$os;
for($i=0;$i<count($key);$i++){
if(!array_key_exists($key[$i],$t)){
$t[$key[$i]]=array();
}
$t=&$t[$key[$i]];
}
array_push($t,$msg);
}else{
if(!is_array($os)){
$os=array();
}
if(!array_key_exists($key,$os)){
$os[$key]=array($msg);
}else{
array_push($os[$key],$msg);
}
}
}
/**
* 获取添加到缓存数组的输出信息
* format中可以指定 {out} 和 {key} 的样式
* get_array_cache($os)
* get_array_cache($os,$format)
* get_array_cache($os,$format,$key)
* get_array_cache($os,$format,$key,$pkey)
* -- fallseir.lee 20061018

*/
function get_array_cache($os,$format=false,$key=false,$pkey=false){
if($format===false){
$format="{out}";
}
$ostrs=array();
if($key===false){
if(is_array($os)){
foreach($os as $k=>$v){
if(is_array($v)){
$ostrs=array_merge($ostrs,get_array_cache($v,$format,$key,$pkey!==false?"$pkey:$k":"$k"));
}else{
$t=preg_replace("/{key}/",$pkey,$format);
$ostrs=array_merge($ostrs,preg_replace("/{out}/",$v,$t));
}
}
}else{
$format=preg_replace("/{key}/","",$format);
$ostrs=array_merge($ostrs,preg_replace("/{out}/",$os,$format));
}
}else{
// out $keyouts[$key[0]][$key[1]]...
if(is_array($key)){
for($i=0;$i<count($key);$i++){
if(false===$os=try_get_array_value($os,$key[$i],false)){
return $ostrs;
}
}
$ostrs = get_array_cache($os,$format,null);
}else{
if(false===$os=try_get_array_value($os,$key,false)){
return $ostrs;
}
$ostrs = get_array_cache($os,$format,false);
}
}
return $ostrs;
}
if(!function_exists(try_get_array_value))
/**
* 尝试从数组中获取指定的值
*/
function try_get_array_value($array, $key, $default = null)
{
if($array && is_array($array)){
if( array_key_exists($key, $array) ){
return $array[$key];
}
}
return $default;
}
}
doc in google http://docs.google.com/View?docid=dg4t629m_43f75qzq

星期二, 十月 10, 2006

note: 使用prototype中的ajax (1)

使用prototype中的ajax
一、prototype 中的ajax调用部分分析
author: fallseir fallseir [at] gmail.com
tags:prototype,ajax,参考

Ajax
getTransport() 获取一个基本的Request对象
自动从 XMLHttpRequest Msxml2.XMLHTTP Microsoft.XMLHTTP 中选择,如果创建失败则返回false
activeRequestCount 当前的活动reqeust数量 默认为0

Ajax.Responders 全局
responders[] responder列表
_each() 对每一个 responder 执行指定的操作
register() 注册一个 responder
unregister() 注销一个 responder
dispatch() 触发每个 responder 中指定的callback动作
继承了 Enumerable 的操作
添加默认处理 onCreate 和 onComplete 对 Ajax.activeRequestCount 进行增减操作
Ajax.Base 基本ajax类
setOptions 设置Ajax选项
使用指定的参数值覆盖默认值,每次设置会重新初始化而不会保留原有值
responseIsSuccess() 判断transport的执行状态是否为 2xx
responseIsFailure() 返回transport执行是否成功 !responseIsSuccess()
Ajax.Request 远程请求
Ajax.Request.Events[] 事件表 = ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete']
继承 Ajax.Base
initialize() 初始化
初始化一个 transport 通过 Ajax.getTransport()
设定 options 通过 指定的 options
通过 request 请求指定的 url
request() 请求远程地址
从 options 中获取参数
options.parameters 参数表
用于发送到请求的url中 使用 xx=xx&xx=xx格式
options.method 请求方式
post | get 当使用其他方式时 请求采用post形式 并将 method 以 _method=method形式追加到parameters上。
options.asynchronous 指定是否使用异步方式请求
触发 onCreate 事件 Ajax.Responders.dispatch('onCreate', this, this.transport);
打开远程请求连接 this.transport.open(this.options.method, this.url,this.options.asynchronous);
设置异步请求的定时回调处理 setTimeout(function() { this.respondToReadyState(1) }.bind(this), 10);
设置transport的状态回调处理 this.transport.onreadystatechange = this.onStateChange.bind(this);
设置请求头信息 this.setRequestHeaders();
发送请求 this.transport.send(this.options.method == 'post' ? body : null);
body 如果 options.postBody 存在就使用 options 中的设置 否则使用 parameters 的值
更新状态 this.onStateChange(); 如果使用非同步方式或overrideMimeType形式的请求
处理过程中如果发生异常将导致 this.dispatchException(e)
setRequestHeaders() 设置 http 请求头信息
如果 options.method 为 post 则通过 options.contentType 设置请求的 Content-type
如果 overrideMimeType 存在则设置 Connection 为 close
使用 options.requestHeaders 中的值覆盖默认值
设置 transport 的头信息 this.transport.setRequestHeader(requestHeaders[i], requestHeaders[i+1]);
onStateChange() 更新 Reqeust 状态
当 transport.readyState 不为 1 (loading) 时,触发状态更新动作 this.respondToReadyState(this.transport.readyState)
header() 从 transport 的 response 中获取指定的 header 项的值
evalJSON() 使用 eval 执行( this.header('X-JSON') )中包含的 javascript 字面形式数据
evalResponse() 使用 eval 执行 response 中包含的 javascript 字面形式数据
出错时触发 dispatchException
respondToReadyState() 处理请求状态
获取状态值对应的状态名
设置 json为 this.evalJSON()
如果当前状态为 Complete 则根据优先顺序选择处理方式
如果 options中包含 'on' + this.transport.status 命名的回调函数
或 'on' + (this.responseIsSuccess() ? 'Success' : 'Failure' 命名的回调函数
则尝试执行回调
如果 response 的 content-type 为javascript 则执行返回的内容
if((this.header('Content-type') || '').match(/^text\/javascript/i)) this.evalResponse();
如果 options 中包含对应的 'on'+event 回调函数 则进行回调
触发全局的Responders 事件 Ajax.Responders.dispatch('on' + event, this, transport, json);
如果当前状态为 Complete 则 清空 transport 的状态回调函数
dispatchException() 处理异常
调用 options 中的异常处理函数 如果存在的话 (this.options.onException || Prototype.emptyFunction)(this, exception);
触发异常处理事件 Ajax.Responders.dispatch('onException', this, exception);

Ajax.Updater 自动更新处理
继承 Request
initialize() 初始化
建立回显区域 containers{success,failure}
container|container.success[,container.failure]
如果指定的container包含success 则设置success为container.success指定的htmldom元素
如果指定的container包含container.failure 则设置 failure
创建 transport
设置请求选项 setOptions
重置完成时的回调 onComplete
增加 updateContent
开始请求 request
updateContent() 更新回显区域
根据状态设定回显区域 receiver
获取回显内容 response
清除response中的js脚本,如果选项中没有设定执行js options.evalScripts
更新内容
如果选项中指定了回显操作options.insertion 则调用指定的回显操作进行回显
否则使用默认方式更新回显区域 Element.update(receiver, response);
如果 responseIsSuccess 设定延时执行 onComplete

Ajax.PeriodicalUpdater
继承 Ajax.Base
initialize() 初始化
设置参数 setOptions
设置请求回调 onComplete=options.onComplete
设置循环周期 frequency
设置衰减 decay
初始化 updater
设置 container
设置 url
开始进行处理 start
start() 开始处理
重置回调处理 options.onComplete = updateComplete
触发计时器事件 onTimerEvent
stop() 停止循环处理
清除 updater 的回调函数 this.updater.options.onComplete = undefined;
清除计时器 clearTimeout(this.timer);
回调 onComplete (this.onComplete || Prototype.emptyFunction).apply(this, arguments);
updateComplete() 重置请求
当updater完成一次请求时,自动回调此函数
根据返回的内容是否存在设定本次的衰减值 decay
设定lastText
重新设定定时器 onTimerEvent
onTimerEvent() 创建 updater
创建updater并执行一次远程请求

参考:
最新prototype.js下载
prototype 类图
prototype.js开发笔记
Developer Notes for prototype.js
js加油站:prototype 源码解读(一)

星期日, 十月 08, 2006

code:php 将字符串转换为html实体

tags:htmlentity,php,iconv
将字符串转换为html实体
$src 原始字符串
$output 输出字符串
$src= htmlspecialchars($src); // translate &"<> to HTML entities
/** translate \n to <br/>**/
$src= str_replace("\n", "<br/>", $src);
$str = iconv($deck->charset, "UTF-16BE", $src); # 将原始字符串转换为utf16编码
for ($i = 0; $i < strlen($str); $i++,$i++) { # 将每个标准ascii字符以外的(大于128)字符转换为实体
$code = ord($str{$i}) * 256 + ord($str{$i + 1});
if ($code < 128) {
$output .= chr($code);
} else if ($code != 65279) {
$output .= "&#".$code.";";
}
}

摘录 html实体与网页编码
--------------------------------------------------------------
--http://www.ugia.cn/?p=72

在php中我们可以用mbstring的mb_convert_encoding函数实现这个正向及反向的转化。
如:

mb_convert_encoding ("你好", "HTML-ENTITIES", "gb2312"); //输出:你好
mb_convert_encoding ("你好", "gb2312", "HTML-ENTITIES"); //输出:你好

可以查看这个页面:htmlentities.html, 不管选择什么网页编码,网页都能正常显示。

如果需要对整个页面转化,则只需要在php文件的头部加上这三行代码:

mb_internal_encoding("gb2312"); // 这里的gb2312是你网站原来的编码
mb_http_output("HTML-ENTITIES");
ob_start('mb_output_handler');

在asp中我们可以用下面这个函数来实现这个转化:

Function htmlentities(str)
For
i = 1 to Len(str)
char = mid(str, i, 1)
If
AscW(char) > 0 then
htmlentities
= htmlentities & "&#" & Ascw(char) & ";"
Else
htmlentities = htmlentities & "&#" & (65536 + ascW(char)) & ";"
End if
Next
End
Function

--------------------------------------------------------------
mb_convert_encoding 只在php5之后才有 我用的是php4所以用不了 :)


摘录:将字符转成unicode
---------------------------------------------------------------
-- http://www.web-bbs.com/forum/htm_data/10/0512/258.html

Js版

<script>
test = "你好abc"

str = ""
for( i=0; i<test.length; i++ )
{
temp = test.charCodeAt(i).toString(16);
str += "\\u"+ new Array(5-String(temp).length).join("0") +temp;
}
document.write (str)
</script>


vbs版


Function Unicode(str1)
Dim str,temp
str = ""
For i=1 to len(str1)
temp = Hex(AscW(Mid(str1,i,1)))
If len(temp) < 5 Then temp = right("0000" & temp, 4)
str = str &amp;amp;amp; "\u" & temp
Next
Unicode = str
End Function

---------------------------------------------------------------
摘录的两个没有进行测试 放在这里有待参考


星期六, 十月 07, 2006

摘录:http响应码 & http 信息头

摘录:http响应码 & http 信息头
tags:http,http code,http head
一、HTTP响应码

响应码由三位十进制数字组成,它们出现在由HTTP服务器发送的响应的第一行。

响应码分五种类型,由它们的第一位数字表示:
1xx:信息,请求收到,继续处理
2xx:成功,行为被成功地接受、理解和采纳
3xx:重定向,为了完成请求,必须进一步执行的动作
4xx:客户端错误,请求包含语法错误或者请求无法实现
5xx:服务器错误,服务器不能实现一种明显无效的请求

下表显示每个响应码及其含义:

100 继续
101 分组交换协
200 OK
201 被创建
202 被采纳
203 非授权信息
204 无内容
205 重置内容
206 部分内容
300 多选项
301 永久地传送
302 找到
303 参见其他
304 未改动
305 使用代理
307 暂时重定向
400 错误请求
401 未授权
402 要求付费
403 禁止
404 未找到
405 不允许的方法
406 不被采纳
407 要求代理授权
408 请求超时
409 冲突
410 过期的
411 要求的长度
412 前提不成立
413 请求实例太大
414 请求URI太大
415 不支持的媒体类型
416 无法满足的请求范围
417 失败的预期
500 内部服务器错误
501 未被使用
502 网关错误
503 不可用的服务
504 网关超时
505 HTTP版本未被支持

二、HTTP头标
头标由主键/值对组成。它们描述客户端或者服务器的属性、被传输的资源以及应该实现连接。

四种不同类型的头标:
1.通用头标:即可用于请求,也可用于响应,是作为一个整体而不是特定资源与事务相关联。
2.请求头标:允许客户端传递关于自身的信息和希望的响应形式。
3.响应头标:服务器和于传递自身信息的响应。
4.实体头标:定义被传送资源的信息。即可用于请求,也可用于响应。


头标格式::

下表描述在HTTP/1.1中用到的头标
Accept 定义客户端可以处理的媒体类型,按优先级排序;
在一个以逗号为分隔的列表中,可以定义多种类型和使用通配符。例如:Accept: image/jpeg,image/png,*/*
Accept-Charset 定义客户端可以处理的字符集,按优先级排序;
在一个以逗号为分隔的列表中,可以定义多种类型和使用通配符。例如:Accept-Charset: iso-8859-1,*,utf-8
Accept-Encoding 定义客户端可以理解的编码机制。例如:Accept-Encoding:gzip,compress
Accept-Language 定义客户端乐于接受的自然语言列表。例如:Accept-Language: en,de
Accept-Ranges 一个响应头标,它允许服务器指明:将在给定的偏移和长度处,为资源组成部分的接受请求。
该头标的值被理解为请求范围的度量单位。例如Accept-Ranges: bytes或Accept-Ranges: none
Age 允许服务器规定自服务器生成该响应以来所经过的时间长度,以秒为单位。
该头标主要用于缓存响应。例如:Age: 30
Allow 一个响应头标,它定义一个由位于请求URI中的次源所支持的HTTP方法列表。例如:Allow: GET,PUT
aUTHORIZATION 一个响应头标,用于定义访问一种资源所必需的授权(域和被编码的用户ID与口令)。
例如:Authorization: Basic YXV0aG9yOnBoaWw=
Cache-Control 一个用于定义缓存指令的通用头标。例如:Cache-Control: max-age=30
Connection 一个用于表明是否保存socket连接为开放的通用头标。例如:Connection: close或Connection: keep-alive
Content-Base 一种定义基本URI的实体头标,为了在实体范围内解析相对URLs。
如果没有定义Content-Base头标解析相对URLs,使用Content-Location URI(存在且绝对)或使用URI请求。
例如:Content-Base: Http://www.myweb.com
Content-Encoding 一种介质类型修饰符,标明一个实体是如何编码的。例如:Content-Encoding: zip
Content-Language 用于指定在输入流中数据的自然语言类型。例如:Content-Language: en
Content-Length 指定包含于请求或响应中数据的字节长度。例如:Content-Length:382
Content-Location 指定包含于请求或响应中的资源定位(URI)。
如果是一绝。对URL它也作为被解析实体的相对URL的出发点。
例如:Content-Location: http://www.myweb.com/news
Content-MD5 实体的一种MD5摘要,用作校验和。
发送方和接受方都计算MD5摘要,接受方将其计算的值与此头标中传递的值进行比较。
例如:Content-MD5:
Content-Range 随部分实体一同发送;标明被插入字节的低位与高位字节偏移,也标明此实体的总长度。
例如:Content-Range: 1001-2000/5000
Contern-Type 标明发送或者接收的实体的MIME类型。例如:Content-Type: text/html
Date 发送HTTP消息的日期。例如:Date: Mon,10PR 18:42:51 GMT
ETag 一种实体头标,它向被发送的资源分派一个唯一的标识符。
对于可以使用多种URL请求的资源,ETag可以用于确定实际被发送的资源是否为同一资源。
例如:ETag: '208f-419e-30f8dc99'
Expires 指定实体的有效期。例如:Expires: Mon,05 Dec 2008 12:00:00 GMT
Form 一种请求头标,给定控制用户代理的人工用户的电子邮件地址。例如:From: webmaster@myweb.com
Host 被请求资源的主机名。对于使用HTTP/1.1的请求而言,此域是强制性的。例如:Host: www.myweb.com
If-Modified-Since 如果包含了GET请求,导致该请求条件性地依赖于资源上次修改日期。
如果出现了此头标,并且自指定日期以来,此资源已被修改,应该反回一个304响应代码。
例如:If-Modified-Since: Mon,10PR 18:42:51 GMT
If-Match 如果包含于一个请求,指定一个或者多个实体标记。只发送其ETag与列表中标记区配的资源。
例如:If-Match: '208f-419e-308dc99'
If-None-Match 如果包含一个请求,指定一个或者多个实体标记。资源的ETag不与列表中的任何一个条件匹配,操作才执行。
例如:If-None-Match: '208f-419e-308dc99'
If-Range 指定资源的一个实体标记,客户端已经拥有此资源的一个拷贝。必须与Range头标一同使用。
如果此实体自上次被客户端检索以来,还不曾修改过,那么服务器只发送指定的范围,否则它将发送整个资源。
例如:Range: byte=0-499If-Range:'208f-419e-30f8dc99'
If-Unmodified-Since 只有自指定的日期以来,被请求的实体还不曾被修改过,才会返回此实体。
例如:If-Unmodified-Since:Mon,10PR 18:42:51 GMT
Last-Modified 指定被请求资源上次被修改的日期和时间。例如:Last-Modified: Mon,10PR 18:42:51 GMT
Location 对于一个已经移动的资源,用于重定向请求者至另一个位置。
与状态编码302(暂时移动)或者301(永久性移动)配合使用。
例如:Location: http://www2.myweb.com/index.jsp
Max-Forwards 一个用于TRACE方法的请求头标,以指定代理或网关的最大数目,该请求通过网关才得以路由。
在通过请求传递之前,代理或网关应该减少此数目。例如:Max-Forwards: 3
Pragma 一个通用头标,它发送实现相关的信息。例如:Pragma: no-cache
Proxy-Authenticate 类似于WWW-Authenticate,便是有意请求只来自请求链(代理)的下一个服务器的认证。
例如:Proxy-Authenticate: Basic realm-admin
Proxy-Proxy-Authorization 类似于授权,但并非有意传递任何比在即时服务器链中更进一步的内容。
例如:Proxy-Proxy-Authorization: Basic YXV0aG9yOnBoaWw=
Public 列表显示服务器所支持的方法集。例如:Public: OPTIONS,MGET,MHEAD,GET,HEAD
Range 指定一种度量单位和一个部分被请求资源的偏移范围。例如:Range: bytes=206-5513
Refener 一种请求头标域,标明产生请求的初始资源。对于HTML表单,它包含此表单的Web页面的地址。
例如:Refener: http://www.myweb.com/news/search.html
Retry-After 一种响应头标域,由服务器与状态编码503(无法提供服务)配合发送,以标明再次请求之前应该等待多长时间。
此时间即可以是一种日期,也可以是一种秒单位。例如:Retry-After: 18
Server 一种标明Web服务器软件及其版本号的头标。例如:Server: Apache/2.0.46(Win32)
Transfer-Encoding 一种通用头标,标明对应被接受方反向的消息体实施变换的类型。例如:Transfer-Encoding: chunked
Upgrade 允许服务器指定一种新的协议或者新的协议版本,与响应编码101(切换协议)配合使用。
例如:Upgrade: HTTP/2.0
User-Agent 定义用于产生请求的软件类型(典型的如Web浏览器)。
例如:User-Agent: Mozilla/4.0(compatible; MSIE 5.5; Windows NT; DigExt)
Vary 一个响应头标,用于表示使用服务器驱动的协商从可用的响应表示中选择响应实体。例如:Vary: *
Via 一个包含所有中间主机和协议的通用头标,用于满足请求。例如:Via: 1.0 fred.com, 1.1 wilma.com
Warning 用于提供关于响应状态补充信息的响应头标。例如:Warning: 99 www.myweb.com Piano needs tuning
www-Authenticate 一个提示用户代理提供用户名和口令的响应头标,与状态编码401(未授权)配合使用。响应一个授权头标。
例如:www-Authenticate: Basic realm=zxm.mgmt
原文:http://blog.liu21st.com/index.php?job=art&articleid=a_20060807_154537

code:从apache日志文件中获取所有的关于google的useragent[shell应用]

tags:shell,cat,awk,sort,uniq


从apache日志文件中获取所有的关于google的useragent

cat [dir]/access_log.2006*| awk '/Google/{sub(".*","",$1); sub(".*","",$2); sub(".*","",$3); sub(".*","",$4); sub(".*","",$5); sub(".*","",$6); sub(".*","",$7); sub(".*","",$8); sub(".*","",$9); sub(".*","",$10); sub(".*","",$11); print ; }'| awk '/Google/'|sort|uniq -c|sort –rn

分析:

cat [dir]/access_log.2006* # 输出所有dir指定的目录下以access_log.2006开头的文件的内容

awk '/Google/ # 过滤出所有包含Google的记录(按行)

{sub(".*","",$1); sub(".*","",$2); sub(".*","",$3); sub(".*","",$4); sub(".*","",$5); sub(".*","",$6); sub(".*","",$7); sub(".*","",$8); sub(".*","",$9); sub(".*","",$10); sub(".*","",$11); print ; }' # 通过 sub 对前11项(按空格进行区分)进行清除 ,print输出剩下的内容。

awk '/Google/' # 过滤出所有包含Google的项

sort|uniq -c # 排序并过滤重复,-c 输出重复次数

sort –rn # 按-n数字进行-r反向排序


数据样式

20060926 – 20061007 关于google的useragent列表

重复次数 useragent

167822 "Feedfetcher-Google; (+http://www.google.com/feedfetcher.html)"

4105 "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"

2017 "Mozilla/5.0 (compatible; Google Desktop)"

1933 "Mozilla/4.0 (compatible; Google Desktop)"

257 "Planet Google (China) +http://planet-google.com/cn/ Planet/1.0~pre1 +http://www.planetplanet.org UniversalFeedParser/3.3 +http://feedparser.org/"

35 "FeedFetcher-Google; (+http://www.google.com/feedfetcher.html)"

13 "Googlebot/2.1+(+http://www.googlebot.com/bot.html)"

12 "Mediapartners-Google/2.1"

10 "Nokia6820/2.0 (4.83) Profile/MIDP-1.0 Configuration/CLDC-1.0 (compatible; Googlebot-Mobile/2.1; +http://www.google.com/bot.html)"

8 "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.8.0.1) Gecko/20060307 Googlebot/2.1;+http://www.google.com/bot.html"

7 "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; Google Wireless Transcoder;)"

4 "Mozilla/4.0 (compatible; GoogleToolbar 2.0.114-big; Windows XP 5.1)"

2 "GoogleSpider2"

1 "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; Maxthon; .NET CLR 1.1.4322; .NET CLR 2.0.50727; Google-TR-4)"


星期五, 九月 29, 2006

wp的config分析 learn wordpress (9)

定义常量的方式
define('DB_NAME', 'wordpress_test');
定义变量的方式
$table_prefix = 'wp_';

数据库设置
DB_NAME DB_USER DB_PASSWORD DB_HOST
table_prefix

多语言设置
WPLANG

当前文件的绝对路径
define('ABSPATH', dirname(__FILE__).'/');
#PS:这个强烈建议去做,在一个预定的位置来记录路径,在以这个路径为基本进行路径组合。
省得当前文件在哪自己都不知道了,特别是在包含来包含去的时候。

从外部导入设置
require_once(ABSPATH.'wp-settings.php');
在wp-setting中对环境进行了一些设置 可以参看前面的几篇文章

wp-setting中进行不需要人为干预的环境初始化

星期四, 九月 28, 2006

学习wordpress的安装过程(一) learn wordpress(8)

tags: install,wordpress,learn
author: fallseir.lee
date:20060929
description:
分析 wordpress 的代码,分析其自动安装过程,从其内部压榨其可用之处。
=-------------------------------* 跟踪WP的安装 *----------------------------=
安装wordpress就不再重复了
现在我们来看下其文件加载过程

首先、通过 http://localhost/wordpress/ 来访问本地安装的wordpress
1、进入 index.php
在index.php中只是定义的一个默认的样式然后导入wp-blog-header.php文件
2、当加载 wp-blog-header.php 文件时
使用 file_exists 来判断 config.php 文件是否已经配置(存在) 通过dirname(__FILE__)来获取当前目录
使用 strstr 和 全局变量 $_SERVER['PHP_SELF'] 来自动匹配转向文件的位置
使用 die 结束任务并返回错误提示,提示用户到这里http://localhost/wordpress/wp-admin/setup-config.php 来安装配置文件。

其次、在setup-config.php中提示用户如何进行数据库连接配置
1、检测默认配置文件 file_exists('../wp-config-sample.php')
2、检测目录是否可写 is_writable('../')
3、根据外部参数状态进行自动参数填充 isset($_GET['step']) 如果没有设置则设置为默认值
4、根据 switch($step) 指定的向导位置,进行相应的处理
5、使用向导提示用户进行数据库参数设置
5.2、判断配置文件是否已经存在,防止自动覆盖已经存在的配置信息
6、$configFile = file('../wp-config-sample.php'); # 使用 file 提取出文件中的行列
7、设置数据库访问环境 并对数据库环境进行测试
define('DB_NAME', $dbname);
define('DB_USER', $uname);
define('DB_PASSWORD', $passwrd);
define('DB_HOST', $dbhost);
require_once('../wp-includes/wp-db.php'); # 导入数据库处理包,假定这个包有自动监测环紧的部分
8、将配置信息写入到配置文件
fopen('../wp-config.php', 'w'); # 写入配置文件
foreach ($configFile as $line_num => $line) { # 按行读取配置信息
switch (substr($line,0,16)) { # 通过前16字进行配置信息匹配
case "define('DB_NAME'": # 如果包含指定的标识
fwrite($handle, str_replace("wordpress", $dbname, $line)); # 使用对应的新数据进行写入
break;
...
default:
fwrite($handle, $line); # 没有匹配的信息原样写入
fclose($handle); # 关闭文件句柄
chmod('../wp-config.php', 0666); # 修改文件访问模式
配置文件更新成功后提示用户进入安装向导 install.php

然后、开始安装数据库 install.php
1、定义开始安装标记 define('WP_INSTALLING', true);
2、检测 wp-config.php 并加载
3、加载 './upgrade-functions.php' 对上一版数据进行升级(暂时理解为)
4、记录协议名支持可能的https
$schema = ( isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) == 'on' ) ? 'https://' : 'http://';
5、组合全路径(PS:将step=2清除了,暂时还不明白为什么)
$guessurl = str_replace('/wp-admin/install.php?step=2', '', $schema . $_SERVER['HTTP_HOST'] . dirname($_SERVER['PHP_SELF']) );
6、设定http头信息
header( 'Content-Type: text/html; charset=utf-8' ); # 指定处理类型和编码
7、内部统一输出方式
_e('WordPress › Installation'); #将所有的程序输出加壳,以便可以进行统一的处理,比如多语言支持。
8、检测数据是否已经安装
$wpdb->hide_errors(); # 关闭错误输出,在检测时允许出现表不存在的异常
$installed = $wpdb->get_results("SELECT * FROM $wpdb->users"); # 执行sql
if ($installed) die('
'.__('Already Installed').'

'.__('You appear to have already installed WordPress. To reinstall please clear your old database tables first.').'
'); # 使用 __() 封装文字数据获取方式,提供对多语言的支持
$wpdb->show_errors(); # 开启错误输出
9、使用 flush 将一部分数据先送到客户端,让用户最快的看到信息减少用户的等待时间
flush();
将内部的缓存全部送出
// Set everything up
wp_cache_flush();
10、PS:一些不认识的标记
make_db_current_silent();
populate_options();
populate_roles();
11、对经常使用的更新操作进行封装
update_option('blogname', $weblog_title);
update_option('admin_email', $admin_email);
12、设置一些默认数据
// Now drop in some default links
$wpdb->query("INSERT INTO $wpdb->linkcategories (cat_id, cat_name) VALUES (1, '".$wpdb->escape(__('Blogroll'))."')");
$wpdb->query("INSERT INTO $wpdb->links (link_url, link_name, link_category, link_rss, link_notes) VALUES ('http://blogs.linux.ie/xeer/', 'Donncha', 1, 'http://blogs.linux.ie/xeer/feed/', '');");
...
// Default category
$wpdb->query("INSERT INTO $wpdb->categories (cat_ID, cat_name, category_nicename, category_count, category_description) VALUES ('0', '".$wpdb->escape(__('Uncategorized'))."', '".sanitize_title(__('Uncategorized'))."', '1', '')");
// First post
$now = date('Y-m-d H:i:s');
$now_gmt = gmdate('Y-m-d H:i:s');
$wpdb->query("INSERT INTO $wpdb->posts (post_author, post_date, post_date_gmt, post_content, post_excerpt, post_title, post_category, post_name, post_modified, post_modified_gmt, comment_count, to_ping, pinged, post_content_filtered) VALUES ('1', '$now', '$now_gmt', '".$wpdb->escape(__('Welcome to WordPress. This is your first post. Edit or delete it, then start blogging!'))."', '', '".$wpdb->escape(__('Hello world!'))."', '0', '".$wpdb->escape(__('hello-world'))."', '$now', '$now_gmt', '1', '', '', '')");

$wpdb->query( "INSERT INTO $wpdb->post2cat (`rel_id`, `post_id`, `category_id`) VALUES (1, 1, 1)" );

// Default comment
$wpdb->query("INSERT INTO $wpdb->comments (comment_post_ID, comment_author, comment_author_email, comment_author_url, comment_date, comment_date_gmt, comment_content) VALUES ('1', '".$wpdb->escape(__('Mr WordPress'))."', '', 'http://wordpress.org/', '$now', '$now_gmt', '".$wpdb->escape(__('Hi, this is a comment.
To delete a comment, just log in, and view the posts\' comments, there you will have the option to edit or delete them.'))."')");
// First Page

$wpdb->query("INSERT INTO $wpdb->posts (post_author, post_date, post_date_gmt, post_content, post_excerpt, post_title, post_category, post_name, post_modified, post_modified_gmt, post_status, to_ping, pinged, post_content_filtered) VALUES ('1', '$now', '$now_gmt', '".$wpdb->escape(__('This is an example of a WordPress page, you could edit this to put information about yourself or your site so readers know where you are coming from. You can create as many pages like this one or sub-pages as you like and manage all of your content inside of WordPress.'))."', '', '".$wpdb->escape(__('About'))."', '0', '".$wpdb->escape(__('about'))."', '$now', '$now_gmt', 'static', '', '', '')");

# PS:从上面的代码可以看书 wp 将数据库操作 都封装到了wpdb对象中,包括可能批量变化的表名,和一些辅助操作$wpdb->escape
13、PS:未知操作
$wp_rewrite->flush_rules();
14、设置管理员信息

// Set up admin user
$random_password = substr(md5(uniqid(microtime())), 0, 6);
# PS:使用md5来生成随机密码呵呵有意思
# 获取email中的用户名
$display_name_array = explode('@', $admin_email); # 不过我经常是使用split来切片一个字符串
$display_name = $display_name_array[0];

# 插入用户
$wpdb->query("INSERT INTO $wpdb->users (ID, user_login, user_pass, user_email, user_registered, display_name, user_nicename) VALUES ( '1', 'admin', MD5('$random_password'), '$admin_email', NOW(), '$display_name', 'admin')");

# PS:$wpdb->insert_id 应该是上一条sql出来的吧
# PS:这个level应该使用来排序的权值吧
$wpdb->query("INSERT INTO $wpdb->usermeta (user_id, meta_key, meta_value) VALUES ({$wpdb->insert_id}, '{$table_prefix}user_level', '10');");
# 将权限列表存储 使用php自己的序列化
$admin_caps = serialize(array('administrator' => true));
$wpdb->query("INSERT INTO $wpdb->usermeta (user_id, meta_key, meta_value) VALUES ({$wpdb->insert_id}, '{$table_prefix}capabilities', '{$admin_caps}');");

# 构建mail
$message_headers = 'From: ' . $weblog_title . ' ';
# 使用 sprintf 对模版进行填充
$message = sprintf(__("Your new WordPress blog has been successfully set up at:

%1\$s

You can log in to the administrator account with the following information:

Username: admin
Password: %2\$s

We hope you enjoy your new weblog. Thanks!

--The WordPress Team
http://wordpress.org/
"), $guessurl, $random_password);
# 原来 guessurl 用在这里,在mail中当然不能使用相对路径

# 发送mail
# PS:但是我的 mail 不可用 也许是我配置错了吧 不过我没有设置过阿
@wp_mail($admin_email, __('New WordPress Blog'), $message, $message_headers);

15、PS:又一次清空缓存 而且和前两次用到的不同
wp_cache_flush();
=-------------------------------* PS:终于跟到安装结束了 *----------------------------=
PS:顺了一遍安装的流程,让我们回顾下有什么东西可以留在脑子里

wp的index.php只有两句
/* Short and sweet */ # 短而美妙的
define('WP_USE_THEMES', true);
require('./wp-blog-header.php');
这里的define应该是引导用户可以在这里进行一些全局的设置,在 config 加载之前
这句 require 才是大头,它将所有的处理都封装了
看他的命名
WP_USE_THEMES
前缀wp使用简写
每个单词使用下划线间隔
常量大写
PS:比较常见的命名方式,使用wp前缀应该是给用户最大的可能不出现重名,还可以和其他的插件进行友好的兼容 用户不必再编写插件或进行扩展时需要查看所有可能用到的页面来判断是否会出现命名重复。
wp-blog-header.php
可以看到这个是wordpress的blog的头信息,也可以理解为在处理开始的部分。
这个header好像处理的东西也不多
首先使用$wp_did_header进行重复加载过滤
然后加载config数据
进行预处理
wp(); # 理解为初始化环境
gzip_compression(); # 进行压缩处理
# 加载样式模版
require_once(ABSPATH . WPINC . '/template-loader.php');

PS:今天先到这,没有外链了,我去写篇wp的config分析
UPDATE:本来加了颜色和样式的 但是发布时竟然出现
郁闷啊 我把样式清除了才可以发布 !!

code:哈希和循环 (perl snippet)

perl 脚本记录
哈希和循环
$ perl -e '
($t1,$t2) = split ":","test:test2:test3",2; # 使用split进行字符串的切片操作 按:将字符串切片成长度为2的数组并分别符值给$t1和$t2
$t={"1"=>$t1,"2"=>$t2}; # 使用$t1和$t2的值构建哈希表
for $k (keys %{$t}){ # 输出%t中的每一个值
print "$k $t->{$k}\n"
};
'
1 test
2 test2:test3

shell:date 常用方式

在linux下获取时间字符串
命令 date
# 以yyyymmdd格式输出23天之前现在这个时刻的时间
$ date +%Y%m%d --date='23 days ago'

$ date -u
Thu Sep 28 09:32:04 UTC 2006

$ date -R
Thu, 28 Sep 2006 17:32:28 +0800

# 测试十亿分之一秒
$ date +'%Y%m%d %H:%M:%S.%N';date +'%Y%m%d %H:%M:%S.%N';date +'%Y%m%d %H:%M:%S.%N';date +'%Y%m%d %H:%M:%S.%N'
20060928 17:44:20.906805000
20060928 17:44:20.909188000
20060928 17:44:20.911535000
20060928 17:44:20.913886000


date 参考
$ date --help
Usage: date [OPTION]... [+FORMAT]
or: date [-u|--utc|--universal] [MMDDhhmm[[CC]YY][.ss]]
Display the current time in the given FORMAT, or set the system date.

-d, --date=STRING display time described by STRING, not `now'
# such as 'n days ago |1 month ago|n years ago'
-f, --file=DATEFILE like --date once for each line of DATEFILE
-ITIMESPEC, --iso-8601[=TIMESPEC] output date/time in ISO 8601 format.
TIMESPEC=`date' for date only,
`hours', `minutes', or `seconds' for date and
time to the indicated precision.
--iso-8601 without TIMESPEC defaults to `date'.
-r, --reference=FILE display the last modification time of FILE
-R, --rfc-2822 output RFC-2822 compliant date string
-s, --set=STRING set time described by STRING
-u, --utc, --universal print or set Coordinated Universal Time
--help display this help and exit
--version output version information and exit

FORMAT controls the output. The only valid option for the second form
specifies Coordinated Universal Time. Interpreted sequences are:

%% 输出%符号 a literal %
%a 当前域的星期缩写 locale's abbreviated weekday name (Sun..Sat)
%A 当前域的星期全写 locale's full weekday name, variable length (Sunday..Saturday)
%b 当前域的月份缩写 locale's abbreviated month name (Jan..Dec)
%B 当前域的月份全称 locale's full month name, variable length (January..December)
%c 当前域的默认时间格式 locale's date and time (Sat Nov 04 12:02:33 EST 1989)
%C n百年 century (year divided by 100 and truncated to an integer) [00-99]
%d 两位的天 day of month (01..31)
%D 短时间格式 date (mm/dd/yy)
%e 短格式天 day of month, blank padded ( 1..31)
%F 文件时间格式 same as %Y-%m-%d
%g the 2-digit year corresponding to the %V week number
%G the 4-digit year corresponding to the %V week number
%h same as %b
%H 24小时制的小时 hour (00..23)
%I 12小时制的小时 hour (01..12)
%j 一年中的第几天 day of year (001..366)
%k 短格式24小时制的小时 hour ( 0..23)
%l 短格式12小时制的小时 hour ( 1..12)
%m 双位月份 month (01..12)
%M 双位分钟 minute (00..59)
%n 换行 a newline
%N 十亿分之一秒 nanoseconds (000000000..999999999)
%p 大写的当前域的上下午指示 locale's upper case AM or PM indicator (blank in many locales)
%P 小写的当前域的上下午指示 locale's lower case am or pm indicator (blank in many locales)
%r 12小时制的时间表示(时:分:秒,双位) time, 12-hour (hh:mm:ss [AP]M)
%R 24小时制的时间表示 (时:分,双位)time, 24-hour (hh:mm)
%s 自基础时间 1970-01-01 00:00:00 到当前时刻的秒数 seconds since `00:00:00 1970-01-01 UTC' (a GNU extension)
%S 双位秒 second (00..60); the 60 is necessary to accommodate a leap second
%t 横向制表位(tab) a horizontal tab
%T 24小时制时间表示 time, 24-hour (hh:mm:ss)
%u 数字表示的星期(从星期一开始 1-7)day of week (1..7); 1 represents Monday
%U 一年中的第几周星期天为开始 week number of year with Sunday as first day of week (00..53)
%V 一年中的第几周星期一为开始 week number of year with Monday as first day of week (01..53)
%w 一周中的第几天 星期天为开始 0-6 day of week (0..6); 0 represents Sunday
%W 一年中的第几周星期一为开始 week number of year with Monday as first day of week (00..53)
%x 本地日期格式 locale's date representation (mm/dd/yy)
%X 本地时间格式 locale's time representation (%H:%M:%S)
%y 两位的年 last two digits of year (00..99)
%Y 年 year (1970...)
%z RFC-2822 标准时间格式表示的域 RFC-2822 style numeric timezone (-0500) (a nonstandard extension)
%Z 时间域 time zone (e.g., EDT), or nothing if no time zone is determinable

By default, date pads numeric fields with zeroes. GNU date recognizes
the following modifiers between `%' and a numeric directive.

`-' (hyphen) do not pad the field
`_' (underscore) pad the field with spaces

Report bugs to .

星期三, 九月 27, 2006

检测是否包含了指定的扩展包 learn wordpress (7)

检测是否包含了指定的扩展包
if ( !extension_loaded('mysql') )
{
header( 'Content-Type: text/html; charset=utf-8' );
die( '您的 PHP 好像并没有安装 MySQL 扩展,而 WordPress 需要它。' );
}
-- wp-settings.php
检测是否加载了某些需要的模块
参考 [http://cn.php.net/manual/zh/function.extension-loaded.php]


if (!extension_loaded('gd')) { # 检测是否加载了 gd 包
if (!
dl('gd.so')) { # 尝试通过默认路径加载 gd.so 包
exit; # 如果加载失败
}
}
$ php -m # 查看当前安装的扩展包
[PHP Modules]
xml
tokenizer
standard
sockets
session
posix
pcre
overload
mysql
mbstring
ctype
如果使用了一些不常用的扩展 最好在开始使用之前对当前的环境进行检测
防止,在使用时出现未定义的异常
不过尝试自动加载之前最好通知用户 以便出现一些兼容问题(虽然这种机率很小,:-))。

检测PHP版本 learn wordpress (6)

检测PHP版本
if ( !(phpversion() >= '4.1') )
{
header( 'Content-Type: text/html; charset=utf-8' );
die( '您的服务器正在运行 PHP 版本 ' . phpversion() . ',但是 WordPress 需要最小 4.1 版本。' );
}
-- wp-settings.php
检测当前使用的PHP的版本号,以防止因版本过低而产生的异常

这里可以看到phpversion的参考
[http://cn.php.net/manual/zh/function.version-compare.php]

// prints -1
echo version_compare("4.0.4", "4.0.6");

// these all print 1
echo version_compare("4.0.4", "4.0.6", "<");
echo
version_compare("4.0.6", "4.0.6", "eq");
?>

上面的例子基本上一看就懂了,使用version_compare 可以对 "." 间隔的数据进行比较
使用 phpversion 可以获取当前使用的 php 的版本号
建议在自己写的 php 页上使用 "." 分割的 version 并在被包含时使用 version_compare 进行版本比较,以便可以检测到一些不容易发现的遗留问题

在 修改 时,加上简要的更新内容说明也是一个很明智的方法。
:)

摘录一段 php.net 上的代码 ,绿色的是我加的一点注释,仅供参考 ;)

mina86 at tlen dot pl
01-Jul-2004 10:40
Here's a wrapper which is more tolerant as far as order of arguments is considered:

/**

* php 版本比较
* ver_cmp($version1,$compare,$version2);
* ver_cmp($compare,$version2);
* ver_cmp($version2);
*/
function ver_cmp($arg1, $arg2 = null, $arg3 = null) {
# 用于缓存 如果获取了一次 phpversion 就不必要再一次获取它了
static
$phpversion = null;
if (
$phpversion===null) $phpversion = phpversion(); #记录phpversion

# 根据实际调用的参数个数来判断执行什么操作
switch (
func_num_args()) {

# 比较输入的version2和当前的phpversion
case
1: return version_compare($phpversion, $arg1);

# 根据输入的操作方式对version2和phpversion进行比较
case
2:
# 自动适应操作符位置 操作符 $
compare 和 $version2 可以互换位置
# 如果没有找到操作符 则对 $version1 和 $version2 进行默认比较操作
if (preg_match('/^[lg][te]|[<>]=?|[!=]?=|eq|ne|<>$/i', $arg1))
return
version_compare($phpversion, $arg2, $arg1);
elseif (
preg_match('/^[lg][te]|[<>]=?|[!=]?=|eq|ne|<>$/i', $arg2))
return
version_compare($phpversion, $arg1, $arg2);
return
version_compare($arg1, $arg2);
default:
$ver1 = $arg1;
# 这句貌似没有什么用
# 自动适应操作符位置 允许操作符在第二个或第三个参数
if (
preg_match('/^[lg][te]|[<>]=?|[!=]?=|eq|ne|<>$/i', $arg2))
return
version_compare($arg1, $arg3, $arg2);
return
version_compare($arg1, $arg2, $arg3);
}
}


It also uses phpversion() as a default version if only one string is present. It can make your code look nicer 'cuz you can now write:
if (ver_cmp($version1, '>=', $version2)) something;
and to check a version string against the PHP's version you might use:
if (ver_cmp('>=', $version)) something;
instead of using phpversion().

对外界环境进行兼容设置 learn wordpress (5)

对外界环境进行兼容设置

// Fix for IIS, which doesn't set REQUEST_URI
# 如果没有设定 REQUEST_URI 则根据其他参数进行设定 REQUEST_URI="SCRIPT_NAME?QUERY_STRING";
if ( empty( $_SERVER['REQUEST_URI'] ) ) {
$_SERVER['REQUEST_URI'] = $_SERVER['SCRIPT_NAME']; // Does this work under CGI?

// Append the query string if it exists and isn't null
if (isset($_SERVER['QUERY_STRING']) && !empty($_SERVER['QUERY_STRING'])) {
$_SERVER['REQUEST_URI'] .= '?' . $_SERVER['QUERY_STRING'];
}
}

// Fix for PHP as CGI hosts that set SCRIPT_FILENAME to something ending in php.cgi for all requests
# 如果是通过CGI来处理的则将SCRIPT_FILENAME重定义为最终的处理文件 SCRIPT_FILENAME="PATH_TRANSLATED";

if ( isset($_SERVER['SCRIPT_FILENAME']) && ( strpos($_SERVER['SCRIPT_FILENAME'], 'php.cgi') == strlen($_SERVER['SCRIPT_FILENAME']) - 7 ) )
$_SERVER['SCRIPT_FILENAME'] = $_SERVER['PATH_TRANSLATED'];

// Fix for Dreamhost and other PHP as CGI hosts
if ( strstr( $_SERVER['SCRIPT_NAME'], 'php.cgi' ) )
unset($_SERVER['PATH_INFO']);

// Fix empty PHP_SELF
# 构建PHP_SELF
$PHP_SELF = $_SERVER['PHP_SELF'];
if ( empty($PHP_SELF) )
$_SERVER['PHP_SELF'] = $PHP_SELF = preg_replace("/(\?.*)?$/",'',$_SERVER["REQUEST_URI"]);

-- wp-settings.php
其实所谓兼容就是不同的外部环境给定的变量有些差异。
这些我没有用过姑且留之。

think:如何才能进行分布式计算

遇到些问题需要去解决 ,不了解这方面的情况,谁能告诉我从何下手。
一个web服务,
需要对其进行分布式优化
需求如下:
前端web服务分布进行负载均衡,
中间的数据层分布进行大数据存储和备份,
底层计算分布进行分布式计算。
非即时处理 可以使用异步的方式进行计算


上图是一份数据流的节点图
设想是
1、外部请求通过 Web Main 使用一定的规则进行分流 将请求定位到 web 1 ... web n 上;
2、web 1-n 向 Data Main 索要数据,并最终从 Data 1-n 上获取需要的数据;
3、 Worker Main 为 worker 1-n 分配任务,worker 1-n 自动执行任务,并将数据更新到需要的 data 节点上。

上图:一次处理的数据流
1、处理请求通过 web 1-n 进入系统;
2、web 1-n 将任务提交给 Data Main;
3、worker main 检测到未处理任务,并进行分割提交给 worker 1-n ;
4、worker 1-n 将根据任务进行处理(应该加一个 worker 会将将处理后的结果合并);
5、worker 1-n 通过 Data Main 对数据进行更新;
6、web 1-n 定期通知 web main 检测任务完成状态,直到任务过期或完成。

星期二, 九月 26, 2006

对指定的参数赋与初值 learn wordpress (4)

对指定的参数付与初值
if ( ! isset($blog_id) )
$blog_id = 1;
-- wp-settings.php
处理过程中的常用手段,预留一些设置变量,可以在类似config的文件中进行定义,来改变处理的方式。

留下一些可以定义的值给前边的任务。就像方法的默认值一样,如果你设置了其他的值,我就按照你指定的方式来处理,如果没有设置,我就按预定的默认方式处理。
可以用在include之前对包含进来的内容进行定制。

确保即将使用的变量被重置 learn wordpress (three)

确保即将使用的变量被重置
unset( $wp_filter, $cache_userdata, $cache_lastcommentmodified, $cache_lastpostdate, $cache_settings, $category_cache, $cache_categories );
-- wp-settings.php
# 清除需要用到的变量,确保不会因为环境(上下文)对后面将要执行的代码产生影响.

如果页面可能被重复加载,或者不确定这个页面会在什么时候被加载
那么我们应该尽可能的为下面的工作清出一块干净的空间,否则,谁也不确定你要的变量会在什么时候携带了一个你不想要的值。(当然,出现这个问题的一部分原因是因为我们使用的变量可能会重名,被重复使用)

清除自动创建的变量 learn wordpress (two)

清除自动创建的变量
// Turn register globals off
function unregister_GLOBALS() {
if ( !ini_get('register_globals') ) # 如果定义的全局变量
return;

if ( isset($_REQUEST['GLOBALS']) )
die('GLOBALS overwrite attempt detected');

// Variables that shouldn't be unset
$noUnset = array('GLOBALS', '_GET', '_POST', '_COOKIE', '_REQUEST', '_SERVER', '_ENV', '_FILES', 'table_prefix');

$input = array_merge($_GET, $_POST, $_COOKIE, $_SERVER, $_ENV, $_FILES, isset($_SESSION) && is_array($_SESSION) ? $_SESSION : array());
foreach ( $input as $k => $v )
if ( !in_array($k, $noUnset) && isset($GLOBALS[$k]) )
unset($GLOBALS[$k]); # 从GLOBALS中清除Request中设定的变量
}
-- wp-settings.php

# 如果指定了自动注册全局变量(register_globals)则清除所有从请求($input)过来的非保留($noUnset)的全局变量(in $GLOBALS).
Global 变量:$GLOBALS
注: $GLOBALS 在 PHP 3.0.0 及以后版本中适用。
由所有已定义全局变量组成的数组。变量名就是该数组的索引。
这是一个“superglobal”,或者可以描述为自动全局变量。这只不过意味这它在所有的脚本中都有效。在函数或方法中不需要使用 global $GLOBALS; 来访问它。
-- 来自《php手册》 http://cn.php.net/manual/zh/reserved.variables.php

防止重复加载同一部分代码 learn wordpress (one)

将writely上的学习笔记copy到这里
note in writely http://www.writely.com/View.aspx?docid=dg4t629m_37gnpq8t
然后使用这里的tag功能进行索引
ok! 开始我的php代码收集之路。

技巧 一 防止重复加载同一部分代码

if (! isset($wp_did_header)):
...
$wp_did_header = true;
...
endif;
-- wp-blog-header.php
## 类似的
if(defined('CBC.TOP_INC_SIGN')) return 1;
if(!defined('COMMON_INC_SIGN')){
die (__FILE__." LINE ".__LINE__.":require common.inc!\n");
return -1;
}
define("CBC.OPERATOR_INC_SIGN",1);
define("CBC.OPERATOR_VERSION","0.0.1");
-- 我的程序的一段代码

考虑页面可能被多次引用的情况
使用标记来确保唯一引用
判断方式
isset # 判断一个变量是否被定义
defined # 判断一个常量标示符是否被定义
function_exists # 判断一个函数是否被定义
class_exists # 判断一个类是否被定义
menthod_exists # 判读一个对象是否定义了指定的方法
property_ exists # 判断一个对象是否定义了指定的属性

只是不知道这个变量和常量哪个更好些