验证我的blog
--huolatdeclare:11:6e1df2d7-5897-4767-918b-c29eb04b9fc6--
message from huolat.com
692b1532 c5ca62c6
message as beta.feedsky.com
风吹花飞扬,雨落任轻狂 coding all in here!
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.)
构思: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 # 记录错误日志
管理shell中的子任务
tags:shell,kill,awk
---------------------------------------------------------------
PS:好久之前的代码了 不过正好用到 就找来发到这里了
---------------------------------------------------------------
Tag:php,rpc,socket,post
因为手里需要所以简单的写了点点,但没有对后期数据进行处理,也没有加异常处理';';
print_r($client->headers);
print_r($client->contents);
echo '
'.htmlspecialchars($request)."\n\n\n";
'.htmlspecialchars($contents)."\n\n\n";
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'`
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 -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&Number=624453&page=0&view=collapsed&sb=5&o=31&fpart=
-- http://www.linuxforum.net/forum/files/345507-colors.txt如果需要在shell脚本里打印不同颜色的字符,可以使用ESC序列。#! /bin/bash
echo -e '\e[44;33;1m colors \e[0m'
echo -e表示启用\字符转义;\e即打印ESC控制符;[固定格式;44设置
背景为蓝色;33设置前景为白色;1设置加亮显示;m固定格式;colors
要打印的字符串;\e[0m设回开始的shell环境颜色设置。
连起来就是打印背景蓝色、前景高亮白色的字符串colors。
# 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
Code-flash播放器
转载自穷困潦倒的阿威 http://my.opera.com/shui1220/blog/show.dml/316714
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
标签: podcast, podcasting
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
使用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 源码解读(一)
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函数实现这个正向及反向的转化。
如:
可以查看这个页面:htmlentities.html, 不管选择什么网页编码,网页都能正常显示。
如果需要对整个页面转化,则只需要在php文件的头部加上这三行代码:
在asp中我们可以用下面这个函数来实现这个转化:
标签: htmlentity, iconv, php
摘录:http响应码 & http 信息头
tags:http,http code,http head
一、HTTP响应码
响应码由三位十进制数字组成,它们出现在由HTTP服务器发送的响应的第一行。
响应码分五种类型,由它们的第一位数字表示:
1xx:信息,请求收到,继续处理
2xx:成功,行为被成功地接受、理解和采纳
3xx:重定向,为了完成请求,必须进一步执行的动作
4xx:客户端错误,请求包含语法错误或者请求无法实现
5xx:服务器错误,服务器不能实现一种明显无效的请求
下表显示每个响应码及其含义:
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 (
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:
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)"
定义常量的方式
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中对环境进行了一些设置 可以参看前面的几篇文章
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:本来加了颜色和样式的 但是发布时竟然出现
郁闷啊 我把样式清除了才可以发布 !!
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
在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
检测是否包含了指定的扩展包
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