1.Apache Rewrite的主要功能
就是实现URL的跳转和隐藏真实地址,基于Perl语言的正则表达式规范。平时帮助我们实现拟静态,拟目录,域名跳转,防止盗链等
2.Apache Rewrite的配置
Apache下的Rewrite配置主要有两种,一种是针对整个apache服务器的配置,此种配置的Rewrite规则是直接在httpd.conf下书写。配置步骤如下:
(1)去除httpd.conf文件中"#LoadModule rewrite_module modules/mod_rewrite.so"前面的"#"号;
(2)然后再在httpd.conf中书写如下规则:
RewriteEngine on
#当访问任何以t_开头,以.html结尾的文件时,将$1用与(.*)匹配的字符替换后,访问相应的test.php页面
RewriteRule ^/t_(.*).html$ /test.php?id=$1
另一种是针对apache服务器下的某一目录的配置,此种配置的Rewrite规则需在此目录下建立一个.htaccess文件来书写。配置步骤如下:
(1)去除httpd.conf文件中"#LoadModule rewrite_module modules/mod_rewrite.so"前面的"#"号;
(2)修改httpd.conf文件中的"AllowOverride None"为"AllowOverride all",同时最好将Options也置为"all",否则可能会出问题。
(3)在目录中建立.htaccess文件,并用记事本打开,书写如下规则:
RewriteEngine on
RewriteRule ^/t_(.*).html$ /test.php?id=$1
3.Apache Rewrite规则的书写
RewriteEngine on
RewriteRule ^/test([0-9]*).html$ /test.php?id=$1
RewriteRule ^/new([0-9]*)/$ /new.php?id=$1 [R]
RewriteEngine on
#当我们访问的地址不是以www.163.com开头的,那么执行下一条规则
RewriteCond %{HTTP_HOST} !^www.163.com [NC]
RewriteRule ^/(.*) http://www.163.com/ [L]
4.Apache Rewrite规则修正符
1) R 强制外部重定向
2) F 禁用URL,返回403HTTP状态码。
3) G 强制URL为GONE,返回410HTTP状态码。
4) P 强制使用代理转发。
5) L 表明当前规则是最后一条规则,停止分析以后规则的重写。
6) N 重新从第一条规则开始运行重写过程。
7) C 与下一条规则关联
如果规则匹配则正常处理,以下修正符无效
8) T=MIME-type(force MIME type) 强制MIME类型
9) NS 只用于不是内部子请求
10) NC 不区分大小写
11) QSA 追加请求字符串
12) NE 不在输出转义特殊字符 %3d$1 等价于 =$1
<IfModule mod_rewrite.c>
RewriteEngine On
# '-s' (is regular file, with size)
# '-l' (is symbolic link)
# '-d' (is directory)
# 'ornext|OR' (or next condition)
# 'nocase|NC' (no case)
# 'last|L' (last rule)
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ createthumb.php?path=%{REQUEST_URI} [NC,L]
</IfModule><?php
define('WWW_PATH', dirname(dirname(__FILE__))); // 站点www目录
require(WWW_PATH.'/PicThumb.class.php'); // include PicThumb.class.php
require(WWW_PATH.'/ThumbConfig.php'); // include ThumbConfig.php
$logfile = WWW_PATH.'/createthumb.log'; // 日志文件
$source_path = WWW_PATH.'/upload/'; // 原路径
$dest_path = WWW_PATH.'/supload/'; // 目标路径
$path = isset($_GET['path'])? $_GET['path'] : ''; // 访问的图片URL
// 检查path
if(!$path){
exit();
}
// 获取图片URI
$relative_url = str_replace($dest_path, '', WWW_PATH.$path);
// 获取type
$type = substr($relative_url, 0, strpos($relative_url, '/'));
// 获取config
$config = isset($thumb_config[$type])? $thumb_config[$type] : '';
// 检查config
if(!$config || !isset($config['fromdir'])){
exit();
}
// 原图文件
$source = str_replace('/'.$type.'/', '/'.$config['fromdir'].'/', $source_path.$relative_url);
// 目标文件
$dest = $dest_path.$relative_url;
// 创建缩略图
$obj = new PicThumb($logfile);
$obj->set_config($config);
if($obj->create_thumb($source, $dest)){
ob_clean();
header('content-type:'.mime_content_type($dest));
exit(file_get_contents($dest));
}
?>
方式二:使用nginx和php实时产生缩略图
当我从后台上传一个截图之后,480*800的截图之后,当时就没有压缩出320*480的小缩略图。好吧,服务器轮询一下,全部产生出320*480的图片。
那下一次呢,又有160*240的图片了,又轮询吗,费时费力,还不能马上就得到小图。这个时候,我们就要开始抱怨了,怎么要这么多种图片啊,设计师,你就不能老早就想好要哪些图片么?
其实,nginx是一个强大的反向代理服务器,通过它的rewrite模块,我们可以实现自动产生缩略图,也不用轮询数据库了。产品设计,要什么尺寸的,客户端直接通过某种规则访问就是了,我马上就产生给你。
而且,后台上传的时候,只要保存一张最大的图片就ok了。
Rewrite方式: nginx
if (!-e $request_filename)
{ rewrite ^/(.*)$ /autoimg.php?r=$1 last; }
Apache:
RewriteEngine On
RewriteRule index.html index.php
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ autoimg.php?path=%{REQUEST_URI} [NC,L]
这样的话,需要其他尺寸的图片,仅仅修改客户端的访问方式即可。
#假设,服务器上面有一个文件:abc.jpg,通过http://filefs.domain.com/file/abc.jpg能够访问到原图。其#实一般的,我们在数据库里面也就保存了“/file/abc.jpg”这部分内容。
#现在,我们要实现通过http://filefs.domain.com/file/abc.jpg.w320.jpg由服务器自动产生#abc.jpg.w320.jpg(w320,320px的宽度)这个缩略图。并返回图片数据。
#要满足以下两个条件:
# 1.如果abc.jpg.w320.jpg存在,则不重新产生图片
# 2.如果不存在,则在同一次的请求中,返回图片数据,和保存图片文件到服务器。
server {
listen 80;
server_name filefs.domain.com;
root /var/www/http/filefs.domain.com;
location / {
index index.html index.htm;
}
location ~ .(png|jpg|jpeg|gif)$ {
#如果文件不存在,则rewrite到产生图片的脚本文件autoimg.php
if (!-f $request_filename) {
rewrite ^/.*$ /autoimg.php;
expires max;
}
#如果文件存在,则设置过期时间,关闭访问日志
if ( -f $request_filename ) {
expires max;
access_log off;
}
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
location ~ autoimg.php$ {#安全性考虑,文件服务器,只这个脚本文件的范围提交给php处理
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /var/www/http/filefs.domain.com$fastcgi_script_name;
include /usr/local/nginx/conf/fastcgi_params;
}
}
<?php
$file = $_SERVER ['REQUEST_URI'];//请求字串 /file/abc.jpg.w320.jpg
$desfile = $_SERVER ['DOCUMENT_ROOT'] . $file; //目标目标路径 /var/www/http/file/abc.jpg.w320.jpg
$dirname = dirname ( $desfile ) . "/";
$filename = basename ( $desfile );
if (preg_match ( "/([^.]+.(png|jpg|jpeg|gif)).w([d]+).(jpg)/i", $filename, $m )) {
$srcfile = $dirname . $m [1];
$width = $m [3]; //匹配出输出文件宽度
if (in_array ( $width, array ( //只产生202和320宽度的文件
202,
320
) ) && file_exists ( $srcfile )) { //而且文件不存在
thumbnail ( $srcfile, $desfile, $width );
}
}
/**
* 生成缩略图
*
* @param 源 $src
* @param 缩放后的宽带 $width
*
*/
function thumbnail($src, $des, $width) {
ob_start ();//开始截获输出流
$imageinfos = getimagesize ( $src );
$ext = strtolower ( pathinfo ( $src, 4 ) );
if ($imageinfos [2] == 1) {
$im = imagecreatefromgif ( $src );
} elseif ($imageinfos [2] == 2) {
$im = imagecreatefromjpeg ( $src );
} elseif ($imageinfos [2] == 3) {
$im = imagecreatefrompng ( $src );
}
if (isset ( $im )) {
$height = $imageinfos [1] * $width / $imageinfos [0];
$dst_img = ImageCreateTrueColor ( $width, $height );
imagesavealpha ( $dst_img, true );
$trans_colour = imagecolorallocatealpha ( $dst_img, 0, 0, 0, 127 );
imagefill ( $dst_img, 0, 0, $trans_colour );
imagecopyresampled ( $dst_img, $im, 0, 0, 0, 0, $width, $height, $imageinfos [0], $imageinfos [1] );
header ( 'content-type:image/jpg' );
imagejpeg ( $dst_img, null, 90 );//输出文件流,90--压缩质量,100表示最高质量。
@imagedestroy ( $im );
@imagedestroy ( $dst_img );
} else {
echo @file_get_contents ( $src );
}
$content = ob_get_contents ();//获取输出流
ob_end_flush ();//输出流到网页,保证第一次请求也有图片数据放回
@file_put_contents ( $des, $content );//保存文件
}
?>