Google

星期三, 五月 28, 2008

最感人的诗篇

网易广东湛江网友 ip:125.90.*.*: 2008-05-28 14:46:17 发表
背儿背上走,
儿已破头亡。
廿里踉跄步,
接儿返故乡。
梦里青山在,
醉中绿水长。
那堪人不在,
未语泪双行。
葬儿黄土里,
埋儿山坡上,
人死万事空,
白发痛断肠。
悠悠小河水。
泛起明月光,
时有秋风语,
萤火自来往。
http://comment.news.163.com/reply/post.jsp?type=null&board=news_guonei7_bbs&threadid=4D11N7U30001124J&showdistrict=&pagex=3

标签:

星期二, 五月 27, 2008

无题

骄傲没有成本,代价却不可估量.

标签:

星期一, 五月 26, 2008

无题

牛B不重要,重要的是适当的时候要吹。

标签:

星期日, 五月 25, 2008

Google Sites开始向所有人免费开放 可自由建个人主页

Google Site是一个简易的建站工具,可以使那些不懂

网页设计或者不懂网页代码的用户去组建自己的网站.

Google Site可以让商务人士创建自己的“局域网”,管理团队项目等.另外,团队中的成员也可以建立自己的个人主页,设置自己的工作计划、兴趣爱好等栏目.对于学校用户,Google Site可以作为虚拟教室,供学生展示自己的家庭作业或为学生提供学习、生活等的资料.今天它已经向所有人免费开放,现在你就可以在Google上建立自己的建一个自己的主页.

访问:Google Sites

访问:范例

http://news.csdn.net/n/20080523/116213.html

标签:

星期二, 五月 20, 2008

Linux美化也疯狂 10个最漂亮桌面展示(图)

漂亮的桌面可绝对不仅仅是Windows和Mac的专利,只要您能细心雕琢,让Linux的KDE和GNOME原本傻傻的界面脱胎换骨是没有任何问题的.

以下就是Digg上被推荐的10个最漂亮的Linux桌面,有的是模拟其它操作系统的作品,有的则完全原创,颇具美感.

你最喜欢哪一个呢?


2)

3)

4)

5)

6)

7)

8)

9)

10)


http://news.csdn.net/n/20080519/116063.html

标签: , ,

:)

10:30了,吃药,睡觉,梦周公。

标签:

星期四, 五月 15, 2008

方法

目标刻在石头上,方法写在沙滩上。
要不断的去尝试。这样就会有更大更多的发现。

http://www.yqmisbbs.com/redirect.php?tid=545&goto=lastpost#lastpost

星期三, 五月 14, 2008

使用CodeIgniter框架快速开发PHP应用:分析网站结构(3)

让我们看看内部细节。

再次强调我们并不处理静态网页和对应的URL,我们将会给你看CI如何分析URL请求和如何响应它。 首先,考虑一个正常的英特网请求。用户建立一个连接到你的网站: www.example.com,

然后经过端口发出一个如下的HTTP request:

GET /folder/file.html HTTP/1.0

GET是请求的类型, HTTP/1.0 指定 HTTP 协议的版本, 中间是相对路径和文件名。但是在你的网站上,找不到简单的静态 HTML 文件。取代它的,所有的收入请求被 index.php 文件拦截并进行处理。

如果使用者正在以正确的URL在你的网站上位置上请求页面-一般是通过点击你网页上的超级链接-request一般看起来象这样:

GET /index.php/tests/showall HTTP/1.0

如果使用者不知道精确的URL, CI 会设定一个默认页面(我们一会儿就告诉你怎么做.)

CI的处理步骤是:

+——————————–+
| internet request comes in: |
| "GET http://127.0.0.1" |
+——————————–+
|
v
+——————————–+
| Router:decides which controller|
| should handle this request |
+——————————–+
|
v
+——————————–+ +——————-+
| Controller: analyzes the | —–> | |
| request and responds:maybe | |Model:provides data|
| by getting data from the model | <—– | |
+——————————–+ +——————-+
|
v
+——————————–+
| View:formats the response |
| (in this case as an HTML page) |
+——————————–+
|
v
+——————————–+
| Page is served up to enquirer |
+——————————–+


一个从英特网到你的网站根目录的请求被 index.php 文件拦截,作用就象一个“站由器”。 换句话说, 它调用一个 ‘控制器’, 然后返回一个’视图’.

“路由器”怎么知道调用哪一个控制器? 就象我们已经见到的,有时候request本身包含的信息会告诉它调用哪个控制器。 举例来说,如果请求说:

GET http://127.0.0.1/index.php/welcome/index

并且如果你有一个控制器叫做welcome,这就是被调用的控制器。

welcome控制器

所以, 让我们看welcome控制器。 它被存放在如下路径:
system/application/controllers/welcome.php
它的内容是这样的:

class Welcome extends Controller {

function Welcome() {
parent::Controller();
}

function index() {
$this->load->view(‘welcome_message’);
}

}
?>

文件的第二行开始是一个类。 每个控制器从一个Controller类继承。 在类中包含二个函数或称为方法-welcome() 和incex().
注:CI 要求控制器名字从一个大写字母(class Welcome) 开始, 但文件名是小写字母:
/system/application/controllers/welcome.php

function Welcome() {
parent::Controller();
}

这三行组成构造函数。 注意到 CI 使用PHP 4 构造函数命名规则,兼容于 PHP 5.-CI在PHP 4 和PHP 5 两个版本中都能工作得很好。构造函数在类实例化时被调用,你可以做一些初始化的工作,比如调用函数库和模型层,或者对类的成员变量进行寝化。
这个例子中构造函数中仅一行,调用父类的构造函数。parent::Controller() 。这只是显式地使用父类功能的一种方法。如果你想要详细地了解CI框架中controller类,你可以研读文件 /system/libraries/controller.php 。
(可以放心的是你可以随时查看CI的源代码,它们已经保存在你机器上的某个目录内。)

http://www.anson-ho.com/index.php/2008/04/27/codeigniter-rapid-development-framework-for-the-use-of-php-applications-analysis-of-site-4/

标签:

使用CodeIgniter框架快速开发PHP应用:分析网站结构(2)

另一方面,你必须认识到,MVC只是用来帮助你的一种设计方式,而不是用来约束你的。MVC可以有不同的实现方式。CI 论坛包含许多如何 ‘正确合理’地实现 MVC 的方式。 ( 我应该在控制器部分实现数据库查询功能吗?我能直接从视图发送数据到模型层吗?或者我必须通过控制器来访问?)

与其寻找理论上的正确方式,不如遵循二项有用的原则。 这些在 CI 用户手册上有相关描述:

。松藕合: 类之间尽可能不要彼此依赖。

。组件智能化: 智能化是组件独立实现特定目标的能力。在 CI框架中,每个类和它内部的函数高度地自治。

这些是Rick开发CI要实现的目标, 他们也会成为你开发你自己的网站时的目标。实现这些目标之后,你代码中使用这些类时就不需要担心有什么副作用了。

CI做到了这一点,我的经验是那助手类和类库中的其它类使用用起来十分容易,工作起来效果也不错。

因此, 如果你的控制器直接操作数据库, 或你的在模型层调用视图, CI 代码将会以适当的方式工作-通常没有技术上的问题-但是从MVC理论来看这样似乎是 ‘不正确的’. 不要烦恼,如果非要这样做,做吧!

CI 的网站结构: 控制器和视图

你的整个 CI 网站是动态的。 就是, 可能找不到制作 ‘静态’ 网页的简单的 HTML 代码。 (如果需要你可以添加,但是他们将会在 CI 结构之外.) 那么, 你的网站文件到底在哪里?

当我们安装 CI 的时候,我们注意到应用目录包括名为models、views和controllers的子目录。 每个 CI 框架应用都包含这三大类型。

标签: , ,

使用CodeIgniter框架快速开发PHP应用:分析网站结构(1)

转贴自CI中国

分析网站结构

既然我们已经安装 CI ,我们开始了解它如何工作。
读者已经知道 CI 实现了MVC式样。 通过对目录和文件的内容进行分类, 而不是让代码大块大块地纠集在一起。
这一章,我们将会对 MVC 理论做个简短的介绍, 然后再介绍 CI 的MVC实现方式。特别地,要了解那些目录和文件如何互相交换信息?网站结构是怎样的?以及CI是如何自如地动作于其中的?

这一章将会介绍:

。MVC 如何架构一个动态网站
。CI如何接收和分析request以及如何调配指定的代码来reponse
。这些指定的代码如何编制
CodeIgniter 语法
。CI提供的各种类和函数,你自己编写的类和函数
。如控向controllers传递URL参数
。如何编写运行良好的视图并把动态内容传递给它们。
。如何返回信息给上网者
。文件和类如何传递信息和互相调用
。助手类文件有什么用?
。有助于网站设计的一些特别提示

MVC-到底有什么用?

MVC,在本文领域内,指的是一个动态网站的组织方法。 设计模式是1979年由挪威人,Trygve Reenskaug首次提出来的,这里是一些概要:
。模型是包含数据的对象,他们与数据库交互,对这些数据进行存取,使其在不同的阶段包含不同的值,不同的值代表了不同的状态,具有特定的含意。
。视图显示模型的状态,他们负责向使用者显示数据。(虽然他们通常是 HMTL 视图, 但是,他们可能是任何形式的接口。 比如PDA屏幕或WAP手机屏幕)
。控制器用来改变模型的状态,他们操作模型,提供动态的数据给视图。
CI框架包含模型、视图和控制器的子目录。 他们里面的每个文件都有.php文件后缀, 包含有特定命名约定的类。
CI 帮助你遵循MVC的约定, 使你更有效地组织代码。 CI允许你有最大的灵活性,你可以获得 MVC 结构的所有好处。
当你编程的時候,试着始终用 MVC 来思考问题。尽可能确保你的 ‘视图’ 聚焦于显示, ’控制器’纯粹地用来控制数据流。 把应用逻辑保留在数据模型和数据库中。

这样,如果你决定开发新的视图,你不必在任何一个控制器或模型中修改代码。 如果你需要更新 ‘商业规则’ ,你只需要在模型中修改代码。

标签: , ,

;)

C/C++还是最棒的

Object Pascal也不错,至少目前Free Pascal的发展比Delphi的命运好像好一点

Python易学易用,语法太灵活了,缩进还是没有;号爽

UML 2.0还没有达到易用,易懂的程度,也许以后描述问题不用它了吧

PHP做网站很不错,CodeIgniter框架也不错,就是对XHTML的支持,特别是UTF-8的支持不是很理想。

标签: , , , , , , ,

为PE文件增加新节,并在新节中增入SHELL CODE加载指定DLL

附件下载:add_section.rar

代码见:http://www.pediy.com/bbshtml/bbs8/pediy8-732.htm

标签: , , ,

Reverse engineer MS Access/Jet databases

# jet2sql.py - M.Keranen  [07/12/2000]
# --------------------------------------------------------------------
# Creates ANSI SQL DDL from a MS Jet database file, useful for reverse
# engineering database designs in E/R tools.
#
# Requires DAO 3.6 library.
# --------------------------------------------------------------------
# Usage: python jet2sql.py infile.MDB outfile.SQL

import sys, string, pythoncom, win32com.client

const = win32com.client.constants
daoEngine = win32com.client.Dispatch('DAO.DBEngine.36')

class jetReverse:
def __init__ (self, infile):

self.jetfilename=infile
self.dtbs = daoEngine.OpenDatabase(infile)

return

def terminate(self):
return

def writeTable(self, currTabl):
self.writeLine('\ncreate table ' + chr(34) + currTabl.Name + chr(34),"",1)
self.writeLine('(',"",1)

# Write Columns
cn=0
for col in currTabl.Fields:
cn = cn +1
self.writeColumn(col.Name, col.Type, col.Size, col.Required, col.Attributes, col.DefaultValue, col.ValidationRule, currTabl.Fields.Count-cn)

# Validation Rule
tablRule = currTabl.ValidationRule
if tablRule <> "":
tablRule = " check(" + tablRule + ") "
self.writeLine("",",",1) # add a comma and CR previous line
self.writeLine(tablRule,"",0)

# Primary Key
pk=self.getPrimaryKey(currTabl)
if pk <> "":
self.writeLine("",",",1) # add a comma and CR previous line
self.writeLine(pk,"",0)

# End of table
self.writeLine("","",1) # terminate previous line
self.writeLine(');',"",1)

# Write table comment
try: sql = currTabl.Properties("Description").Value
except pythoncom.com_error: sql=""
if sql <> "":
sql = "comment on table " + chr(34) + currTabl.Name + chr(34) + " is " + chr(34) + sql + chr(34) +";"
self.writeLine(sql,"",1)

# Write column comments
for col in currTabl.Fields:
try: sql = col.Properties("Description").Value
except pythoncom.com_error: sql=""
if sql <> "":
sql = "comment on column " + chr(34) + currTabl.Name + chr(34) + "." + chr(34) + col.Name + chr(34) + " is " + chr(34) + sql + chr(34) + ";"
self.writeLine(sql,"",1)

# Write Indexes
self.writeIndexes(currTabl)

return

def writeColumn(self, colName, colType, length, requird, attributes, default, check, colRix):
# colRix: 0 based index of column from right side. 0 indicates rightmost column

if colType == const.dbByte: dataType = "Byte"
elif colType == const.dbInteger: dataType = "Integer"
elif colType == const.dbSingle: dataType = "Single"
elif colType == const.dbDouble: dataType = "Double"
elif colType == const.dbDate: dataType = "DateTime"
elif colType == const.dbLongBinary: dataType = "OLE"
elif colType == const.dbMemo: dataType = "Memo"
elif colType == const.dbCurrency: dataType = "Currency"
elif colType == const.dbLong:
if (attributes & const.dbAutoIncrField): dataType = "Counter"
else: dataType = "LongInteger"
elif colType == const.dbText:
if length == 0: dataType = "Text"
else: dataType = "char("+str(length)+")"
elif colType == const.dbBoolean:
dataType = "Bit"
if default == "Yes": default = "1"
else: default = "0"
else:
if length == 0: dataType = "Text"
else: dataType = "Text("+str(length)+")"

if default <> "":
defaultStr = "default " + default + " "
else: defaultStr = ""

if check <> "":
checkStr = "check(" + check + ") "
else:
checkStr = ""

if requird or (attributes & const.dbAutoIncrField):
mandatory = "not null "
else:
mandatory = ""

sql = " " + chr(34) + colName + chr(34) + " " + dataType + " " + defaultStr + checkStr + mandatory
if colRix > 0:
self.writeLine(sql,",",1)
else:
self.writeLine(sql,"",0)

return

def getPrimaryKey(self, currTabl):

# Get primary key fields
sql = ""
for idx in currTabl.Indexes:
if idx.Primary:
idxName = idx.Name
sql = " primary key "
cn=0
for col in idx.Fields:
cn=cn+1
sql = sql + chr(34) + col.Name + chr(34)
if idx.Fields.Count > cn : sql = sql + ","
return sql

def writeIndexes(self, currTabl):

# Write index definition
nIdx = -1
for idx in currTabl.Indexes:
nIdx = nIdx + 1
idxName = idx.Name
tablName = currTabl.Name
if idx.Primary:
idxName = tablName + "_PK"
elif idxName[:9] == "REFERENCE":
idxName = tablName + "_FK" + idxName[10:]
else:
idxName = tablName + "_IX" + str(nIdx)

sql = "create "
if idx.Unique: sql = sql + "unique "
if idx.Clustered: sql = sql + "clustered "
sql = sql + "index " + chr(34) + idxName + chr(34)
sql = sql + " on " + chr(34) + tablName + chr(34) + " ("

# Write Index Columns
cn=0
for col in idx.Fields:
cn = cn + 1
sql = sql + chr(34) + col.Name + chr(34)
if col.Attributes & const.dbDescending:
sql = sql + " desc"
else:
sql = sql + " asc"
if idx.Fields.Count > cn: sql = sql + ","

sql=sql + " );"

self.writeLine(sql,"",1)
return

def writeForeignKey(self, currRefr):

# Export foreign key
sql = "\nalter table " + chr(34) + currRefr.ForeignTable + chr(34)
self.writeLine(sql,"",1)

sql = " add foreign key ("
cn = 0
for col in currRefr.Fields:
cn = cn + 1
sql = sql + chr(34) + col.ForeignName + chr(34)
if currRefr.Fields.Count > cn: sql = sql + ","

sql = sql + ")"
self.writeLine(sql,"",1)

sql = " references " + chr(34) + currRefr.Table + chr(34) + " ("
cn = 0
for col in currRefr.Fields:
cn = cn + 1
sql = sql + chr(34) + col.Name + chr(34)
if currRefr.Fields.Count > cn: sql = sql + ","

sql = sql + ")"
if (currRefr.Attributes & const.dbRelationUpdateCascade) <> 0:
sql = sql + " on update cascade"
if (currRefr.Attributes & const.dbRelationDeleteCascade) <> 0:
sql = sql + " on delete cascade"
sql=sql+";"
self.writeLine(sql,"",1)

return

def writeQuery(self, currQry):

sql = "\ncreate view " + chr(34) + currQry.Name + chr(34) + " as"
self.writeLine(sql,"",1)

# Write Query text
sql=string.replace(currQry.SQL,chr(13),"") # Get rid of extra linefeeds
self.writeLine(sql,"",1)

# Write Query comment
try: sql = currQry.Properties("Description").Value
except pythoncom.com_error: sql=""
if sql <> "":
sql = "comment on table " + chr(34) + currQry.Name + chr(34) + " is " + chr(34) + sql + chr(34)
self.writeLine(sql,"",1)

return

def writeLine(self,strLine, delimit, newline):
# Used for controlling where lines terminate with a comma or other continuation mark
sqlfile.write(strLine)
if delimit: sqlfile.write(delimit)
if newline: sqlfile.write('\n')
return


if __name__ == '__main__':
if len(sys.argv)<2:
print "Usage: jet2sql.py infile.mdb outfile.sql"
else:
jetEng = jetReverse(sys.argv[1])
outfile = sys.argv[2]

sqlfile = open(outfile,'w')

print "\nReverse engineering %s to %s" % (jetEng.jetfilename, outfile)

# Tables
sys.stdout.write("\n Tables")
for tabl in jetEng.dtbs.TableDefs:
sys.stdout.write(".")
if tabl.Name[:4] <> "MSys" and tabl.Name[:4] <> "~TMP":
jetEng.writeTable(tabl)

# Relations / FKs
sys.stdout.write("\n Relations")
for fk in jetEng.dtbs.Relations:
sys.stdout.write(".")
jetEng.writeForeignKey(fk)

# Queries
sys.stdout.write("\n Queries")
for qry in jetEng.dtbs.QueryDefs:
sys.stdout.write(".")
jetEng.writeQuery(qry)

print "\n Done\n"

# Done
sqlfile.close()
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52267
jetEng.terminate()

标签: ,

25个顶级PHP模板引擎

为了找到一个好的模板引擎,我在互联网上进行搜索,目前已经整理出了以下名单:

Smarty
Smarty的特点是将模板编译成PHP脚本,然后执行这些脚本。很快,非常灵活。

Heyes Template Class
一个非常容易使用,但功能强大并且快速的模板引擎,它帮助你把页面布局和设计从代码中分离。

FastTemplate
一个简单的变量插值模板类,它分析你的模板,把变量的值从HTML代码中分离处理。

ShellPage
一个简单易用的类,可以让你的整个网站布局基于模板文件,修改模板就能改变整个站点。

STP Simple Template Parser
一个简单、轻量级并且易于使用的模板分析类。它可以从多个模板中组装一个页面,把结果页面输出到浏览器或者文件系统。

OO Template Class
一个你可以用在自己程序中的面向兑现的模板类。

SimpleTemplate
一个可以创建和结构化网站的模板引擎。它可以解析和编译模板。

bTemplate
短小但是快速的模板类,允许你把PHP逻辑代码从HTML修饰代码中分离。

Savant
一个强大且轻量级的PEAR兼容模板系统。它是非编译型的,使用PHP语言本身做为它的模板语言。

ETS - easy template system
可以使用完全相同数据重组模板的模板系统。

EasyTemplatePHP
适用于你的站点的一个简单但是强大的模板系统。

vlibTemplate
一个快速、全能的模板系统,它包含一个缓存和调试类。

AvanTemplate
多字节安全的模板引擎,占用很少系统资源。它支持变量替换,内容块可以设置显示或隐藏。

Grafx Software’s Fast Template
一个修改版本的Fast Template系统,它包括缓存功能,调试控制台以及沉默去除为赋值块。

TemplatePower
一个快速、简单、功能强大的模板类。主要功能有嵌套的动态块支持,块/文件包含支持以及显示/隐藏未赋值的变量。

TagTemplate
这个库的功能被设计来使用模板文件,同时允许你从HTML文件检索信息。

htmltmpl: templating engine
一个适用于Python和PHP的模板引擎。它面向希望在项目中分离代码和设计的web应用开发人员。

PHP Class for Parsing Dreamweaver templates
一个分析Dreamweaver模板的简单类,被用于Gallery 2 和WordPress的自定义模块中。

MiniTemplator (Template Engine)
针对HTML文件的一个紧凑型模板引擎。对于模板变量和块定义它具有简单的语法。其中块可以嵌套。

Layout Solution
简化网站开发和维护。它拥有常用的变量和页面元素使你不需要重复做页面布局工作。

Cached Fast Template
它已经纳入 FastTemplate ,允许你缓存模板文件,甚至可以在分离的块内容上缓存不同的规格。

TinyButStrong
一个支持MySQL, Odbc, Sql-Server和ADODB的模板引擎。它包含7个方法和两个属性。

Brian Lozier’s php based template engine
只有2K大小,非常快并且是面向对象设计。

WACT
一个从设计中分离代码的模板引擎。

PHPTAL
一个PHP下面的XML/XHTML模板库。

http://www.yeeyan.com/articles/view/2930/1993

标签: , , , , , , ,

PHP 6 的新特性

PHP的下一个版本,V6,包含了很的新特性和语法改进,会使它在面向对象方面性更易用。其他重要的特性:比如在核心函数中对Unicode (统一编码)的支持,这意味着 PHP 6提供了更好的更可靠国际支持。

PHP已经很流行,被无数的站点使用,被大部分因特网接入商所支持,被Yahoo这样的大网络公司使用着。在即将来临的PHP版本中准备增加一些成功的新特性,使PHP在某些场合下更易用更安全。你准备好接受 PHP 6 了吗?如果你明天就升级了,你的程序会运行得很好吗?你该怎么办?这篇文章集合了PHP 6的改变,他们中的一些备份移植到版本的PHP v5.x,您目前的脚本可能需要进行一些调整。

如果你现在使用不是PHP,但是一直在考虑它,考虑一下它的新特性。这些特点,从Unicode的核心支持到XML支持,使它更容易为你写的功能填补PHP的应用。

PHP 6 新特性

PHP 6当前已经作为开发者快照使用,所以你可以下载和试用一下这篇文章列出很多特性,这些特性已经在当前的快照中实现了。见资源

改进 Unicode 支持

在PHP的核心函数中,有很多对Unicode 字符串的支持的改进,这些新特性将产生巨大的影响因为它允许PHP为国际字符提供更多的支持。所以如果一个开发者或者架构师使用不同的语言,例如Java程序语言,是因为它具有超过PHP的国际化支持的话,当支持改进时他会花一点时间来考虑一下PHP。

因为今天你已经可以下载到开发者版本的 PHP V6,你将看到一些功能函数已经支持Unicode字符串。有一个函数清单已经被测试和验证了完全可以处理Unicode,参见资源

命名空间

命名空间是一种避免因函数或者类之间的命名冲突而使你的函数和类以及方法无法读取,而不使用前缀命名惯例的一种方法。因此,通过使用命名空间,你可以命名别人可能已经使用的类名,而不用担心在运行时会出错。表一提供了一个在PHP中使用命名空间的示例。

您不用在源代码中做更新或更改,因为你写的任何PHP代码可以不包含命名空间而运行得很好。因为命名空间特性似乎会移植到PHP 5.3 X中,如果它可以使用,您可以在自己的程序中引用命名空间。

表一,命名空间示例

php
// I'm not sure why I would implement my own XMLWriter, but at least
// the name of this one won't collide with the one built in to PHP
namespace NathanAGood;
class XMLWriter
{
// Implementation here...
}

$writer = new NathanAGood::XMLWriter();

?>

Web 2.0 特性

依赖于你怎么使用PHP和你现在脚本的是什么样子的,现在的语言和语法差异,可能会或者不会最大程度的影响下面一些特性,这是指那些直接让你引用的Web 2.0功能到你的PHP应用程序。

SOAP

SOAP是一种网络服 务“说话”的协议,并且支持不少其他语言,例如Java和微软的.NET,虽然有其他的方法来驱动和使用网络服务,比如 表象化状态转变(Representational State Transfer )REST,SOAP仍然在使不同平台具有可操作性中是最常用的。此外,SOAP在PHP扩展和PEAR库中使用,SOAP在PHP中默认是不支持的,因 此你启用这个扩展或者叫你的ISP启用。此外,PEAR包允许你建立SOAP客户端和服务器,如SOAP包。

如果你改变了默认设置,SOAP将会在PHP 6中启用。这个扩展将提供你很容易的的实现SOAP客户端和SOAP服务,允许你编写的应用提供使用或者网络服务。

如果SOAP扩展是默认设置,那就意味着你不能在PHP中设置它们,如果您开发的PHP应用程序并且它们发布到一个ISP服务器上,您可能需要检查一下你的ISP,以验证SOAP并启用为他们升级。

XML

在PHP 5.1中XMLReader 和XMLWriter已经变成PHP核心的一部分,这使你工作起来更轻松如果在你的PHP程序中需要使用到XML的话。和SOAP扩展一样,如果你使用SOAP或者XML这是个好消息因为PHP 6比已经出炉的PHP4 更适合你。

被删除的东西

除了具有的一些新功能,PHP 6引擎将删除一些在前面版本中已经有的功能。大部分这些功能,如register_globalssafe_mode 在目前的PHP中被视为“破的”。因为他们可能会暴露一些安全风险。PHP在努力的清除中,在下一个版本中这些将从PHP中删除或者废弃。反对者认为大部分ISP或者企业会保留现在的脚本因为升级到PHP6会破坏现在的的脚本,但是支持者认为很高兴看到PHP团队修补了这些漏洞,并且提供了一个干净,安全的运行工具。

将从PHP删除的功能有:

magic_quotes register_globals register_long_arrays safe_mode

http://www.yeeyan.com/articles/view/muxi/7659

标签:

星期二, 五月 13, 2008

Lazarus Unicode说明

Lazarus對Unicode的支援還需要進一步開發,尤其是在Windows平台上。以下提供一些基本的資訊,讓想要加強Lazarus對Unicode支援的人參考,如果您發現這些資訊有誤、不足或過時了,請您不吝修正、補充或更新它,謝謝。

如果您已經初步了解Unicode的標準,且您已經在Delphi上面有使用過WideString這個型別來撰寫程式,會有助於您理解Lazarus對Unicode支援的加強工作。如果您使用過非Latin編碼的字元集來撰寫腳本語言,也會有些幫助的。

請注意: 實作的細節部分目前還在討論中,這部分的文件隨時都有可能更新。


http://wiki.freepascal.org/LCL_Unicode_Support/zh_TW

标签: , , , ,

How To Control Your Updates in ADO Through "Update Criteria"

SUMMARY

The ADO Client Cursor Engine allows you to control how it builds the action queries that update the database according to the changes you make to the recordset object. This article is designed to help you understand how to control how ADO performs these updates.

Back to the top

MORE INFORMATION

When you open a recordset against the Customers table in the Northwind database (NWind.MDB) and use a client side cursor, ADO retrieves enough information about the structure of the table in order to use an action query to update the table.

An action query is a query that modifies a database and does not return data. For example, "UPDATE Customers SET CompanyName = 'Acme' WHERE CustomerID = 17" is an action query.

ADO determines which field, or set of fields, is the primary key and uses that information to make sure it can find the correct row in the database to update. If you are going to perform updates with the client cursor engine, make sure you have a primary key defined in your table. If you don't, you may accidentally update more rows than you intended.

When you use a client side recordset, ADO exposes a property in the recordset's Properties collection called "Update Criteria." This property allows you to control the information in the WHERE clause in the action query that ADO builds to update the database. The default value for this property is 2 - adCriteriaUpdCols. By default, ADO will use the primary key and all fields being updated in the WHERE clause of the action query. For example:
   rsCustomers.CursorLocation = adUseClient
rsCustomers.Open "SELECT * FROM Customers", cnNWind, _
adOpenStatic, adLockOptimistic, adCmdText
rsCustomers.Fields("CompanyName").Value = "Acme"
rsCustomers.Update
will cause ADO to execute the following action query
   UPDATE Customers SET CompanyName = 'Acme'
WHERE CustomerID = 'ALFKI' AND CompanyName = 'Alfreds Futterkiste'
The WHERE clause contains information about the primary key and the original value for the field to update. This ensures that if another user has modified the value of the CompanyName field to a value other than the value that ADO originally retrieved, ADO will not update that row and will raise an error instead.

To change the value of this property, use code similar to the following
   rsCustomers.CursorLocation = adUseClient
rsCustomers.Properties("Update Criteria").Value = adCriteriaAllCols
rsCustomers.Open "SELECT * FROM Customers", cnNWind, _
adOpenStatic, adLockOptimistic, adCmdText
rsCustomers.Fields("CompanyName").Value = "Acme"
rsCustomers.Update
This code will cause ADO to include every field in the WHERE clause. You would use this value for the "Update Criteria" property if you want to make sure that the update made by the current user will only succeed if no changes have been made to any fields in that row in the table.

The available constants for this property are as follows:
   adCriteriaKey = 0

Uses only the primary key

adCriteriaAllCols = 1

Uses all columns in the recordset

adCriteriaUpdCols = 2 (Default)

Uses only the columns in the recordset that have been modified

adCriteriaTimeStamp = 3

Uses the timestamp column (if available) in the recordset
NOTE: Specifying adCriteriaTimeStamp may actually use adCriteriaAllCols method to execute the Update if there is not a valid TimeStamp field in the table. Also, the timestamp field does not need to be in the recordset itself.

http://support.microsoft.com/default.aspx?scid=kb;EN-GB;q190727&GSSNB=1

标签: , ,

不注册调用ActiveX Dll

那本书(Advanced Visual Basic)中让vb能够函数指针的方法不错,但是要添加类型库,还要自己创建轻量com对象显得颇为麻烦.我想,不如直接利用vb自己建对象算了.
代码如下:


'建一class,如下

'---------------------------------------------------------------------------------------
' Module : cFucPtr
' DateTime : 2006-2-7 17:36
' Author : Lingll
' Email : lingll_xl@163.com
' HomePage : http://lingll.yeah.net/
' Purpose :
'---------------------------------------------------------------------------------------

Option Explicit

'存储加载dll后获得的函数地址
Private m_NewFucPtr As Long

Public Function DllGetClassObject( _
ByRef rclsid As UUID, ByRef riid As UUID, ByRef ppv As IClassFactory) As Long

End Function

Public Sub SetFunctionPtr(newptr&)
m_NewFucPtr = newptr
End Sub


'再建一module

Option Explicit

Public Declare Function LoadLibrary Lib "kernel32.dll" Alias "LoadLibraryA" (ByVal lpLibFileName As String) As Long
Public Declare Function FreeLibrary Lib "kernel32.dll" (ByVal hLibModule As Long) As Long
Public Declare Function GetProcAddress Lib "kernel32.dll" (ByVal hModule As Long, ByVal lpProcName As String) As Long
Public Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (ByRef Destination As Any, ByRef Source As Any, ByVal Length As Long)

Public Type typAsm
code(1) As Long
End Type
Public asm As typAsm


'然后,初始化时,让asm为如下值,
asm.code(0) = &HFF515859
asm.code(1) = &H90003460
'这个是汇编代码,具体是
'pop ecx
'pop eax
'push ecx
'jmp DWORD PTR [eax + 52]
'这是抄回来的,具体原理我不太清楚,如下是原注释
'Here's the magic asm for doing the function pointer call.
'The stack comes in with the following:
'esp: return address
'esp + 4: this pointer for FunctionDelegator
'All that we need to do is remove the this pointer from the
'stack, replace it with the return address, then jmp to the
'correct function. In other words, we're just squeezing the
'this pointer completely out of the picture.
'The code is:
'pop ecx (stores return address)
'pop eax (gets the this pointer)
'push ecx (restores the return address)
'jmp DWORD PTR [eax + 4] (jump to address at this + 4, 3 byte instruction)
'The corresponding byte stream for this is: 59 58 51 FF 60 04
'We pad these six bytes with two int 3 commands (CC CC) to get eight
'bytes, which can be stored in a Currency constant.
'Note that the memory location of this constant is not executable, so
'it must be copied into a currency variable. The address of the variable
'is then used as the forwarding function.


'下面是调用代码:
Dim tadd As Long, vTab&
Dim tobj As cFucPtr

Dim tLib&

Dim tUn As olelib.IUnknown
Dim tDem As dllDemo.IDemo
Dim tFac As olelib.IClassFactory

Set tobj = New cFucPtr

'加载dll
tLib = LoadLibrary(App.Path & "\dllDemo.dll")
If tLib <> 0 Then
tadd = GetProcAddress(tLib, "DllGetClassObject")
End If

Dim asmadd&
If tadd <> 0 Then
'获取vtable地址
CopyMemory vTab, ByVal ObjPtr(tobj), 4
asmadd = VarPtr(asm)
'替换掉cFucPtr.DllGetClassObject地址
CopyMemory ByVal (vTab + (8 - 1) * 4), asmadd, 4

'设置函数地址
tobj.SetFunctionPtr tadd

tobj.DllGetClassObject ClsId_Obj, iid_iclassfactory, tFac


If Not tFac Is Nothing Then
tFac.CreateInstance Nothing, iid_iunknow, tUn
Set tFac = Nothing
Set tDem = tUn
Set tUn = Nothing
tDem.test
End If
End If
Set tDem = Nothing
If tLib <> 0 Then FreeLibrary tLib

'一定要在所有对象都释放掉了才能使用FreeLibrary,不然会出错


将上面的代码修改一下,就可以很方便的在vb中使用函数指针了,hoho,vb可以用函数指针咯,不写了.

http://www.xker.com/page/e2007/0116/9680.html

标签: , , , ,

四川挺住

纪念那些在地震中消失的人们。
支持所有正在为此忙碌的人们。

星期日, 五月 11, 2008

NVIDIA发炮:用CPU衡量PC性能的时代已经过去

性能的标准。而在其中GPU又将是核心的核心。GPU的时代已经到来。”NVIDIA亚太区高级市场总监庄海欧今日下午在接受专访时说。

视觉享受是不是多余的?

为了佐证他的结论,庄海欧打开了微软开发的可从不同角度显示城市地理情况的三维地图软件,和一个能够在三维空间里自由显示图片的软件,华丽相比传统的二维显示有着革命性的改变。他说,这种炫特的效果,只有通过GPU的处理才能呈现。3D显示的时代已经带来,人们可以看到的显示效果都将发生改变。

他又拿出自己的iPod Photo,“视觉的享受是不是多余的,如果你用过那些给你带来不同感受的产品,就不会有这种的疑问。早先人们听iPod只能按照艺人、唱片、歌曲名的方式选取曲。但现在苹果提供了按封面选取的服务。这就是不同的视觉感受,不过现在苹果提供的服务还是最初级的3D效果,而且在滑动封面时还比较卡,如果用了GPU它一定会给你不同的感受。而日常使用的GPS,如果有了三维的呈现,精准度也会大不同。”

GPU挑战大型机

庄海欧用一个个不同的例子来佐证GPU的神奇。他说,在高性能计算中GPU的作用更加强大,以往以CPU为处理核心的大型计算机多台联网才而可以完成的计算,通过GPU处理只需很少的终端,其成本也只有原来的十分之一。

庄海欧表示,人们应该改变对服务器和PC的选购标准。“同样的价格,如果选用一个更好的GPU,普通的CPU带来的视觉感受一定会比相反的选择高数倍。同样,对于石油勘探、宇宙模型计算、动态画面模拟等高性能计算领域,资金投资在GPU,会比用在CPU上为你带来数倍,甚至数十倍效果提升。”

和英特尔AMD比速度

不过CPU制造商们 也并没有闲着。AMD在并购ATI时看重的就是后者在显示领域的优势。而在并购ATI之初,AMD就提出开发CPU+GPU组合的Fusion处理器设 想。而英特尔在今年IDF(英特尔技术开发者大会)上也表示,将开发一套面向可编程的显示计算通用架构芯片Larrabee架构,它令CPU内整合图形处 理芯片成为现实。

面对两家竞争对手的提出的整合概念,NVIDIA并不特别担心。庄海欧表示,CPU和GPU是两个完全不同,CPU是解决程序运行,GPU核心是解决并行计算,两者很难实现完全融合。而且独立显卡与集成显卡的优劣,犹如台式机和笔记本电脑在性能上差别,前者永远会好于后者。目前,NVIDIA与英特尔和AMD也都保持着良好的合作关系,他们也希望NVIDIA可以为其提供更好的GPU,实现更好的整机机能。

“条条大路通罗马,就看谁跑得快,所有的竞争都是在比速度。”庄海鸥说。


http://news.csdn.net/n/20080509/115809.html

标签: , ,

Borland以2300万美元卖掉CodeGear开发工具部门

2008年5月7日,Thoma Cressey Bravo下的公司Embarcadero Technologies,宣布他们已经签署了一份对Borland Software Corporation (NASDAQ: BORL) 的资产收购协议, 收购其旗下的CodeGear公司。交易将会在30-60天内结束。公司合并后,将会在Embarcadero Technologies名下运作。

Thoma Cressey Bravo的合伙人Orlando Bravo说:“应用程序和数据库开发正在降温,这两家公司的协作是非常及时且合理的。”Jim Douglas, CodeGear的CEO说:“今天的宣布对于我们CodeGear的客户、员工、合作伙伴和社区来说,是一个好消息。我们可以将资源更集中的专注在我们的核心产品和市场上”。

整个收购额大约在2300万美元左右, 而Borland将继续拥有CodeGear大约700万的未收账款的权力。

CodeGear 所销售的产品都是Borland最知名的,包括JBuilder、Java开发工具、Delphi与C++Builder。最近CodeGear还创造了PHP与Ruby的开发工具。

两年前,Borland首席执行官Tod Nielson宣布计划卖掉这个工具部门,好让它能与应用生命周期管理产品线分开。工具部门难以生存是因为来自免费开放源代码产品的竞争,尤其是Eclipse IDE。

CodeGear产品主要是以个别程序设计师为主,而生命周期管理产品则是为整组的开发者、测试人员与架构师而设计。

该消息宣布后,Borland迟迟无法找到买主。

这次出面买下的Embarcadero主要销售资料库管理与设计工具,年营收6000万美元。这项收购将可让这家公司接触到好几百万使用CodeGear软件的开发人员。

http://news.csdn.net/n/20080509/115826.html

标签: , ,

让人悲伤的消息,CodeGear被收购

Borland出售Code Gear予Embarcadero公司

旧金山消息-Borland公司已将其开发工具部门CodeGear出售给Embarcadero Technologies公司。

Embarcadero称,这将合并开发工具市场和数据库工具市场上的领袖厂商。收购涉及金额高达3000万美金,将在30-60日内完成收购。

“CodeGear拥有忠实的开发者社区和全球渠道,是公认的市场领导者,”Embarcadero Technologies公司CEO Wayne Williamd在声明说。“通过对其强大产品线的整合,Embarcadero将扩展到新市场、开发先进产品、引领业界飞跃。两家公司的合并将为客户及合作伙伴释放巨大潜能。”

Embarcadero说,合并将把Embarcadero造就成全球最大的平台独立软件供应商。

“这对CodeGear客户、雇员、合作伙伴和社区是个大好消息,”CodeGear CEO Jim Douglas在声明中说。“我们将拥有更多资源,集中于核心产品及市场。”

CodeGear生产Java和Windows开发工具,例如JBuilder、Delphi等。该公司也在进入Ruby on Rails开发工具市场。

CodeGear于2006年从Borland公司独立出来,当时Borland决定将业务集中在应用程序生命周期管理市场,但找不到合适的买主来收购开发工具部门,于是CodeGear成为独立的子公司。

合并后的机构将以Embarcadero Technologies的名义运作,不过还没决定是否完全放弃CodeGear的名称。

在2300万美元的收购价之外,Borland还将保有700万美元的CodeGear应收账款

http://news.csdn.net/n/20080509/115830.html


标签: , ,

星期六, 五月 10, 2008

如何通过smarty生成静态化网页

Smarty最大的功能是做模版的页面缓存。也就是通过Smarty可以完成两个步骤:编译+解析

第一步:编译。是指把模版文件的标签替换为纯php,再保存在缓存位置,保存的文件扩展名是PHP,我把这个步骤叫做编译(这是我自己的叫法,不是官方的)

第二步:解析。也就是把刚才编译的PHP文件解析执行而已~~这个就不用多做解释了

切入正题,在Smarty.class.php文件中加入如下代码

function MakeHtmlFile($file_name, $content)
{ //目录不存在就创建
if (!file_exists (dirname($file_name))) {
if (!@mkdir (dirname($file_name), 0777)) {
die($file_name."目录创建失败!");
}
}

if(!$fp = fopen($file_name, "w")){
echo "文件打开失败!";
return false;
}


if(!fwrite($fp, $content)){
echo "文件写入失败!";
fclose($fp);
return false;
}

fclose($fp);
chmod($file_name,0666);
} 这个函数的作用就是保存文件~~

调用方法如下

require '../libs/Smarty.class.php';


$smarty = new Smarty;


//…………省略变量定义和赋值


//$smarty->display('index.tpl');
$content=$smarty->fetch("index.tpl");

$smarty->MakeHtmlFile('./index.html',$content);//生成

http://hi.baidu.com/anvycn/blog/item/a313761ec50fbaf01bd5768d.html

标签: , , , ,

提高网页打开速度的一些小技巧

互联网带宽越来越宽,似乎让网页的加载速度得到了质的飞跃。其实不然,因为随着带宽的提高,网页上的对象也越来越多,因此加快网页打开速度还是一个重要的课题。加快网页的打开速度,有三个路径,一是提高网络带宽,二是用户在本机做优化,三是网站设计者对网页做一定的优化。这篇文章站在一个网站设计者的角度,分享一些优化网页加载速度的小技巧。



一、优化图片

几乎没有哪个网页上是没有图片的。如果你经历过56K猫的年代,你一定不会很喜欢有大量图片的网站。因为加载那样一个网页会花费大量的时间。

即使在现在,网络带宽有了很多的提高,56K猫逐渐淡出,优化图片以加快网页速度还是很有必要的。

优化图片包括减少图片数、降低图像质量、使用恰当的格式。

1、减少图片数:去除不必要的图片。

2、降低图像质量:如果不是很必要,尝试降低图像的质量,尤其是jpg格式,降低5%的质量看起来变化不是很大,但文件大小的变化是比较大的。

3、使用恰当的格式:请参阅下一点。

因此,在上传图片之前,你需要对图片进行编辑,如果你觉得photoshop太麻烦,可以试试一些在线图片编辑工具。懒得编辑而又想图片有特殊的效果?可以试试用过调用javascript来实现图片特效

二、图像格式的选择

一般在网页上使用的图片格式有三种,jpg、png、gif。三种格式的具体技术指标不是这篇文章探讨的内容,我们只需要知道在什么时候应该使用什么格式,以减少网页的加载时间。

1、JPG:一般用于展示风景、人物、艺术照的摄影作品。有时也用在电脑截屏上。

2、GIF:提供的颜色较少,可用在一些对颜色要求不高的地方,比如网站logo、按钮、表情等等。当然,gif的一个重要的应用是动画图片。就像用Lunapic制作的倒映图片

3、PNG:PNG格式能提供透明背景,是一种专为网页展示而发明的图片格式。一般用于需要背景透明显示或对图像质量要求较高的网页上。

三、优化CSS

CSS叠层样式表让网页加载起来更高效,浏览体验也得到提高。有了CSS,表格布局的方式可以退休了。

但有时我们在写CSS的时候会使用了一些比较罗嗦的语句,比如这句:


margin-top: 10px;
margin-right: 20px;
margin-bottom: 10px;
margin-left: 20px;

你可以将它简化为:

margin: 10px 20px 10px 20px;

又或者这句:

A paragraph of decorated text


Second paragraph


Third paragraph


Forth paragraph



可以用div来包含:


A paragraph of decorated text


Second paragraph


Third paragraph


Forth paragraph




简化CSS能去除冗余的属性,提高运行效率。如果你写好CSS后懒得去做简化,你可以使用一些在线的简化CSS工具,比如CleanCSS

四、网址后加斜杠

有些网址,比如"www.kenengba.com/220",当服务器收到这样一个地址请求的时候,它需要花费时间去确定这个地址的文件类型。如果220是一个目录,不妨在网址后多加一个斜杠,让其变成www.kenengba.com/220/,这样服务器就能一目了然地知道要访问该目录下的index或default文件,从而节省了加载时间。

五、标明高度和宽度

这点很重要,但很多人由于懒惰或其它原因,总是将其忽视。当你在网页上添加图片或表格时,你应该指定它们的高度和宽度,也就是height和width参 数。如果浏览器没有找到这两个参数,它需要一边下载图片一边计算大小,如果图片很多,浏览器需要不断地调整页面。这不但影响速度,也影响浏览体验。

下面是一个比较友好的图片代码:

moon image

当浏览器知道了高度和宽度参数后,即使图片暂时无法显示,页面上也会腾出图片的空位,然后继续加载后面的内容。从而加载时间快了,浏览体验也更好了。

六、减少http请求

当浏览者打开某个网页,浏览器会发出很多对象请求(图像、脚本等等),视乎网络延时情况,每个对象加载都会有所延迟。如果网页上对象很多,这可以需要花费大量的时间。

因此,要为http请求减负。如何减负?

1、去除一些不必要的对象。

2、将临近的两张图片合成一张。

3、合并CSS

看看下面这段代码,需要加载三个CSS:

<link rel="stylesheet" type="text/css" href="/body.css">
<link rel="stylesheet" type="text/css" href="/side.css">
<link rel="stylesheet" type="text/css" href="/footer.css">

我们可以将其合成一个:

<link rel="stylesheet" type="text/css" href="/style.css">

从而减少http请求。

七、其它小技巧(译者添加)

1、去除不必要加载项。

2、如果在网页上嵌入了其它网站的widget,如果有选择余地,一定要选择速度快的。

3、尽量用图片代替flash,这对SEO也有好处。

4、有些内容可以静态化就将其静态化,以减少服务器的负担。

5、统计代码放在页尾。

标签: ,

星期五, 五月 09, 2008

Google:Unicode征服ASCII 成互联网最常用编码

我是这样看的。在互联网上,罗马拼音字母正四处逃窜,因为网络上日益充斥着阿拉伯字元、中国方块字和欧洲的特殊字元符号。

换言之,诚如Google资深国际软件架构师Mark Davis在其博客发文所言,Unicode现在已超越ASCII,成为互联网上最常用的字元编码方式。几乎在同时,西欧编码也被征服了。

Unicode是一种字元编码标准,能兼容数十种语文,以及标有读音识别符号的罗马字母。ASCII则是沿用数十年之久的标准,字元数目以128或256个字元为限,而且很难跨越原有的Remington打字机字元范围以外。

Davis指出,Unicode在去年12月上旬打败ASCII和西欧编码。

他说:不只是超越,更令人印象深刻的是,这么快就后来居上。他边说边指着一幅显示Unicode使用率扶摇直上的图表。

Google便非常喜爱Unicode网站,每当Google处理网站资料时,就会先转换成Unicode(如果该网站本来不是用Unicode的话),如此一来可加强国际搜索功能。

Davis说,目前Google只把资料转换成5.1版的Unicode,这样可让讲马来话等语言的人士,如今也可搜索内含这些新字元的文字。

不过,Unicode比ASCII差的一点是,所需的记忆空间至少比存储罗马拼音字元大一倍。

  

http://news.csdn.net/n/20080507/115756.html

标签: , ,

能提供双倍P2P传输速度的软件

西北大学的计算机科学家开发了一种文件共享软件,通过寻找和确定邻近的计算机从而提供双倍的P2P文件传输速度。这款叫Ono的插件是专为Azureus BT客户端开发的,源代码以GPL许可发布,软件开发者可以将其整合到各个不同的P2P客户端中。

根据统计报告,互联网70%的流量为P2P占用。Ono,目前下载人数已超过15万,可以在不牺牲用户带宽的情况下帮助ISP们减少交叉网络的流量。如果 ISP能恰当的配置网络,Ono能惊人的改进传输速度——达到平均速度的207%。博士生David Choffnes说,“寻找邻近的计算机听起来很简单,但实际上互联网并非是一张google地图,每台计算机都有一个地址,但并没有告诉你哪一台挨你很 近。”Ono,夏威夷语中的意思是“美味的”,主要是依靠在全世界有1万多台服务器的内容发行网络Akamai公司的网站或者其它流行的门户的访问速度来 判断距离。

http://news.chinaunix.net/a/2008/05/06/1092332.shtml

标签: , , ,

轻松六步使你的Oracle存储过程迅速加密

本文教你轻松六步法让你的Oracle存储过程迅速加密。
软件环境: 1、操作系统:windows 2000 Server。 2、数 据 库:Oracle 8i R2 (8.1.7) for NT 企业版。 3、安装路径:C:\Oracle。 实现方法: 1、
  D:\>set NLS_LANG=AMERICAN_AMERICA.USACII7 或 D:\>set NLS_LANG=AMERICAN_AMERICA.WE8ISO8859P1 或 D:\>set NLS_LANG=CHINESE_CHINA.ZHS16GBK D:\>set

直接打set命令可以查看环境变量。 2、在D:\下创建a.sql文件,内容如下:
create or replace procedure test1(i in number) as begin dbms_output.put_line('输入参数是'to_char(i)); end;

3、
D:\>wrap iname=a.sql PL/SQL Wrapper: Release 8.1.7.0.0 - ProdUCtion on Tue Nov 27 22:26:48 2001 Copyright (c) Oracle Corporation 1993, 2000.All Rights Reserved. Processing a.sql to a.plb

4、运行a.plb“SQL> @d:\a.plb”过程已创建。 5、运行存储过程:
SQL> set serveroutput on SQL> execute test1(1);


输入参数是1,PL/SQL 过程已成功完成。 6、查看存储过程的代码:
SQL> select name,text from all_source where type='PROCEDURE' and name='TEST1';

结果:看不到其原码。

http://database.csdn.net/page/52ff043f-91fe-42c2-b65d-7e1833b3a218

标签: ,

调查结果:Linux系统最需要的是电脑游戏

一项调查正在向Linux用户展开,在5月6号初步的结果是大多数Linux用户把票设给了游戏,其次是软件应用,丰富的主流软件做为单独的一项排在了第四。

  据悉产商也持相同的观点,他们认为现在Linux必需要出现一个好的转折点,否则Linux的局面将非常被动。现在开源运动正在全球展开,最大的推动者应该是开发者。

  一位使用五年的Linux用户在调查中评论到Linux保持特色实际是自私的,一个大家庭中永远不属于少数人。他虽然不喜欢游戏但还是很无情的第一个 投了游戏,如果支持大众玩的游戏那Linux的普及就直线上升。他还指出,当今的Linux技术数一数二,甚至高出了Windows,它只不过是应用输给 了 Windows。所以大家看到超级计算机中Linux占八成以上,在桌面占二成吗?不是,是零点二成。

来源:赛迪网

http://linux.chinaunix.net/news/2008/05/08/1001098.shtml

对于我,网上银行第一,游戏第二,开发这方面Linux已经很强大了。

标签:

星期四, 五月 08, 2008

金额阿拉伯数字转换为中文的自定义函数

CREATE FUNCTION ChangeBigSmall
(@ChangeMoney money)
RETURNS VarChar(100) AS

BEGIN
Declare @String1 char(20)
Declare @String2 char(30)
Declare @String4 Varchar(100)
Declare @String3 Varchar(100) --从原A值中取出的值
Declare @i int --循环变量
Declare @J Int --A的值乘以100的字符串长度
Declare @Ch1 Varchar(100) --数字的汉语读法
Declare @Ch2 Varchar(100) --数字位的汉字读法
Declare @Zero Int --用来计算连续有几个零
Declare @ReturnValue VarChar(100)

Select @ReturnValue = ''
Select @String1 = '零壹贰叁肆伍陆柒捌玖'
Select @String2 = '万仟佰拾亿仟佰拾万仟佰拾元角分'

Select @String4 = Cast(@ChangeMoney*100 as int)

select @J=len(cast((@ChangeMoney*100) as int))

Select @String2=Right(@String2,@J)

Select @i = 1

while @i<= @j Begin

Select @String3 = Substring(@String4,@i,1)

if @String3<>'0' Begin

Select @Ch1 = Substring(@String1, Cast(@String3 as Int) + 1, 1)
Select @Ch2 = Substring(@String2, @i, 1)
Select @Zero = 0 --表示本位不为零
end
else Begin
If (@Zero = 0) Or (@i = @J - 9) Or (@i = @J - 5) Or (@i = @J - 1)
Select @Ch1 = '零'
Else
Select @Ch1 = ''

Select @Zero = @Zero + 1 --表示本位为0

--如果转换的数值需要扩大,那么需改动以下表达式 I 的值。
Select @Ch2 = ''

If @i = @J - 10 Begin
Select @Ch2 = '亿'
Select @Zero = 0
end

If @i = @J - 6 Begin
Select @Ch2 = '万'
Select @Zero = 0
end

if @i = @J - 2 Begin
Select @Ch2 = '元'
Select @Zero = 0
end

If @i = @J
Select @Ch2 = '整'

end

Select @ReturnValue = @ReturnValue + @Ch1 + @Ch2

select @i = @i+1
end

--最后将多余的零去掉
If CharIndex('仟仟',@ReturnValue) <> 0
Select @ReturnValue = Replace(@ReturnValue, '仟仟', '仟')

If CharIndex('佰佰',@ReturnValue) <> 0
Select @ReturnValue = Replace(@ReturnValue, '佰佰', '佰')

If CharIndex('零元',@ReturnValue) <> 0
Select @ReturnValue = Replace(@ReturnValue, '零元', '元')

If CharIndex('零万',@ReturnValue) <> 0
Select @ReturnValue = Replace(@ReturnValue, '零万', '万')

If CharIndex('零亿',@ReturnValue) <> 0
Select @ReturnValue = Replace(@ReturnValue, '零亿', '亿')

If CharIndex('零整',@ReturnValue) <> 0
Select @ReturnValue = Replace(@ReturnValue, '零整', '整')

If CharIndex('零佰',@ReturnValue) <> 0
Select @ReturnValue = Replace(@ReturnValue, '零佰', '零')

If CharIndex('零仟',@ReturnValue) <> 0
Select @ReturnValue = Replace(@ReturnValue, '零仟', '零')

If CharIndex('元元',@ReturnValue) <> 0
Select @ReturnValue = Replace(@ReturnValue, '元元', '元')

return @ReturnValue

END
http://www.sdgn.cn/access/11624.html

标签: ,

福布斯:云计算已成未来经济的必然选择

导语:国外杂志《福布斯》今天发表分析文章称,“云计算(cloud computing)”是一个相对较新的概念,但事实上它的起源可追溯到互联网诞生之初。就目前来看,云计算概念最具革命性的并不在其本身,而是许多与之 相关的条件,随着这些条件逐渐成熟,云计算已越来越成为经济发展过程中的一种必然选择和趋势。

  云计算的概念其实相当简单:即通过互联网提供软件与服务,并由网络浏览器界面来实现。用户加入云计算不需要安装服务器或任何客户端软件,可在任何时 间、任何地点、任何设备(前提是接入互联网)上随时随意访问,业界称这种服务模式为“软件即服务(SaaS)”,而对大多数用户来说,它不过就是一个网 络。

  事实上在过去15年里,云计算一直在不断地发展,没有人能够准确预期云计算将给我们的生活带来哪些巨大变化,但随着这一运动的不断推进,不管是作为消费者还是商业人士,他们都可以感受到云计算带来的巨大变化。

  在推动云计算发展的诸多因素中,网络宽带发挥了重要作用,同时,谷歌等搜索引擎也使得云计算成为不可阻挡的发展趋势。今天通过搜索引擎几乎可以检索到所有格式的信息,包括网页、书籍、视频和图像等。

  搜索引擎目前并没有发展到终点,而仅仅是一个开始,就如同爱迪生当初发明的第一只白炽灯,才仅仅照亮了一间屋子。最初信息是单向流动的,现在却不受时 空限制能够自由流动。随着云计算时代的到来,人们生活的交互性将越来越强,因此创建一个全球对话和多层面的协作已完全成为可能。比如,一名身在印度的会计 师可以和纽约的同事同时制作同一张表格,并随时进行讨论;一个遍布全球的设计师团队可在同一个文档中规划一件新产品。类似的交流本身就具有革命性,因为在 这一协作过程中地缘差别已经消失,创意和思想可自由共享与交流。

  与许多类似的产业革命一样,云计算经济正在推动着不同产业改变旧有的模式。在今天这样一个信息时代,公司通常都要花费巨额资金用于开发或采用拥有版权 的数据,同时还得花费巨资保护这些数据。然而现在有越来越多的公司将上述数据托管给云计算,因为这么做的优势非常明显,除可以节省大量硬件、软件和能耗开 支之外,还具有高效和安全等特点。也许有人对云计算的安全性存有疑问,不过像谷歌这样的公司,其全球运营都采用云计算模式,因此不管自身还是用户的安全都 是其首要考虑的问题。

  云计算可能带来长久而真实的改变,而这一改变的迹象才刚刚显现出来。每一位关注未来经济发展的人士都可能会有这样的认识:即拥有信息将成为一种决定性的优势,而云计算正好为信息共享与协作提供了一种既廉价又简捷的方式。

  在云计算时代,即便是一些小公司也可以与跨国公司一样拥有同样的网络影响力,毕竟网络浏览器的窗口都是同样的尺寸,不管是谁在提供信息。这场革命的发源地当初或许只是加州的一间车库,但革命的火种已经走出国界,飘洋过海传播到了全球。

http://news.chinaunix.net/a/2008/05/07/1093146.shtml

标签: , ,

星期三, 五月 07, 2008

E61可用的音乐播放器

天天动听手机音乐盒是一款集播放、音效、搜索、下载等众多功能于一身,完全免费的手机音乐播放器。由于其支持最多手机机型和音频格式,支持丰富的皮肤下载 等功能,同时其与手机搭配和谐、操作简易、管理人性的特点,深受姆指一族的青睐。天天动听也力求以您的需求为主导,把您的思想融入其中。



http://www.ttpod.com/

标签: ,

星期二, 五月 06, 2008

Ubuntu新版Linux免费下载血战Novell

Ubuntu Server 8.04将从本周四开始让用户免费下载。这将使Canonical的Ubuntu与Red Hat Enterprise和Novell平Suse Linux Enterprise更激烈地争夺企业市场。

Ubuntu Server 8.04的支持周期为5年。它能够在Sun的服务器上运行,其中包括Sun Fire X2100 M2、X2200 M2、Sun Fire X4150。Sun负责开放源代码软件业务的经理乔治表示,Ubuntu Server 8.04面向企业市场。

Canonical首席执行官马克表示,Ubuntu Server 8.04一直面临稳定性问题困扰,我们通过更多测试提高了其可靠性。他在接受采访时说,我们将每二年推出一个新的版本。

马克表示,Sun的认证包括1、2、4路x86服务器,Ubuntu没有针对4路以上的系统对Ubuntu Server 8.04进行优化。另外,Canonical还在与惠普、IBM、戴尔就认证问题进行接触。

Ubuntu 8.04中包含Windows整合功能。通过使用第三方厂商Likewise的Likewise Enterprise产品,Ubuntu

8.04能够使用微软活动目录用户身份管理系统的服务。马克说,与Windows网络的整合非常重要。

Ubuntu 8.04还整合有Open JDK,这意味着Ubuntu首次整合了Java虚拟机,能够运行Java应用程序。另外,它还包含有开放源代码版Alfresco内容管理软件、 Bacula网络备份软件、Parallels虚拟软件、Tresys安全软件、PHP、Zimbra电子邮件。

http://linux.chinaunix.net/news/2008/04/23/994703.shtml

标签: ,

星期一, 五月 05, 2008

Web Site inside a Delphi EXE

This is the third article in the series about storing more than just executable code inside a Delphi application.
In the introductory article we saw how Delphi uses standard Windows resource files like icons, bitmaps and cursors. As explained, resource files that store such kind of data can be created with Delphi's Image Editor. The second article explained how to use sound files, video clips, animations and more generally any kind of binary files in a Delphi executable - we placed a mp3 file inside a Delphi exe. As stated, we use Borland Resource Compiler (BRCC32.exe) to create a resource file that gets linked with an executable file.

Many of you have asked how your application can be a container for any Web-style content, including HTML resources and pictures that are part of your project.
This articles will show you how HTML and associated files (pictures) can easily be included within a Delphi application. As a result, you simply have to distribute an EXE file that includes HTML pages, as it would do with icons and cursors.

Creating a HTML page
For the start we have to assemble a (simple) html page. Use your favorite HTML editor and create one page with one associated picture. I'll name mine aboutindex.htm.
Note that when you add a picture tag inside a htm page it looks something like:

We have to alter the IMG tags so that the SRC attribute equals the name we are to give to a picture in a resource:

My HTML code looks like:

HTML inside a Delphi exe
This is a HTML Delphi resource test:


Creating and compiling a resource file
Remember that to create a new resource script file, you have to:
1. Create a new text file in your projects directory.
2. Rename it to AHTMLDelphi.rc.
3. Write down the following two lines of text in the AHTMLDelphi.rc file.

DELPHIINDEX HTML "c:\Delphi\projects\aboutindex.htm"
ABOUTDP GIF "c:\library\graphics\adp.gif"

Note: the resource type "HTML" is RT_HTML, predefined as the resource type "23". This is the default resource type for the RES protocol.

In this way we have prepared one HTML page and one GIF picture to be included in the binary code of our EXE module.

The next step is to compile the .rc file. To compile the AHTMLDelphi.rc file to a .res file execute this command at the command prompt (in the projects directory):

BRCC32 AHTMLDelphi.RC

The final step is to add the following compiler directive to a unit in your project. RES file must be included in the program's build by adding a line like this:

{$R AHTMLDelphi.RES}

Displaying inside a Web browser
When you have the application's exe (let's call it: myhtmldelphi.exe) the HTML resource contained within can be accessed via the RES: protocol. Run Internet Explorer and, in the Address bar, type the following:

res://c:\myhtmldelphi.exe/RT_HTML/DELPHIINDEX

This should result in:

HTML page from a Delphi resource

That's it. If you have any questions; like how use the HREF tag inside a html resource, or how to display the html page inside a Delphi form; please post them on the Delphi Programming Forum!

标签: ,

google正在创建一个王国

Google其实不仅仅是一个内容的搜寻者,目前他还在不停的向内容的拥有者和创建者方向发展,这一点通过google提供的公共服务API可见一斑。gmail可以将非搜索用户紧紧的粘贴住,而blogger服务则能让用户自动创造内容。如果说前面的这两点是最基本基本的应用,那么google又提供了中级一点的web应用,你可以通过google page crator来创建静态web页面;如果需要在静态页面中展示动态内容那也相当的容易,因为google的gdata可以让你自由存取数据甚至可以只用javascript而不需要服务器端程序来实现;还有google的mashup能让你快速的完成小型web应用程序的建立。

前面的这些都不足以让我心动直到google的app engine的出现,app engine是一个很诱人的服务,可惜没有抢到最初的试用用户名额。按照我粗浅的理解,app engine可以认为这是google提供的虚拟主机服务。而这“虚拟主机”的大致配置如下:

  1. 磁盘空间500M;
  2. 支持语言:python(当前只支持python,今后可能会有其他语言的支持。要是能支持php,那些虚拟主机商还怎么活啊)
  3. CPU限制:每个月5000,000PV(dreamhost的上限大约每月不到1000,000PV);
  4. 价格:基本用户免费;
  5. 数据库,gdata,SQL语句采用GQL(类似SQL的语言,是google自己的企业标准);
  6. 用户认证(可以集成在google的用户认证中),当然也可以自己用python来实现;
  7. uptime(没有明确的保证,估计和其他服务一样,收费用户将会有99.9%的uptime保证,免费用户就看你对google的信心了)

上面的配置是不是很诱人呢?并且还是免费的,但是如果要能使用上这个免费的平台,你还得要重新熟悉新的语言,新的数据库操作等等。但是能用上 google稳定的服务器,那也值得一试的。要知道google在全球各地有n多的分布式数据中心,所以它的稳定性和负载能力是其他服务商无法比拟的,用 它自己的话说就是:An App Engine application runs on many web servers simultaneously. Any web request can go to any web server, and multiple requests from the same user may be handled by different web servers. Distribution across multiple web servers is how App Engine ensures your application stays available while serving many simultaneous users.

希望这个服务能尽快被推出,到时候我们就可以用一系列google的API创建出丰富的应用了,不过吃人嘴短,互联网要是真被google统治了,那或许将会是一场灾难。

另外,在中国,使用google的服务还是有强大的风险的,要么冒着被封的危险使用google的服务,要么在那里左右为难,干巴巴的望着!

google code确实是一个好东西!

http://www.storyday.com/html/y2008/1534_google-is-creating-an-empire.html

谢谢兄弟,我加入了等待申请的行列。

标签:

htaccess文件使用

pache系统中的.htaccess文件(或者”分布式配置文件”提供了针对目录改变配置的方法, 即,在一个特定的文档目录中放置一个包含一个或多个指令的文件, 以作用于此目录及其所有子目录。作为用户,所能使用的命令受到限制。管理员可以通过Apache的AllowOverride指令来设置。

  子目录中的指令会覆盖更高级目录或者主服务器配置文件中的指令。

  .htaccess必须以ASCII模式上传,最好将其权限设置为644。

  错误文档的定位

  常用的客户端请求错误返回代码:
  401 Authorization Required
  403 Forbidden
  404 Not Found
  405 Method Not Allowed
  408 Request Timed Out
  411 Content Length Required
  412 Precondition Failed
  413 Request Entity Too Long
  414 Request URI Too Long
  415 Unsupported Media Type

  常见的服务器错误返回代码:
  500 Internal Server Error

  用户可以利用.htaccess指定自己事先制作好的错误提醒页面。一般情况下,人们可以专门设立一个目录,例如errors放置这些页面。然后再.htaccess中,加入如下的指令:

  ErrorDocument 404 /errors/notfound.html
  ErrorDocument 500 /errors/internalerror.html

  一条指令一行。上述第一条指令的意思是对于404,也就是没有找到所需要的文档的时候得显示页面为/errors目录下的notfound.html页面。不难看出语法格式为:

  ErrorDocument 错误代码 /目录名/文件名.扩展名

  如果所需要提示的信息很少的话,不必专门制作页面,直接在指令中使用HTML号了,例如下面这个例子:

  ErrorDocument 401 “你没有权限访问该页面,请放弃!”

  文档访问的密码保护

  要利用.htaccess对某个目录下的文档设定访问用户和对应的密码,首先要做的是生成一个.htpasswd的文本文档,例如:

  zheng:y4E7Ep8e7EYV

  这里密码经过加密,用户可以自己找些工具将密码加密成.htaccess支持的编码。该文档最好不要放在www目录下,建议放在www根目录文档之外,这样更为安全些。

  有了授权用户文档,可以在.htaccess中加入如下指令了:

  AuthUserFile .htpasswd的服务器目录
  AuthGroupFile /dev/null (需要授权访问的目录)
  AuthName EnterPassword
  AuthType Basic (授权类型)

  require user wsabstract (允许访问的用户,如果希望表中所有用户都允许,可以使用 require valid-user)

  注,括号部分为学习时候自己添加的注释

  拒绝来自某个IP的访问

  如果我不想某个政府部门访问到我的站点的内容,那可以通过.htaccess中加入该部门的IP而将它们拒绝在外。

  例如:

  order allow,deny
  deny from 210.10.56.32
  deny from 219.5.45.
  allow from all

  第二行拒绝某个IP,第三行拒绝某个IP段,也就是219.5.45.0~219.2.45.255

  想要拒绝所有人?用deny from all好了。不止用IP,也可以用域名来设定。

  保护.htaccess文档

  在使用.htaccess来设置目录的密码保护时,它包含了密码文件的路径。从安全考虑,有必要把.htaccess也保护起来,不让别人看到其中的内容。虽然可以用其他方式做到这点,比如文档的权限。不过,.htaccess本身也能做到,只需加入如下的指令:

  order allow,deny
  deny from all

  URL转向

  我们可能对网站进行重新规划,将文档进行了迁移,或者更改了目录。这时候,来自搜索引擎或者其他网站链接过来的访问就可能出错。这种情况下,可以通过如下指令来完成旧的URL自动转向到新的地址:

  Redirect /旧目录/旧文档名 新文档的地址

  或者整个目录的转向:

  Redirect 旧目录 新目录

  改变缺省的首页文件

   一般情况下缺省的首页文件名有default、index等。不过,有些时候目录中没有缺省文件,而是某个特定的文件名,比如在pmwiki中是 pmwiki.php。这种情况下,要用户记住文件名来访问很麻烦。在.htaccess中可以轻易的设置新的缺省文件名:

  DirectoryIndex 新的缺省文件名

  也可以列出多个,顺序表明它们之间的优先级别,例如:

  DirectoryIndex filename.html index.cgi index.pl default.htm

  防止盗链

  如果不喜欢别人在他们的网页上连接自己的图片、文档的话,也可以通过htaccess的指令来做到。

  所需要的指令如下:

  RewriteEngine on
  RewriteCond %{ HTTP_REFERER } !^$
  RewriteCond %{ HTTP_REFERER } !^http://(www.)?mydomain.com/.*$ [NC]
  RewriteRule .(gif&line;jpg)$ - [F]

  如果觉得让别人的页面开个天窗不好看,那可以用一张图片来代替:

  RewriteEngine on
  RewriteCond %{ HTTP_REFERER } !^$
  RewriteCond %{ HTTP_REFERER } !^http://(www.)?mydomain.com/.*$ [NC]
  RewriteRule .(gif&line;jpg)$ http://www.mydomain.com/替代图片文件名 [R,L]

http://www.williamlong.info/archives/440.html

标签: ,

Google排名优化-面向Google(Search Engine Friendly)的URL设计

内容摘要:不得不承认,将动态网页链接rewriting成静态链接是最保险和稳定的面向搜索引擎优化方式

此外随着互联网上的内容以惊人速度的增长也越来越突出了搜索引擎的重要性,如果网站想更好地被搜索引擎收录,网站设计除了面向用户友好(User Friendly)外,搜索引擎友好 (Search Engine Friendly)的设计也是非常重要的。进入搜索引擎的页面内容越多,则被用户用不同的关键词找到的几率越大。在Google的算法调查一文 中提到一个站点被Google索引页面的数量其实对PageRank也是有一定影响的。由于Google 突出的是整个网络中相对静态的部分(动态网页索引量比较小),链接地址相对固定的静态网页比较适合被Google索引(怪不得很多大网站的邮件列表归档和BLOG按日期归档的文档很容被搜的到),因此很多关于面向搜索引擎 URL设计优化(URI Pretty)的文章中提到了很多利用一定机制将动态网页参数变成像静态网页的形式:
比如可以将:
http://phpunixman.sourceforge.net/index.php?mode=man&parameter=ls

变成:http://phpunixman.sourceforge.net/index.php/man/ls

实现方式主要有2种:

把URI地址用作参数传递:URL REWRITE

最简单的是基于各种WEB服务器中的URL重写转向(Rewrite)模块的URL转换:
这样几乎可以不修改程序的实现将 news.asp?id=234 这样的链接映射成 news/234.html,从外面看上去和静态链接一样。Apache服务器上有一个模块(非缺省):mod_rewrite:URL REWRITE功能之强大足够写上一本书。

当我需要将将news.asp?id=234的映射成news/234.html时,只需设置:
RewriteRule /news/(\d+)\.html /news\.asp\?id=$1 [N,I]
这样就把 /news/234.html 这样的请求映射成了 /news.asp?id=234
当有对/news/234.html的请求时:web服务器会把实际请求转发给/news.asp?id=234

而在IIS也有相应的REWRITE模块:比如ISAPI REWRITEIIS REWRITE,语法都是基于正则表达式,因此配置几乎和apache的mod_rewrite是相同的:

比对于某一个简单应用可以是:
RewriteRule /news/(\d+)\.html /news/news\.php\?id=$1 [N,I]
这样就把 http://www.chedong.com/news/234.html 映射到了 http://www.chedong.com/news/news.php?id=234

一个更通用的能够将所有的动态页面进行参数映射的表达式是:
把 http://www.myhost.com/foo.php?a=A&b=B&c=C
表现成 http://www.myhost.com/foo.php/a/A/b/B/c/C。
RewriteRule (.*?\.php)(\?[^/]*)?/([^/]*)/([^/]*)(.+?)?$1(?2$2&:\?)$3=$4?5$5: [N,I]

以下是针对phpBB的一个Apache mod_rewrite配置样例:

    RewriteEngine On
RewriteRule /forum/topic_(.+)\.html$ /forum/viewtopic.php?t=$1 [L]
RewriteRule /forum/forum_(.+)\.html$ /forum/viewforum.php?f=$1 [L]

RewriteRule /forum/user_(.+)\.html$ /forum/profile.php?mode=viewprofile&u=$1 [L]

这样设置后就可以通过topic_1234.html forum_2.html user_34.html这样的链接访问原来的动态页面了。

通过URL REWRITE还有一些好处:
mod_rewrite和isapirewrite基本兼容,但是还是有些不同,比如:isapirewrite中"?"需要转义成"\?",mod_rewrite不用,isapirewrite支持 "\d+" (全部数字),mod_rewrite不支持

  • 隐藏后台实现:这在后台应用平台的迁移时非常有用:当从asp迁移到java平台 时,对于前台用户来说,根本感受不到后台应用的变化;
  • 简化数据校验:因为像(\d+)这样的参数,可以有效的控制数字的格式甚至位数;

比如我们需要将应用从news.asp?id=234迁移成news.php?query=234时,前台的表现可以一直保持为 news/234.html。从实现应用和前台表现的分离:保持了URL的稳定性,而使用mod_rewrite甚至可以把请求转发到其他后台服务器上。

基于PATH_INFO的URL美化

Url美化的另外一个方式就是基于PATH_INFO:
PATH_INFO是一个CGI 1.1的标准,经常发现很多跟在CGI后面的"/value_1/value_2"就是PATH_INFO参数:
比如:http://phpunixman.sourceforge.net/index.php/man/ls 中:$PATH_INFO = "/man/ls"

PATH_INFO是CGI标准,因此PHP Servlet等都有的支持。 比如Servlet中就有request.getPathInfo()方法。
注意:/myapp/servlet/Hello/foo的 getPathInfo()返回的是/foo,而/myapp/dir/hello.jsp/foo的getPathInfo()将返回的 /hello.jsp,从这里你也可以知道jsp其实就是一个Servlet的PATH_INFO参数。ASP不支持PATH_INFO
PHP中基于PATH_INFO的参数解析的例子如下:
//注意:参数按"/"分割,第一个参数是空的:从/param1/param2中解析出$param1 $param2这2个参数
if ( isset($_SERVER["PATH_INFO"]) ) {
list($nothing, $param1, $param2) = explode('/', $_SERVER["PATH_INFO"]);
}

如何隐蔽应用:例如 .php,的扩展名:
在APACHE中这样配置:

ForceType application/x-httpd-php


如何更像静态页面:app_name/my/app.html
解析的PATH_INFO参数的时候,把最后一个参数的最后5个字符“.html”截断即可。
注意:APACHE2中缺省是不允许PATH_INFO的,需要设置 AcceptPathInfo on

特别是针对使用虚拟主机用户,无权安装和配置mod_rewrite的时候,PATH_INFO往往就成了唯一的选择。

OK,这样以后看见类似于http://www.example.com/article/234这样的网页你就知道可能是 article/show.php?id=234这个php程序生成的动态网页,很多站点表面看上去可能有很多静态目录,其实很有可能都是使用1,2个程 序实现的内容发布。比如很多WIKIWIKI系统都使用了这个机制:整个系统就一个简单的wiki程序,而看上去的目录其实都是这个应用拿后面的地址作为 参数的查询结果。

利用基于MOD_REWRITE/PATH_INFO + CACHE服务器的解决方案对原有的动态发布系统进行改造,也可以大大降低旧有系统升级到新的内容管理系统的成本。并且方便了搜索引擎收录入索引。

附:如何在IIS上利用PHP支持PATH_INFO

PHP的ISAPI模式安装备忘:只试成 php-4.2.3-Win32

解包目录
========
php-4.2.3-Win32.zip c:\php

PHP.INI初始化文件
=================
复制:c:\php\php.ini-dist 到 c:\winnt\php.ini

配置文件关联
============
按照install.txt中的说明配置文件关联

运行库文件
==========
复制 c:\php\php4ts.dll 到 c:\winnt\system32\php4ts.dll

这样运行后:会发现php把PATH_INFO映射到了物理路径上
Warning: Unknown(C:\CheDong\Downloads\ariadne\www\test.php\path): failed to create stream: No such file or directory in Unknown on line 0

Warning: Unknown(): Failed opening 'C:\CheDong\Downloads\ariadne\www\test.php\path' for inclusion (include_path='.;c:\php4\pear') in Unknown on line 0

安装ariadne的PATCH
==================
停止IIS服务
net stop iisadmin
ftp://ftp.muze.nl/pub/ariadne/win/iis/php-4.2.3/php4isapi.dll
覆盖原有的c:\php\sapi\php4isapi.dll

注:
ariadne是一个基于PATH_INFO的内容发布系统,
PHP 4.3.2 RC2中CGI模式的PATH_INFO已经修正,照常安装即可。

参考资料:
URL Rewrite文档:
ISAPI REWRITE文档
IIS的ISAPI REWRITE下载(免费)
http://httpd.apache.org/docs/mod/mod_rewrite.html
http://httpd.apache.org/docs-2.0/mod/mod_rewrite.html

搜索引擎友好的URL设计
http://www.sitepoint.com/article/485
说不定这个URL原来就是articel.php?id=485

一个基于PATH_INFO的开源内容管理系统
http://typo3.com/

Google的PageRank算法说明:
http://pr.efactory.de/

标签: , ,

A Survey of Google's PageRank

Within the past few years, Google has become the far most utilized search engine worldwide. A decisive factor therefore was, besides high performance and ease of use, the superior quality of search results compared to other search engines. This quality of search results is substantially based on PageRank, a sophisticated method to rank web documents.

The aim of these pages is to provide a broad survey of all aspects of PageRank. The contents of these pages primarily rest upon papers by Google founders Lawrence Page and Sergey Brin from their time as graduate students at Stanford University.

It is often argued that, especially considering the dynamic of the internet, too much time has passed since the scientific work on PageRank, as that it still could be the basis for the ranking methods of the Google search engine. There is no doubt that within the past years most likely many changes, adjustments and modifications regarding the ranking methods of Google have taken place, but PageRank was absolutely crucial for Google's success, so that at least the fundamental concept behind PageRank should still be constitutive.

The PageRank Concept

Since the early stages of the world wide web, search engines have developed different methods to rank web pages. Until today, the occurence of a search phrase within a document is one major factor within ranking techniques of virtually any search engine. The occurence of a search phrase can thereby be weighted by the length of a document (ranking by keyword density) or by its accentuation within a document by HTML tags.

For the purpose of better search results and especially to make search engines resistant against automatically generated web pages based upon the analysis of content specific ranking criteria (doorway pages), the concept of link popularity was developed. Following this concept, the number of inbound links for a document measures its general importance. Hence, a web page is generally more important, if many other web pages link to it. The concept of link popularity often avoids good rankings for pages which are only created to deceive search engines and which don't have any significance within the web, but numerous webmasters elude it by creating masses of inbound links for doorway pages from just as insignificant other web pages.

Contrary to the concept of link popularity, PageRank is not simply based upon the total number of inbound links. The basic approach of PageRank is that a document is in fact considered the more important the more other documents link to it, but those inbound links do not count equally. First of all, a document ranks high in terms of PageRank, if other high ranking documents link to it.

So, within the PageRank concept, the rank of a document is given by the rank of those documents which link to it. Their rank again is given by the rank of documents which link to them. Hence, the PageRank of a document is always determined recursively by the PageRank of other documents. Since - even if marginal and via many links - the rank of any document influences the rank of any other, PageRank is, in the end, based on the linking structure of the whole web. Although this approach seems to be very broad and complex, Page and Brin were able to put it into practice by a relatively trivial algorithm.

The PageRank Algorithm

http://pr.efactory.de/

标签: ,

Apache的ReWrite的应用

Apache的mod_rewrite是提供了强大 URL操作的杀手级的模块,可以实现几乎所有你梦想的URL操作类型,其代价是你必须接受其复杂性,因为mod_rewrite的主要障碍就是初学者不容易理解和运用,即使是Apache专家有时也会发掘出mod_rewrite的新用途。

换句话说:对mod_rewrite,或者是打退堂鼓永不再用,或者是喜欢它并一生受用。

ReWrite可以应用在以下方面或者解决以下问题:
URL的规划
规范的URL
说明:
在有些网站服务器上,一个资源会拥有多个URL,在实际应用和发布中应该被使用的是规范的URL,其他的则是简写或者是内部使用的。无论用户在请求中使用什么形式的URL,他最终看见的都应该是规范的URL。

方案:
对所有的不规范的URL执行一个外部的HTTP重定向,以改变它在浏览器地址栏中的显示及其后继的请求。下例中的规则集用规范的/u/user替换/~user,并修正了/u/user所遗漏的后缀的斜杠。

代码:
RewriteRule ^/~([^/]+)/?(.*) /u/$1/$2 [R]
RewriteRule ^/([uge])/([^/]+)$ /$1/$2/ [R]


规范的主机名
说明:
...
方案:
代码:
RewriteCond %{HTTP_HOST} !^fully\.qualified\.domain\.name [NC]
RewriteCond %{HTTP_HOST} !^$
RewriteCond %{SERVER_PORT} !^80$
RewriteRule ^/(.*) http://fully.qualified.domain.name:%{SERVER_PORT}/$1 [L,R]
RewriteCond %{HTTP_HOST} !^fully\.qualified\.domain\.name [NC]
RewriteCond %{HTTP_HOST} !^$
RewriteRule ^/(.*) http://fully.qualified.domain.name/$1 [L,R]


被移动过的DocumentRoot
说明:
通常,网站服务器的DocumentRoot直接对应于URL"/",但是,它常常不是处于最高一级,而可能只是众多数据池中的一个实体。比如,在 Intranet站点中,有/e/www/(WWW的主页)、/e/sww/ (Intranet的主页)等等,而DocumentRoot指向了/e/www/,则必须保证此数据池中的所有内嵌的图片和其他元素对后继请求有效。

方案:
只须重定向URL /到/e/www/即可。这个方案看起来很简单,但只是有了mod_rewrite模块的支持,它才简单,因为传统的URL Aliases机制(由mod_alias及其相关模块提供)只是作了一个前缀匹配,DocumentRoot是一个对所有URL的前缀,因而无法实现这样的重定向。而用mod_rewrite的确很简单:

代码:
RewriteEngine on
RewriteRule ^/$ /e/www/ [R]


后缀斜杠的问题
说明:
每个网管对引用目录后缀斜杠的问题都有一本苦经,如果遗漏了,服务器会产生一个错误,因为如果请求是/~quux/foo而不是/~quux/foo/,服务器会去找一个叫foo的文件,而它是一个目录,所以就报错了。事实上,大多数情况下,它自己会试图修正这个错误,但是有时候需要你手工纠正,比如,在重写了许多CGI脚本中的复杂的URL以后。

方案:
解决这个微妙问题的方案是让服务器自动添加后缀的斜杠。对此,必须使用一个外部的重定向,使浏览器正确地处理后继的对诸如图片的请求。如果仅仅作一个内部的重写,可能只对目录页面有效,而对内嵌有使用相对URL的图片的页面则无效,因为浏览器有请求内嵌目标的可能。比如,如果不用外部重定向,/~quux/foo/index.html页面中对image.gif的请求,其结果将是/~quux/image.gif!。

所以,应该这样写:

代码:
RewriteEngine on
RewriteBase /~quux/
RewriteRule ^foo$ foo/ [R]

又懒又疯狂的做法是把这些写入其宿主目录中的顶级.htaccess中,但是须注意,如此会带来一些处理上的开销。

代码:
RewriteEngine on
RewriteBase /~quux/
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^(.+[^/])$ $1/ [R]


集群网站的同类URL规划
说明:
我们希望在一个Intranet集群网站中,对所有WWW服务器建立一个同类的一致性的URL规划,也就是,所有的URL(对单个服务器来说,是本地的依赖于此服务器的!)是独立于服务器的!我们需要的是一个具有独立于服务器的一致性规划的WWW名称空间,即,URL不需要包含正确的物理的目标服务器,而由集群本身来自动定位物理的目标主机。

方案:
首先,目标服务器的信息来自(产生)于包含有用户、组以及实体的外部地图,其格式形如:

代码:
user1 server_of_user1
user2 server_of_user2
: :


这些信息被存入map.xxx-to-host文件。其次,如果URL在一个服务器上无效,需要引导所有的服务器重定向URL

代码:
/u/user/anypath
/g/group/anypath
/e/entity/anypath



代码:
http://physical-host/u/user/anypath
http://physical-host/g/group/anypath
http://physical-host/e/entity/anypath


以下规则集依靠地图文件来完成这个操作(假定,如果一个用户在地图中没有对应的项,则使用server0为默认服务器):

代码:
RewriteEngine on

RewriteMap user-to-host txt:/path/to/map.user-to-host
RewriteMap group-to-host txt:/path/to/map.group-to-host
RewriteMap entity-to-host txt:/path/to/map.entity-to-host

RewriteRule ^/u/([^/]+)/?(.*) http://${user-to-host:$1|server0}/u/$1/$2
RewriteRule ^/g/([^/]+)/?(.*) http://${group-to-host:$1|server0}/g/$1/$2
RewriteRule ^/e/([^/]+)/?(.*) http://${entity-to-host:$1|server0}/e/$1/$2

RewriteRule ^/([uge])/([^/]+)/?$ /$1/$2/.www/
RewriteRule ^/([uge])/([^/]+)/([^.]+.+) /$1/$2/.www/$3\


移动宿主目录到不同的网站服务器
说明:
通常,许多网管在建立一个新的网站服务器时,都会有这样的要求:重定向一个网站服务器上的所有宿主目录到另一个网站服务器。

方案:
很简单,用mod_rewrite。在老的网站服务器上重定向所有的URL /~user/anypath到http://newserver/~user/anypath。

代码:
RewriteEngine on
RewriteRule ^/~(.+) http://newserver/~$1 [R,L]


结构化的宿主目录
说明:
一些拥有几千个用户的网站通常都使用结构化的宿主目录规划,即,每个宿主目录位于一个带有特定前缀比如其用户名的第一个字符的子目录下。那么,/~foo /anypath代表/home/f/foo/.www/anypath,而/~bar/anypath代表/home/b/bar/.www /anypath。

方案:
可以使用下列规则集来扩展~以达到上述目的。

代码:
RewriteEngine on
RewriteRule ^/~(([a-z])[a-z0-9]+)(.*) /home/$2/$1/.www$3


文件系统的重组
说明:
这是一个不加雕琢的例子:一个大量使用针对目录的规则集以实现平滑观感,而从来不用调整数据结构的杀手级的应用。背景:net.sw从1992年开始,存放了我收集的免费的有效的Unix软件包。它是我的爱好也是我的工作,因为在学习计算机科学的同时,业余时间还做了多年的系统和网络的管理员。每周我都需要整理软件,因而建立了一个层次很深的目录结构来存放各种软件包:

代码:
drwxrwxr-x 2 netsw users 512 Aug 3 18:39 Audio/
drwxrwxr-x 2 netsw users 512 Jul 9 14:37 Benchmark/
drwxrwxr-x 12 netsw users 512 Jul 9 00:34 Crypto/
drwxrwxr-x 5 netsw users 512 Jul 9 00:41 Database/
drwxrwxr-x 4 netsw users 512 Jul 30 19:25 Dicts/
drwxrwxr-x 10 netsw users 512 Jul 9 01:54 Graphic/
drwxrwxr-x 5 netsw users 512 Jul 9 01:58 Hackers/
drwxrwxr-x 8 netsw users 512 Jul 9 03:19 InfoSys/
drwxrwxr-x 3 netsw users 512 Jul 9 03:21 Math/
drwxrwxr-x 3 netsw users 512 Jul 9 03:24 Misc/
drwxrwxr-x 9 netsw users 512 Aug 1 16:33 Network/
drwxrwxr-x 2 netsw users 512 Jul 9 05:53 Office/
drwxrwxr-x 7 netsw users 512 Jul 9 09:24 SoftEng/
drwxrwxr-x 7 netsw users 512 Jul 9 12:17 System/
drwxrwxr-x 12 netsw users 512 Aug 3 20:15 Typesetting/
drwxrwxr-x 10 netsw users 512 Jul 9 14:08 X11/

1996 年7月,我决定通过一个漂亮的Web接口公开我的收藏。“漂亮”是指提供一个接口以直接浏览整个目录结构,同时不对这个结构做任何改变 - 甚至也不在结构顶部放置CGI脚本。为什么呢?因为这个结构还要能够被FTP访问,而且我不希望其中有任何Web或者CGI的成分。

方案:
这个方案分为两个部分:第一个部分,是用于在空闲时间建立所有目录页面的CGI脚本集。我把它们放在/e/netsw/.www/,如下:

代码:
-rw-r--r-- 1 netsw users 1318 Aug 1 18:10 .wwwacl
drwxr-xr-x 18 netsw users 512 Aug 5 15:51 DATA/
-rw-rw-rw- 1 netsw users 372982 Aug 5 16:35 LOGFILE
-rw-r--r-- 1 netsw users 659 Aug 4 09:27 TODO
-rw-r--r-- 1 netsw users 5697 Aug 1 18:01 netsw-about.html
-rwxr-xr-x 1 netsw users 579 Aug 2 10:33 netsw-access.pl
-rwxr-xr-x 1 netsw users 1532 Aug 1 17:35 netsw-changes.cgi
-rwxr-xr-x 1 netsw users 2866 Aug 5 14:49 netsw-home.cgi
drwxr-xr-x 2 netsw users 512 Jul 8 23:47 netsw-img/
-rwxr-xr-x 1 netsw users 24050 Aug 5 15:49 netsw-lsdir.cgi
-rwxr-xr-x 1 netsw users 1589 Aug 3 18:43 netsw-search.cgi
-rwxr-xr-x 1 netsw users 1885 Aug 1 17:41 netsw-tree.cgi
-rw-r--r-- 1 netsw users 234 Jul 30 16:35 netsw-unlimit.lst


其中的DATA/子目录包含了上述目录结构,即实在的net.sw,由rdist在需要的时候自动更新。第二个部分的遗留问题是:如何连接这两个结构为一个平滑观感的URL树?我希望在运行适当的CGI脚本而使用各种URL的时候,使用户感觉不到DATA/目录的存在。方案如下:首先,我把下列配置放在服务器上DocumentRoot中的针对目录的配置文件里,以重写公布的URL /net.sw/ 为内部路径 /e/netsw:

代码:
RewriteRule ^net.sw$ net.sw/ [R]
RewriteRule ^net.sw/(.*)$ e/netsw/$1


第一条规则是针对遗漏后缀斜杠的请求的!第二条规则才是真正实现功能的。接着,就是放在针对目录的配置文件/e/netsw/.www/.wwwacl中的杀手级的配置了:

代码:
Options ExecCGI FollowSymLinks Includes MultiViews

RewriteEngine on

# we are reached via /net.sw/ prefix
RewriteBase /net.sw/

# first we rewrite the root dir to
# the handling cgi script
RewriteRule ^$ netsw-home.cgi [L]
RewriteRule ^index\.html$ netsw-home.cgi [L]

# strip out the subdirs when
# the browser requests us from perdir pages
RewriteRule ^.+/(netsw-[^/]+/.+)$ $1 [L]

# and now break the rewriting for local files
RewriteRule ^netsw-home\.cgi.* - [L]
RewriteRule ^netsw-changes\.cgi.* - [L]
RewriteRule ^netsw-search\.cgi.* - [L]
RewriteRule ^netsw-tree\.cgi$ - [L]
RewriteRule ^netsw-about\.html$ - [L]
RewriteRule ^netsw-img/.*$ - [L]

# anything else is a subdir which gets handled
# by another cgi script
RewriteRule !^netsw-lsdir\.cgi.* - [C]
RewriteRule (.*) netsw-lsdir.cgi/$1


阅读提示:

注意前半部分中的标志L(最后),和无对应项('-')
注意后半部分中的符号!(非),和标志C (链)
注意最后一条规则的全匹配模式
代码:
NCSA imagemap和Apache mod_imap
说明:
许多人都希望在从NCSA网站服务器向较现代的Apache网站服务器转移中实现平滑过渡,即希望老的NCSA imagemap程序能在Apache的较现代的mod_imap支持下正常运作。但问题在于,到处都是通过/cgi-bin/imagemap /path/to/page.map引用imagemap程序的连接,而在Apache下,应该写成/path/to/page.map。

方案:
使用全局规则在空闲时间去除所有这些请求的前缀:

代码:
RewriteEngine on
RewriteRule ^/cgi-bin/imagemap(.*) $1 [PT]


在多个目录中搜索页面
说明:
有时会有必要使网站服务器在多个目录中搜索页面,对此,MultiViews或者其他技术无能为力。

方案:
编制一个明确的规则集以搜索目录中的文件。

代码:
RewriteEngine on

# first try to find it in custom/...
# ...and if found stop and be happy:
RewriteCond /your/docroot/dir1/%{REQUEST_FILENAME} -f
RewriteRule ^(.+) /your/docroot/dir1/$1 [L]

# second try to find it in pub/...
# ...and if found stop and be happy:
RewriteCond /your/docroot/dir2/%{REQUEST_FILENAME} -f
RewriteRule ^(.+) /your/docroot/dir2/$1 [L]

# else go on for other Alias or ScriptAlias directives,
# etc.
RewriteRule ^(.+) - [PT]


按照URL的片段设置环境变量
说明:
如果希望保持请求之间的状态信息,但又不希望使用CGI来包装所有页面,而只通过分离URL中的有用信息来编码。

方案:
可以用一个规则集来分离出状态信息,并设置环境变量以备此后用于XSSI或CGI。如此,一个/foo/S=java/bar/的URL会被解析为/foo/bar/,而环境变量STATUS则被设置为"java"。

代码:
RewriteEngine on
RewriteRule ^(.*)/S=([^/]+)/(.*) $1/$3 [E=STATUS:$2]


虚拟用户主机
说明:
如果需要为用户username支持一个www.username.host.domain.com的主页,但不是用在此机器上建虚拟主机的方法,而是用仅在此机器上增加一个DNS记录的方法实现。

方案:
对HTTP/1.0的请求,这是无法实现的;但是对HTTP/1.1的在HTTP头中包含有主机名的请求,可以用以下规则集来内部地重写http://www.username.host.com/anypath为/home/username/anypath:

代码:
RewriteEngine on
RewriteCond %{HTTP_HOST} ^www\.[^.]+\.host\.com$
RewriteRule ^(.+) %{HTTP_HOST}$1 [C]
RewriteRule ^www\.([^.]+)\.host\.com(.*) /home/$1$2


为外来访问者重定向宿主目录
说明:
对不是来自本地域ourdomain.com的外来访问者的请求,重定向其宿主目录URL到另一个网站服务器www.somewhere.com,有时这种做法也会用在虚拟主机的上下文中。

方案:
只须一个重写条件:

代码:
RewriteEngine on
RewriteCond %{REMOTE_HOST} !^.+\.ourdomain\.com$
RewriteRule ^(/~.+) http://www.somewhere.com/$1 [R,L]


重定向失败的URL到其他网站服务器
说明:
如何重写URL以重定向对网站服务器A的失败请求到服务器B,是一个常见的问题。一般,可以用Perl写的CGI脚本通过ErrorDocument来解决,此外,还有mod_rewrite方案。但是须注意,这种方法的执行效率不如用ErrorDocument的CGI脚本!

方案:
第一种方案,有最好的性能而灵活性欠佳,出错概率小所以安全:

代码:
RewriteEngine on
RewriteCond /your/docroot/%{REQUEST_FILENAME} !-f
RewriteRule ^(.+) http://webserverB.dom/$1


但是其问题在于,它只对位于DocumentRoot中的页面有效。虽然可以增加更多的条件(比如同时还处理宿主目录,等等),但是还有一个更好的方法:

代码:
RewriteEngine on
RewriteCond %{REQUEST_URI} !-U
RewriteRule ^(.+) http://webserverB.dom/$1


这种方法使用了mod_rewrite提供的“向前参照(look-ahead)”的功能,是一种对所有URL类型都有效而且安全的方法。但是,对网站服务器的性能会有影响,所以如果网站服务器有一个强大的CPU,那就用这个方法。而在慢速机器上,可以用第一种方法,或者用性能更好的 ErrorDocument CGI脚本。

扩展的重定向
说明:
有时候,我们会需要更多的对重定向URL的(有关字符转义机制方面的)控制。通常,Apache内核中的URL转义函数uri_escape()同时还会对anchor转义,即,类似"url#anchor"的URL,因此,你不能用mod_rewrite对此类URL直接重定向。那么如何实现呢?

方案:
必须用NPH-CGI脚本使它自己重定向,因为对NPH(non-parseable headers [无须解析的HTTP头])不会发生转义操作。首先,在针对服务器的配置中(应该位于所有重写规则的最后),引入一种新的URL类型xredirect::

代码:
RewriteRule ^xredirect:(.+) /path/to/nph-xredirect.cgi/$1 \
[T=application/x-httpd-cgi,L]


以强制所有带xredirect:前缀的URL被传送到如下的nph-xredirect.cgi程序:

代码:
#!/path/to/perl
##
## nph-xredirect.cgi -- NPH/CGI script for extended redirects
## Copyright (c) 1997 Ralf S. Engelschall, All Rights Reserved.
##

$| = 1;
$url = $ENV{'PATH_INFO'};

print "HTTP/1.0 302 Moved Temporarily\n";
print "Server: $ENV{'SERVER_SOFTWARE'}\n";
print "Location: $url\n";
print "Content-type: text/html\n";
print "\n";
print "\n";
print "\n";
print "\n";
print "\n";
print "\n";
print "
Moved Temporarily (EXTENDED)
\n";
print "The document has moved here.

\n";
print "\n";
print "\n";

##EOF##


这是一种可以重定向所有URL类型的方法,包括不被mod_rewrite直接支持的类型。所以,还可以这样重定向news:newsgroup:

代码:
RewriteRule ^anyurl xredirect:news:newsgroup


注意:无须对上述规则加[R]或[R,L],因为xredirect:会在稍后被其特殊的传送规则扩展。
文档访问的多路复用
说明:
你知道http://www.perl.com/CPAN的CPAN(Comprehensive Perl Archive Network)吗?它实现了一个重定向以提供,全世界的CPAN镜像中离访问者最近的一个FTP站点,也可以称之为FTP访问多路复用服务。CPAN是通过CGI脚本实现的,那么用mod_rewrite如何实现呢?

方案:
首先,我们注意到mod_rewrite从3.0.0版本开始,还可以重写"ftp:"类型。其次,对客户端顶级域名的路径最近的求取可以用RewriteMap实现。利用链式规则集,并用顶级域名作为查找多路复用地图的键,可以这样做:

代码:
RewriteEngine on
RewriteMap multiplex txt:/path/to/map.cxan
RewriteRule ^/CxAN/(.*) %{REMOTE_HOST}::$1 [C]
RewriteRule ^.+\.([a-zA-Z]+)::(.*)$ ${multiplex:$1|ftp.default.dom}$2 [R,L]

##
## map.cxan -- Multiplexing Map for CxAN
##

de ftp://ftp.cxan.de/CxAN/
uk ftp://ftp.cxan.uk/CxAN/
com ftp://ftp.cxan.com/CxAN/
:
##EOF##

依赖于时间的重写
说明:
在页面内容依时间不同而变化的场合,比如重定向特定页面,许多网管仍然采用CGI脚本的方法,如何用mod_rewrite来实现呢?

方案:
有许多类似TIME_xxx的变量可以用在重写条件中,利用STRING和=STRING的类型比较,并加以连接,就可以实现依赖于时间的重写:

代码:
RewriteEngine on
RewriteCond %{TIME_HOUR}%{TIME_MIN} >0700
RewriteCond %{TIME_HOUR}%{TIME_MIN} <1900 RewriteRule ^foo\.html$ foo.day.html RewriteRule ^foo\.html$ foo.night.html


此例使URL foo.html在07:00-19:00时指向foo.day.html,而在其余时间,则指向foo.night.html,对主页是一个不错的功能...

对YYYY过渡为XXXX的向前兼容
说明:
在转变了大批.html文件为.phtml,使文档.YYYY过渡成为文档.XXXX后,如何保持URL的向前兼容(仍然虚拟地存在)?

方案:
只须按基准文件名重写,并测试带有新的扩展名的文件是否存在,如果存在,则用新的,否则,仍然用原来的。

代码:
# backward compatibility ruleset for
# rewriting document.html to document.phtml
# when and only when document.phtml exists
# but no longer document.html
RewriteEngine on
RewriteBase /~quux/
# parse out basename, but remember the fact
RewriteRule ^(.*)\.html$ $1 [C,E=WasHTML:yes]
# rewrite to document.phtml if exists
RewriteCond %{REQUEST_FILENAME}.phtml -f
RewriteRule ^(.*)$ $1.phtml [S=1]
# else reverse the previous basename cutout
RewriteCond %{ENV:WasHTML} ^yes$
RewriteRule ^(.*)$ $1.html



内容的处理
新旧URL(内部的)
说明:
假定已经把文件bar.html改名为foo.html,需要对老的URL向前兼容,即让用户仍然可以使用老的URL,而感觉不到文件被改名了。

方案:
通过以下规则内部地重写老的URL为新的:

代码:
RewriteEngine on
RewriteBase /~quux/
RewriteRule ^foo\.html$ bar.html


新旧URL(外部的)
说明:
仍然假定已经把文件bar.html改名为foo.html,需要对老的URL向前兼容,但是要让用户得到文件被改名的暗示,即,其浏览器的地址栏中显示的是新的URL。

方案:
作一个HTTP的强制重定向以改变浏览器和用户界面上的显示:

代码:
RewriteEngine on
RewriteBase /~quux/
RewriteRule ^foo\.html$ bar.html [R]


依赖于浏览器的内容
说明:
至少对重要的顶级页面,有时候有必要提供依赖于浏览器的最佳的内容,即对最新的Netscape提供最大化的版本,对Lynx提供最小化的版本,而对其他的浏览器则提供一个功能一般的版本。

方案:
对此,内容协商无能为力,因为浏览器不提供其那种形式的类型,所以只能在HTTP头"User-Agent"上想办法。以下规则集可以完成这个操作:如果 HTTP头"User-Agent"以"Mozilla/3"开头,则页面foo.html被重写为foo.NS.html,而后重写操作终止;如果是"Lynx"或者版本号为1和2的"Mozilla",则重写为foo.20.html;而其他所有的浏览器收到的页面则是foo.32.html:

代码:
RewriteCond %{HTTP_USER_AGENT} ^Mozilla/3.*
RewriteRule ^foo\.html$ foo.NS.html [L]

RewriteCond %{HTTP_USER_AGENT} ^Lynx/.* [OR]
RewriteCond %{HTTP_USER_AGENT} ^Mozilla/[12].*
RewriteRule ^foo\.html$ foo.20.html [L]

RewriteRule ^foo\.html$ foo.32.html [L]


动态镜像
说明:
假定,需要在我们的名称空间里加入其他远程主机的页面。对FTP服务器,可以用mirror程序以在本地机器上维持一个对远程数据的最新的拷贝;对网站服务器,可以用类似的用于HTTP的webcopy程序。但这两种技术都有一个主要的缺点:此本地拷贝必须通过这个程序的执行来更新。所以,比较好的方法是,不采用静态镜像,而采用动态镜像,即,在有数据请求时自动更新(远程主机上更新的数据)。

方案:
为此,使用Proxy Throughput功能(flag [P]),以映射远程页面甚至整个远程网络区域到我们的名称空间:

代码:
RewriteEngine on
RewriteBase /~quux/
RewriteRule ^hotsheet/(.*)$ http://www.tstimpreso.com/hotsheet/$1 [P]

RewriteEngine on
RewriteBase /~quux/
RewriteRule ^usa-news\.html$ http://www.quux-corp.com/news/index.html [P]


反向动态镜像
说明:
...
方案:
代码:
RewriteEngine on
RewriteCond /mirror/of/remotesite/$1 -U
RewriteRule ^http://www\.remotesite\.com/(.*)$ /mirror/of/remotesite/$1


通过Intranet取得丢失的数据
说明:
这是一种在受防火墙保护的(内部的)Intranet(www2.quux-corp.dom)上保存和维护实际数据,而虚拟地运行企业级(外部的)Internet网站服务器(www.quux-corp.dom)的巧妙的方法。这种方法是外部服务器在空闲时间从内部服务器取得被请求的数据。

方案:
首先,必须确保防火墙对内部服务器的保护,并只允许此外部服务器取得数据。对包过滤(packet-filtering)防火墙,可以如下制定防火墙规则:

代码:
ALLOW Host www.quux-corp.dom Port >1024 --> Host www2.quux-corp.dom Port 80
DENY Host * Port * --> Host www2.quux-corp.dom Port 80


按你的实际配置,只要对上例稍作调整即可。接着,建立通过代理后台获取丢失数据的mod_rewrite规则:

代码:
RewriteRule ^/~([^/]+)/?(.*) /home/$1/.www/$2
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^/home/([^/]+)/.www/?(.*) http://www2.quux-corp.dom/~$1/pub/$2 [P]


负载的均衡
说明:
如何均衡www.foo.com的负载到www[0-5].foo.com(一共是6个服务器)?

方案:
这个问题有许多可能的解决方案,在此,我们讨论通称为“基于DNS(DNS-based)的”方案,和特殊的使用mod_rewrite的方案:

DNS循环(DNS Round-Robin)
最简单的方法是用BIND的DNS循环特性,只要按惯例设置www[0-9].foo.com的DNS的A(地址)记录,如:

代码:
www0 IN A 1.2.3.1
www1 IN A 1.2.3.2
www2 IN A 1.2.3.3
www3 IN A 1.2.3.4
www4 IN A 1.2.3.5
www5 IN A 1.2.3.6


然后,增加以下各项:

代码:
www IN CNAME www0.foo.com.
IN CNAME www1.foo.com.
IN CNAME www2.foo.com.
IN CNAME www3.foo.com.
IN CNAME www4.foo.com.
IN CNAME www5.foo.com.
IN CNAME www6.foo.com.


注意,上述看起来似乎是错误的,但事实上,它的确是BIND中的一个预期的特性,而且也可以这样用。无论如何,现在www.foo.com已经被解析,BIND可以给出www0-www6 - 虽然每次在次序上会有轻微的置换/循环,客户端的请求可以被分散到各个服务器。可是,这并不是一个优秀的负载均衡方案,因为,DNS解析信息可以被网络中其他名称服务器缓冲,而一旦www.foo.com被解析为wwwN.foo.com,则其后继请求都将被送往www.foo.com。但是最终结果是正确的,因为请求的总量的确被分散到各个服务器了

DNS 负载均衡
一种成熟的基于DNS的负载均衡方法是使用 http://www.stanford.edu/~schemers/docs/lbnamed/lbnamed.html的lbnamed程序,它是一个Perl 5程序,带有若干辅助工具,实现了真正的基于DNS的负载均衡。

代理吞吐循环(Proxy Throughput Round-Robin)
这是一个使用mod_rewrite及其代理吞吐特性的方法。首先,在DNS记录中,将www0.foo.com固定为www.foo.com,如下:

代码:
www IN CNAME www0.foo.com.


其次,将www0.foo.com转换为一个专职代理服务器,即,由这个机器把所有到来的URL通过内部代理分散到另外5个服务器(www1-www5)。为此,必须建立一个规则集,对所有URL调用一个负载均衡脚本lb.pl。

代码:
RewriteEngine on
RewriteMap lb prg:/path/to/lb.pl
RewriteRule ^/(.+)$ ${lb:$1} [P,L]


以下是lb.pl:

代码:
#!/path/to/perl
##
## lb.pl -- load balancing script
##

$| = 1;

$name = "www"; # the hostname base
$first = 1; # the first server (not 0 here, because 0 is myself)
$last = 5; # the last server in the round-robin
$domain = "foo.dom"; # the domainname

$cnt = 0;
while () {
$cnt = (($cnt+1) % ($last+1-$first));
$server = sprintf("%s%d.%s", $name, $cnt+$first, $domain);
print "http://$server/$_";
}

##EOF##

最后的说明:这样有用吗?www0.foo.com似乎也会超载呀?答案是:没错,它的确会超载,但是它超载的仅仅是简单的代理吞吐请求!所有诸如SSI、CGI、ePerl等等的处理完全是由其他机器完成的,这个才是要点。
硬件/TCP循环
还有一个硬件解决方案。Cisco有一个叫LocalDirector的东西,实现了TCP/IP层的负载均衡,事实上,它是一个位于网站集群前端的电路级网关。如果你有足够资金而且的确需要高性能的解决方案,那么可以用这个。

反向代理
说明:
...
方案:
代码:
##
## apache-rproxy.conf -- Apache configuration for Reverse Proxy Usage
##

# server type
ServerType standalone
Listen 8000
MinSpareServers 16
StartServers 16
MaxSpareServers 16
MaxClients 16
MaxRequestsPerChild 100

# server operation parameters
KeepAlive on
MaxKeepAliveRequests 100
KeepAliveTimeout 15
Timeout 400
IdentityCheck off
HostnameLookups off

# paths to runtime files
PidFile /path/to/apache-rproxy.pid
LockFile /path/to/apache-rproxy.lock
ErrorLog /path/to/apache-rproxy.elog
CustomLog /path/to/apache-rproxy.dlog "%{%v/%T}t %h -> %{SERVER}e URL: %U"

# unused paths
ServerRoot /tmp
DocumentRoot /tmp
CacheRoot /tmp
RewriteLog /dev/null
TransferLog /dev/null
TypesConfig /dev/null
AccessConfig /dev/null
ResourceConfig /dev/null

# speed up and secure processing

Options -FollowSymLinks -SymLinksIfOwnerMatch
AllowOverride None


# the status page for monitoring the reverse proxy

SetHandler server-status


# enable the URL rewriting engine
RewriteEngine on
RewriteLogLevel 0

# define a rewriting map with value-lists where
# mod_rewrite randomly chooses a particular value
RewriteMap server rnd:/path/to/apache-rproxy.conf-servers

# make sure the status page is handled locally
# and make sure no one uses our proxy except ourself
RewriteRule ^/apache-rproxy-status.* - [L]
RewriteRule ^(http|ftp)://.* - [F]

# now choose the possible servers for particular URL types
RewriteRule ^/(.*\.(cgi|shtml))$ to://${server:dynamic}/$1 [S=1]
RewriteRule ^/(.*)$ to://${server:static}/$1

# and delegate the generated URL by passing it
# through the proxy module
RewriteRule ^to://([^/]+)/(.*) http://$1/$2 [E=SERVER:$1,P,L]

# and make really sure all other stuff is forbidden
# when it should survive the above rules...
RewriteRule .* - [F]

# enable the Proxy module without caching
ProxyRequests on
NoCache *

# setup URL reverse mapping for redirect reponses
ProxyPassReverse / http://www1.foo.dom/
ProxyPassReverse / http://www2.foo.dom/
ProxyPassReverse / http://www3.foo.dom/
ProxyPassReverse / http://www4.foo.dom/
ProxyPassReverse / http://www5.foo.dom/
ProxyPassReverse / http://www6.foo.dom/

##
## apache-rproxy.conf-servers -- Apache/mod_rewrite selection table
##

# list of backend servers which serve static
# pages (HTML files and Images, etc.)
static www1.foo.dom|www2.foo.dom|www3.foo.dom|www4.foo.dom

# list of backend servers which serve dynamically
# generated page (CGI programs or mod_perl scripts)
dynamic www5.foo.dom|www6.foo.dom


新的MIME类型,新的服务
说明:
网上有许多很技巧的CGI程序,但是用法晦涩,许多网管弃之不用。即使是Apache的MEME类型的动作处理器,也仅仅在CGI程序不需要在其输入中包含特殊URL(PATH_INFO和QUERY_STRINGS)时才很好用。首先,配置一种新的后缀为.scgi(for secure CGI)文件类型,其处理器是很常见的cgiwrap程序。问题是:如果使用同类URL规划(见上述),而用户宿主目录中的一个文件的URL是/u /user/foo/bar.scgi,可是cgiwrap要求的URL的格式是/~user/foo/bar.scgi/,以下规则解决了这个问题:

代码:
RewriteRule ^/[uge]/([^/]+)/\.www/(.+)\.scgi(.*) ...
... /internal/cgi/user/cgiwrap/~$1/$2.scgi$3 [NS,T=application/x-http-cgi]


另外,假设需要使用其他程序:wwwlog(显示access.log中的一个URL子树)和wwwidx(对一个URL子树运行Glimpse),则必须对这些程序提供URL区域作为其操作对象。比如,对/u/user/foo/执行swwidx程序的超链是这样的:

代码:
/internal/cgi/user/swwidx?i=/u/user/foo/


其缺点是,必须同时硬编码超链中的区域和CGI的路径,如果重组了这个区域,就需要花费大量时间来修改各个超链。

方案:
方案是用一个特殊的新的URL格式,自动拼装CGI参数:

代码:
RewriteRule ^/([uge])/([^/]+)(/?.*)/\* /internal/cgi/user/wwwidx?i=/$1/$2$3/
RewriteRule ^/([uge])/([^/]+)(/?.*):log /internal/cgi/user/wwwlog?f=/$1/$2$3


现在,这个搜索到/u/user/foo/的超链简化成了:

代码:
HREF="*"


它会被内部地自动转换为

代码:
/internal/cgi/user/wwwidx?i=/u/user/foo/


如此,可以为使用:log的超链,拼装出调用CGI程序的参数。

从静态到动态
说明:
如何无缝转换静态页面foo.html为动态的foo.cgi,而不为浏览器/用户所察觉。

方案:
只须重写此URL为CGI-script,以强制为可以作为CGI-script运行的正确的MIME类型。如此,对/~quux/foo.html的请求其实会执行/~quux/foo.cgi。

代码:
RewriteEngine on
RewriteBase /~quux/
RewriteRule ^foo\.html$ foo.cgi [T=application/x-httpd-cgi]


空闲时间内的内容协商
说明:
这是一个很难解的功能:动态生成的静态页面,即,它应该作为静态页面发送(从文件系统中读出,然后直接发出去),但是如果它丢失了,则由服务器动态生成。如此,可以静态地提供CGI生成的页面,除非有人(或者是一个cronjob)删除了这些静态页面,而且其内容可以得到更新。

方案:
以下规则集实现这个功能:
代码:
RewriteCond %{REQUEST_FILENAME} !-s
RewriteRule ^page\.html$ page.cgi [T=application/x-httpd-cgi,L]
这样,如果page.html不存在或者文件大小为null,则对page.html的请求会导致page.cgi的运行。其中奥妙在于,page.cgi 是一个将输出写入page.html的(同时也写入STDOUT)的常规的CGI脚本,执行完毕,服务器则将page.html的内容发出。如果网管需要强制更新其内容,只须删除page.html即可(通常由一个cronjob完成)。

自动更新的文档
说明:
建立一个复杂的页面,能够在用编辑器写了一个更新的版本时自动在浏览器上得到刷新,这不是很好吗?这可能吗?

方案:
这是可行的! 这需要综合利用MIME多成分、网站服务器的NPH和mod_rewrite的URL操控特性。首先,建立一个新的URL特性:对在文件系统中更新时需要刷新的所有URL加上:refresh。

代码:
RewriteRule ^(/[uge]/[^/]+/?.*):refresh /internal/cgi/apache/nph-refresh?f=$1


然后,修改URL

代码:
/u/foo/bar/page.html:refresh


以内部地操控此URL

代码:
/internal/cgi/apache/nph-refresh?f=/u/foo/bar/page.html


接着就是NPH-CGI脚本部分了。虽然,人们常说"left as an exercise to the reader"icon_wink.gif,我还是给出答案了。

代码:
#!/sw/bin/perl
##
## nph-refresh -- NPH/CGI script for auto refreshing pages
## Copyright (c) 1997 Ralf S. Engelschall, All Rights Reserved.
##
$| = 1;

# split the QUERY_STRING variable
@pairs = split(/&/, $ENV{'QUERY_STRING'});
foreach $pair (@pairs) {
($name, $value) = split(/=/, $pair);
$name =~ tr/A-Z/a-z/;
$name = 'QS_' . $name;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
eval "\$$name = \"$value\"";
}
$QS_s = 1 if ($QS_s eq '');
$QS_n = 3600 if ($QS_n eq '');
if ($QS_f eq '') {
print "HTTP/1.0 200 OK\n";
print "Content-type: text/html\n\n";
print "&b&ERROR&/b&: No file given\n";
exit(0);
}
if (! -f $QS_f) {
print "HTTP/1.0 200 OK\n";
print "Content-type: text/html\n\n";
print "&b&ERROR&/b&: File $QS_f not found\n";
exit(0);
}

sub print_http_headers_multipart_begin {
print "HTTP/1.0 200 OK\n";
$bound = "ThisRandomString12345";
print "Content-type: multipart/x-mixed-replace;boundary=$bound\n";
&print_http_headers_multipart_next;
}

sub print_http_headers_multipart_next {
print "\n--$bound\n";
}

sub print_http_headers_multipart_end {
print "\n--$bound--\n";
}

sub displayhtml {
local($buffer) = @_;
$len = length($buffer);
print "Content-type: text/html\n";
print "Content-length: $len\n\n";
print $buffer;
}

sub readfile {
local($file) = @_;
local(*FP, $size, $buffer, $bytes);
($x, $x, $x, $x, $x, $x, $x, $size) = stat($file);
$size = sprintf("%d", $size);
open(FP, "&$file");
$bytes = sysread(FP, $buffer, $size);
close(FP);
return $buffer;
}

$buffer = &readfile($QS_f);
&print_http_headers_multipart_begin;
&displayhtml($buffer);

sub mystat {
local($file) = $_[0];
local($time);

($x, $x, $x, $x, $x, $x, $x, $x, $x, $mtime) = stat($file);
return $mtime;
}

$mtimeL = &mystat($QS_f);
$mtime = $mtime;
for ($n = 0; $n & $QS_n; $n++) {
while (1) {
$mtime = &mystat($QS_f);
if ($mtime ne $mtimeL) {
$mtimeL = $mtime;
sleep(2);
$buffer = &readfile($QS_f);
&print_http_headers_multipart_next;
&displayhtml($buffer);
sleep(5);
$mtimeL = &mystat($QS_f);
last;
}
sleep($QS_s);
}
}

&print_http_headers_multipart_end;

exit(0);

##EOF##
大型虚拟主机
说明:
Apache的功能很强,在有几十个虚拟主机的情况下运行得很好,但是如果你是ISP,需要提供几百个虚拟主机,那么这就不是一个最佳的选择了。

方案:
为此,需要用代理吞吐(Proxy Throughput)功能(flag [P])映射远程页面甚至整个远程网络区域到自己的名称空间:

代码:
##
## vhost.map
##
www.vhost1.dom:80 /path/to/docroot/vhost1
www.vhost2.dom:80 /path/to/docroot/vhost2
:
www.vhostN.dom:80 /path/to/docroot/vhostN

代码:
##
## httpd.conf
##
:
# use the canonical hostname on redirects, etc.
UseCanonicalName on

:
# add the virtual host in front of the CLF-format
CustomLog /path/to/access_log "%{VHOST}e %h %l %u %t \"%r\" %>s %b"
:

# enable the rewriting engine in the main server
RewriteEngine on

# define two maps: one for fixing the URL and one which defines
# the available virtual hosts with their corresponding
# DocumentRoot.
RewriteMap lowercase int:tolower
RewriteMap vhost txt:/path/to/vhost.map

# Now do the actual virtual host mapping
# via a huge and complicated single rule:
#
# 1. make sure we don't map for common locations
RewriteCond %{REQUEST_URL} !^/commonurl1/.*
RewriteCond %{REQUEST_URL} !^/commonurl2/.*
:
RewriteCond %{REQUEST_URL} !^/commonurlN/.*
#
# 2. make sure we have a Host header, because
# currently our approach only supports
# virtual hosting through this header
RewriteCond %{HTTP_HOST} !^$
#
# 3. lowercase the hostname
RewriteCond ${lowercase:%{HTTP_HOST}|NONE} ^(.+)$
#
# 4. lookup this hostname in vhost.map and
# remember it only when it is a path
# (and not "NONE" from above)
RewriteCond ${vhost:%1} ^(/.*)$
#
# 5. finally we can map the URL to its docroot location
# and remember the virtual host for logging puposes
RewriteRule ^/(.*)$ %1/$1 [E=VHOST:${lowercase:%{HTTP_HOST}}]
:


对访问的限制
阻止Robots
说明:
如何阻止一个完全匿名的robot取得特定网络区域的页面?一个/robots.txt文件可以包含若干"Robot Exclusion Protocol(robot排除协议)"的行,但不足以阻止此类robot。

方案:
可以用一个规则集以拒绝对网络区域/~quux/foo/arc/(对一个很深的目录区域进行列表可能会使服务器产生很大的负载)的访问。还必须确保仅阻止特定的robot,就是说,仅仅阻止robot访问主机是不够的,这样会同时也阻止了用户访问该主机。为此,就需要对HTTP头的User-Agent信息作匹配。

代码:
RewriteCond %{HTTP_USER_AGENT} ^NameOfBadRobot.*
RewriteCond %{REMOTE_ADDR} ^123\.45\.67\.[8-9]$
RewriteRule ^/~quux/foo/arc/.+ - [F]
阻止内嵌的图片
说明:
假设,http://www.quux-corp.de/~quux/有一些内嵌图片的页面,这些图片很好,所以就有人用超链连到他们自己的页面中了。由于这样徒然增加了我们的服务器的流量,因此,我们不愿意这种事情发生。

方案:
虽然,我们不能100%地保护这些图片不被写入别人的页面,但至少可以对发出HTTP Referer头的浏览器加以限制。

代码:
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http://www.quux-corp.de/~quux/.*$ [NC]
RewriteRule .*\.gif$ - [F]

RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !.*/foo-with-gif\.html$
RewriteRule ^inlined-in-foo\.gif$ - [F]


对主机的拒绝
说明:
如何拒绝一批外部列表中的主机对我们服务器的使用?

方案:
代码:
For Apache >= 1.3b6:

RewriteEngine on
RewriteMap hosts-deny txt:/path/to/hosts.deny
RewriteCond ${hosts-deny:%{REMOTE_HOST}|NOT-FOUND} !=NOT-FOUND [OR]
RewriteCond ${hosts-deny:%{REMOTE_ADDR}|NOT-FOUND} !=NOT-FOUND
RewriteRule ^/.* - [F]

For Apache <= 1.3b6: RewriteEngine on RewriteMap hosts-deny txt:/path/to/hosts.deny RewriteRule ^/(.*)$ ${hosts-deny:%{REMOTE_HOST}|NOT-FOUND}/$1 RewriteRule !^NOT-FOUND/.* - [F] RewriteRule ^NOT-FOUND/(.*)$ ${hosts-deny:%{REMOTE_ADDR}|NOT-FOUND}/$1 RewriteRule !^NOT-FOUND/.* - [F] RewriteRule ^NOT-FOUND/(.*)$ /$1

代码:
##
## hosts.deny
##
## ATTENTION! This is a map, not a list, even when we treat it as such.
## mod_rewrite parses it for key/value pairs, so at least a
## dummy value "-" must be present for each entry.
##

193.102.180.41 -
bsdti1.sdm.de -
192.76.162.40 -

对代理的拒绝
说明:
如何拒绝某个主机或者来自特定主机的用户使用Apache代理?

方案:
首先,要确保Apache网站服务器在编译时配置文件中mod_rewrite在mod_proxy的下面(!),使它在mod_proxy之前被调用。然后,如下拒绝某个主机...

代码:
RewriteCond %{REMOTE_HOST} ^badhost\.mydomain\.com$
RewriteRule !^http://[^/.]\.mydomain.com.* - [F]

...如下拒绝user@host-dependent:

代码:
RewriteCond %{REMOTE_IDENT}@%{REMOTE_HOST} ^badguy@badhost\.mydomain\.com$
RewriteRule !^http://[^/.]\.mydomain.com.* - [F]


特殊的认证
说明:
有时候,会需要一种非常特殊的认证,即,对一组明确指定的用户,允许其访问,而没有(在使用mod_access的基本认证方法时可能会出现的)任何提示。

方案:
可是使用一个重写条件列表来排除所有的朋友:

代码:
RewriteCond %{REMOTE_IDENT}@%{REMOTE_HOST} !^friend1@client1.quux-corp\.com$
RewriteCond %{REMOTE_IDENT}@%{REMOTE_HOST} !^friend2@client2.quux-corp\.com$
RewriteCond %{REMOTE_IDENT}@%{REMOTE_HOST} !^friend3@client3.quux-corp\.com$
RewriteRule ^/~quux/only-for-friends/ - [F]


基于提交者(Referer)的反射器
说明:
如何配置一个基于HTTP头"Referer"的反射器以反射到任意数量的提交页面?

方案:
使用这个很技巧的规则集...

代码:
RewriteMap deflector txt:/path/to/deflector.map

RewriteCond %{HTTP_REFERER} !=""
RewriteCond ${deflector:%{HTTP_REFERER}} ^-$
RewriteRule ^.* %{HTTP_REFERER} [R,L]

RewriteCond %{HTTP_REFERER} !=""
RewriteCond ${deflector:%{HTTP_REFERER}|NOT-FOUND} !=NOT-FOUND
RewriteRule ^.* ${deflector:%{HTTP_REFERER}} [R,L]


... 并结合对应的重写地图:

代码:
##
## deflector.map
##

http://www.badguys.com/bad/index.html -
http://www.badguys.com/bad/index2.html -
http://www.badguys.com/bad/index3.html http://somewhere.com/

它可以自动将请求(在地图中指定了"-"值的时候)反射回其提交页面,或者(在地图中URL有第二个参数时)反射到一个特定的URL。


其他
外部重写引擎
说明:
一个常见的问题: 如何解决似乎无法用mod_rewrite解决的FOO/BAR/QUUX/之类的问题?

方案:
可以使用一个与RewriteMap功能相同的外部RewriteMap程序,一旦它在Apache启动时被执行,则从STDIN接收被请求的URL,并将处理过(通常是重写过的)的URL(以相同顺序!)在STDOUT输出。

代码:
RewriteEngine on
RewriteMap quux-map prg:/path/to/map.quux.pl
RewriteRule ^/~quux/(.*)$ /~quux/${quux-map:$1}


代码:
#!/path/to/perl

# disable buffered I/O which would lead
# to deadloops for the Apache server
$| = 1;

# read URLs one per line from stdin and
# generate substitution URL on stdout
while (<>) {
s|^foo/|bar/|;
print $_;
}

这是一个作演示的例子,只是把所有的URL /~quux/foo/...重写为/~quux/bar/...,而事实上,可以把它修改以获得任何你需要的功能。但是要注意,虽然一般用户都可以使用,可是只有系统管理员才可以定义这样的地图。

http://www.phpv.net/html/188.html

标签:

星期日, 五月 04, 2008

Lua入门

Lua是一个被设计成用于扩展C/C++编程的轻量级脚本语言。不幸的是,网上很少有关于这个语言的在线教程。我主要通过阅读其源代码来了解它是怎样工作并且通过一些发布的程序学习它。希望,通过下面的教程,会让学习Lua更加简单。

本教程涵盖了Lua5.1。在Lua的每一个版本中都有一些非常不同之处。下面的示例代码将不能在老版本的Lua下运行。如果你仍然在使用老版本而且不愿意升级,不用担心,我已经在文章底部提供了4.0和5.0教程的源代码下载连接。好了,让我们开始吧!

首先,你需要下载Lua。你需要从Lua下载页面去下载源代码。如果你需要编译好了的二进制库,你能在LuaBinaries 中找到你想要的库(lib or dll)。

现在,我们需要安装Lua。在Linux下,你应该先解压文件,然后以root 用户在命令行键入"make linux"和"make linux install"。如果你需要帮助,请参考源代码文件夹中的INSTALL文件。现在,我下载了windows平台下的二进制库包并把它们解压到"C:\ Program Files\lua5.1"。

在Linux下不需要我们做任何设置,但是在windows平台下我们必须配置Visual C++,以便让编译器和连接器找到Lua文件。

  1. 打开Visual C++,选择Tools菜单中的选项菜单。
  2. 展开"项目",并选择"VC++ 目录"。
  3. 选择"包含文件",添加一个新路径"C:\Program Files\lua5.1\include"。
  4. 在选择"库文家",添加路径"C:\Program Files\lua5.1\lib\dll"(这里假设你下载的库为dll,你也可以下载静态链接库)。
  5. 确定。

现在你可以开始编译你的第一个Lua应用了。

使用Lua开始你的第一个程序

这个程序简短且直接,下面做一点说明:

  1. lua_open()返回一个指向Lua解释器的一个指针。
  2. luaL_openlibs()用于装载Lua库,它提供了一些简单的函数,如:print。
  3. 通过调用luaL_dofile()执行脚本。它的作用是读取并解释脚本。
  4. 最后,通过lua_close()函数关闭Lua。

保存文件为luatest.cpp。如果你直接使用C而不是C++,将文件名改为luatest.c,然后将extern "C"删除。

#include 
extern "C" {
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
}
/* Lua解释器指针 */
lua_State* L;
int main ( int argc, char *argv[] )
{
/* 初始化Lua */
L = lua_open();
/* 载入Lua基本库 */
luaL_openlibs(L);
/* 运行脚本 */
luaL_dofile(L, "test.lua");
/* 清除Lua */
lua_close(L);
/* 暂停 */
printf( "Press enter to exit…" );
getchar();
return 0;
}

下面是test.lua的内容。

-- simple test
print "Hello, World!"

编译

在Linux下,在命令行键入:

g++ luatest.cpp -llua -ldl -o luatest

然后,键入下列命令运行:

./luatest

如果没有问题,程序将在终端输出Hello, World!

在Visual C++你将需要进行下列步骤:

  1. 创建一个新的空Win32控制台应用工程。
  2. 将"luatest.cpp"加入你的工程。
  3. 选择项目菜单中的属性菜单。
  4. 在"连接器"的"输入"栏目的"附加依赖项"中输入"lua5.1.lib"。
  5. 确定。

此时,按F7构建程序。

如果你采用的是dll库,请确保将其放在应用程序的目录中或者windows系统能够找到它的地方。如果你采用的是静态连接库,则不需要。 (Groov0V翻译,转载自CSDN)

谢谢这么简洁清晰的表述
g++ luatest.cpp `pkg-config lua5.1 --libs --cflags` -o luates

http://www.wujianrong.com/archives/2007/10/lua.html

标签: ,

脚本语言:LUA简介


Lua 是一个扩展式程序设计语言,它被设计成支持通用的过程式编程,并有相关数据描述的设施。 Lua 也能对面向对象编程,函数式编程,数据驱动式编程提供很好的支持。 它可以作为一个强大、轻量的脚本语言,供任何需要的程序使用。 Lua 以一个用 clean C 写成的库形式提供。(所谓 Clean C ,指的 ANSI C 和 C++ 中共通的一个子集)

作为一个扩展式语言,Lua 没有 "main" 程序的概念:它只能 嵌入 一个宿主程序中工作,这个宿主程序被称作 embedding program 或简称为 host 。 宿主程序可以通过调用函数执行一小段 Lua 代码,可以读写 Lua 变量,可以注入 C 函数让 Lua 代码调用。 这些扩展的 C 函数,可以大大的扩展了 Lua 可以处理事务的领域,这样就可以订制出各种语言, 而它们共享一个统一的句法格式的框架。 Lua 的官方发布版就包含了一个叫做 lua 的简单的宿主程序,它用 Lua 库提供了一个保证独立的 Lua 解释器。

Lua 是一个自由软件,它的使用许可决定了对它的使用过程一般没有任何保证。 这份手册中描述的东西的实现,可以在 Lua 的官方网站 www.lua.org 找到,

跟其它的许多参考手册一样,这份文档有些地方比较枯燥。 关于 Lua 的设计想法的探讨,可以看看 Lua 网站上提供的技术论文。 有关用 Lua 编程的细节介绍,可以读一下 Roberto 的书,Programming in Lua (Second Edition)

http://www.codingnow.com/2000/download/lua_manual.html

标签: , ,

赖勇浩:动态大比拼Python、Lua和Ruby

So which of the three languages is the best to use on your project? That depends a great deal on what you want to accomplish. To wrap up the book, I've outlined some of the pros and cons of each language in this section.
这三种语言中的哪一种更合适你的项目?很大程度取决于你想达到什么样的目标。作为一书的结尾,在这一节里,我会描述一下它们各自的优点和不足。
Python Pros and Cons
Python的优点和不足
The pros of Python are as follows:
Python的优点如下:
· Python has more extension modules than the other languages.
· Python比其它语言有更多扩展模块。
· Many online Python tutorials exist. There are also plenty of English books and reference materials, many sample scripts exist online, and there is a wealth of introductory material. The Python.org Website is a good place to start looking for these because it has sections for beginners, tutorials, guides organized by topic, and lists of links and references.
· 在网上可以找到很多Python教程。不仅如此,还有大量的英文书籍和资料。Python.org有很多为初学者准备的依主题组织的资料、教程和编程指南,此外还有很多链接和参考。
· Most folks really enjoy the syntax of the Python language because it appears clean and is easy to read.
· 很多人都喜欢Python语言的语法,因为它清晰易读。
· Python has an edge where libraries are concerned. There are many libraries, and, for the most part, they are well documented.
· Python在支持库上大占优势,因为它有很多库,而且大部分都有完善的文档支持。
· Lots of tools that tie into Python are available, and they are often easier to find than the tools for Lua and Ruby.
· 很多工具可以用于Python,但难以找到适用于Lua和Ruby的。
The cons of Python are as follows:
Python的不足:
· Existing Python debuggers are considered quirky and slow. Debugging support on Macintosh and consoles is even weaker.
· 现有的Python调试器诡异而且效率低下。在Macintosh(苹果计算机)和控制台下进行调试是一个梦魇。
· It can be difficult to bundle Python with other languages. There are lots of binary DLLs, and Python has (compared to the other languages) a large standard distribution.
· Python难以与其它语言集成,它有太多的二进制DLL,而且Python带了巨大的标准发布包。
· Lots of folks really dislike the white space sensitivity of Python syntax.
· 同样的,也有很多人不喜欢Python对空白符敏感的语法。
· Python can be quite slow at times, as everything is an object on the heap.
· 因为栈上的任何东西都是对象,所以Python有时候会慢得难以忍受。
Lua Pros and Cons
Lua的优点和不足
The pros of Lua are as follows:
Lua的优点:
· Lua is probably the fastest of the three languages and usually uses the least amount of runtime memory.
· Lua在这三种语言中是运行时速度最快而且占内在最少的。
· Lau has the smallest memory footprint for bundling.
· 集成Lua只会增加极少的内存占用率。
· The Lau C API is very well documented and has good examples for integrating with C.
· Lua的C API有着完备着文档和很好的例子,可以容易地通过C集成在软件里。
The cons of Lua are as follows:
Lua的不足:
· The documentation has improved but is still a bit sketchy overall. Of the three languages, Lua it is probably the least documented (the API being the exception), with the least amount of code comments. This makes for the largest ramp-up time to learn, and there isn't much in the way of introductory Lua material.
· 尽管Lua的文档已经增进不少,但仍然有所不足。三种语言中,Lua可能是文档最少的(API方面是个例外),因为代码中极少注释,这也增加了学习的难度。另外,对Lua的本质也没有什么介绍。
· There isn't a lot of built-in functionality for Lua. There is little support if you need to create a large, complex application.
· Lua内建的功能很少,并没有对创建大型的复杂应用程序提供足够支持。
· Lua could use a better garbage collectorthe current development is moving towards that now. Right now, Lua GC uses a very simple and traditional simple mark and sweep.
· Lua应该使用更好的垃圾收集机制,Lua现在的GC仍然使用非常简单而且传统的“标记和清除”方式。
Pros and Cons of Ruby
Ruby的优点和不足
The pros of Ruby are as follows:
Ruby的优点:
· Ruby possesses fairly good advanced debuggers.
· Ruby有极好的高级调试器。
· Ruby is object oriented from the ground up, and programmers who are OOP enthusiasts or who are used to the OOP paradigm will find the language extremely comfortable.
· Ruby是最彻底的面向对象语言,对于OOP狂热者和惯于使用OOP范式的程序员,他们将会发现Ruby是最适合他们的语言。
· Ruby has arguably the simplest syntax, with no real rules exceptions. Especially true for OOP enthusiasts.
· Ruby的语法极为简单,没有让人出乎意料规则,特别适合OOP行家的习惯。
The cons of Ruby are as follows:
Ruby的不足:
· Lack of English documentation.
· 英文文档极度缺乏。
· Fewer existing works and samples for games than with the other languages.
· 与其它语言相比,在游戏方面所作的工作和实例都少得多。

http://soft.zdnet.com.cn/software_zone/2007/0702/415264.shtml

标签: , , ,

sql server 远程访问

在数据库的各种应用程序开发中,连接数据库是数据库应用程序开发的第一步,同时也是最重要的一步。而对于不同的数据库他们的连接模式各有不同,对应的连接串也不同。
程序员可能都有这样的经历,有时不知道连接数据库所需要的连接串究竟如何写或者经常写错而导致不能正确访问数据库。当然很多编程工具能够通过可视化的界面直接产生正确的连接字符串,但字符串中各个参数的具体含义也不清楚,经常混淆。本文就针对大部分常用数据库列举出不同连接方法所需要的连接字符串并加以说明,以便程序员参考!




Sql Server
· ODBC
o 标准连接(Standard Security):
"Driver={SQL Server};Server=Aron1;Database=pubs;Uid=sa;Pwd=asdasd;"
1)当服务器为本地时Server可以使用(local);
"Driver={SQL Server};Server=(local);Database=pubs;Uid=sa;Pwd=asdasd;"
2)当连接远程服务器时,需指定地址、端口号和网络库
"Driver={SQL Server};Server=130.120.110.001;Address=130.120.110.001,1052;Network=dbmssocn;
Database=pubs;Uid=sa;Pwd=asdasd;"
注:Address参数必须为IP地址,而且必须包括端口号
o 信任连接(Trusted connection): (Microsoft Windows NT 集成了安全性)
"Driver={SQL Server};Server=Aron1;Database=pubs;Trusted_Connection=yes;"
或者
"Driver={SQL Server};Server=Aron1;Database=pubs; Uid=;Pwd=;"
o 连接时弹出输入用户名和口令对话框:
Conn.Properties("Prompt") = adPromptAlways
Conn.Open "Driver={SQL Server};Server=Aron1;DataBase=pubs;"
· OLE DB, OleDbConnection (.NET)
o 标准连接(Standard Security):
"Provider=sqloledb;Data Source=Aron1;Initial Catalog=pubs;User Id=sa;Password=asdasd;"
o 信任连接(Trusted connection):
"Provider=sqloledb;Data Source=Aron1;Initial Catalog=pubs;Integrated Security=SSPI;"
(如果连接一个具体的已命名SQLServer实例,使用Data Source=Servere NameInstance Name;但仅适用于 SQLServer2000)例如:”Provider=sqloledb;Data Source=MyServerNameMyInstanceName;Initial Catalog=MyDatabaseName;User Id=MyUsername;Password=MyPassword;”
o 连接时弹出输入用户名和口令对话框:
Conn.Provider = "sqloledb"
Conn.Properties("Prompt") = adPromptAlways
Conn.Open "Data Source=Aron1;Initial Catalog=pubs;"
o 通过IP地址连接:
"Provider=sqloledb;Data Source=190.190.200.100,1433;Network Library=DBMSSOCN;Initial Catalog=pubs;User ID=sa;Password=asdasd;"
(DBMSSOCN=TCP/IP代替Named Pipes, Data Source的末尾是需要使用的端口号(缺省为1433))
· SqlConnection (.NET)
o 标准连接(Standard Security):
"Data Source=Aron1;Initial Catalog=pubs;User Id=sa;Password=asdasd;"
或者
"Server=Aron1;Database=pubs;User ID=sa;Password=asdasd;Trusted_Connection=False"
(这两个连接串的结果相同)
o 信任连接(Trusted connection):
"Data Source=Aron1;Initial Catalog=pubs;Integrated Security=SSPI;"
或者
"Server=Aron1;Database=pubs;Trusted_Connection=True;"
(这两个连接串的结果相同)
(可以用serverNameinstanceName代替Data Source,取值为一个具体的SQLServer实例,但仅适用于 SQLServer2000)
o 通过IP地址连接:
"Data Source=190.190.200.100,1433;Network Library=DBMSSOCN;Initial Catalog=pubs;User ID=sa;Password=asdasd;"
(DBMSSOCN=TCP/IP代替Named Pipes, Data Source的末尾是需要使用的端口号(缺省为1433))
o SqlConnection连接的声明:
C#:
using System.Data.SqlClient;
SqlConnection SQLConn = new SqlConnection();
SQLConn.ConnectionString="my connectionstring";
SQLConn.Open();

VB.NET:
Imports System.Data.SqlClient
Dim SQLConn As SqlConnection = New SqlConnection()
SQLConn.ConnectionString="my connectionstring"
SQLConn.Open()
· Data Shape
o MS Data Shape
"Provider=MSDataShape;Data Provider=SQLOLEDB;Data Source=Aron1;Initial Catalog=pubs;User ID=sa;Password=asdasd;"
· 更多
o 如何定义使用哪个协议
§ 举例:
"Provider=sqloledb;Data Source=190.190.200.100,1433;Network Library=DBMSSOCN;Initial Catalog=pubs;User ID=sa;Password=asdasd;"
名称 网络协议库
dbnmpntw Win32 Named Pipes
dbmssocn Win32 Winsock TCP/IP
dbmsspxn Win32 SPX/IPX
dbmsvinn Win32 Banyan Vines
dbmsrpcn Win32 Multi-Protocol (Windows RPC)
§ 重要提示
当通过SQLOLEDB提供者进行连接时使用以下语法:
Network Library=dbmssocn
但通过MSDASQL提供者进行连接时使用以下语法:
Network=dbmssocn
o 所有SqlConnection连接串属性
§ 下表显示了ADO.NET SqlConnection对象的所有连接串属性. 其中大多数的属性也在ADO中使用.所有属性和描述来自于msdn.
名称 缺省值 描述
Application Name 应用程序名称或者当没有提供应用程序时为.Net SqlClient数据提供者
AttachDBFilename或者extended properties或者Initial File Name 主要文件的名字,包括相关联数据库的全路径。数据库名字必须通过关键字'database'来指定。
Connect Timeout或者Connection Timeout 15 在中止连接请求,产生错误之前等待服务器连接的时间(以秒为单位)
Connection Lifetime 0 当一个连接返回到连接池,当前时间与连接创建时间的差值,如果时间段超过了指定的连接生存时间,此连接就被破坏。它用于聚集设置中在运行服务器和准备上线 的服务器之间强制负载平衡。
Connection Reset 'true' 当连接从连接池移走时决定是否重置数据库连接。当设置为'false'时用于避免获得连接时的额外服务器往复代价。
Current Language SQL Server语言记录名称
Data Source或Server或Address或Addr或Network Address 要连接的SQL Server实例的名字或者网络地址
Enlist 'true' 为真时,连接池自动列出创建线程的当前事务上下文中的连接。
Initial Catalog或Database 数据库名
Integrated Security或者Trusted_Connection 'false' 连接是否为信任连接。其取值为'true', 'false'和'sspi'(等于'true').
Max Pool Size 100 连接池中允许的最大连接数
Min Pool Size 0 连接池中允许的最小连接数
Network Library或Net 'dbmssocn' 网络库用于建立与一个 SQL Server实例的连接。值包括dbnmpntw (命名管道), dbmsrpcn (多协议), dbmsadsn (Apple Talk), dbmsgnet (VIA), dbmsipcn (共享内存) 和 dbmsspxn (IPX/SPX), 和 dbmssocn (TCP/IP). 所连接的系统必须安装相应的动态链接库。如果你没有指定网络,当你使用一个局部的服务器 (例如, "." 或者 "(local)"),将使用共享内存
Packet Size 8192 与 SQL Server的一个实例通讯的网络包字节大小
Password-或Pwd SQL Server帐户登录口令
Persist Security Info 'false' 设置为'false',当连接已经打开或者一直处于打开状态时,敏感性的安全信息 (如口令)不会返回作为连接的一部分信息。
Pooling 'true' 为真时,从合适的连接池中取出SQLConnection对象,或者必要时创建SQLConnection对象并把它增加到合适的连接池中。
User ID SQL Server登录用户
Workstation ID the local computer name 连接到SQL Server的工作站名称
§ 注意:
使用分号分隔每个属性
如果一个名字出现多于两次,在连接串中的最后一次出现的值将被使用。
如果你通过在应用中由用户输入字段的值来构建连接串,你必须保证用户不会通过用户值里的另一个值插入到一个额外的属

性来改变连接串。

http://topic.csdn.net/t/20041223/10/3669416.html

标签: , ,

ZScreen - A Great New Open Source Screen Shot Utility

I've recently come across a great utility for taking screen shots of either your entire desktop or an application window. This program,ZScreen , is packed with features! I find I always need to take screen shots but I find it's always been a pain because not only do I have to take the screen shot, I have to open it in a graphic editor to grab what I need from it, then upload it somewhere. All in all a good screen shot takes me about 2 minutes. I was really excited when i came across this.

Features

Full Screen or Window Screen Shots - With ZScreen you can take either full screen or screens shots of your active window. This comes in handy if you don't want to waste space or image area with unnecessary content. You can currently do this with Windows' build in screen shot feature (Print Screen Key).

Screen Shot Cropping - You also have the ability to crop your screen shots with ZScreen. Using hot keys, your able to take a screen shot then, using your mouse, highlight the area you wish to capture instead of the entire screen or application window. Further giving you freedom to grab just the parts you want.

Editing Your Screen Shot - ZScreen also has the great option to automatically open your favorite graphic editing program to modify or notate the screen shot. This is handy if you need something to be highlighted, pointed out, or easily visibly in anyway. Complete freedom to manipulate your screen shot quickly. Closing / Saving the image automatically saves the screen shot as you've modified it.

Automatic FTP of Your Screen Shot - This is my favorite feature by far. ZScreen allows you to input your settings in the back end control panel for FTP access. If you set this up, your screen shots will be instantly FTP'd to your server of choice. The advanced configuration allows you to set it up to make it as easy as possible allowing you to specify the domain and path that the link will then be created with.

Links Placed In Clipboard - The next great feature is the clipboard addition. With every screen shot you take that is automatically FTP'd to your server / hosting, a link is placed in your clipboard for easy pasting over instant message, IRC, email or wherever you may need it. This allows who ever you send it to the ability to instantly see what you want to show them on your screen.

Hot Keys - You can also setup hot keys for your screen capturing which helps keep things simple by being able to specify between an active window shot or a full screen shot with the ability to crop. For instance, I've mine setup as Shift + Alt+ i

There are many more features that I haven't listed. If you are a person that takes screen shots as often as I do, definitely check this out. It's 100% free and open source. Very good work by my standards and highly recommended.

I absolutely love this application. Since I do the majority of my graphics work in Windows this is a perfect addition to the tools I can't live without. Big thanks to Brandon at BrandonZ.net for creating this.

You can find more information, screen shots, features, and downloads by visiting the ZScreen Page at BrandonZ.net

http://www.alfredfox.com/blog/Software/44/ZScreen_-_A_Great_New_Open_Source_Screen_Shot_Utility

标签: , ,

Flex

Overview of Flex

Flex is a tool for generating scanners. A scanner, sometimes called a tokenizer, is a program which recognizes lexical patterns in text. The flex program reads user-specified input files, or its standard input if no file names are given, for a description of a scanner to generate. The description is in the form of pairs of regular expressions and C code, called rules. Flex generates a C source file named, "lex.yy.c", which defines the function yylex(). The file "lex.yy.c" can be compiled and linked to produce an executable. When the executable is run, it analyzes its input for occurrences of text matching the regular expressions for each rule. Whenever it finds a match, it executes the corresponding C code.

http://flex.sourceforge.net/

标签: , ,

Bison

安装指导参见: the 节 called 安装 Bison-1.875 在 第 6 章.

Bison的内容

Bison 是替代yacc的语法解析器. Bison能生成可以分析文本文件结构的程序.

安装下列程序: bison 和 yacc

安装下列库文件: liby.a

简短说明

bison 是替代yacc的语法分析程序生成器. yacc是 Yet Another Compiler Compiler(又一个编译器的编译器)的缩写.

yacc是bison的包装脚本,实际上是以-y的参数调用bison. 这个是为了和那些用yacc而不是bison的程序兼容.

liby.a 是 Yacc 库,包含了与Yacc兼容的 yyerror 和主要函数。通常这个库没什么用,但 POSIX 要求有它.

Bison 安装依赖关系

Bison 依赖于: Bash, Binutils, Coreutils, Diffutils, GCC, Gettext, Glibc, Grep, M4, Make, Sed.

http://man.chinaunix.net/linux/lfs/htmlbook/appendixa/bison.html

标签: ,

星期六, 五月 03, 2008

ubuntu对技术白痴型女友来说足够易用吗?

译者注:为了测试Linux对并不十分精通技术的人群的易用 性,本文作者让他的女友在一套全新安装的Ubuntu 8.04上完成一些基本的任务。实验的结果显示,很多看似简单的任务对于一个从没有接触过Linux的用户来说似乎还是相当困难,为提高对初学者的友好 性,Ubuntu还有许多可以改进的地方。由于原文比较长,请恕我只翻译了大概的内容,原文请见http://contentconsumer.wordpress ... -for-my-girlfriend/

让女友试用Ubuntu

简介

我从2002年开始倒腾Linux到现在这么多年过来了,我想看看新出的Linux系统是不是对于大部分人来说已经足够易用,于是我让女友Erin用新安 装的Ubuntu 8.04来完成一些基本任务。结果有些令人吃惊,很多看似简单的任务对于过去没有使用Linux经验的人来说依旧非常困难。Linux还有很多需要改进的 地方以使其能给“电脑白痴们”提供更好的用户体验。

Erin具备一些基本的计算机知识,比如上网、打字、制表和照片处理等,这对于一个哲学系大学生来说已经足够了。在用于实验的Ubuntu系统上,我提前 为她设好了帐户。她可以轻松的登录进去,她很喜欢heron(Ubuntu 8.04 Hardy Heron)的壁纸。接着我便将设计好的任务一一让她完成,而我不提供任何帮助。

任务一:告诉我波黑的首都在哪里

Erin很快找到了Firefox的链接,然后在wikipedia上找到了问题的答案:萨拉热窝。

任务二:在YouTube上看视频

(注:这是YouTube所特有的问题,它会主动检测你机器上是否有Flash插件,如果没有,它给出一个Adobe的网页让你去下载。而正常情况下Firefox会自动帮你下载Flash插件。碰巧让我选上了YouTube算是运气不好)

Erin在试图播放YouTube上一段Beatles的视频时,YouTube提示它需要去Adobe官方下载所需的Flash插件,而在 Adobe主页上有.tar.gz、RPM和YUM三种格式的包。RPM和YUM显然无法在Ubuntu上使用。Erin点击了.tar.gz包中的 flashplayer-install也没有任何反应,因为这个程序只能在terminal下运行。最终Erin无法完成这个任务。(译者 注:YouTube好心帮了倒忙)

任务三:下载一部辣妹的专辑

Erin的第一反应就是去在应用程序菜单中找Limeware的替代品,接着她还尝试运行Windows版的uTorrent,结果均告失败。然后她找到 了一个下载BitTorrent种子文件的网站,点击了一个辣妹专辑的torrent文件之后,Firefox提示是否要用Transmission打开 此文件。Erin犹豫了一下,点了确定,很快这部专辑便被下载到了她的桌面。

我觉得这里唯一的问题是Firefox所提示软件的名称,如果提示是“是否用Transmission BT客户端打开此文件”,那么可以减少很多麻烦。(译者注:在应用程序菜单中就是用的“Transmission BT客户端”这样比较易懂的名称,当然要是不知道BitTorrent是什么,看这个名字还是云里雾里的,类似的名称问题在任何系统中都是无法避免的)

任务四:画一副图,并保存为3种不同的格式

Erin很快在“图像”菜单中找到了“OpenOffice.org绘图”,与她所期待的一个类似Windows的简易画图软件不同, “OpenOffice.org绘图”是一个非常复杂的矢量绘图软件。最终她完成了任务,不过她不知道用“导出”命令将图片转换为熟悉的格式,而是用了 “另存为...”将图片存成了的.odg、.otg和.sxg格式。我无法理解为什么Ubuntu不提供一个像KPaint一样简单的画图程序。(同时我 也奇怪为什么OpenOffice.org绘图会在标准安装里,我从没见过谁用过这样的程序)(译者注:无语,我就在用,它实际上是OOo很重要的一个组 成部分,和“Microsoft Word 图片”控件很类似。另外我还在用看上去更不可理喻的Xfig,相反KPaint一类的画图软件对我倒是毫无用处)

任务五:从我的音乐收藏中找一首专辑,并将其刻录到CD上

Erin找到了“Brasero光盘刻录程序”,它的界面很不错。但当Brasero提示添加所要刻录的歌曲的时候,Erin却找不到存放音乐的 Windows分区。她找了Ubuntu默认建立的Music目录,Home目录和桌面,但是错过了"492.8GB Media",也就是那个Windows分区,她也没有仔细去看“文件系统”,那里面怪异的名称让她望而却步。之后她在“位置”菜单中找到了搜索程序,但 她只尝试了搜索Home目录和Music目录,而没有试“文件系统”。后来她告诉我那个程序不能根据文件类型搜索,实在是太笨了。

Ubunbu应该更清楚的显示其他分区在什么地方,分区的快捷方式也应该使用更有意义的名称。另外,搜索程序应该增加一个搜索“整个电脑”的选项以替代“ 文件系统”。没有经验的用户很难搞清楚“etc”、“dev”和“mnt”等等目录是干什么的。(译者注:作者有点吹毛求疵了。我认为Ubuntu在这方 面已经非常尽力了,如果分区有卷标的话,那个分区快捷方式的名称将使用卷表名,如没有则显示存储容量,U盘没有挂载的时候显示的则是生产厂商的名称和容 量。另外,也许“整个电脑”对于新手来说更为容易理解,不过“文件系统”这个术语在这里要准确得多,特别是考虑到有虚拟挂载点、网络挂载点时候)

任务六:改变鼠标的速度

没啥问题,她很快就搞定了

任务七:改变电脑的主题

也很轻松就弄好了

任务八:在网上找一幅图片,将其设为桌面

Firefox的右键菜单中没有将图片直接“设置为背景”的功能。不过她还是顺利解决了。

任务九:改变屏幕分辨率

她在系统属性菜单中找到了屏幕分辨率设置程序,并将分辨率改为720x400。然而,由于这个分辨率太低,使她无法看到设置程序最下方的确定按钮,也就没 有办法把分辨率调回原来的设置。最后我只好在看不见的情况下用tab键切换到确定按钮上。如果屏幕分辨率很低,这个程序根本没法使用。(译者注:这确实是 Ubuntu/Gnome需要改进的地方,如果这个设置程序最上方有个菜单可能能避免不少类似的问题。考虑到这是Ubuntu第一次使用此程序,有点这样 的小毛病也情有可原,实际上Windows也同样的问题。目前有一个凑合的办法,按Alt-F7,然后再按方向键,可以将窗口上移)

任务十:将她的头像PS到我的照片上

她通过右键菜单用GIMP打开了我们俩各自的照片。她有一些Photoshop的基础,而GIMP的不同风格界面使她有点迷惑,度过了开始一段不适应之 后,她还是完成了任务。我不明白为什么GIMP的排版布局不能像Photoshop一样呢。(译者注:我不是GIMP或者Photoshop的专家,不敢 在这个总是引发口水仗争议问题上乱发言,不过我个人觉得,在多桌面、多显示器的环境下,GIMP的界面布局还是有它的合理性的。而作为免费的非专业照片处 理软件,GIMP的功能也不错了)

任务十一:登录MSN

Erin在应用程序菜单中的互联网子菜单里找到了“Pidgin即时通讯软件”。她问我这个是否就是MSN,我回答不完全是,于是她打开了Pidgin。 当Pidgin提示她增加一个帐户的时候,她被帐户设置里选项所迷惑,比如“screen name”、“local alias”,这些术语在她所熟悉的MSN中从没有出现过。经历了好几次失败的尝试之后,Erin终于登录上了MSN,这也让她可以向朋友们诉苦 Linux有多讨厌。

如果Pidgin有一个欢迎窗口告诉用户Pigin是做什么的,并询问是否要增加或登陆MSN等帐号,那么Erin的问题就很容易解决。如果 “screen name”能根据不同类型的协议使用不同的术语,那也会很有帮助。另外,“local alias”是具体做什么的也给新手造成了很多困惑。

当Erin试图退出Pidgin的时候,她以为直接点右上角的关闭按钮即可,但实际上Pidgin退到了屏幕右上角的系统提示区。Erin又花了一些时间 才找到那个图标。当你第一次关闭Pidgin的时候,它应该提示这个程序并没有真正退出,而只是缩到了系统提示区。(译者注:作者的这几个建议非常好,用 了很久的Pidgin/Gaim之后,我都有些忘记了最开始的一些挣扎,其实开始我也遇到过弄不清screen name/local alias/friendly name具体意义的情况,如果Pidgin能做一个wizard来添加IM协议,那可以大大方便初学者,我印象中好像有些Pidgin/Gaim的变种就 有这样的功能,希望Pidgin也能采用)

任务十二:安装Skype

Erin去了skype.com,很容易就找到了适合Ubuntu的.deb安装包,并顺利安装。唯一的问题是,她不知道Skype装到哪里去了,不知什么原因,她没有去看网络程序菜单。如果有像Windows一样提示“有新程序安装”就可以解决这个问题了。

结论

Ubuntu桌面体验的最主要问题是程序设计者对一般用户的水平做出了太高的假设。他们假设用户知道程序是怎么安装或者知道文件系统是怎样构架。而普通用 户遇到问题是不会去google搜寻帮助或者去读Ubuntu自带的相关文档的。一些简单的信息提示和向导可以对用户完成一些任务有关键性的帮助。

我希望一登录进入桌面就能看到一个欢迎画面,上面有一些小的视频解释Linux和Ubuntu的基本概念。也许它还可以问“你想做什么?”,然后根据选择去解释具体如何做。

直到一个电脑盲可以坐在Linux系统前不费力气的完成她想做得事情,Linux都不能说已经为桌面应用做好准备。Erin很聪明,学得快,现代科技的知识也算充足。如果她都会有这么大麻烦,那老年人或者中年人还有多少机会呢?

译者注:本文作者对 Linux易用性的某些缺陷的分析很不错,给出的解决方案也相当好,但是他最后的结论我却很难赞同。事实上,Erin能在没有得到作者的任何帮助,也没有 通过网络搜索的情况下完全依赖原有的Windows知识,在一套干净的Ubuntu 8.04上基本完成了所有的任务,这已经标志着Ubuntu易用性设计的很大成功了。计算机系统本身的复杂性就决定了使用新系统的时候所需的学习成本是不 可避免的,就算从WinXP升级到Vista也不可能一帆风顺。这种成本的存在并不能简单归结为Linux系统的易用性差。实际上已经有很多实例反证了作 者的猜想,经过简单的指导,中老年人完全可以顺利的使用一台配置好的Linux系统。

http://bbs.chinaunix.net/thread-1090939-1-1.html

肯定的是,本文作者是在假定用户为熟练Windows用户的情况下做的。但是现在有几个没用呢?

标签: ,

AjaxChess:中国象棋游戏在线玩

AjaxChess:中国象棋游戏在线玩
2007-06-11 Toy Posted in AppsRSSTrackback
AjaxChess 是一款基于 Ajax 技术而构建的在线中国象棋游戏,该游戏支持拖曳操作,具有动画效果,不需要任何插件。无论你使用 Windows,还是 Linux,亦或 Mac OS 系统,都可以玩此游戏。而且,这个游戏支持目前的 IE、Firefox、Opera、Safari 等 Web 浏览器。
screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmousewheel="return imgzoom(this);" alt="" border="0">
各位棋迷朋友值得去试试 screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmousewheel="return imgzoom(this);" alt="" border="0">
- http://ajaxchess.pragmaticlogic.com/
Tags: chinese chess, games


http://bbs.chinaunix.net/thread-947541-1-2.html

标签:

星期四, 五月 01, 2008

Ubuntu Tweak 0.3.0正式发布!

上周Ubuntu 8.04 LTS的发布异常热闹,想必大家的Ubuntu都已更新至Ubuntu 8.04了吧?经过一个月的开发和测试,Ubuntu Tweak也发布了其0.3系列的第一个版本:0.3.0,完全支持8.04。推荐所有旧版本的用户更新!


—–
Ubuntu Tweak为在Ubuntu各个版本中取得最佳的兼容性,对代码进了非常大的改动,0.3.0因此而发布。
因为Ubuntu Tweak的开发始于Ubuntu 7.04时代,因此Ubuntu Tweak支持从7.04往后的所有Ubuntu版本,一些新旧版本不同的特性和选项都会智能判断并选择开启或关闭。
另外,由于改善了兼容性,Ubuntu Tweak也能运行在一些基于GNOME的主流发行版上,我仅在Fedora 9Preview上完成测试,并不保证所有功能和特性均能正常运行。这个还需要大家帮助测试。另外我也没有时间为其他发行版制作软件包,这个就要由大家来 做了。
下图显示了Ubuntu Tweak 0.3.0运行在Fedore 9 Preview上:
screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open('http://pic.yupoo.com/tualatrix/699625767893/medium.jpg');}" onmousewheel="return imgzoom(this);" alt="" border="0">
每次Ubuntu Tweak发布新版本,都会有新的特性加入,这次也不例外。
Ubuntu Tweak 0.3.0新增了“快捷键”的设置功能。
在日常应用中,你一定会有一些经常要启动的应用程序吧?何不为它们设定一个快捷键,只要按一下按键,就能启动它们呢?
Ubuntu Tweak 0.3.0就提供了这样一个统一且简易的界面来设定快捷键。输入启动该程序的命令,再自动捕获一个单键或组合键,以后启动该应用程序就能非常快捷啦。
screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open('http://pic.yupoo.com/tualatrix/9772857b4475/vcq9r8e0.jpg');}" onmousewheel="return imgzoom(this);" alt="" border="0">
此外,Ubuntu Tweak修正了大量bug,改善了很多细节部分。这些,就要大家自己去感受了。
下载地址:
源代码:
ubuntu-tweak_0.3.0.orig.tar.gz
debian软件包:
ubuntu-tweak_0.3.0-1~ppa2_all.deb
使用APT源的用户请将旧源修改为新源,即将gutsy改成hardy(不论你是用哪个Ubuntu发行版):
deb http://ppa.launchpad.net/tualatrix/ubuntu hardy main
deb-src http://ppa.launchpad.net/tualatrix/ubuntu hardy main


http://linux.chinaunix.net/news/2008/04/30/997915.shtml

标签: ,

CodeIgnitor,管理你的应用程序

默认情况下,你会将应用程序放入system/application/中,并且可能用 CodeIgniter 只管理这一个应用程序。当然,多个应用程序共享一个 CodeIgniter, 甚至对 application 文件夹进行重命名或更换路径也是可行的。

对应用程序文件夹重命名

如果你要对 application 进行重命名, 你可能还要打开 index.php 文件,对变量 $application_folder 也要进行更改:

$application_folder = "application";

更改你的应用程序的文件夹路径

你可以将 application文件夹从system 文件夹中挪放到服务器的其他的位置。但是你还要更改 index.php 文件里将$application_folder变量设置为服务器的全路径

$application_folder = "/Path/to/your/application";

在一个 CodeIgniter 下运行多个应用程序

如果你想要多个应用程序共享同一个 CodeIgniter, 你要将 application 下所有的文件夹放在不同的应用程序的文件夹内。

例如,你要建立两个应用程序 "foo" 和 "bar",你的应用程序文件夹的结构可能会像下面的这样:

system/application/foo/
system/application/foo/config/
system/application/foo/controllers/
system/application/foo/errors/
system/application/foo/libraries/
system/application/foo/models/
system/application/foo/views/
system/application/bar/
system/application/bar/config/
system/application/bar/controllers/
system/application/bar/errors/
system/application/bar/libraries/
system/application/bar/models/
system/application/bar/views/

要选择使用某个应用程序,你需要打开主 index.php 文件,并且设置 $application_folder 变量为目标路径。例如,通过如下设置,就可以选择使用 "foo" 应用程序:

$application_folder = "application/foo";

注意: 每一个应用程序都会需要它自己的index.php文件来调用他的目标程序。你可以随意对 index.php 文件进行命名。

http://codeigniter.org.cn/user_guide/general/managing_apps.html

标签: ,

辽ICP备05003652号
流风洄雪听天籁,轻云蔽日看落花

Powered by Blogger