编程相关
编写PHP的安全策略
PHP最初是被称作Personal Home Page,后来随着PHP成为一种非常流行的脚本语言,名称也随之改变了,叫做Professional HyperText PreProcessor。以PHP4.2为例支持它的WEB服务器有:Apache, Microsoft Internet information Sereve, Microsoft Personal web Server,AOLserver,Netscape Enterprise 等等。 PHP是一种功能强大的语言和解释器,无论是作为模块方式包含到web服务器里安装的还是作为单独的CGI程序程序安装的,都能访问文件、执行命令或者在服务器上打开链接。而这些特性都使得PHP运行时带来安全问题。虽然PH P是特意设计成一种比用Perl或C语言所编写的CGI程序要安全的语言,但正确使用编译时和运行中的一些配置选项以及恰当的应用编码将会保证其运行的安全性。 一、安全从开始编译PHP开始。 在编译PHP之前,首先确保操作系统的版本是最新的,必要的补丁程序必须安装过。另外使用编译的PHP也应当是最新的版本,关于PHP的安全漏洞也常有发现,请使用最新版本,如果已经安装过PHP请升级为最新版本:4.2.3 相关链接:http://security.e-matters.de/advisories/012002.html 安装编译PHP过程中要注意的3个问题: 1、只容许CGI文件从特定的目录下执行:首先把处理CGI脚本的默认句柄删除,然后在要执行CGI脚本的目录在http.conf 文件中加入ScriptAlias指令。 #Addhadler cgi-script .cgi ScriptAlias /cgi-bin/ “/usr/local/apache/cgi-bin/” AllowOverride None Options None Order allow,deny Allow from all AllowOverride None Options ExecCGI Order allow,deny Allow from all SriptAlias的第一个参数指明在Web中的可用相对路径,第二个参数指明脚本放在服务器的目录。应该对每个目录 别名都用Directory,这样可使得除系统管理员之外的人不知道Web服务器上CGI脚本的清单。 Directory允许用户创建自己的CGI脚本。也可用SriptAliasMatch,但Directory更容易使用。 允许用户创建自己 CGI脚本可能会导致安全问题,你可能不希望用户创建自己的CGI。 Apache默认配置是注释掉cgi—script的处理句柄,但有/cgi-bin目录使用SriptAlias和Directory指令。 你也可禁止CGI执行,但仍允许执行PHP脚本。 2.把PHP解析器放在web目录外 把PHP解析器放在Web目录树外是非常重要的做法。这样可以防止web服务器对PHP的解析器的滥用。特别是 不要把PHP解析器放在cgi-bin或允许执行CGI程序的目录下。然而,使用Action解析脚本是不可能的,因为用Action指令时,PHP解析器大多数要放在能够执行CGI的目录下只有当PHP脚本作为CGI程序执行时,才能把PHP解析器放在Web目录树之外。 如果希望PHP脚本作为CGI程序执行(这们可以把PHP解析器放在Web目录树之外),可以这样: ( 1)所有的PHP脚本必须位于能执行CGI程序的目录里。 ( 2)脚本必须是可执行的(仅在UNIX/Linux机器里)。 (3)脚本必须在文件头包括PHP解析器的路径。 你可用下面命令使PHP脚本为可执行: #chmod +x test.php4 这样使在当前目录下的文件名为test.PhP4的脚本变为可执行。 下面是一个能作为CGI程序运行的PHP脚的小例子。 #!/usr/local/bin/php echo “This is a my small cgi program” 3....
正则表达式学习笔记
正则表达式(regular expression)描述了一种字符串匹配的模式,可以用来检查一个串是否含有某种子串、将匹配的子串做替换或者从某个串中取出符合某个条件的子串等。 列目录时, dir .txt或ls .txt中的.txt就不是一个正则表达式,因为这里与正则式的*的含义是不同的。 为便于理解和记忆,先从一些概念入手,所有特殊字符或字符组合有一个总表在后面,最后一些例子供理解相应的概念。 正则表达式 是由普通字符(例如字符 a 到 z)以及特殊字符(称为元字符)组成的文字模式。正则表达式作为一个模板,将某个字符模式与所搜索的字符串进行匹配。 可以通过在一对分隔符之间放入表达式模式的各种组件来构造一个正则表达式,即/expression/ 普通字符 由所有那些未显式指定为元字符的打印和非打印字符组成。这包括所有的大写和小写字母字符,所有数字,所有标点符号以及一些符号。 非打印字符 字符 含义 \cx 匹配由x指明的控制字符。例如, \cM 匹配一个 Control-M 或回车符。x 的值必须为 A-Z 或 a-z 之一。否则,将 c 视为一个原义的 'c' 字符。 \f 匹配一个换页符。等价于 \x0c 和 \cL。 \n 匹配一个换行符。等价于 \x0a 和 \cJ。 \r 匹配一个回车符。等价于 \x0d 和 \cM。 \s 匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。 \S 匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。 \t 匹配一个制表符。等价于 \x09 和 \cI。 \v 匹配一个垂直制表符。等价于 \x0b 和 \cK。 特殊字符 所谓特殊字符,就是一些有特殊含义的字符,如上面说的"*.txt"中的*,简单的说就是表示任何字符串的意思。如果要查找文件名中有*的文件,则需要对*进行转义,即在其前加一个\。ls \*.txt。正则表达式有以下特殊字符。 特别字符 说明 $ 匹配输入字符串的结尾位置。如果设置了 RegExp 对象的 Multiline 属性,则 $ 也匹配 '\n' 或 '\r'。要匹配 $ 字符本身,请使用 \$。 ( ) 标记一个子表达式的开始和结束位置。子表达式可以获取供以后使用。要匹配这些字符,请使用 \( 和 \)。 * 匹配前面的子表达式零次或多次。要匹配 * 字符,请使用 \*。 + 匹配前面的子表达式一次或多次。要匹配 + 字符,请使用 \+。 ....
一个简单的中文分词 CLucene
CLucene - a C++ search engine http://sourceforge.net/projects/clucene/ 传统的全文检索都是基于数据库的,Sql Server Oracle mysql 都提供全文检索,但这些比较大,不适合单机或小应用程序(Mysql4.0以上可以作为整合开发),Mysql也不支持中文。 后来得知Apache有一个开源的全文检索引擎,而且应用比较广,Lucene是Apache旗下的JAVA版的全文检索引擎,性能相当出色,可惜是java版的,我一直在想有没有C或C++版的,终于有一天在http://sourceforge.net 淘到一个好东东,Clucene!CLucene是C++版的全文检索引擎,完全移植于Lucene,不过对中文支持不好,而且有很多的内存泄露,:P Cluene不支持中文的分词,我就写了一个简单的中文分词,大概思路就是传统的二分词法,因为中文的分词不像英文这类的语言,一遇到空格或标点就认为是一个词的结束,所以就采用二分词法,二分词法就是例如:北京市,就切成 北京 , 京市。这样一来词库就会很大,不过是一种简单的分词方法(过段时间我再介绍我对中文分词的一些思路) ,当然了,在检索时就不能输入“北京市”了,这样就检索不到,只要输入:“+北京 +京市”,就可以检索到北京市了,虽然精度不是很高,但适合简单的分词,而且不怕会漏掉某些单词。 我照着Clucene的分词模块,做了一个ChineseTokenizer,这个模块就负责分词工作了,我把主要的函数写出来 ChineseTokenizer.cpp: Token* ChineseTokenizer::next() { while(!rd.Eos()) { char_t ch = rd.GetNext(); if( isSpace((char_t)ch)!=0 ) { continue; } // Read for Alpha-Nums and Chinese if( isAlNum((char_t)ch)!=0 ) { start = rd.Column(); return ReadChinese(ch); } } return NULL; } Token* ChineseTokenizer::ReadChinese(const char_t prev) { bool isChinese = false; StringBuffer str; str.append(prev); char_t ch = prev; if(((char_t)ch>>8)&&(char_t)ch>=0xa0) isChinese = true; while(!...
PECL中的clucene库
getMessage() . ‘, ‘; echo ‘File: ‘ . $e->getFile() . ‘, ‘; echo ‘Line: ‘ . $e->getLine(); exit(); } $query = ”; if (isset($_SERVER['argv'][1])) { $query = $_SERVER['argv'][1]; } else { $query = “time”; /* Should return 3 results */ } echo “Search results for: ‘$query’\n”; $hits = $searcher->search($query); $length = $hits->length(); echo “Number of results: $length\n”; for ($i = 0; $i < $length; $i++) { echo 'path: ' . $hits->get($i, ‘path’) ....
数据库编码为gb2312,重新改写了wap程序编码为utf-8
$user = iconv("utf-8", "gb2312",addslashes(urldecode($_POST['username']))); $pass = md5(urldecode($_POST['password'])); $SQL = "SELECT `password` FROM " . USER_TABLE . " WHERE `username` = '$user'"; $Result = $DB -> query($SQL); $Row = $DB -> queryArray($Result); if($Row['password'] == $pass){ session_register(name'); $_SESSION[name'] = iconv("gb2312", "utf-8",$user); }
使用PHP连接LDAP服务器
本文将演示如何使用PHP连接一个LDAP服务器。具体的例子是连接到一个公共的LDAP服务器并且进行搜索。这个例子模拟的是Netscape Communicator 4.*,通过自己的地址本连接到LDAP资源。 LDAP介绍 可能不少人已经听说过LDAP,但是却不了解它具体是什么东东和如何工作。在这里我将不会很详细地介绍LDAP,只是对该协议做一个简介。 LDAP是一个用来发布目录信息到许多不同资源的协议。通常它都作为一个集中的地址本使用,不过根据组织者的需要,它可以做得更加强大。 LDAP最基本的形式是一个连接数据库的标准方式。该数据库为读查询作了优化。因此它可以很快地得到查询结果,不过在其它方面,例如更新,就慢得多。要特别注意的是,LDAP通常作为一个hierarchal数据库使用,而不是一个关系数据库。因此,它的结构用树来表示比用表格好。正因为这样,就不能用SQL语句了。 简单说来,LDAP是一个得到关于人或者资源的集中、静态数据的快速方式。 要求 PHPV.4(以前的版本也可以,不过没有经过测试),编译支持LADP,即使用编译时带–with-ldap公共的LDAP目录。在例子中提供了两个。 例子概览 1.设置公共LDAP服务器的信息 2.创建一个LDAP查询 3.连接到LDAP服务器 4.如果连接成功,处理查询 5.格式化输出 6.关闭连接 7.设计搜索界面的HTML表格 8.显示结果 设置公共LDAP服务器的信息 我们要做的第一件事情是定义所有欲搜索的LDAP服务器的信息 “LDAP_NAME” = 新的LDAP项目的名字 “LDAP_SERVER” = 新的LDAP项目的IP地址或者主机名 “LDAP_ROOT_DN” = 新的LDAP项目的根的辨识名 建立LDAP查询 前面已经提到,LDAP查询与SQL查询是不一样的。因此,语句要受到一定的限制,以下是一个基本的例子。 //Create Query $ldap_query = “cn=$common”; 在我们的例子中,“cn”是我们要进行搜索的属性,而$common是由搜索的form中得到的字符串变量。LDAP的查询语句语句可使用通配符‘*’。例如‘$stanley’将可以找出‘dan stanley’。 连接到LDAP服务器 以下的函数连接到一个LDAP资源,并且将连接的识别号赋给一个变量,就好象连接到一个通常的数据库一样,例如MySQL。 在我们的例子中,“$connect_id”是连接的识别号,$LDAP_SERVER是可能的ldap服务器数组,而$SERVER_ID是由搜索表格得到的LDAP服务器变量。 如果连接成功,处理查询 如果连接成功的话,我们将得到一个有效的LDAP连接识别号,这样我们就可以处理查询。 一旦我们与LDAP服务器建立好连接,我们就必须进行认证。PHP在连接大多数的数据库时,都是通过发送用户名和密码来进行的。不过,在LDAP中,认证是未知的,直到进行一个bind操作。在我们的例子中,“$bind_id”是绑定连接的标识符。我们是通过匿名绑定到公共的LDAP服务器的。因此,在执行ldap_bind()时,只使用连接识别号就可以了,无需其它的参数。 在经过认证后(这里是匿名的),我们就可以使用ldap_search()函数来执行查询,产生的$search_id是我们搜索的连接识别符。 然后,我们使用ldap_get_entries()函数将结果集赋给$result_array变量。这样我们能够以逻辑的方式排列信息,以便显示。 格式化输出 在执行完LDAP搜索后,返回的数据是以查找的顺序排列的。不过我们在排序时没有SQL这样方便,使用ORDER BY语句就可以了。通常多数公共的LDAP目录都没有标准的大小规范。排序是基于字符的ASCII值,我们必须将字符全部格式化为小写,以便按字母的顺序输出。 要特别注意的是,返回的LDAP结果集是一个多维的数组。因此,我们脚本中的$result_array的结构如下: $result_array[0]["cn"] [0] = "Dannie Stanley" ["dn"] [0] = "uid=dannie,dc=spinweb.net" ["givenname"][0] = "Dannie" ["sn"] [0] = "Stanley" ["mail"] [0] = "danSPAM@spinweb....
PHP中的日期处理
我正打算用PHP编写一种帮助处理系统。我发现我必须知道处理完最后一位客户的问题后已经过去了多长时间?当我过去用ASP时解决这个问题相当简单,ASP有相应的函数DateDiff可以给出两个日期间间隔多少月、多少天和多少秒。当我搜寻完PHP手册后我发现PHP并没有类似的函数。 本文包含以下内容: 1、 得到目前的日期和时间-我们有多少种方式? 2、 改变日期显示的方式-日期和时间的显示形式 3、 转换现在的日期为Unix的时间戳值 4、 改变日期 a. 增加时间 b. 减去时间 c. 找出两日期之间的间隔 5、 为PHP添加DateAdd函数 6、 为PHP添加DateDiff函数 **得到目前的日期和时间 在Unix中,时间的表示方式为计算从1970年1月1日零时起所过去的秒数,这称为UNIX 时间戳(Unix Epoch)。 如果我们有这样一段的代码: ? echo time(); ? 将返回值958905820 而此时的时间为2000年5月21日12时43分。 你也许会说这相当不错。当这对我毫无帮助,或者只有一点帮助。在PHP中,对日期处理的函数都必须用到由time()返回的时间戳值。同时,由于PHP在Unix和Windows系统中均使用同样的时间戳值,这就允许你不需要修改代码即可在不同的系统间移植。另外的一个好处是time()函数返回的是一个整数,你可以将其作为整数字段或文本字段存入数据库,而不必使用特别的日期/时间字段。 你已经基本了解了Unix的时间戳值,现在让我们来展示它的实际用途。 改变日期显示的方式-日期和时间的显示形式 PHP提供两个办法来将Unix的时间戳值转换成为有用的数据。第一个是date()函数。这个函数有两个参数-第一个字符串用于设定你所希望返回的格式,第二个为Unix的时间戳值。 格式化字符串通过一些简单的特殊格式化字符来显示你所希望看到的格式的日期和时间。假设你希望日期以这样的格式显示“18h01 Sunday 21 May”。 我们需要对字符串中的每一部分使用一个特殊格式化字符,你可以从PHP手册中日期和时间函数库中找到。这样的特殊格式化字符数量不少,他们所表示的类似于星期几、月的英文名、用2位或4位数表示的年份,是否是上午(AM)或下午(PM)以及其他。对于这个例子我们需要的特殊字符为: ‘H’ -24 小时制的小时 ‘i’- 分钟 ‘l’- 星期几的英文全名 ‘d’- 本月的第几日 ‘F’- 月份的英文全名 因此我们的格式化字符串为”Hhi l d F”, PHP代码为: ? echo date (“Hhi l d F” ,time()); ? 当我们执行这段代码,我们发现我们所得到的结果为: 180609 Sunday 21 May 这样的结果看起来有些奇怪。让我们再查一下PHP手册,原来’h’所代表的是12 小时制的小时数。这再次证明了一句真理:“计算机只做你所告诉它该做的,而不是你想要它做的”。我们有两个选择。第一个是在h前使用转义字符“”: echo date (“Hhi l d F”, time()); 我们得到这样的结果: 18h12 Sunday 21 May 这正是我们所要的。但如果我们在一个十分复杂的句子中需要包含日期和时间,我们是否需要对每个字符使用转义字符? 答案当然是不。我们使用另一个函数strftime()。 strftime()有两个好处。第一个好处我们并不在本文讨论范围内-如果你使用setlocale()函数,你可以通过strftime得到相应语言的月份的名称。另外的一个好处是你可以将特别的日期和时间的格式化字符包含在你的字符串中。这同时也意味着无论你是否要学习date()函数的所有特殊格式化字符,你都必须学习一整套完全不同的格式化字符。 strftime()工作的方式和date()没有什么不同,除了特殊格式化字符的前面必须添加一个百分号%。如果用strftime()函数,前面例子的代码如下: ?...
怎么样可以把 phpinfo()屏蔽掉?
Q:怎么样可以把 phpinfo()屏蔽掉? A:路径:C:winntphp.ini(NT和2000)C:windows(95,98) 在 php.ini 配置文件里面有这个选项 disable_functions = ; This directive allows you to disable certain ; functions for security reasons. It receives ; a comma separated list of function names. ; This directive is NOT affected by whether ; Safe Mode is turned on or off. 改成 disble_functions = phpinfo
php中rename()函数的妙用
大家都知道,rename()函数可以对文件或目录进行重命名的操作。其实它还可以做很多事情。 熟悉unix的朋友应该知道shell命令mv,它相当与win32的移动,而且移动的同时可进行重命名。我发现,php的rename()函数就相当于mv,它不仅仅只有简单的重命名的功能,同样可以改变文件甚至整个目录的路径。 例如: $oldpath —-文件或目录原来路径 $newpath —-新定义路径 那么 rename($oldpath,$newpath)就可以完成文件/目录移动的操作 经过我的测试,win32和unix的php4版本都支持这个功能。 另外,好象php4的win32版取消了unlink()函数。那么还可以巧用rename()函数来完成删除的操作,例如: $path —- 文件或目录路径 $tmp —- tmp目录(/tmp) 用rename($path,$tmp) 将文件移动到tmp目录.
PHP中如何使用header发送头部信息
在照彭武兴先生的《PHP BIBLE》中所述,header可以送出Status标头,如 就可以让用户浏览器出现文件找不到的404错误,但是我试了这样是不行的。 后来我到w3.org上查了http的相关资料,终于试出来了如何Header出状态代码(Status),与大家分享。 其实应该是这样的: Header(“http/1.1 403 Forbidden”); ?> 第一部分为HTTP协议的版本(HTTP-Version) 第二部分为状态代码(Status) 第三部分为原因短语(Reason-Phrase) 三部分中间用一个空格分开,且中间不能有回车,第一部分和第二部分是必需的,第三部分则是给人看的,可写可不写甚至乱写。 还有,这一句的输出必须在Html文件的第一行。 下面我给出各代码所代表的意思(是从w3.org上查到的,够权威了): * 1xx: Informational - Request received, continuing process * 2xx: Success - The action was successfully received, understood, and accepted * 3xx: Redirection - Further action must be taken in order to complete the request * 4xx: Client Error - The request contains bad syntax or cannot be fulfilled * 5xx: Server Error - The server failed to fulfill an apparently...
一个全面获取图象信息的函数getImageInfo()
$img_info[0], “height”=>$img_info[1], “type”=>$img_type “size”=>$img_size } return $new_img_info; } ?>
只需两个参数:最傻瓜的一个通用分页类
/** ** 通用分页类。只需提供数据总数与每页显示数。 ** 无需指定URL,链接由程序生成。方便用于检索结果分页。 ** @author : lino(luckfeng@gmail.com) ** @site : http://www.ypren.com ** @version : 0.3 ** @date : 2006/2/24 **/ class Pager{ var $url; var $countall; var $page; var $thestr; var $backstr; var $nextstr; var $pg; //构造函数,实例化该类的时候自动执行该函数 function Pager($countall,$countlist){ @$this->pg=sprintf("%d",$_GET["pg"]); //保证pg在未指定的情况下为从第1页开始 if ($this->pg==0){ $this->pg=1; } if (!isset($this->pg)){ $this->pg=1; } //记录数与每页显示数不能整队时,页数取余后加1 $this->countall = $countall; if ($this->countall%$countlist!=0){ $this->page=sprintf("%d",$this->countall/$countlist)+1; } else{ $this->page=$this->countall/$countlist; } //得到当前的URL。具体实现请看最底部的函数实体 $this->url = Pager::getUrl(); //生成12345等数字形式的分页。 if ($this->page<=10){ for ($i=1;$i<$this->page+1;$i++){ $this->thestr=$this->thestr....
刚才在村子里看到的很有意思
原来三元运算可以这样写 <code><font color="#000000"> </font><font color="#0000bb">< ?php $test</font></font><font color="#007700">= </font><font color="#0000bb">59</font><font color="#007700">; </font><font color="#ff8000">//学生分数 </font><font color="#0000bb">$res </font><font color="#007700">= ((</font><font color="#0000bb">$temp_res </font><font color="#007700">= </font><font color="#0000bb">$test </font><font color="#007700">- </font><font color="#0000bb">60</font><font color="#007700">) < </font></font><font color="#0000bb">0</font><font color="#007700">) ? </font><font color="#dd0000">'离及格差'</font><font color="#007700">.-</font><font color="#0000bb">$temp_res </font><font color="#007700">: </font><font color="#dd0000">'超出及格'</font><font color="#007700">.</font><font color="#0000bb">$temp_res</font><font color="#007700">; echo </font><font color="#dd0000">'此学生成绩为:'</font><font color="#007700">.</font><font color="#0000bb">$test</font><font color="#007700">.</font><font color="#dd0000">'分 --'</font><font color="#007700">.</font><font color="#0000bb">$res</font><font color="#007700">.</font><font color="#dd0000">'分'</font><font color="#007700">; </font><font color="#0000bb">?> </font></code>
PHP的内码转换函数 mb_convert_encoding()
因为某程序要用输出UTF-8编码..但是原数据是GBK编码的 百度 找了很多有关内码转换的类..但是缺点很多.又不支持GBK TO UTF-8 不过一个一个找还是在PHP官方的FAQ找到了mb_convert_encoding() 该函数要在PHP4.0.6以上才有..听说有的 想关链接: http://cn.php.net/manual/zh/function.mb-convert-encoding.php 做一个GBK To UTF-8 < ?php header(“content-Type: text/html; charset=Utf-8”); echo mb_convert_encoding(“妳係我的友仔”, “UTF-8”, “GBK”); ?> 再来个GB2312 To Big5 < ?php header(“content-Type: text/html; charset=big5”); echo mb_convert_encoding(“你是我的朋友”, “big5”, “GB2312”); ?>