星期二, 十月 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