php中utf-8编码下用正则表达式如何匹配汉字

http://www.cnblogs.com/yehu/archive/2010/09/03/1816662.html

文本的编码必须为utf8才能匹配,可以使用iconv来转码。

Posted in PHP | Leave a comment

MYSQL INNODB 数据库恢复

MySQL的数据库文件直接复制便可以使用,但是那是指“MyISAM”类型的表。
而使用MySQL-Front直接创建表,默认是“InnoDB”类型,这种类型的一个表在磁盘上只对应一个“*.frm”文件,不像MyISAM那样还“*.MYD,*.MYI”文件。
MyISAM类型的表直接拷到另一个数据库就可以直接使用,但是InnoDB类型的表
却不行。解决方法就是:

同时拷贝innodb数据库表“*.frm”文件和innodb数据“ibdata1”文件到合适的位置。启动MySQL的Windows服务,如果不能成功的话,查看data文件夹中有个“*.err”错误日志文件,其中会对启动失败的原因有所描述的。比如我碰到过两种错误原因。
一种是类似这样的错误信息:

INIFile code

InnoDB: Error: log file .\ib_logfile0 is of different size 0 10485760 bytes InnoDB: than specified in the .cnf file 0 25165824 bytes!

这是因为在mysql配置文件中配置的日志文件大小与实际的不相符。
解决方法是直接删掉旧的“ib_logfile0”等日志文件,重启MySQL后会自动生成新的日志文件的。
另一中则是这样的错误信息

INIFile code

InnoDB: Operating system error number 5 in a file operation. InnoDB: The error means mysqld does not have the access rights to InnoDB: the directory. It may also be you have created a subdirectory InnoDB: of the same name as a data file. InnoDB: File name .\ibdata1 InnoDB: File operation call: ‘open’. InnoDB: Cannot continue operation.

经检查原来是“ibdata1”文件在复制的过程中不知怎的被加上只读属性了。
解决方法是去掉“ibdata1”文件的只读属性便可。

15.2.8.1. 强制恢复

如果数据库页被破坏,你可能想要用SELECT INTO OUTFILE从从数据库转储你的表,通常以这种方法获取的大多数数据是完好的。即使这样,损坏可能导致SELECT * FROM tbl_name或者InnoDB后台操作崩溃或断言,或者甚至使得InnoDB前滚恢复崩溃。 尽管如此,你可以用它来强制InnoDB存储引擎启动同时阻止后台操作运行,以便你能转储你的表。例如:你可以在重启服务器之前,在选项文件的[mysqld]节添加如下的行:

[mysqld]

innodb_force_recovery = 4

innodb_force_recovery被允许的非零值如下。一个更大的数字包含所有更小数字的预防措施。如果你能够用一个多数是4的选项值来转储你的表,那么你是比较安全的,只有一些在损坏的单独页面上的数据会丢失。一个为6的值更夸张,因为数据库页被留在一个陈旧的状态,这个状态反过来可以引发对 B树和其它数据库结构的更多破坏。

· 1 (SRV_FORCE_IGNORE_CORRUPT)

即使服务器检测到一个损坏的页,也让服务器运行着;试着让SELECT * FROM tbl_name 跳过损坏的索引记录和页,这样有助于转储表。

· 2 (SRV_FORCE_NO_BACKGROUND)

阻止主线程运行,如果崩溃可能在净化操作过程中发生,这将阻止它。

· 3 (SRV_FORCE_NO_TRX_UNDO)

恢复后不运行事务回滚。

· 4 (SRV_FORCE_NO_IBUF_MERGE)

也阻止插入缓冲合并操作。如果你可能会导致一个崩溃。最好不要做这些操作,不要计算表统计表。

· 5 (SRV_FORCE_NO_UNDO_LOG_SCAN)

启动数据库之时不查看未完成日志:InnoDB把未完成的事务视为已提交的。

· 6 (SRV_FORCE_NO_LOG_REDO)

不要在恢复连接中做日志前滚。

数据库不能另外地带着这些选项中被允许的选项来使用。作为一个安全措施,当innodb_force_recovery被设置为大于0的值时,InnoDB阻止用户执行INSERT, UPDATE或DELETE操作.

即使强制恢复被使用,你也可以DROP或CREATE表。如果你知道一个给定的表正在导致回滚崩溃,你可以移除它。你也可以用这个来停止由失败的大宗导入或失败的ALTER TABLE导致的失控回滚。你可以杀掉mysqld进程,然后设置innodb_force_recovery为3,使得数据库被挂起而不需要回滚,然后舍弃导致失控回滚的表。
15.2.8.2. 检查点

InnoDB实现一种被认识为“模糊”检查点设置的检查点机制。InnoDB以小批量从缓冲池刷新已修改的数据库页。没必要以单个批次刷新缓冲池,单批次刷新实际操作中可能会在检查点设置进程中停止用户SQL语句的处理。

在崩溃恢复中,InnoDB找寻被写进日志的检查点标签。它知道所有在该标签之前对数据库的修改被呈现在数据库的磁盘映像中。然后InnoDB从检查点往前扫描日志文件,对数据库应用已写入日志的修改。

InnoDB以循环方式写日志文件。所有使得缓冲池里的数据库页与磁盘上的映像不同的已提交修改必须出现在日志文件中,以备万一InnoDB需要做一个恢复。这意味着,当InnoDB开始重新使用一个日志文件,它需要确认在磁盘上的数据库页映像包含已写进InnoDB准备重新使用的日志文件里的修改。换句话说,InnoDB必须创建一个检查点,这经常涉及已修改数据库页到磁盘的刷新。

前面的叙述解释了为什么使你的日志文件非常大会在设置检查点中节约磁盘I/O。设置日志文件总的大小和缓冲池一样大或者甚至比缓冲池大通常是有意义的。大日志文件的缺点是崩溃恢复要花更长的时间,因为有更多写入日志的信息要应用到数据库上。
15.2.9. 把一个InnoDB数据库移到另一台机器

在Windows上, InnoDB 总是在内部以小写名字的方式存储数据库和表。要从Unix把二进制格式的数据库移到Windows,或者从Windows移到Unix,你应该让所有表和数据库的名字小写。要实现这个,一个方便的方式是在创建任何数据库和表之前,在你的my.cnf或my.ini文件的[mysqld]节内添加如下行:

[mysqld]

lower_case_table_names=1

类似于MyISAM数据文件,InnoDB数据和日志文件在所有有相同浮点数格式的平台上是二进制兼容的。你可以拷贝所有列在15.2.8节,“InnoDB数据库的备份和恢复”里的相关文件来简单地移动一个InnoDB数据库。如果浮点格式不同,但你没有在表中使用FLOAT或DOUBLE数据类型,则过程是一样:简单地拷贝相关文件。如果格式不容,且你的表包含浮点数据,你必须使用mysqldump在一台机器转储你的表,然后在另一台机器导入转储文件。

假设表空间有足够的空间供导入事务产生的大型回滚片断使用,则提高性能的一个方法是在导入数据时关掉autocommit模式。仅在导入整个表或表的一个片断之后提交。

Posted in 未分类 | Tagged | Leave a comment

Linux 调优基本策略(ulimit)

ulimit -a 用来显示当前的各种用户进程限制。
    Linux对于每个用户,系统限制其最大进程数。为提高性能,可以根据设备资源情况,
    设置各linux 用户的最大进程数,下面我把某linux用户的最大进程数设为10000个:
     ulimit -u 10000
     对于需要做许多 socket 连接并使它们处于打开状态的 Java 应用程序而言,
     最好通过使用 ulimit -n xx 修改每个进程可打开的文件数,缺省值是 1024。
     ulimit -n 4096 将每个进程可以打开的文件数目加大到4096,缺省为1024
     其他建议设置成无限制(unlimited)的一些重要设置是:
     数据段长度:ulimit -d unlimited
     最大内存大小:ulimit -m unlimited
     堆栈大小:ulimit -s unlimited
     CPU 时间:ulimit -t unlimited
     虚拟内存:ulimit -v unlimited
  
     暂时地,适用于通过 ulimit 命令登录 shell 会话期间。
     永久地,通过将一个相应的 ulimit 语句添加到由登录 shell 读取的文件中, 即特定于 shell 的用户资源文件,如:
 
1)、解除 Linux 系统的最大进程数和最大文件打开数限制:
        vi /etc/security/limits.conf
        # 添加如下的行
        * soft noproc 11000
        * hard noproc 11000
        * soft nofile 4100
        * hard nofile 4100
       说明:* 代表针对所有用户
                    noproc 是代表最大进程数
                    nofile 是代表最大文件打开数
2)、让 SSH 接受 Login 程式的登入,方便在 ssh 客户端查看 ulimit -a 资源限制:
        a、vi /etc/ssh/sshd_config
             把 UserLogin 的值改为 yes,并把 # 注释去掉
        b、重启 sshd 服务:
              /etc/init.d/sshd restart
3)、修改所有 linux 用户的环境变量文件:
vi /etc/profile
ulimit -u 10000
ulimit -n 4096
ulimit -d unlimited
ulimit -m unlimited
ulimit -s unlimited
ulimit -t unlimited
ulimit -v unlimited
 
 
 
/**************************************
 
有时候在程序里面需要打开多个文件,进行分析,系统一般默认数量是1024,(用ulimit -a可以看到)对于正常使用是够了,但是对于程序来讲,就太少了。
修改2个文件。
1./etc/security/limits.conf
vi /etc/security/limits.conf
加上:
* soft nofile 8192
* hard nofile 20480
2./etc/pam.d/login
session required /lib/security/pam_limits.so
**********
另外确保/etc/pam.d/system-auth文件有下面内容
session required /lib/security/$ISA/pam_limits.so
这一行确保系统会执行这个限制。
***********
3.一般用户的.bash_profile
#ulimit -n 1024
重新登陆ok
 
 
————-
对于solaris
 

其实在系统里面有这样一个命令ulimit,以下是ulimit -a执行的结果:

time(seconds) unlimited
file(blocks) unlimited
data(kbytes) unlimited
stack(kbytes) 8192
coredump(blocks) unlimited
nofiles(descriptors) 1024
memory(kbytes) unlimited

其中nofiles就是文件描述符的变量值,该值受rlim_fd_cur这个参数的影响,可以用ulimit -n number命令来修改。但不管怎么改,程序仍然不能突破fd=256的限制。在Solaris Tunable Parameters Reference Manua这本书里面能查到以下的资料:

A 32-bit program using standard I/O is limited to 256 file descriptors。
A 64-bit program using standard I/O can use up to 2 billion descriptors。

这也就是说32位的程序是没有办法突破这个限制的,只有64位的程序才能使用高达2亿个文件描述符,SUN的软硬件在很早以前就实现了64位的架构,现在唯一要解决的就是将程序编译成64位程序,为了生成64位程序,就必须要有64位的编译器(其实不是这样的),如果你去www.sunfreeware.com下载64位编译器gcc,网站上没有特别注明是64位的gcc,但是会有个意外的收获,就是该软件的说明里面注明了只要在用gcc编译的时候加上-m64的option就能生成64位程序了。

于是用gcc -m64去编译生成一个64位程序后,用ulimit -n 102400将number of fd设成很大的情况下,所有问题迎刃而解,再也不存在文件描述符不够用的情况。

在/etc/system文件设置rlimi_fc_max和rlim_fd_cur格式如下:

 
* set hard limit on file descriptors
set rlim_fd_max = 4096
* set soft limit on file descriptors
set rlim_fd_cur = 1024

命令ulimit使用格式如下:

usage: ulimit [ -HSacdfnstv ] [ limit ]
ulimit -a是显示各参数的设置值,ulimit -n是用来设置fd的最大值的。
*************************************************

如何修改文件描述符限制?

Solaris有两个参数控制进程可打开的文件描述符:rlim_fd_max,rlim_fd_cur。前者修改是个硬设置,修改需要权限,后者 是个软设置,用户可以limit或者setrlimit() 修改,该值最大不能超过前者。一般我们在/etc/system里修改这两个参数

set rlim_fd_max = 65535

set rlim_fd_cur = 65535

 

 

A: You have two ways to modify the limit number of files that a process
can open simutanously.
One: modify the /etc/system file add the following entry:
set rlim_fd_cur = #n
#n is the number you want. Should be no more than 1024.
You should reboot the machine.
Two: Use the system command: ulimit
$ulimit -n #n
Note: You should use B-shell.
And using the same terminal session(in the same terminal
window) to run the your application program( to guarantee your
application process is a child process of the setting
terminal.)You can man ulimit to see the detailed usaged.
The disadvantage brought by incread the file limite for a
process or the whole system is increasing the system memory
usage. But, for today\'s machine, this disadvantage is not too
expensive. (William said:) There is no limit for max open
socket number in Java. But the operating system has a limit for
max open file descriptors.A socket resource is treated as a
file descriptor in Unix. The previous email answered your
question. You can try as said.

Posted in Linux, 未分类 | Leave a comment

.htaccess文件使用权威指南

Blocking bad bots and site rippers (aka offline browsers) 阻止坏爬虫和离线浏览器

例如,这样禁止msnbot:

RewriteCond %{HTTP_USER_AGENT} ^msnbot
RewriteRule ^.* – [F,L]
 

 

转一篇:

 

.htaccess可以做大量范围的事情,包括:文件夹密码保护、用户自动重新指向、自定义错误页面、变更你的文件扩展名、屏蔽特定的用户IP地址、只允许特定的IP地址、停止目录表以及使用其他文件作为index文件,等等……。希望这个.htaccess文件使用权威指南可以帮助到你。

如果你还不知道.htaccess是什么的话,可以看这里:

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

 Unix、Linux系统或者是任何版本的Apache Web服务器都是支持.htaccess的,但是有的主机服务商可能不允许你自定义自己的.htaccess文件。
 

  笼统地说,.htaccess可以帮我们实现包括:文件夹密码保护、用户自动重定向、自定义错误页面、改变你的文件扩展名、封禁特定IP地址的用户、只允许特定IP地址的用户、禁止目录列表,以及使用其他文件作为index文件等一些功能。(更多介绍)

1. Introduction 介绍
文件名 .htaccess 属性 644 (RW-R–R–)
htaccess会影响它所在目录下的所有子目录
注意大多数内容都要求保持在一行之内,不要换行,否则会引起错误
2. Error Documents 错误文档

    Official document: ErrorDocument Directive
    ErrorDocument code document

例子

    ErrorDocument 400 /errors/badrequest.html
    ErrorDocument 404 http://yoursite/errors/notfound.html
    ErrorDocument 401 “Authorization Required”

(注意之后内容如果出现的双引号需要转义为 \”)
常见HTTP状态码
Successful Client Requests
200 OK
201 Created
202 Accepted
203 Non-Authorative Information
204 No Content
205 Reset Content
206 Partial Content
Client Request Redirected
300 Multiple Choices
301 Moved Permanently
302 Moved Temporarily
303 See Other
304 Not Modified
305 Use Proxy
Client Request Errors
400 Bad Request
401 Authorization Required
402 Payment Required (not used yet)
403 Forbidden
404 Not Found
405 Method Not Allowed
406 Not Acceptable (encoding)
407 Proxy Authentication Required
408 Request Timed Out
409 Conflicting Request
410 Gone
411 Content Length Required
412 Precondition Failed
413 Request Entity Too Long
414 Request URI Too Long
415 Unsupported Media Type
Server Errors
500 Internal Server Error
501 Not Implemented
502 Bad Gateway
503 Service Unavailable
504 Gateway Timeout
505 HTTP Version Not Supported
3. Password Protection 密码保护
Official document: Authentication, Authorization and Access Control
假设密码文件为.htpasswd

    AuthUserFile /usr/local/safedir/.htpasswd (这里必须使用全路径名)
    AuthName EnterPassword
    AuthType Basic

两种常见验证方式:

    Require user windix

(仅允许用户windix登陆)

    Require valid-user

(所有合法用户都可登陆)
Tip: 如何生成密码文件
使用htpasswd命令(apache自带)
第一次生成需要创建密码文件

    htpasswd -c .htpasswd user1

之后增加新用户

    htpasswd .htpasswd user2

4. Enabling SSI Via htaccess 通过htaccess允许SSI(Server Side Including)功能

    AddType text/html .shtml
    AddHandler server-parsed .shtml
    Options Indexes FollowSymLinks Includes
    DirectoryIndex index.shtml index.html

5. Blocking users by IP 根据IP阻止用户访问

    order allow,deny
    deny from 123.45.6.7
    deny from 12.34.5. (整个C类地址)
    allow from all

6. Blocking users/sites by referrer 根据referrer阻止用户/站点访问
需要mod_rewrite模块
例1. 阻止单一referrer: badsite.com

    RewriteEngine on
    # Options +FollowSymlinks
    RewriteCond %{HTTP_REFERER} badsite\.com [NC]
    RewriteRule .* – [F]

例2. 阻止多个referrer: badsite1.com, badsite2.com

    RewriteEngine on
    # Options +FollowSymlinks
    RewriteCond %{HTTP_REFERER} badsite1\.com [NC,OR]
    RewriteCond %{HTTP_REFERER} badsite2\.com
    RewriteRule .* – [F]

[NC] – 大小写不敏感(Case-insensite)
[F] – 403 Forbidden
注意以上代码注释掉了”Options +FollowSymlinks”这个语句。如果服务器未在 httpd.conf 的 段落设置 FollowSymLinks, 则需要加上这句,否则会得到”500 Internal Server error”错误。
7. Blocking bad bots and site rippers (aka offline browsers) 阻止坏爬虫和离线浏览器
需要mod_rewrite模块
坏爬虫? 比如一些抓垃圾email地址的爬虫和不遵守robots.txt的爬虫(如baidu?)
可以根据 HTTP_USER_AGENT 来判断它们
(但是还有更无耻的如”中搜 zhongsou.com”之流把自己的agent设置为 “Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0)” 太流氓了,就无能为力了)

    RewriteEngine On
    RewriteCond %{HTTP_USER_AGENT} ^BlackWidow [OR]
    RewriteCond %{HTTP_USER_AGENT} ^Bot\ mailto:craftbot@yahoo.com [OR]
    RewriteCond %{HTTP_USER_AGENT} ^ChinaClaw [OR]
    RewriteCond %{HTTP_USER_AGENT} ^Custo [OR]
    RewriteCond %{HTTP_USER_AGENT} ^DISCo [OR]
    RewriteCond %{HTTP_USER_AGENT} ^Download\ Demon [OR]
    RewriteCond %{HTTP_USER_AGENT} ^eCatch [OR]
    RewriteCond %{HTTP_USER_AGENT} ^EirGrabber [OR]
    RewriteCond %{HTTP_USER_AGENT} ^EmailSiphon [OR]
    RewriteCond %{HTTP_USER_AGENT} ^EmailWolf [OR]
    RewriteCond %{HTTP_USER_AGENT} ^Express\ WebPictures [OR]
    RewriteCond %{HTTP_USER_AGENT} ^ExtractorPro [OR]
    RewriteCond %{HTTP_USER_AGENT} ^EyeNetIE [OR]
    RewriteCond %{HTTP_USER_AGENT} ^FlashGet [OR]
    RewriteCond %{HTTP_USER_AGENT} ^GetRight [OR]
    RewriteCond %{HTTP_USER_AGENT} ^GetWeb! [OR]
    RewriteCond %{HTTP_USER_AGENT} ^Go!Zilla [OR]
    RewriteCond %{HTTP_USER_AGENT} ^Go-Ahead-Got-It [OR]
    RewriteCond %{HTTP_USER_AGENT} ^GrabNet [OR]
    RewriteCond %{HTTP_USER_AGENT} ^Grafula [OR]
    RewriteCond %{HTTP_USER_AGENT} ^HMView [OR]
    RewriteCond %{HTTP_USER_AGENT} HTTrack [NC,OR]
    RewriteCond %{HTTP_USER_AGENT} ^Image\ Stripper [OR]
    RewriteCond %{HTTP_USER_AGENT} ^Image\ Sucker [OR]
    RewriteCond %{HTTP_USER_AGENT} Indy\ Library [NC,OR]
    RewriteCond %{HTTP_USER_AGENT} ^InterGET [OR]
    RewriteCond %{HTTP_USER_AGENT} ^Internet\ Ninja [OR]
    RewriteCond %{HTTP_USER_AGENT} ^JetCar [OR]
    RewriteCond %{HTTP_USER_AGENT} ^JOC\ Web\ Spider [OR]
    RewriteCond %{HTTP_USER_AGENT} ^larbin [OR]
    RewriteCond %{HTTP_USER_AGENT} ^LeechFTP [OR]
    RewriteCond %{HTTP_USER_AGENT} ^Mass\ Downloader [OR]
    RewriteCond %{HTTP_USER_AGENT} ^MIDown\ tool [OR]
    RewriteCond %{HTTP_USER_AGENT} ^Mister\ PiX [OR]
    RewriteCond %{HTTP_USER_AGENT} ^Navroad [OR]
    RewriteCond %{HTTP_USER_AGENT} ^NearSite [OR]
    RewriteCond %{HTTP_USER_AGENT} ^NetAnts [OR]
    RewriteCond %{HTTP_USER_AGENT} ^NetSpider [OR]
    RewriteCond %{HTTP_USER_AGENT} ^Net\ Vampire [OR]
    RewriteCond %{HTTP_USER_AGENT} ^NetZIP [OR]
    RewriteCond %{HTTP_USER_AGENT} ^Octopus [OR]
    RewriteCond %{HTTP_USER_AGENT} ^Offline\ Explorer [OR]
    RewriteCond %{HTTP_USER_AGENT} ^Offline\ Navigator [OR]
    RewriteCond %{HTTP_USER_AGENT} ^PageGrabber [OR]
    RewriteCond %{HTTP_USER_AGENT} ^Papa\ Foto [OR]
    RewriteCond %{HTTP_USER_AGENT} ^pavuk [OR]
    RewriteCond %{HTTP_USER_AGENT} ^pcBrowser [OR]
    RewriteCond %{HTTP_USER_AGENT} ^RealDownload [OR]
    RewriteCond %{HTTP_USER_AGENT} ^ReGet [OR]
    RewriteCond %{HTTP_USER_AGENT} ^SiteSnagger [OR]
    RewriteCond %{HTTP_USER_AGENT} ^SmartDownload [OR]
    RewriteCond %{HTTP_USER_AGENT} ^SuperBot [OR]
    RewriteCond %{HTTP_USER_AGENT} ^SuperHTTP [OR]
    RewriteCond %{HTTP_USER_AGENT} ^Surfbot [OR]
    RewriteCond %{HTTP_USER_AGENT} ^tAkeOut [OR]
    RewriteCond %{HTTP_USER_AGENT} ^Teleport\ Pro [OR]
    RewriteCond %{HTTP_USER_AGENT} ^VoidEYE [OR]
    RewriteCond %{HTTP_USER_AGENT} ^Web\ Image\ Collector [OR]
    RewriteCond %{HTTP_USER_AGENT} ^Web\ Sucker [OR]
    RewriteCond %{HTTP_USER_AGENT} ^WebAuto [OR]
    RewriteCond %{HTTP_USER_AGENT} ^WebCopier [OR]
    RewriteCond %{HTTP_USER_AGENT} ^WebFetch [OR]
    RewriteCond %{HTTP_USER_AGENT} ^WebGo\ IS [OR]
    RewriteCond %{HTTP_USER_AGENT} ^WebLeacher [OR]
    RewriteCond %{HTTP_USER_AGENT} ^WebReaper [OR]
    RewriteCond %{HTTP_USER_AGENT} ^WebSauger [OR]
    RewriteCond %{HTTP_USER_AGENT} ^Website\ eXtractor [OR]
    RewriteCond %{HTTP_USER_AGENT} ^Website\ Quester [OR]
    RewriteCond %{HTTP_USER_AGENT} ^WebStripper [OR]
    RewriteCond %{HTTP_USER_AGENT} ^WebWhacker [OR]
    RewriteCond %{HTTP_USER_AGENT} ^WebZIP [OR]
    RewriteCond %{HTTP_USER_AGENT} ^Wget [OR]
    RewriteCond %{HTTP_USER_AGENT} ^Widow [OR]
    RewriteCond %{HTTP_USER_AGENT} ^WWWOFFLE [OR]
    RewriteCond %{HTTP_USER_AGENT} ^Xaldon\ WebSpider [OR]
    RewriteCond %{HTTP_USER_AGENT} ^Zeus
    RewriteRule ^.* – [F,L]

[F] – 403 Forbidden
[L] – 连接(Link)
8. Change your default directory page 改变缺省目录页面

    DirectoryIndex index.html index.php index.cgi index.pl

9. Redirects 转向
单个文件

    Redirect /old_dir/old_file.html http://yoursite.com/new_dir/new_file.html

整个目录

    Redirect /old_dir http://yoursite.com/new_dir

效果: 如同将目录移动位置一样

    http://yoursite.com/old_dir -> http://yoursite.com/new_dir
    http://yoursite.com/old_dir/dir1/test.html -> http://yoursite.com/new_dir/dir1/test.html

Tip: 使用用户目录时Redirect不能转向的解决方法
当你使用Apache默认的用户目录,如 http://mysite.com/~windix,当你想转向 http://mysite.com/~windix/jump时,你会发现下面这个Redirect不工作:

    Redirect /jump http://www.google.com

正确的方法是改成

    Redirect /~windix/jump http://www.google.com
    (source: .htaccess Redirect in “Sites” not redirecting: why?
    )

10. Prevent viewing of .htaccess file 防止.htaccess文件被查看

    order allow,deny
    deny from all

11. Adding MIME Types 添加 MIME 类型

    AddType application/x-shockwave-flash swf

Tips: 设置类型为 application/octet-stream 将提示下载
12. Preventing hot linking of images and other file types 防盗链
需要mod_rewrite模块

    RewriteEngine on
    RewriteCond %{HTTP_REFERER} !^$
    RewriteCond %{HTTP_REFERER} !^http://(www/\.)?mydomain.com/.*$ [NC]
    RewriteRule \.(gif|jpg|js|css)$ – [F]

解析:
若 HTTP_REFERER 非空 (来源为其他站点,非直接连接) 并且
若 HTTP_REFERER 非(www.)mydomain.com开头(忽略大小写[NC]) (来源非本站)
对于所有含有 .gif/.jpg/.js/.css 结尾的文件给出 403 Forbidden 错误[F]
也可指定响应,如下例显示替换图片
RewriteRule \.(gif|jpg)$ [R,L]
[R] – 转向(Redirect)
[L] – 连接(Link)
13. Preventing Directory Listing 防止目录列表时显示

    IndexIgnore *
    IndexIgnore *.jpg *.gif

Tips:
允许目录列表显示: Options +Indexes
禁止目录列表显示: Options -Indexes
显示提示信息: 页首 文件HEADER, 页尾 文件README

Posted in apache | 1 Comment

Apache Rewrite 规则的常见应用

一:目的

本文旨在提供如何用Apache重写规则来解决一些常见的URL重写方法的问题,通过常见的实例给用户一些使用重写规则的基本方法和线索。

二:为什么需要用重写规则?
一个网站,如果是长期需要放在internet上提供服务,必定会有不断地更新和维护,如临时转移到其它服务器进行维护,重新组织目录结构,变换URL甚 至改变到新的域名等等,而为了让客户不会因此受到任何影响,最好的方法就是使用Apache Rewrite Rule(重写规则)。

三: 重写规则的作用范围
1) 可以使用在Apache主配置文件httpd.conf中
2) 可以使用在httpd.conf里定义的虚拟主机配置中
3) 可以使用在基本目录的跨越配置文件.htaccess中

四:重写规则的应用条件
只有当用户的WEB请求最终被导向到某台WEB服务器的Apache后台,则这台WEB服务器接受进来的请求,根据配置文件该请求是主配置还是虚拟主机, 再根据用户在浏览器中请求的URI来配对重写规则并且根据实际的请求路径配对.htaccess中的重写规则。最后把请求的内容传回给用户,该响应可能有 两种:

1) 对浏览器请求内容的外部重定向(Redirect)到另一个URL。让浏览器再次以新的URI发出请求(R=301或者R=302,临时的或是永久的重定向)
如:一个网站有正规的URL和别名URL,对别名URL进行重定向到正规URL,或者网站改换成了新的域名则把旧的域名重定向到新的域名(Redirect)

2) 也可能是由Apache内部子请求代理产生新的内容送回给客户[P,L] 这是Apache内部根据重写后的URI内部通过代理模块请求内容并送回内容给客户,而客户端浏览器并不知道,浏览器中的URI不会被重写。但实际内容被 Apache根据重写规则后的URI得到。
如:在公司防火墙上运行的Apache启动这种代理重写规则,代理对内部网段上的WEB服务器的请求。

五:重写规则怎样工作?
我们假定在编译Apache时已经把mod_rewrite编译成模块,确信你的httpd.conf中有 LoadModule rewrite_module libexec/mod_rewrite.so
并且在Addmodule中有 Addmodule mod_rewrite.c 则可以使用重写规则。
当外部请求来到Apache,Apache调用重写规则中的定义来重写由用户浏览器指定请求的 URI,最后被重写的URI如果是重定向,则送由浏览器作再一次请求;如果是代理则把重写后的 URI 交给代理模块请求最终的内容(Content),最后把内容送回给浏览器。

六: 何时使用.htaccess中的重写规则定义?
假如你对你的的网站内容所在的服务器没有管理员权限,或者你的网站放在ISP的服务器上托管等等条件下,你无法改写主配置文件,然而你可以对你的WEB站 点内容所在的目录有写权限,则你可以设置自己的.htaccess文件达到同样的目的。但你需要确定主配置文件中对你的网站所在的目录定义了下面的内容:

Options Indexes FollowSymLinks
AllowOverride all

否则你的.htaccess不会工作。

七: 应用举例
假定Apache被编译安装在主机192.168.1.56的/usr/local/apache/ 目录下面,我们编译进了重写和代理模块。

1) 隐藏Apache下的某个目录,使得对该目录的任何请求都重定向到另一个文件。

a> httpd.conf的实现方法

我们放下面的部分到/usr/local/apache/conf/httpd.conf

options Indexes followsymlinks
allowoverride all
rewriteengine on
rewritebase /
rewriterule ^(.*)$ index.html.en [R=301]

注:rewriteengine on 为重写引擎开关,如果设为off,则任何重写规则定义将不被应用,该开关的另一好处就是如果为了临时拿掉重写规则,则改为off再重启动Apache即 可,不必将下面一条条的重写规则注释掉。rewritebase / 的作用是如果在下面的rewriterule定义中被重写后的部分(此处为文件名index.html.en)前面没有/,则是相对目录,相对于这个 rewritebase后面的定义也就是/usr/local/apache/htdocs/index.html.en,否则,如果此处没有 rewritebase /这一项,则被重写成http: //192.168.1.56/usr/local/apache/htdocs/manual/index.html.en ,显然是不正确的。

不过这里我们也可以不用rewritebase / , 而改为
rewriteengine on
rewriterule ^(.*)$ /index.html.en [R=301]
或者
rewriteengine on
rewriterule ^(.*)$ http://192.168.1.56/index.html.en [R=301]

b> .htaccess的实现方法

我们先放下面的部分到httpd.conf

options Indexes followsymlinks
allowoverride all

然后放下面的部分到/usr/local/apache/htdocs/manual/.htaccess中
rewriteengine on
rewritebase /
rewriterule ^(.*)$ index.html.en [R=301]

注:对文件.htaccess所作的任何改动不需要重启动Apache.

问:要是把这个manual目录重定向到用户jephe的自己的主目录呢?
用下面的.htaccess方案。
rewriteengine on
rewritebase /~jephe/
rewriterule ^(.*)$ $1 [R=301]

则对manual目录下任何文件的请求被重定向到~jephe目录下相同文件的请求。

2) 转换www.username.domain.com的对于username的主页请求为
www.domain.com/username

对于HTTP/1.1的请求包括一个Host: HTTP头,我们能用下面的规则集重写
http://www.username.domain.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

注:
rewritecond 条件重写规则,当满足后面定义的条件后才会应用下面的重写规则,rewritecond有各种变量,请查阅相关文档。

3) 防火墙上的重写规则代理内部网段上服务器的请求。

NameVirtualhost 1.2.3.4

servername www.domain.com
rewriteengine on
proxyrequest on
rewriterule ^/(.*)$ http://192.168.1.3/$1 [P,L]

注:当外部浏览器请求www.domain.com时被解析到IP地址1.2.3.4 ,Apache 交出mod_rewrite处理转换成http://192.168.1.3/$1后再交由代理模块mod_proxy得到内容后传送回用户的浏览器。

4) 基本预先设定的转换MAP表进行重写 rewritemap

转换www.domain.com/{countrycode}/anypath 到Map表中规定的URI,上面是虚拟主机中的定义

rewritelog /usr/local/apache/logs/rewrite.log
rewriteloglevel 9

rewriteengine on
proxyrequest on
rewritemap sitemap txt:/usr/local/apache/conf/rewrite.map
rewriterule ^/([^/]+)+/(.*)$ http://%{REMOTE_HOST}:1 [C]
rewriterule (.*):[a-z]+)$ ${sitemap2|http://h.i.j.k/} [R=301,L]

文件/usr/local/apache/conf/rewrite.map的内容如下:

sg http://a.b.c.d/
sh http://e.f.g.h/

注:当用户请求http://www.domain.com/sg/anypath时被重写为http://a.b.c.d/anypath .
当需要调试时请用rewritelog and rewriteloglevel 9联合,9为最大即得到最多的调试信息最小为1,最小的调试信息,默认为0,没有调试信息。sitemap的语法是${sitemap: LookupKey | Defaultvalue} ,有些书上把$写成了%是错误的。
Apache模块 mod_rewrite
说明: 提供了一个基于规则的实时转向URL请求的引擎
状态: Extension
模块名: rewrite_module
源文件: mod_rewrite.c
兼容性: 包含在Apache 1.3及其更新版本中

RewriteBase 指令
说明: 设置目录级重写的基准URL
语法: RewriteBase URL-path
默认值: 参见使用方法.
上下文: 目录, .htaccess
覆盖项: FileInfo
状态: Extension
模块: mod_rewrite

For Apache Hackers
以下列出了内部处理的详细步骤:
Request: /xyz/oldstuff.html Internal Processing: /xyz/oldstuff.html     -> /abc/def/oldstuff.html (per-server Alias) /abc/def/oldstuff.html -> /abc/def/newstuff.html (per-dir    RewriteRule) /abc/def/newstuff.html -> /xyz/newstuff.html      (per-dir    RewriteBase) /xyz/newstuff.html     -> /abc/def/newstuff.html (per-server Alias) Result: /abc/def/newstuff.html虽然这个过程看来很繁复,但是由于目录级重写的到来时机已经太晚了, 它不得不把这个(重写)请求重新注入到Apache核心中,所以Apache内部确实是这样处理的。但是:它的开销并不象看起来的那样大,因为重新注入完 全在Apache服务器内部进行, 而且这样的过程在Apache内部也为其他许多操作所使用。 所以,你可以充分信任其设计和实现是正确的。
说明: 定义重写发生的条件  
语法: RewriteCond TestString CondPattern
上下文: 服务器配置, 虚拟主机, 目录, .htaccess
覆盖项: FileInfo
状态: Extension
模块: mod_rewrite

RewriteCond指令定义了一个规则的条件,即,在一个RewriteRule指令之前有一个或多个RewriteCond指令。 条件之后的重写规则仅在当前URI与pattern匹配并且符合这些条件的时候才会起作用
正则表达式只是用于字符串匹配的特征串, 我们从如何表示一个字符开始.
[ ] : 表示选择一个字符.
(.) : 表示任何了个除换行符(\n)之外的字符.
\r  : 表示回车
\n  : 表示换行
\t  : 表示TAB键
\w  : 表示字母,数字或下划线, 等同于[A-Za-z0-9_]
\W  : 表示非字母,数字或下划线, 等同于[^A-Za-z0-9_]
\s  : 表示空白字符, 等同于[ \f\n\r\t]
\S  : 表示非空白字符, 等同于[^ \f\n\r\t]
\d  : 表示数字字符, 等同于[0-9]
\D  : 表示非数字字符, 等同于[^0-9]
    当我们需要表示有特定意义的字符时,  可以用"\"来进行转义, 如要表示一对中括号, 就用"\[\]",其他的类似. 当"*", "+", ".", "(", ")", "$", "?", "|", "{"出现在中括号内时, 就只表示字符本身而没有其他含义.
| : 或者
* : 表示出现0个或多个
+ : 表示出现1个或多个
? : 表示出现0个或1个
{n} : 表示重复出现n次
{m,n} : 表示重复出现最少m次, 最多n次
    到这一部份就比较难理解了, 还是举例子来解释吧.
(ab|cd|ef) "ab", "cd", "ef"中的任一个
[a-zA-Z]+ 只包括字母的单词
[A-Z][a-z]* 第一个字母是大写的单词
\d+\.?\d* 表示一个数字
[a-z]{4} 四个小写字母
[+-]?\d*\.\d{1,6} 小数点后有1到6位的数
.|\n 任何字符
.* 一行
^\s*$ 空行

使用UrlRewriteFilter动态URL静态化
   (方法一)
                     假设你已经使用mod_jk2.so整合了Apache2.05x与Tomcat5.x
要完成的功能如下重定向:
将URL http://host/test.jps?id=1 重定向为 http://host/1.html
将URL http://host/conent.jsp?id=1&id2=3 重定向为 http://host/1_3.html
1. 修改Apache2\conf\httpd.conf文件,加载mod_rewrite.so
LoadModule rewrite_module modules/mod_rewrite.so

2. 在每个虚拟主机的地方设置Rewrite参数
<VirtualHost *:80>
    ServerAdmin wiseweidong@gmail.com
    DocumentRoot "I:/Job/Java"
    ServerName localhost
    RewriteEngine on
    RewriteRule /([0-9]+).html /test.jsp?id=$1 [PT]
    RewriteRule /([0-9]+)_([0-9]+).html /content.jsp?id=$1&id2=$2 [PT]
</VirtualHost>
(方法二)
    所用基于动态的url http://www.nihaoblog.com/content.jsp?id=1&contentid=404按照各大搜索引擎的喜好,应 该美化成http://www.nihaoblog.com/content/1_404.html静态网页的方式,尽管目前的google及几大搜索引 擎宣称支持动态页网的抓取,但与传统的html文件相比较抓取率仍不在一个数量级。Apche的mod_rewrite模块具有此功能,但是对于租用虚拟 主机的用户来说就比较麻烦不太可能对所有运营商有更多的要求,需要条件依赖就不具通用性。
    目前有一个解决方法,通过UrlRewriteFilter可以完全实现动态URL表态化,你可以将它直接应用到你的web应用中,不管你用的是jsp+javabean还是struts.
   
下面是使用方法:
    1、下载http://tuckey.org/urlrewrite/#download目前版本是1.2,解压缩后将文件考到相应的web-inf/lib和web-inf下,。
    2、配置web.xml
<filter>
       <filter-name>UrlRewriteFilter</filter-name>
       <filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>
</filter>
<filter-mapping>
       <filter-name>UrlRewriteFilter</filter-name>
       <url-pattern>/*</url-pattern>
</filter-mapping>
根据自己的需要,将相应目录下的url转给UrlRewriteFilter来处理。
    3、配置urlwrite规则文件WEB-INF/urlrewrite.xml
http://www.nihaoblog.com/content.jsp?id=1&contentid=404
静态化为:
http://www.nihaoblog.com/content/1_404.html
配置如下:
<rule>
    <from>/content/([0-9]+)_([0-9]+).html</from>
    <to>/content.jsp?id=$1&contentid=$2</to>
</rule>
RewriteRule
Syntax: RewriteRule Pattern Substitution [flags]
  一条RewriteRule指令,定义一条重写规则,规则间的顺序非常重要。对Apache1.2及以后的版本,模板(pattern)是一个 POSIX正则式,用以匹配当前的URL。当前的URL不一定是用记最初提交的URL,因为可能用一些规则在此规则前已经对URL进行了处理。
  对mod_rewrite来说,!是个合法的模板前缀,表示“非”的意思,这对描述“不满足某种匹配条件”的情况非常方便,或用作最后一条默认规则。当使用!时,不能在模板中有分组的通配符,也不能做后向引用。
  当匹配成功后,Substitution会被用来替换相应的匹配,它除了可以是普通的字符串以外,还可以包括:
$N,引用RewriteRule模板中匹配的相关字串,N表示序号,N=0..9
%N,引用最后一个RewriteCond模板中匹配的数据,N表示序号
%{VARNAME},服务器变量
${mapname:key|default},映射函数调用
这些特殊内容的扩展,按上述顺序进行。
  一个URL的全部相关部分都会被Substitution替换,而且这个替换过程会一直持续到所有的规则都被执行完,除非明确地用L标志中断处理过程。
  当susbstitution有”-”前缀时,表示不进行替换,只做匹配检查。
  利用RewriteRule,可定义含有请求串(Query String)的URL,此时只需在Sustitution中加入一个?,表示此后的内容放入QUERY_STRING变量中。如果要清空一个 QUERY_STRING变量,只需要以?结束Substitution串即可。
  如果给一个Substitution增加一个http://thishost[:port]的前缀,则mod_rewrite会自动将此前缀去掉。因此,利用http://thisthost做一个无条件的重定向到自己,将难以奏效。要实现这种效果,必须使用R标志。
  Flags是可选参数,当有多个标志同时出现时,彼此间以逗号分隔。
'redirect|R [=code]' (强制重定向)
  给当前的URI增加前缀http://thishost[:thisport]/, 从而生成一个新的URL,强制生成一个外部重定向(external redirection,指生的URL发送到客户端,由客户端再次以新的URL发出请求,虽然新URL仍指向当前的服务器). 如果没有指定的code值,则HTTP应答以状态值302 (MOVED TEMPORARILY),如果想使用300-400(不含400)间的其它值可以通过在code的位置以相应的数字指定,也可以用标志名指定: temp (默认值), permanent, seeother.
  注意,当使用这个标志时,要确实substitution是个合法的URL,这个标志只是在URL前增加http://thishost[:thisport]/前缀而已,重写操作会继续进行。如果要立即将新URL重定向,用L标志来中重写流程。
'forbidden|F' (强制禁止访问URL所指的资源)
  立即返回状态值403 (FORBIDDEN)的应答包。将这个标志与合适的RewriteConds 联合使用,可以阻断访问某些URL。
'gone|G' (强制返回URL所指资源为不存在(gone))
  立即返回状态值410 (GONE)的应答包。用这个标志来标记URL所指的资源永久消失了.
# 'proxy|P' (强制将当前URL送往代理模块(proxy module))
  这个标志,强制将substitution当作一个发向代理模块的请求,并立即将共送往代理模块。因此,必须确保substitution串是一个合 法的URI (如, 典型的情况是以http://hostname开头),否则会从代理模块得到一个错误. 这个标志,是ProxyPass指令的一个更强劲的实现,将远程请求(remote stuff)映射到本地服务器的名字空间(namespace)中来。
  注意,使用这个功能必须确保代理模块已经编译到Apache 服务器程序中了. 可以用“httpd -l ”命令,来检查输出中是否含有mod_proxy.c来确认一下。如果没有,而又需要使用这个功能,则需要重新编译“httpd''程序并使用 mod_proxy有效。
'last|L' (最后一条规则)
  中止重写流程,不再对当前URL施加更多的重写规则。这相当于perl的last命令或C的break命令。
'next|N' (下一轮)
  重新从第一条重写规则开始执行重写过程,新开的过程中的URL不应当与最初的URL相同。 这相当于Perl的next命令或C的continue命令. 千万小心不要产生死循环。
# 'chain|C' (将当前的规则与其后续规则綑绑(chained))
  当规则匹配时,处理过程与没有綑绑一样;如果规则不匹配,则綑绑在一起的后续规则也不在检查和执行。
'type|T=MIME-type' (强制MIME类型)
  强制将目标文件的MIME-type为某MIME类型。例如,这可用来模仿mod_alias模块对某目录的ScriptAlias指定,通过强制将该目录下的所有文件的类型改为 “application/x-httpd-cgi”.
'nosubreq|NS' (used only if no internal sub-request )
  这个标志强制重写引擎跳过为内部sub-request的重写规则.例如,当mod_include试图找到某一目录下的默认文件时 (index.xxx),sub-requests 会在Apache内部发生. Sub-requests并非总是有用的,在某些情况下如果整个规则集施加到它上面,会产生错误。利用这个标志可排除执行一些规则。
'nocase|NC' (模板不区分大小写)
  这个标志会使得模板匹配当前URL时忽略大小写的差别。
'qsappend|QSA' (追加请求串(query string))
  这个标志,强制重写引擎为Substitution的请求串追加一部分串,则不是替换掉原来的。借助这个标志,可以使用一个重写规则给请求串增加更多的数据。
'noescape|NE' (不对输出结果中的特殊字符进行转义处理)
  通常情况下,mod_write的输出结果中,特殊字符(如'%', '$', ';', 等)会转义为它们的16进制形式(如分别为'%25', '%24', and '%3B')。这个标志会禁止mod_rewrite对输出结果进行此类操作。 这个标志只能在 Apache 1.3.20及以后的版本中使用。
'passthrough|PT' (通过下一个处理器)
  这个标志强制重写引擎用filename字段的值来替换内部request_rec数据结构中uri字段的值。. 使用这个标志,可以使后续的其它URI-to-filename转换器的Alias、ScriptAlias、Redirect等指令,也能正常处理 RewriteRule指令的输出结果。用一个小例子来说明它的语义:如果要用mod_rewrite的重写引擎将/abc转换为/def,然后用 mod_alas将/def重写为ghi,则要:
RewriteRule ^/abc(.*) /def$1 [PT]
Alias /def /ghi
如果PT标志被忽略,则mod_rewrite也能很好完成工作,如果., 将 uri=/abc/… 转换为filename=/def/… ,完全符合一个URI-to-filename转换器的动作。接下来 mod_alias 试图做 URI-to-filename 转换时就会出问题。
注意:如果要混合都含有URL-to-filename转换器的不同的模块的指令,必须用这个标志。最典型的例子是mod_alias和mod_rewrite的使用。
'skip|S=num' (跳过后面的num个规则)
  当前规则匹配时,强制重写引擎跳过后续的num个规则。用这个可以来模仿if-then-else结构:then子句的最后一条rule的标志是skip=N,而N是else子句的规则条数。
'env|E=VAR:VAL' (设置环境变量)
  设置名为VAR的环境变量的值为VAL,其中VAL中可以含有正则式的后向引用($N或%N)。这个标志可以使用多次,以设置多个环境变量。这儿设置 的变量,可以在多种情况下被引用,如在XSSI或CGI中。另外,也可以在RewriteCond模板中以%{ENV:VAR}的形式被引用。

注意:一定不要忘记,在服务器范围内的配置文件中,模板(pattern)用以匹配整个URL;而在目录范围内的配置文件中,目录前缀总是被自动去掉后再 进行模板匹配的,且在替换完成后自动再加上这个前缀。这个功能对很多种类的重写是非常重要的,因为如果没有去前缀,则要进行父目录的匹配,而父目录的信息 并不是总能得到的。一个例外是,当substitution中有http://打头时,则不再自动增加前缀了,如果P标志出现,则会强制转向代理。
注意:如果要在某个目录范围内启动重写引擎,则需要在相应的目录配置文件中设置“RewriteEngine on”,且目录的“Options FollowSymLinks”必须设置。如果管理员由于安全原因没有打开FollowSymLinks,则不能使用重写引擎。
注:顺序
下表从最高优先级到最低优先级列出各种正则表达式操作符的优先权顺序:

操作符描述

\ 转义符

(), (?, (?=), [] 圆括号和方括号

*, +, ?, {n}, {n,}, {n,m} 限定符

^, $, \anymetacharacter 位置和顺序

| “或”操作
RewriteRule news/(\d+)\.html news\.php\?id=$1 [N,L]
这样就实现了将http://localhost/news/1000.html 解析为 http://localhost/news.php?id=1000的功能
http://211.100.227.106:8080/wp-cp-m7/index.jsp?mod=free&act=watch&cid=714
index/[a-zA-Z]/[a-zA-Z]/(\d+)_(\d+)\.html index\.jsp\?mod=$1&act=$2&cid=
RewriteRule ^(power([^/]*))/([^/]+)\.htm(l?)$ series\.php\?fclassname=$1&fb_babrand=$3 [NC]
$ 匹配输入字符串的结束位置。如
将URL http://host/test.jps?id=1 重定向为 http://host/1.html
将URL http://host/conent.jsp?id=1&id2=3 重定向为 http://host/1_3.html
RewriteEngine on
    RewriteRule /([0-9]+).html /test.jsp?id=$1 [PT]
    RewriteRule /([0-9]+)_([0-9]+).html /content.jsp?id=$1&id2=$2 [PT]
index.jsp?lid=2&mod=free&act=watch&cid=714&mid=112312&type=adlska
index/lang/mod/act/type/cid_mid.html
RewriteRule index/(\d+\.?\d*)/(a-z)/(a-z)/(a-z)/([0-9]+)_([0-9]+).html /index.jsp?lid=$1&mod=&2&act=$3&type=$4&cid=$5&mid=$6 [PT]
RewriteRule index/(a-z)/(a-z)/(a-z)/([0-9]+)_([0-9]+).html /index.jsp?mod=&1&act=$2&type=$3&cid=$4&mid=$5 [PT]
RewriteRule /(a-z)/(a-z)/([0-9]+)_([0-9]+).html /?mod=&1&act=$2&cid=$3&mid=$4 [PT]
index.jsp?mod=free&act=watch&cid=714
index.jsp?mod=free&act=watch
index.jsp?mod=free
              
               RewriteRule ^([^/]+)/([^/]+)/(\d+)_(\d+).html$ /index.jsp?mod=$1&act=$2&cid=$3&mid=$4
RewriteRule ^([^/]+)/([^/]+)/([^/]+)/(\d+)_(\d+).html$ /index.jsp?lid=$1&mod=$2&act=$3&cid=$4&mid=$5
         
RewriteRule ^([^/]+)/([^/]+)/(\d+).html$ /index.jsp?mod=$1&act=$2&cid=$3
RewriteRule ^([^/]+)/([^/]+)/(\d+)/(\d+).html$ /index.jsp?lid=$1&mod=$2&act=$3&cid=$4
        
RewriteRule ^(\d+)/(\d+).html$ /index.jsp?mod=$1&act=$2
RewriteRule ^(\d+)/([^/]+)/([^/]+).html$ /index.jsp?lid=$1&mod=$2&act=$3
      
RewriteRule ^([^/]+).html$ /index.jsp?mod=$1
RewriteRule ^(\d+)/([^/]).html$ /index.jsp?lid=$1&mod=$2

Posted in apache, PHP | Leave a comment

apache的RewriteRule的问题

下面这个规则
RewriteEngine On
RewriteBase /
RewriteRule ^station/(.+).html$ station.php?city=$1
这样必须在网站根目录下面有station这个目录,才能传参数生效。这个问题困扰了我半天总算搞定了。

Posted in 未分类 | Tagged | Leave a comment

巧用math函数在smarty模板中给变量动态赋值

今天无意中发现了Math函数,感觉很好用,稍加修改就可以达到上述效果:

  1. <!–{math equation=x x=0 assign=i}–>
  2. <!–{section name=smartyVar loop=10 }–>
  3. <!–{math equation=$i+1 assign=i}–>
  4. <br />
  5. <!–{$i}–>
  6. <br />
  7. <!–{/section}–>

输出效果:

  1. <br />
  2. 1
  3. <br />
  4.  
  5. <br />
  6. 2
  7. <br />
  8.  
  9. <br />
  10. 3
  11. <br />
  12.  
  13. <br />
  14. 4
  15. <br />
  16.  
  17. <br />
  18. 5
  19. <br />
  20.  
  21. <br />
  22. 6
  23. <br />
  24.  
  25. <br />
  26. 7
  27. <br />
  28.  
  29. <br />
  30. 8
  31. <br />
  32.  
  33. <br />
  34. 9
  35. <br />
  36.  
  37. <br />
  38. 10
  39. <br />

如果$i的初始值不是0,例如1,”math equation=x x=1 assign=i”还可以写成”math equation=1 assign=i”,省略其中的x变量.是0时不可以省,否则会出现警告信息Warning: Smarty error: math: missing equation parameter
虽然在模板中再为变量赋值不是一个好主意,但真的需要时可以按上面的方法试一下

Posted in 未分类 | Leave a comment

一个不错的PHP框架

Kohana:

http://kohanaframework.org/

代码搜索:

http://github.com/

Posted in 未分类 | Tagged | Leave a comment

赚钱的简单方法

觉得不错,转贴一篇。

1、选定一个好的文章发布系统,好的是指对引擎友好,对浏览者阅读友好
2、买一个DV,或者可以拍摄moive的DC
3、选一个或几个老百姓敢兴趣的主题,那就是你的文章分类
4、每天不要坐在家里,多多出去,带着DV/DC,看到有趣或者自己觉得有话题可说的人,事,物或者随便什么,拍摄一下,回去写文章
5、为了更好的完成第4条,建议多看一写摄影和电影相关书籍,外加多看一写个人传记,增强拍摄和写评论的能力。
6、学习wiki风格,多为浏览者考虑,切记
7、选择好的流量&money转换工具,列如GGAD,当然GGAD不是主题评论的最好途径,绝对不是。
8、把收入的20%进行广告投入,40%进行投资。
9、多听多说

以上已经过滤法律和道德因素

只是思路,实践靠自己,不要索取太多,要考虑奉献一些。

如果能真正去做的人,我想他是对人类是有贡献的,相信我,没错的。

Posted in 经营 | Leave a comment

优秀程序员的45个习惯

强烈推荐大家将这些打印出来,贴在自己的办公桌旁边的墙上,学习实践。

态度篇

1. 做实事

不要抱怨,发牢骚,指责他人,找出问题所在,想办法解决。对问题和错误,要勇于承担。

2. 欲速则不达

用小聪明、权宜之计解决问题,求快而不顾代码质量,会给项目留下要命的死角。

3. 对事不对人

就事论事,明智、真诚、虚心地讨论问题,提出创新方案。

4. 排除万难,奋勇前进

勇气往往是克服困难的唯一方法。

学习篇

5. 跟踪变化

新技术层出不穷并不可怕。坚持学习新技术,读书,读技术杂志,参加技术活动,与人交流。要多理解新词背后的所以然,把握技术大趋势,将新技术用于产品开发要谨慎。

6. 对团队投资

打造学习型团队,不断提高兄弟们的平均水平。

7. 懂得丢弃

老的套路和技术,该丢,就得丢。不要固步自封。

8. 打破砂锅问到底

不断追问,真正搞懂问题的本质。为什么?应该成为你的口头禅。

9. 把握开发节奏

控制好时间,养成好习惯,不要加班。

开发流程篇

10. 让客户做决定

让用户在现场,倾听他们的声音,对业务最重要的决策应该让他们说了算。

11. 让设计指导而不是操纵开发

设计是前进的地图,它指引的是方向,而不是目的本身。设计的详略程度应该适当。

12. 合理地使用技术

根据需要而不是其他因素选择技术。对各种技术方案进行严格地追问,真诚面对各种问题。

13. 让应用随时都可以发布

通过善用持续集成和版本管理,你应该随时都能够编译、运行甚至部署应用。

14. 提早集成,频繁集成

集成有风险,要尽早尽量多地集成。

15. 提早实现自动化部署

16. 使用演示获得频繁反馈

17. 使用短迭代,增量发布

18. 固定价格就意味着背叛承诺

估算应该基于实际的工作不断变化。

用户篇

19. 守护天使

自动化单元测试是你的守护天使。

20. 先用它再实现它

测试驱动开发其实是一种设计工具。

21. 不同环境,就有不同问题

要重视多平台问题。

22. 自动验收测试

23. 度量真实的进度

在工作量估算上,不要自欺欺人。

24. 倾听用户的声音

每一声抱怨都隐藏着宝贵的真理。

编程篇

25. 代码要清晰地表达意图(免费样章链接)

代码是给人读的,不要耍小聪明。

26. 用代码沟通

注释的艺术。

27. 动态地进行取舍(免费样章链接)

记住,没有最佳解决方案。各种目标不可能面面俱到,关注对用户重要的需求。

28. 增量式编程

写一点代码就构建、测试、重构、休息。让代码干净利落。

29. 尽量简单

宁简勿繁。如果没有充足的理由,就不要使用什么模式、原则和特别的技术。

30. 编写内聚的代码

类和组件应该足够小,任务单一。

31. 告知,不要询问

多用消息传递,少用函数调用。

32. 根据契约进行替换

委托往往优于继承。

调试篇

33. 记录问题解决日志(免费样章链接)

不要在同一地方摔倒两次。错误是最宝贵的财富。

34. 警告就是错误

忽视编译器的警告可能铸成大错。

35. 对问题各个击破(免费样章链接)

分而治之是计算机科学中最重要的思想之一。但是,要从设计和原型阶段就考虑各部分应该能够很好地分离。

36. 报告所有的异常

37. 提供有用的错误信息(免费样章链接)

稍微多花一点心思,出错的时候,将给你带来极大便利。

团队协作篇

38. 定期安排会面时间

常开会,开短会。

39. 架构师必须写代码(免费样章链接)

不写代码的架构师不是好架构师。好的设计都来自实际编程。编程可以带来深入的理解。

40. 实行代码集体所有制

让开发人员在系统不同区域中不同的模块和任务之间轮岗。

41. 成为指导者

教学相长。分享能提高团队的总体能力。

42. 让大家自己想办法(免费样章链接)

指引方向,而不是直接提供解决方案。让每个人都有机会在干中学习。

43. 准备好后再共享代码

不要提交无法编译或者没有通过单元测试的代码!

44. 做代码复查

复查对提高代码质量、减少错误极为重要。

45. 及时通报进展与问题(免费样章链接)

主动通报,不要让别人来问你。

Posted in 未分类 | Leave a comment