PHP 权限设计及算法

权限设计

大概有这几种 模式:

用户+组+角色+权限

用户+组+权限

用户+角色+权限

用户+权限

最近看了别人的设 计方法,大多以“整数”来表示权限值,如添加、浏览、删除和修改,分别用1、2、4、8这几个整数来代替,不过,各人的做法有所不同,举例如下:

1. 用2的n次幂组成权限值的集合,如1、2、4、8、16...,某用户的权限值为其子集中的整数之和,如 7=1+2+4,5=1+4。如果要从数据库检索包含某几种权限的用户,则先把这几种权限值相加,假设和为k,然后select * from table where 1 and 用户权限值 = 'k';如果要判断某用户有哪些权限,则取出其权限值k,分别用k&1,K&2,K&4,k&16...,如果为真,则 表示有值等于“&”右边整数的权限,例如,如果k&4为真,则此用户有权限表中值等于4的权限;

2.用质数2、3、5、 7、11...组成权限集合,某用户的权限为其子集中各整数的乘积,如 210 = 2*3*5*7,我觉得这种方法很有趣,难点在于如何分解质因数;但我有些不认同原作者的提法,他认为权限之间可能存在包含关系,如某用户有删除权限,则 其一定有浏览权限,要不然就没法删除,事实确实是这样,不过我认为这样太复杂了,容易出错,我觉得权限最好是“原子”的,互不干扰,也就是说某用户有删除 权限而没浏览权限则其无法进行删除操作,

 

 因为他看不到东西,解决这个矛盾的 关键是在给用户赋权时,把浏览权限也赋给他;

3.不用整数,而 是用“向量表”方法(也许我说的不一定对),把所有可能的权限按一定的顺序排列,如添加、浏览、修改、删除...,用户的权限值为固定100位长度的字符 串,如100010100001....01,从左起每一位对应一种操作权限,如果有这种权限,则此位的值为1,反之,则为0,作者之所以把用户权限值固 定为100位,我想是考虑到升级问题,但我认为这还不够科学,我认为用户的权限值长度应小于权限个数,举例如下:

权限排列表:添加、浏览、修改、删除,用户A有添加和浏览的的权限,则其权限值为11,用户B有浏 览和修改的权限则其权限值为011,用户C有浏览和删除的权限则其权限值为0101,这样设计的好处为:当权限表中增加别的权限时,不会影响用户表或角色 表;

4. 我曾经的做法,在后台管理中把权限分为两大类:栏目权限和操作权限,每个栏目对应一个目录,操作权限细分为浏览、添加、修改和删除,用户进入系统后首先判 断有没有栏目权限,然后判断有没有操作权限,判断栏目权限相对简单一些,首先获取访问页面的路径path,然后分解出目录,对应用户拥有的目录权限,如果 此目录包含在用户有权管理的目录数组中(从数据库取出),则其有进入此目录的权限,否则,没有,然而,在判断操作权限好象有些麻烦,但突然想到添加、浏 览、修改和删除与我的文件命名规则是基本是对应的,但有点不同的是,我把添加和删除的功能合并在一个文件中了,例如文件名为 proAddEdit.php,幸好意识到修改文件时多了个传递参数id,于是,我用正则解决了这个问题,今天看来,这种方法似乎过时了,因为不适应面向 对象的思想和用框架体系来开发系统!

IIS下PHP的CGI,ISAPI,FastCGI比较

来自php
-under-iis-for-cgi-isapi-fastcgi
-compare/">博吧

在Windows IIS 6.0下配置
PHP,通常有CGI、ISAPI和FastCGI三种配置
方式
,这三种模式
都可以在IIS 6.0下成功运行,下面我就讲一下这三种方式
配置
区别
和性能上的差异。

  1、CGI(通用网关接口/Common Gateway Interface)一般是可执行程序
,例如EXE文件
,和WEB服务器
各自占据着不同的进程
,而且一般一个CGI程序
只能处理一个用户
请求
。这样,当用户
请求
数量非常
时,会大量占用系统
资源
,如内存、CPU时间
等,造成效能低下。

  2、ISAPI(Internet Server Application Program Interface)是微软
提供的一套面向WEB服务的API接口,它能实现CGI提供的全部功能
,并在此基础上进行
扩展
,如提供了过滤器应用程序
接口。ISAPI应用大
数以DLL动态
库的形式
使用
,可以在被用户
请求
后执行,,在处理完一个用户
请求
不会
马上消失,而是继续驻留在内存中等待处理别的用户
输入。此外,ISAPI的DLL应用程序
和WEB服务器
处于同一个进程
中,效率
要显著高于CGI。

  在Windows Server 2003的IIS6下配置
ISAPI方式
的PHP,配置
方法
是,在IIS的“WEB服务扩展
”中,添加一个新的WEB服务扩展
程序
后缀
为PHP,ISAPI程序
php
5isapi.dl
l,然后再“环境变量
”-“系统
变量
”中增加变量
名PHPRC,数值
php
.ini的路径
,在Internet信息
服务管理器中,选择
网站
或应用程序
的根目录
,打开目录
属性
页(右键选择
属性
”),再选择
“主目录
”。点击“配置
按钮
选择
“映射”Tab页。点击“添加...”,在“可执行文件
”设为: c:\php
\php
5isapi.dl
l,扩展
名" title="扩展
名" >扩展
名设为.php
选择
“确认文件
是否存在”,然后“确定”保存设置
。重启服务器
即可完成PHP的配置

  3、FastCGI是可伸缩架构的CGI开放扩展
,其主要行为是将CGI解释器进程
保持在内存中并因此获得
较高的性能。传统的CGI解释器的反复加载
是CGI性能低下的主要原因
,如果CGI解释器保持在内存中并接受FastCGI进程
管理器调度,则可以提供良好的性能、伸缩性等。

  FastCGI已经集成于IIS7,也支持
IIS6,在IIS6中的安装
方法
可参见微软
的官方文档
,我这里简单翻译一下。

  先点这里下载
一个32位的FastCGI extension
for IIS,然后将其安装
安装
后的文件
应该
放到system32\inetsrv目录
下。

  之后打开system32\inetsrv目录
,执行下面的
句" title="
句" >
句,其中c:\php
为你的PHP目录
,可以修改为其他数值

  cscrip
t fcgiconf
ig.js
-add -section:"PHP" -extension
:php
-path:"c:\php
\php
-cgi.exe
"

  在Internet信息
服务管理器中,选择
网站
或应用程序
的根目录
,打开目录
属性
页(右键选择
属性
”),再选择
“主目录
”。点击“配置
按钮
选择
“映射”Tab页。点击“添加...”,在“可执行文件
”设为: c:\windows\system32\inetsrv\fcgie
xt.dl
l,扩展
名" title="扩展
名" >扩展
名设为.php
选择
“确认文件
是否存在”,然后“确定”保存设置

  修改php
.ini文件
,增加如下
句" title="
句" >
句:

  fastcgi
.impersonate = 1
  cgi.fix_pathinfo = 1
  cgi.force_redirect = 0

  之后打开system32\inetsrv目录
,执行以下
句" title="
句" >
句:

  cscrip
t fcgiconf
ig.js
-set -section:"PHP" -InstanceMaxRequests:10000
  cscrip
t fcgiconf
ig.js
-set -section:"PHP" -EnvironmentVars:PHP_FCGI_MAX_REQUESTS:10000

  最后,配置
c:\php
目录
安全
性,使得IIS_WPG组对于这个目录
有读取和执行的权限

  这时候,基于FastCGI的PHP就成功配置
到IIS6上了。

  不过根据我自己的测试,FastCGI的性能比ISAPI的好像高不了
少,不知道Windows Server 2008下的IIS7是不是
会好一些。这里是微软
提供的基于内置FastCGI的IIS7安装
PHP的方法

格式化php代码的两种方法

 

本文来自小屋sjolzy.cn【原创】

 

1/     组装 phpCodeBeautifier + Emeditor (详细见:php格式化代码+Emeditor 太爽了

下载phpCB.exe(下载地址:http://www.waterproof.fr/products/phpCodeBeautifier/

使用Emeditor扩展外部工具:工具->打开外部工具->自定义工具->新建
标题,php代码格式化
命令,点击浏览,找到phpCB.exe的路径
参数,"$(Path)" 
初始目录,不填 
图标,随便
保存文件,可打勾可不打
使用输出栏,打上勾
之后打开php文件 就能选工具里的php代码格式化,就会输出格式化后的代码。再保存一下。

 

2/    phpCB批量转换的php程序(详细见:phpCB批量转换php文件视图/)

 

phpCB批量转换的php程序:
<?
header("Content-type: text/html; charset=gb2312");
 
define('ROOT_PATH', dirname(__FILE__));
 
$topath="ww"; //要格式化视图的目录名,前后都不要“/”
$path=ROOT_PATH."/".$topath;
$arr=get_all_files($path);
 
for($i=0;$i<count($arr);$i++)
{
 
$phpext=fileext($arr[$i]);
if($phpext=="php")
{
$cmd="phpCB.exe ".$arr[$i]." > ".$arr[$i].".phpCB";
system($cmd);
unlink($arr[$i]);
@rename($arr[$i].".phpCB",$arr[$i]);
 
}
 
}
 
function get_all_files($path){
$list = array();
foreach(glob($path . '/*') as $item){
if(is_dir($item)){
$list = array_merge($list , get_all_files( $item ));
} else {
$list[] = $item;
}
}
return $list;
}
 
function fileext($filename) {
return trim(substr(strrchr($filename, '.'), 1, 10));
}
 
?>

使用方法:把phpCB.exe放在windows/system32/目录下,php执行程序和要转换的文件夹放同一级路径,先配置$topath,然后在浏览器里访问本程序,没有结果输出。

标签: php, 代码, 目录, 工具

更改 Firefox 的缓存目录

在 Firefox 地址栏输入 about:cache 以后可以看到 Firefox 的默认磁盘缓存目录是在 Windows 用户配置文件夹里面。

设置磁盘缓存目录放入其他目录:

地址栏输入 about:config,右键新建两个字符串,一个名为: "browser.cache.disk.parent_directory" (硬盘缓存)
另一个名为:"browser.cache.offline.parent_directory"(脱机缓存)

然后输入新的临时文件的路径即可。比如 D:\Temporary Internet Files
检查 browser.cache.disk.enable和browser.cache.offline.enable,这个必须要设定为 true
地址栏输入 about:cache,可以看到缓存目录已经改变了。

改变firefox的配置文件目录:

在关闭firefox的情况下运行firefox -p打开配置工具,新建配置文件,选择目录。可以删除原配置,不过如果不手动将原来的配置文件复制到新的目录,启动firefox后要重新配置。

如何写MVC基础框架



转老逆原创帖!

VC模式下,客户直接发送请求到控制器,控制器根据用户请求的资源分发到相对应的模型来处理,模型完成了业务逻辑后,把所要的数据发送到视图,视图显示返回给客户。这就是web 或是说B/S架构的MVC工作流程。

控制器:

用户的所有请求会发送到控制器,由控制器来根据需要调用模型和视图。比如用户请求index.php 控制器文件,index.php里面不会设计到任何的数据库操作、逻辑操作。它只会寻找执行用户请求的业务模型,把所有的业务逻辑操作交给模型也就是 MVC中的M。把控制器独立出来,形成单入口访问模式,方便做全局管理,比如:日志记录等。

模型:

模型是业务逻辑数据的集合,比如数据库操作,复杂的逻辑运算等。按照功能或项目模块来分成一个个模型,模型间的耦合性很小有利于项目以后的扩展和修改。

视图:

Web技术中的MVC的C层。其主要是由 HTML 、XML语言组成的界面。以前的web界面是视图和模型混杂在一起使用,形成了杂乱的代码,这样使日后程序的维护十分艰难。PHP中知名的模板引擎 smarty 就是为了实现模型和视图分离的一种技术。现在smarty 在PHP行业中被开发者广泛使用。

MVC思想不是为了某种语言而设计的,它适用于所有的面向对象的语言。比如知名的实现MVC思想的JAVA语言的 Struts 框架。当然PHP 框架也是百花齐放如 :Zend Framework 、 Fleaphp 、Thinkphp 、Cakephp 等,都能很好的实现MVC思想而且他们大量应用了GOF 设计模式,开发人员如果基于以上几种MVC框架来进行项目开发的话,开发的效率和代码质量都会大幅度提升,特别是多人协作开发的项目。那PHP怎么实现 MVC的呢?下面给大家开发一个简单的MVC基础框架来说明这一点,完整代码附光盘09/20。

类驱动

在php5中可以使用__autoload 函数来实现类自动加载。但单纯这样的方式不够灵活的。比如类文件存放在不同的目录里面,而此时又需要自动加载的情况下,我们就需要在__autoload函数里进行复杂的逻辑判断来实现自动加载。
比如需要实例化两个类:Myblog 、Mybook。Mylog类在根目录下的Lib/test.php 文件里,Mybook类在根目录下的App/command.php 文件里。

__autoload

函数里实现加载:


[php]php
function __autoload($class){

if($class =='Myblog') include 'Lib/test.php';

if($class =='Mybook') include 'App/command.php';



if(!include_once($classpath)){//加栽类

throw newException("加载类库失败");

}
}
[size=10.5pt]?>

这只是实例化两个不同目录下的两个类而已。如果项目中使用面向对象开发的话,类不会那么少,大家可以想像一下。如果要加载数个不同目录下的类,在__autoload函数里实现会是多么的麻烦和不灵活。

在这里给出个比较简单的解决方案,而且这个解决方案在很多MVC框架中都得以很好的应用

我们只需要在类的命名方式上做些改变,以类的目录路径为类名:

/Yhmphp/ App.php 里的Mysession类,命名为:Yhmphp_App_Mysession。用‘ _ ’下划线来替换

路径分割符,以相对路径下的目录路径做类名。

又比如根目录下的Lib目录下test.php 文件里面(/Lib/test.php) 有个Myblog 类,可以这样给Myblog类命名:

class Lib_Myblog{}
?>
实例化Lib_Myblog类:

$myblog = newLib_Myblog;
[size=10.5pt]?>

__autoload函数里用str_replace函数把路径分割符替换类名中的‘ _ ’下划线,这样就可以准确的找到Lib_Myblog类的所在文件的路径然后准确的加载了:

function __autoload($class){

$classpath =str_replace('_','/',$class).'.php';

if(!include_once($classpath)){//加栽类

throw newException("加载类库失败");

}
}
[size=10.5pt]?>

模型的路由:

当我们给单入口文件(控制器)index.php
加上了模型选参m(index.php?m=myblog),控制器就会去寻找 myblog模型类,并实例化,然后执行myblog模型类中的 model 方法,最后执行show方法
来显示视图。

class App_Run
{

publicfunction routing(){

$model =MOBILE_MODEL.'_'.MODEL_SWITCHING.'_'.$_REQUEST['m'];

if(class_exists($model)){

$cake= new $model;

method_exists($cake,'model')&& $cake->model(); //执行模型里面的 model方法

method_exists($cake,’show’)&& $cake->show(); //视图层

}else{

thrownew Exception("数据模型不存在");

}
}
}
[size=10.5pt]?>

常量MBILE_MODEL定义了模型存放的目录名,在这里做了定义方便日后模型目录的更改。这是个良好的习惯。能统一定义的信息就该统一。能模块化的业务逻辑就应该模块化。为日后的项目维护和项目扩展做好铺垫。

MBILE_MODEL

在Config/__Active.php文件里面这样定义:

[php]php
/**
系统配置
*/
define('MOBILE_ROOT', ''); //站根目录
define('MOBILE_MODEL','Modules'); //模型目录名
[size=10.5pt]?>

class_exists() 函数来判断客户请求的($_REQUEST['m']) 模型类是否存在。Class_exists() 方法依据__autoload() 函数来加载判断。所以__autoload()函数必须在class_exists() 方法之前先加载。

模型类如果存在,就使用method_exists() 方法来判断执行模型类里面的model 方法里面的业务逻辑,然后再执行show() 方法显示视图。这样就完成了一个 MVC 流程。

存放模型的目录是 Modules 目录。这个在上面的MOBILE_MODEL常量中已经定义。难道所有的业务模型都存在一个Modules目录里面吗?这样的设计的确有点问题。文件夹里 面的文件过多,损耗程序寻找模型加载的时间,而且模型过多存在一个目录之中,会让这个项目变得很杂乱。比如前台和后台的模型目录和视图目录就应该分开存 放。

/**
多模型目录
*/
if(empty($_GET['c']) && ) $_GET['c'] ='Default';
if(empty($_GET['m'])) $_GET['m'] = 'Index';

define ('MODEL_SWITCHING',$_GET['c']) ; //前台后台目录切换
[size=10.5pt]?>

常量MODEL_SWITCHING 就是为解决这个问题设计的:
我们先看最后一句代码:

[size=10.5pt]define('MODEL_SWITCHING',$_GET['c']) ; //前台后台目录切换


它定义了常量MODEL_SWITCHING 以$_GET ['c']变量为值。App_Run 类中,常量MOBILE_MODEL 、MODEL_SWITCHING 和$_GET['m'] 组成了模型的加载路径:
$model = MOBILE_MODEL.'_'.MODEL_SWITCHING.'_'.$_GET['m'];

这样设计以后我们想添加多个模型目录都是很容易的事情了。比如:项目需要添加两个模型目录。前台模型目录:Default 和 后台模型目录:Admin 。只需要在默认的模型目录 Modules 下创建 Default 和Admin 两个目录,然后客户访问的URL 中 添加一个 参数c :
访问Default 目录下的Myblog业务模型: index.php?c=default&m=myblog
访问Admin 目录下的Member业务模型: index.php?c=admin&m=member
我们可以再设计灵活及人性化点,就是当$_GET[‘m’]和$_GET[‘c’] 客户没有设置的时候来给模型目录和业务模型类设置一个默认值。
if(empty($_GET['c'])
) $_GET['c'] = 'Default';
if(empty($_GET['m'])) $_GET['m'] = 'Index';

控制器
PHP MVC典型的设计就是使用单入口php文件来实现MVC中的C:控制器。所有的客户请求全部经过index.php 控制器集中控制。然后按需进行分发:

/**
入口文件
*/
try{

error_reporting(E_ALL);//关闭错误输出

require'Config/__Homeswitching.php';

require'Config/__Active.php';

require'App/Auto.php';


$set = newApp_Run;

$set->routing();


}catch (Exception $e){


echo($e->getMessage());


}
[size=10.5pt]?>

多模型设置文件:__Homeswitching.php,定义基础模型目录文件:__Active.php,类驱动文件:Auto.php
加载完后,再实例化模型路由App_Run类,执行其 routing() 方法 寻找完成客户请求。

业务模型

业务模型类是整个项目中使用最多的。它就是MVC 中的M (模型)。类里面封装了大量的业务逻辑。比如:客户向index.php 控制器 请求 (index.php?m=newbook)newbook业务模型,来查询最新出的图书。 那么newbook业务模型类所需要完成的任务就是查询数据库,从数据库中提取最新的图书资料,然后发送到视图层(View)显示给客户。显然,MVC 模式可以把 模型与模型、功能与功能之间的耦合度变得很小、扩展性很强。

/**

* 模型类

* */
class Modules_Default_Index
extends App_Manage
{



privatenewbook=’’;

publicfunction __c****truct(){

parent::__c****truct();

}



publicfunction show(){

$this->tpl->assign(‘newbook’,$this->newbook);
 
$this->tpl->display('Index');

}



publicfunction model(){

/**实现业务逻辑*/

$this->newbook = ‘PHP MVC’;

}
}
[size=10.5pt]?>

业务模型类里面有两个主要方法: model() 、show() 方法。Model() 方法主要实现业务逻辑,比如:读数据库、写数据库等。Show() 方法主要和model() 方法联系获取业务逻辑的数据,然后输出给视图(php模板)。

读者请思考下以下几个问题:
模型类 Modules_Default_Index 为什么要起这个名字?前面__autoload讲解中已讲解。Show() 方法是否能去掉只实现model() 模型?模型的路由小节中讲解。

全局类
在项目开发里,有很多我们自己封装好的类:数据库操作类、模板类、email发送类、分页类、文本缓存类、内存缓存类memcache等等。这些 类中有些是每个模型都必须加载使用的,比如 数据库操作类、分页类。难道我们每个模型里都要显式的实例化一次?那真是太麻烦了。所以设计一个全局管理类App_Manage :

class App_Manage{
protected$tpl;
protected$mem;
protected$email;
publicfunction __c****truct(){

$this->tpl = new Lib_Tpl;
/*
$this->mem = new Lib_Memcached;


$this->email= new Lib_Mailer();*/
}
[font=宋体]}[/font]
[font=宋体][size=10.5pt]?>

在App_Manage中。我们简单的在其构造方法中实例化了几个常用的类。每个模型都继承App_Manage类,这样模型类里面就可以使用父类的方法和属性,以此实现全局类:

public function __c****truct(){

parent::__c****truct();

}

 
 

htaccess文件详解


.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 % !^$
RewriteCond % !^http://(www.)?mydomain.com...*$ [NC]
RewriteRule .(gif|jpg)$ - [F]
如果觉得让别人的页面开个天窗不好看,那可以用一张图片来代替:
RewriteEngine on
RewriteCond % !^$
RewriteCond % !^http://(www.)?mydomain.com...*$ [NC]
RewriteRule .(gif|jpg)$ http://www.mydomain.com/替代图片文件名 [R,L]
source:http://wsabstract.com/howt...

编辑本段.htaccess实现网址规范化


网址规范化在SEO中是一个比较重要的环节,同时存在不同的网址版本,不但可能造成复制,还不能正确的集中权重。
目前大多数网站,绑定域名都有带WWW和不带两个版本,甚至很多网站同时绑定多个域名。经过处理(跳转、CNAME……),对于访问者来说可能没有任何影响,看到的都是同样的内容;但对于搜索引擎,就无法确定哪一个网址是真正的主页。
可控因素,网站内容链接应该保持同一个版本,比如整站中,返回首页的地址为固定的一个版本。但还有一个不可控的因素,就是别人链到你的网站,所使用的网址。很多自发链接或交换链接时,别人可能会省略掉WWW,或采用绑定的另一域名。
外界因素不可控,我们可以从网站内部来控制。利用Apache的.htaccess,使用301重定向,规范网址。
新建一个空文件,文件名.htaccess,填入重定向规则后,上传到网站根目录。
用301将不带WWW的域名重定向
rewriteEngine on
rewriteCond % ^379.cc [NC]
rewriteRule ^(.*)$ http://www.379.cc/$1 [R=301,L]
用301将绑定的其他多个域名重定向到主域名
RewriteEngine on
RewriteCond % ^379.cc$ [OR]
RewriteCond % ^bbs.379.cc$ [OR]
RewriteCond % ^luoyang.cc$ [OR]
RewriteCond % ^www.luoyang.cc$ [OR]
RewriteCond % ^bbs.luoyang.cc$
RewriteRule ^(.*)$ http://www.379.cc/$1 [R=301,L]
当然,也可以再扩展一下,将index.html、index.php等也重定向一下:
RewriteEngine on
RewriteCond % ^[A-Z]{3,9}\ /index\.php\ HTTP/
RewriteRule ^index\.php$ http://www.379.cc/ [R=301,L]
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
Blocking users/sites by referrer 根据referrer阻止用户/站点访问
需要mod_rewrite模块
例1. 阻止单一referrer: badsite.com
RewriteEngine on
# Options +FollowSymlinks
RewriteCond % badsite\.com [NC]
RewriteRule .* - [F]
例2. 阻止多个referrer: badsite1.com, badsite2.com
RewriteEngine on
# Options +FollowSymlinks
RewriteCond % badsite1\.com [NC,OR]
RewriteCond % badsite2\.com
RewriteRule .* - [F]
[NC] - 大小写不敏感(Case-insensite)
[F] - 403 Forbidden
注意以上代码注释掉了”Options +FollowSymlinks”这个语句。如果服务器未在 httpd.conf 的 段落设置 FollowSymLinks, 则需要加上这句,否则会得到”500 Internal Server error”错误。
Blocking bad bots and site rippers (aka offline browsers) 阻止坏爬虫和离线浏览器
需要mod_rewrite模块
坏爬虫? 比如一些抓垃圾email地址的爬虫和不遵守robots.txt的爬虫(如baidu?)
可以根据 HTTP_USER_AGENT 来判断它们
(但是对于一些搜索引擎把自己的agent设置为 “Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0)” ,就无能为力了)
RewriteEngine On
RewriteCond % ^BlackWidow [OR]
RewriteCond % ^Bot\ mailto:craftbot@yahoo.com [OR]
RewriteCond % ^ChinaClaw [OR]
RewriteCond % ^Custo [OR]
RewriteCond % ^DISCo [OR]
RewriteCond % ^Download\ Demon [OR]
RewriteCond % ^eCatch [OR]
RewriteCond % ^EirGrabber [OR]
RewriteCond % ^EmailSiphon [OR]
RewriteCond % ^EmailWolf [OR]
RewriteCond % ^Express\ WebPictures [OR]
RewriteCond % ^ExtractorPro [OR]
RewriteCond % ^EyeNetIE [OR]
RewriteCond % ^FlashGet [OR]
RewriteCond % ^GetRight [OR]
RewriteCond % ^GetWeb! [OR]
RewriteCond % ^Go!Zilla [OR]
RewriteCond % ^Go-Ahead-Got-It [OR]
RewriteCond % ^GrabNet [OR]
RewriteCond % ^Grafula [OR]
RewriteCond % ^HMView [OR]
RewriteCond % HTTrack [NC,OR]
RewriteCond % ^Image\ Stripper [OR]
RewriteCond % ^Image\ Sucker [OR]
RewriteCond % Indy\ Library [NC,OR]
RewriteCond % ^InterGET [OR]
RewriteCond % ^Internet\ Ninja [OR]
RewriteCond % ^JetCar [OR]
RewriteCond % ^JOC\ Web\ Spider [OR]
RewriteCond % ^larbin [OR]
RewriteCond % ^LeechFTP [OR]
RewriteCond % ^Mass\ Downloader [OR]
RewriteCond % ^MIDown\ tool [OR]
RewriteCond % ^Mister\ PiX [OR]
RewriteCond % ^Navroad [OR]
RewriteCond % ^NearSite [OR]
RewriteCond % ^NetAnts [OR]
RewriteCond % ^NetSpider [OR]
RewriteCond % ^Net\ Vampire [OR]
RewriteCond % ^NetZIP [OR]
RewriteCond % ^Octopus [OR]
RewriteCond % ^Offline\ Explorer [OR]
RewriteCond % ^Offline\ Navigator [OR]
RewriteCond % ^PageGrabber [OR]
RewriteCond % ^Papa\ Foto [OR]
RewriteCond % ^pavuk [OR]
RewriteCond % ^pcBrowser [OR]
RewriteCond % ^RealDownload [OR]
RewriteCond % ^ReGet [OR]
RewriteCond % ^SiteSnagger [OR]
RewriteCond % ^SmartDownload [OR]
RewriteCond % ^SuperBot [OR]
RewriteCond % ^SuperHTTP [OR]
RewriteCond % ^Surfbot [OR]
RewriteCond % ^tAkeOut [OR]
RewriteCond % ^Teleport\ Pro [OR]
RewriteCond % ^VoidEYE [OR]
RewriteCond % ^Web\ Image\ Collector [OR]
RewriteCond % ^Web\ Sucker [OR]
RewriteCond % ^WebAuto [OR]
RewriteCond % ^WebCopier [OR]
RewriteCond % ^WebFetch [OR]
RewriteCond % ^WebGo\ IS [OR]
RewriteCond % ^WebLeacher [OR]
RewriteCond % ^WebReaper [OR]
RewriteCond % ^WebSauger [OR]
RewriteCond % ^Website\ eXtractor [OR]
RewriteCond % ^Website\ Quester [OR]
RewriteCond % ^WebStripper [OR]
RewriteCond % ^WebWhacker [OR]
RewriteCond % ^WebZIP [OR]
RewriteCond % ^Wget [OR]
RewriteCond % ^Widow [OR]
RewriteCond % ^WWWOFFLE [OR]
RewriteCond % ^Xaldon\ WebSpider [OR]
RewriteCond % ^Zeus
RewriteRule ^.* - [F,L]
[F] - 403 Forbidden
[L] - 连接(Link)