#logo
PHOTO   GUESTBOOK

Totoal 2 article(s) about '关注领域/interest/Web & Network'

  1. windows7下PHP5.3.x访问MySQL连接错误问题 2010/05/23
  2. Apache Rewrite Module (2) 2008/03/26
好久没玩这东西了。
看了下上次备份下来的,PHP5.1.x,MySQL5.0.x,还是个Dev版本。
直接去抓了最新的发布版,升到Apache/2.2.15 (Win32) +PHP/5.3.2(Win32 VC6)+MySQL5.1.47(Win32),OS是Win7(x86)。

配置web服务器不是一次两次了,不过这次版本跨度有点大,还是看了下各个官方的升级说明。
Apache和MySQL变化不大,倒是这个PHP5.3.x以后变化有点大。
首先是Access的方式变化,



引用官方说明就是,
MySQL也为PHP6专门设计了一个native driver,称为mysqlnd,这是一个采用PHP开源协议(即 PHP license)的MySQL数据库驱动,避免了任何可能存在的版权问题,所以PHP开发者可以放心大胆地使用。

mysqlnd成为php 5.3中的默认mysql驱动,它有如下优点:
解决了版权隐患问题,如上所述;由于版权问题,PHP5中没有默认支持MySQL,不像以前的PHP4那样可以直接使用MySQL函数。Mysql支持还需要把libmysql.dll复制到windows目录,然后修改php.ini等等,比较麻烦。
功能改进、效率提高,包括优化过的数据库持久化连接,这非常重要;
mysqlnd编译安装更简单,因为它是php源码树的一个组成部分;
Mysqlnd目前只支持PHP6,将来会支持PHP5,因为PHP5的接受程度一直在稳定上升,特别是很多PHP开发框架如Zend Framework等的渐渐普及,将带动PHP5的普及;
mysqlnd和php内部机制结合更紧密,是优化过的mysql驱动;
mysqlnd更节省内存,从测试结果来看,比传统的mysql扩展节省40%的内存;
mysqlnd更快;
mysqlnd提供了丰富的性能统计功能;
这个改动应同时对mysql和pdo_mysql扩展生效。
看上去不错,而且不用像以前那样把一堆文件复制到 \Widnows\System32下面了。

可这次装完,问题来了。
Warning: mysql_connect() [function.mysql-connect]: [2002] 由于连接方在一段时间后没有正确答复或连接的主机没有反应,连接尝试 (trying to connect via tcp://localhost:3306) in D:\www\index.php on line 9 ”
经Console连接测试,确认了MySQL安装正确,而且HTTPD+PHP的环境在没有MySQL连接的情况下工作正常。

先看了下MySQL和PHP文档的相关说明,
The error (2002) Can't connect to ... normally means that thereis no MySQL server running on the system or that you are using an incorrect Unix socket file name or TCP/IP port number when trying to connect to the server. You should also check that the TCP/IP port you are using has not been blocked by a firewall or port blocking service.

PHP manual says the following on mysql_connect:

Note: Whenever you specify "localhost" or "localhost:port" as server, the MySQL client library will override this and try to connect to a local socket (named pipe on Windows). If you want to use TCP/IP, use "127.0.0.1" instead of "localhost". If the MySQL client library tries to connect to the wrong local socket, you should set the correct path as Runtime Configuration in your PHP configuration and leave the server field blank.

接下来做了下Google作业,确认出现的问题是否是因为这个原因导致的。搜索关键字是"PHP5.3 MySQL 错误"还有"PHP5.3 MySQL error 2002"。
看来碰到和我一样问题的人还不少,基本上都是Win7上配置的人。
根据说明和其他人碰到的问题的描述,试了下将localhost改成127.0.0.1访问就可以了。看来是localhost的解释问题。
打开hosts文件一看,Win7下对localhost 127.0.0.1一行是被注释掉的...
将注释删掉,再用localhost访问,OK~
2010/05/23 18:34 2010/05/23 18:34
#fist posted at 2010/05/23 18:34
No Trackback, No Comment

前几天在VirtualHost上装了一个TextCube。
这东西很多地方用Rewrite来重写URL美化了URL。
不知道作者的本意是美化还是隐藏其真实路径,但确实简化了PATH_INFO中过长的地址信息。

因为我的TC不是放在站点WEB根目录下的,以后我还想放一些其他目录而且同样想把PATH_INFO简化,所以装了TC后顺便将其Rewrite部分做了些补充和优化。

好像很久没有用这东西了,上一次用这东西好像还是两年前,有些应用还真想不起来。
做完顺便整理了一下Rewrite的应用,算是做个Memo。

一、哪些情况需要使用URL Rewrite
在通常的网站更新和维护中,根据各类需求,会发生服务器转移、维护、目录结构的重新组织、变换URL甚至改变到新的域名等情况。而为了让用户不会因此受到任何影响,最好的方法就是使用URL Rewrite(这里我只讨论Apache的Rewrite模块,mod_rewrite)。
所以,URL Rewrite的最大的好处算是隐藏后台实现了。
这在后台应用平台的迁移时非常有用,对于前台用户来说,根本感觉不到后台应用的变化。

二、Apache Url Rewrite的作用范围
1、Apache主配置文件httpd.conf中;
2、httpd.conf里定义的虚拟主机配置中;
3、Web目录的跨越配置文件.htaccess中(此时所涉及到的目录的AllowOverride设定值需设置成为FileInfo)。

三、Apache URL Rewrite的应用条件
当用户的Web请求最终被导向到某台Web服务器的Apache守护进程,Apache根据配置文件判断该请求是主配置还是虚拟主机,再根据用户在浏览器中请求的URL来匹配Apache URL Rewrite,并且根据实际的请求路径匹配.htaccess中的Apache URL Rewrite,最后把请求的内容传回给用户。该响应可能有2种。
1、将请求内容外部重定向(Redirect)到另一个URL。
让浏览器再次以新的URL发出请求(R=301或者R=302,临时的或是永久的重定向)。
如,一个网站有正规的URL和别名URL,对别名URL进行重定向到正规URL,或者网站改换成了新的域名,则把旧的域名重定向到新的域名。

2、由Apache内部子请求代理产生新的内容送回给用户。
这是Apache内部根据重写后的URL,通过代理模块请求内容并将最终内容送回给客户,客户端浏览器不必再次请求,浏览器中的URL不会被重写,但实际内容由Apache根据Apache URL Rewrite后的URL生成。
例如,在公司防火墙上运行的Apache启动这种代理Apache URL Rewrite,代理对内部网段上的Web服务器的请求。

四、应用事例

mod_rewrite

首先,可以使用rewrite的前提是确定加载了 mod_rewrite 模块。

Apache 1.x 需要确认 conf/httpd.conf 中有如下两段代码,且注释已被去掉:

  LoadModule rewrite_module libexec/mod_rewrite.so
  AddModule mod_rewrite.c

Apache 2.x 需要确认 conf/httpd.conf 中有如下代码,且注释已被去掉:

LoadModule rewrite_module modules/mod_rewrite.so

mod_rewrite指定和语法,设定值:

指令 语法 默认值
RewriteEngine RewriteEngine on|off Off
RewriteOptions RewriteOptions Option MaxRedirects=10
RewriteLog RewriteLog file-path None
RewriteLogLevel RewriteLogLevel Level RewriteLogLevel 0
RewriteLock RewriteLock file-path None
RewriteMap RewriteMap MapName MapType:MapSource Notused per default
RewriteBase RewriteBase URL-path physical directory path
RewriteCond RewriteCond TestString CondPattern None
RewriteRule RewriteRule Pattern Substitution None

其中:

RewriteEngine 为开关重构引擎
RewriteOptions 设置一些特殊参数
RewriteLog 为设定重写log文件
RewriteLogLevel 设置日志级别
RewriteLock 设置RewriteMap程序的同步锁文件
RewriteMap 定义重写影射
RewriteBase 设置目录范围内重写的基本URL
RewriteCond 定义规则条件,可以通过检查HTTP_REFERER,REQUEST_FILENAME,HTTP_HOST等实现。-f表示硬盘中存在此文件,!-f表示文件不存在。
RewriteRule 定义重写规则


假定Apache被编译安装在主机192.168.1.xx的/usr/local/apache目录下面,同时编译了重写和代理模块。

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

(1)httpd.conf的实现方法

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

< Directory “/usr/local/apache/htdocs/manual/”>
   options Indexes followsymlinks
   allowoverride all
   rewriteengine on
   rewritebase /
   rewriterule ^(.*)$ index.html.en [R=301]
< /Directory >

注:“rewriteengine on”为重写引擎开关,如果设为“off”,则任何Apache URL Rewrite定义将不被应用,该开关的另一用处就是如果为了临时去掉Apache URL Rewrite,可以将引擎开关设为“off”再重新启动Apache即可,不必将其中的各条Apache URL Rewrite注释掉。

“rewritebase /”的作用是如果在下面的rewriterule定义中被重写后的部分(此处为文件名index.html.en)前面没有“/”,则表明是相对目录,相对于这个rewritebase后面的定义也就是/usr/local/apache/htdocs/index.html.en,否则,如果此处没有“rewritebase /”这一项,则被重写成http://192.168.1.xx/usr/local/apache/htdocs/manual/index.html.en,显然是不正确的。

我们也可以不用“rewritebase /”,而是将其改为如下部分。

rewriteengine on
rewriterule ^(.*)$ /index.html.en [R=301]

或者更改为:

rewriteengine on
rewriterule ^(.*)$ http://192.168.1.xx/index.html.en [R=301]

(2).htaccess的实现方法

我们将下面的部分放到httpd.conf中。

< Directory “/usr/local/apache/htdocs/manual/”>
   options Indexes followsymlinks
   allowoverride all
< /Directory >

然后将下面的部分放到/usr/local/apache/htdocs/manual/.htaccess中。
注: 对文件.htaccess所做的任何改动不需要重启动Apache。

rewriteengine on
rewritebase /
rewriterule ^(.*)$ index.html.en [R=301]

还可以利用.htaccess方案将这个manual目录重定向到用户phpoa自己的主目录。

rewriteengine on
rewritebase /~phpoa/
rewriterule ^(.*)$ $1 [R=301]

这样,对manual目录下任何文件的请求被重定向到~phpoa目录下相同文件的请求。

2、将http://www.username.domain.com对于username的主页请求转换为对http://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”表明是条件Apache URL Rewrite,当满足后面定义的条件后才会应用下面的重写规
则,“rewritecond”有各种变量,请查阅相关文档。

3、防火墙上的Apache Url Rewrite代理内部网段上服务器的请求

NameVirtualhost 1.2.3.4

< Virtualhost 1.2.3.4:80 >
    servername www.domain.com
    rewritengin on
    proxyrequest on
    rewriterule ^/(.*)$ http://192.168.1.3/$1 [P,L]
< /Virtualhost >

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

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

转换http://www.domain.com/{countrycode}/anypath到Map表中规定的URL,前面是虚拟主机中的定义。

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] )$ ${sitemap:$2|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和 rewriteloglevel 9联合,9为最大,即得到最多的调试信息;最小为1,表示得到最少的调试信息;默认为0,表示没有调试信息。



Some quick stuff:

在REWRITE的设定中会使用很多正则表达式,下面是一些最基本的正则表达式;

  • ([a-z]+) - just small letters
  • ([A-Z]+) - just big letters
  • ([0-9]+) - just numbers
  • ([a-zA-Z_-]+) - small and big letters and minus (-)
  • ([a-zA-Z0-9_-]+) - small and big letters, numbers and minus (-)
  • (.*) - everything - warning!!!! don't ever use - this have to much permissions



注:apache官方不建议使用.htaccess方式,可能是出于安全性的考虑吧。

2008/03/26 02:44 2008/03/26 02:44
#fist posted at 2008/03/26 02:44
No Trackback, Comments (2)