• 20 Nov 2008 /  服务器配置
    不能正常显示中文,你可以在putty下window-〉Appearance-〉Translation中, Received data assumed to be in which character set 中,把Use font encoding改为UTF-8.

      如果出现无法输入中文的情况,修改putty的设置:Appearance-〉Font settings-〉Change…,选择Fixedsys字体,字符集选CHINESE_GB2312.而且这样设置,显示的字体也舒服多了,呵呵.

    现在打开putty,登录成功后,在shell中输入:export LC_ALL=’zh_CN.utf8′,现在已经可以完美的支持中文了
      当然如果是在本地终端,你可以使用zhcon来显示和输入.

    Tags: , ,

  • 20 Nov 2008 /  ASP

    在写完了php的数据库类之后,发现其实ASP也是可以做到数据库连接对象隐藏的!现在最主流的ASP写法都是将conn做为全局变量。以前封装的几个类也或多或少的用到了conn对象。也就是在配置文件里必须有一个 conn的全局变量,我们需要的时候用 link_database() 来给conn赋值,然后在页面的结尾都需要显示的conn.close();通常我们在每个页面的结尾加上如下代码:

    if isobject(conn) then conn.close:set conn=nothing

    这样做存在什么问题呢?不优美了!相比自己写的PHP类,显得耦合度很高,我竟然需要用到全局变量来控制数据库操作!有没有更好的方法呢?以前也想过,不过最后因为过度封装反而影响了开发的速度,结果还是回到最原始的conn全局变量的写法来。其实要100%封装ASP的数据库操作是完全可以的!下面先来看下我们理想的写法。数据库更新删除添加我就不写了,没什么好说的,我们可以做到。要封装最麻烦的是和分页结合在一起的部分。如果我用调用PHP数据库操作类的写法应该如下:

    Set objConn=New DBClass ‘建立一个新的对象
    objConn.Connection() ‘连接数据库
    objConn.PageSize=20 ‘一页显示20条
    objConn.Execute(”select * from T”) ‘传入select语句,自动判断是查询还是更新

    ‘以下是循环读取数据
    while(objConn.Read())
              Response.write objConn.Get(”ID”) & “ ”
              Response.write objConn.Get(”test”) & “<br />”
    Wend
    objConn.ShowPage() ‘分页导航

    看上面的写法多么优美!我们没有任何的连接数据库的对象。我们希望不需要写conn.close(),只要页面销毁对象的时候自动关闭数据库连接,我们希望不需要考虑页面的参数,ShowPage() 已经帮我们完成了。我们也不希望去考虑数据如何传递,我们只需要简单的Get就可以获得我们想要的数据。想想,如果能这样,我可以用VB去封装一个数据库操作的类,我可以直接用 Set objConn=Server.Create(”DBClass”) 来生成一个对象,VB是编译好了的,性能肯定很高。这样的写法能做到吗?答案是肯定的!完全可以通过ASP有限的面向对象特性封装成一个这样的类。

    首先我们分析下,这个类我们需要将conn,rs等 传统的东西都包含进去。也就是我们在调用Connection方法的时候就得产生一个conn对象,当然这个对象是类里面私有的。然后我们在给PageSize赋值的时候,我们的对象就知道接下来是要进行分页操作了!当执行Execute的时候,我们同样也判断是否是select 语句,如果是,则产生一个rs对象,这个rs肯定也是私有的。那如何得到值呢?以前一直被rs(”id”)这种方式误导了,认为要构建一个数据库操作类,应该和C#那样objConn(”ID”)来得到,其实应该是用类里面的一个方法,暂且我们定义为Get(str) 我们可以将Get映射到 rs(str) 里面来,这样就可以在外部得到想要的一切数据了。好,还有另外的情况!rs.movenext呢?我们需要控制游标下移啊。在这里我用类似.net 里面的Read()方法来完成。其实很好做,反过来,如果是第一条记录,直接给返回true。如果不是第一条记录,怎么办呢?控制rs.movenext()嘛。这样我们的写法不就和.net里面统一了吗? 所以通过Get完全可以获得我们想获得的任何记录。至于分页,能顺利进行吗?答案是肯定的!其实一个分页函数只和2个变量有关!第一个是最大值,第2个是一页显示多少条记录。而至于当前页,完全可以通过全局的request对象获得参数值。第1个最大值,可以调用rs的recodcount得到,一页显示多少条,前面的变量已经赋了。所以分页也可以解决!

    通过以上的分析一个优美的数据库操作类就完成了。这个类我们完全可以独立运行,不需要任何所谓的全局conn对象。而且非常健壮,在类撤销的时候,会自动关闭数据库连接。

    到了上面的分析,基本上解决了问题,但是有一个问题:海量数据的分页!肯定不能用rs来分页,如果超过10万条,都放到内存,还不慢死!可惜sqlserver和access 都不支持limit,支持该多少好啊。当然不支持不意味着不能实现高性能的分页。获得记录条数,还是改造select语句,将其改造为 select count(*)。而取得数据记录用 排除法,select top not in 这种方法来实现。当然这里的改造select 语句可比mysql的要复杂得多啊,毕竟是将一条select 语句改造成一条复合语句。以前封装C#的数据库操作类的时候已经封装了一个,相信看看以前的代码处理起来会比较简单。当然类里面肯定得做开关来支持海量数据分页。

    至此,这个数据库操作分页类就分析完毕了,至于代码,暂不公布,还没写完,这种方式还是昨天坐车的时候想到的。写了这么久的程序,接触了VB,VC++,C#,Java,ASP,到前段时间接触的PHP,可谓各大主流的编程语言都过了一遍了。越来越深刻的感觉到,任何一种语言其实都可以写得很优美!任何一种语言都可以提高可复用性,提高健壮性。

    其实我还感觉ASP还可以实现更多的面向性。因为ASP有个很有用的函数:execute .将字符串当表达式执行!以前一直是用来表单给rs赋值用的。也许在这个数据库操作类里面我们可以加入更新,添加的部分。用execute语句可以像这样来更新数据:objConn.Form2Rs(”ID,UserName,Password,TX”) 只要这样一写,表单的值就全跑到数据库去了。当然必须Form名和数据库字段名对应!

    其实有时候想来,编程和设计其实并没有区别,让代码看起来更优美,更简单是不断追求的。

    Tags: ,

  • 18 Nov 2008 /  PHP

    PHP刚入门,如何能快速用PHP开发应用呢?个人一直认为,语法变量函数都很好掌握,毕竟PHP这种类C语言很好学。关键是要封装几个自己的类:数据库操作类,常用验证类,还有一个就是搭框架要用的常用函数的集合。有了这3个类库,再加PHP本身的函数,一般的开发都会很简单了。

    这里首先展示一个自己封装的PHP数据库操作类。为什么先写这个类呢?因为一旦这个类完成,基本的数据库添删改查都解决了。好了废话少说,先看类的调用情况,我这里用2个文件展示一个轻量级的架构,一个ini.php ,这个文件定义写一些常量以及需要包含的类文件,另外一个就是test.php文件了,展示怎么调用这个数据库操作类,test.php完成数据库的查询,分页操作,并且我做一条简单的插入操作的演示;在这里实验用的数据表为 t_test(id,test) ,这个表就2个字段。演示地址:http://myphp.net0791.com/test.php

    先看 ini.php 文件:

    define (”db_name”,”db_lt”);//$dbname数据库名
    define (”db_username”,”db_xxx”);//$dbusername登陆数据库用户名
    define (”db_password”,”xxxx”);//$dbpassword登陆数据库密码 

    require_once(’db_class.php’);

    $objDB=new DBClass();
    $objDB->connect(db_name,db_username,db_password,’gbk’); 

    看,这个文件很简单,做3样事,1)定义数据库用户名密码等;2)引用一个类文件 3) 创建一个新对象,并调用它的方法连数据库。 这是一个非常平常的引用文件,和我们的asp的 conn.asp 基本完成一样的事;当然其实第3步可以放在test.php里面;不过我更喜欢放在这里!因为DBClass类在写的时候就考虑很全面了,等下从test.php就可以看出;

    test.php 文件:

    require_once(’ini.php’);
    $objDB->pagesize=10;      //设置分页的页数,如果不需要分页则不设置;
    $objDB->execute(’select * from t_test order by id asc’);  //需要执行的查询语句,当然也可以是非查询语句,execute函数会智能判断;
    //$objDB->execute(’insert into t_test(test) values(\’测试\’)'); //执行插入语句,execute会自动判断是查询还是插入,这个函数可以在页面多次调用,只要还是同一数据库;
    while($rs=$objDB->fetch_array())  //利用fetch_array()函数去将查询结果分成数组{
     echo ‘<br>’;
     echo $rs['id'];
     echo ‘&nbsp;&nbsp;’;
     echo $rs['test'];
     echo ‘<br>’;
    }
    $objDB->free_result();  //如果是查询,则请空查询结果,方便下一次select的传入;
    echo $objDB->showpage(); //分页显示! 不需要传额外的任何东西,页码的越界问题DBClass都考虑了,而且自动记忆URL的内容,方便做搜索和多参数的分页

    大家看上面的test.php, 写法非常方便,在整个过程中,我们不需要考虑数据库连接,因为在对象销毁的过程中,会自动关闭连接;而且不必考虑分页参数等问题,因为分页函数已经帮我们做完了这些;那么一个查询可以归纳为:

    1)创建对象;2)连接数据库;3)设置每页显示记录条数并执行sql语句;4)获得结果一维数组;5)按自己想要的方式显示;6)清空结果集;7)分页;

    当然这里的 第6步其实也可以省略,因为类销毁的时候会自动清空结果集;

    这种写法其实非常类似于ADO的写法,唯一区别就在 ADO 循环的时候需要 while(rs.EOF) 而且需要 rs.movenext() 将游标下移;其实这种写法已经比ado的更简化一步了。就是少了rs.movenext();循环的条件就是$rs这个一维数组是否为空;

    其实DBClass 类是非常灵活的,如果不需要分页的时候,只要不设置每页显示记录条数就可以了。正因为这种灵活性,所以一般我倾向于将对象的建立放在ini.php里,这里可以建立一个 DBClass对象作为全局对象,因为我们每个页面基本都需要和数据库合并起来!那需要做符合查询怎么办呢?我们可以将第2次查询封装在函数里,因为函数的作用域只有本身,这样只要在函数里建立一个DBClass就可以完成局部查询,而且查询完毕(退出函数)会自动清空数据库连接。这样的程序就比较健壮了。DBClass在分页的时候还考虑到了伪静态情况下分页!因为很多时候我们的分页都是需要做成:/test.php/1.html     这种形式,这里的1.html是可以换的,比如 2.html。如果要做成伪静态怎么办呢?也很简单,只要把echo $objDB->showpage(); 改成: echo $objDB->pageindex(’/test.php/$$.html’); 就可以了;其实showpage() 就是调用了pageindex的方法,如果要改成英文的也很好做,只需要showpage(’English’) 就可以了。

    当然,也可以继承DBClass构建出自己的类,在DBClass里面全部的内部变量都是public 或 protected 的属性,方便做扩展。

    DBClass类文件下载:db_class

    Tags: , ,

  • 14 Nov 2008 /  PHP

    学习PHP,先将与ASP相异的部分归纳出来,再用php的类封装一个验证类,数据库操作类(包含分页),再找套在线编辑器,PHP就算入门了。

    PHP与ASP都是解析型语言,不要预先定义变量,不过PHP与ASP还是有很大的不同

    1)PHP的变量作用域更小!比如,我在写ASP的函数时,为了和全局变量相区分,需要在函数里dim显式定义变量。而PHP则完全相反,如果没有定义,则变量的作用域只在函数里。如果是全局变量,需要用 global 定义;PHP字符串连接用”.”,并且单引号才是输出字符串,双引号则类似于C++,可以将表达式;

    2)PHP更灵活,很多地方用到了较难理解的细节!比如,对于if和while的判断,本来应该是判断true or false , 但是由于是解析型的语言,直接用变量是否为null或0作为判断,如果是null或0则为false,如果不为null或0则为true;这些语言的灵活性虽然方便了我们,但是也加大了阅读理解的难度。用得最多的在返回数据分组。如果在asp里面我会用 if rs.eof 来判断是否有记录,而在php里面直接 $rs=mysql_fetch_array($result) 开始一直不理解,当然,C#,java也有一样的语法,比如 rs.read(); 但是C#是面向对象的,这个read() 方法本来就是要返回布尔值的,如果读到则在读取对象内部的数组;而PHP是利用函数来完成此功能,可读性很差!在我写完这条函数的时候,我一直很纳闷,又不是对象,怎么能这样写呢? 原来正是利用语言的灵活性才写出这样的代码;它的意思就是对$rs 进行判断,如果不为null则go on,是null就中断。当然我这里只举了一个例子,这样的例子还有很多!比如 or die(”)  这样的写法,利用了编译器的预编译原理,也就是,如果or 前面为true,就没必要执行die了,如果不为true就执行die(”) ;  其实我个人建议:学PHP如果有更好的方法实现相同的功能,最好不要这样写,这样会引起很多的歧义!当然,稍微有点C语言基础的都知道怎么回事,毕竟大学里面学c,c++老师都会说。

    3)PHP支持范围运算符”::” ; 这个东西很有用,可以写出类似C# static静态函数的东西,也就是不构建对象也能输出内容,这样对于一些封装的判断很管用;而且PHP支持继承等高级面向对象属性,这比ASP强很多!在PHP5里面有类似static 关键字的东西,可是效果和不加static 是一样的。可能是因为PHP5要兼容PHP4做的吧;所以建议在写PHP类的死后能加上private保护类的函数被外部调用;但是对于变量,如果加上了static 则可以直接用运算符输出;

    4) PHP的类利用默认值可以实现多态;比如

    class A {
     static $a=’123′;
       function expa($a,$b=1,$c=2) {
            return $a+$b+$c;
        }
    }

    echo A::expa(1);

    在这个例子里,只输入了一个变量,照样可以执行,只要对其他的2个赋初始值;这样的好处就是函数的多态性,在C#里面必须写几个函数,当然函数名可以相同;而在PHP里可以很好用这个方法解决;如果相同的函数名,则会报重定义错误。

    Tags: ,

  • 12 Nov 2008 /  PHP

    这几天的日志好像标签没办法访问,百度发现只要在以下代码修改下就可以了:

    wd-includes/rewrite.php 找以下代码:

    function get_tag_permastruct() {
      if (isset($this->tag_structure)) {
       return $this->tag_structure;
      }

      if (empty($this->permalink_structure)) {
       $this->tag_structure = ”;
       return false;
      }

    红色代码里加一个!符号变成:if (!empty($this->permalink_structure))

    Tags: ,

  • 12 Nov 2008 /  ASP

    最近一个朋友的动网论坛老被人攻击,CPU利用率一直居高不下,只要把论坛目录一改名,CPU利用率马上下来!找了半天都无法找到原因,初步估计是有人写了程序恶意访问他的服务器,造成某个ASP页面一直打开关闭数据库,使得CPU居高不下。在任务管理器查看服务器线程数,关闭他的IIS进程池,线程数 760个,打开进程池,线程数 810个,也就是说有人伪造了50个访问不停的刷他的某个ASP页面。如何解决?

    首先分析他的代码,发现网页全部生成静态文件,不需要处理,而论坛全部都调用conn.asp文件。好像可以解决了,于是我写了一个check.asp,conn.asp包含这个文件。

    然后在check.asp 里面,加入判断代码,思路是:如果是用程序提交访问,势必没有cookie,如果能提交cookie也无法获得cookie!那么每次访问,我就先判断是否有cookie,没有就写一个cookie,再判断cookie是否为我设置的那个数,如果是,则访问,不是马上Response.End() 断掉请求。开始测试,效果挺理想的,可是后来还是CPU利用率很高!怎么办呢? 开始设想,可定是他为找了cookie!mygod,竟然伪造cookie,怎么办呢?接着想办法,如果我一次给他分配2个Cookie,一个随机,另一个是这个cookie通过一个算法演变的,然后服务器端判断2个cookie通过这个算法是否相等!好像问题终于可以解决了。其实还差一点,如果是搜索引擎呢?搜索引擎肯定无法抓取这样的页面,那么在写cookie之前,先判断是否为蜘蛛,至此,问题基本解决!

    代码如下:

    <%
    ‘检查是否是蜘蛛人
    function check(user_agent)
     allow_agent=split(”Baiduspider,Scooter,ia_archiver,Googlebot,FAST-WebCrawler,MSNBOT,Slurp”,”,”)
     check_agent=false
     for agenti=lbound(allow_agent) to ubound(allow_agent)
      if instr(user_agent,allow_agent(agenti))>0 then
       check_agent=true
       exit for
      end if
     next
     check=check_agent
    end function

    Sub LT_Check()
     dim user_agent,http_reffer,server_name,chk_rnd 
     

     user_agent=Request.ServerVariables(”HTTP_USER_AGENT”)
     http_reffer=Request.ServerVariables(”HTTP_REFERER”)
     server_name=Request.ServerVariables(”SERVER_NAME”)
     if not check(user_agent) then
      if Request.Cookies(”check_1a”)=”" then
       randomize
       chk_rnd=rnd
       Response.Cookies(”check_1a”)=chk_rnd
       Response.Cookies(”check_22″)=Request.Cookies(”check_1a”)*0.3435  end if
      ’response.write Request.Cookies(”check_22″)
      if cstr(Request.Cookies(”check_22″))<>cstr(Request.Cookies(”check_1a”)*0.3435) then response.end()
     end if
    End SUb

    call LT_Check()
    %>

    在这里我用了最简单的一个算法,直接让第2个cookie乘以 一个数,这样就出了2个cookie了,然后验证这2个cookie是否相等,如果攻击者想伪造Cookie似乎很困难。当然,如果我是攻击者,看到这段代码,我马上就能写出相应的攻击的程序,只要伪造2个数,一个数是另一个的0.3435就可以了嘛!但是,攻击者在不看这个文章的时候,能一下想到这个方法还是很难的,毕竟随机数嘛,而且如果他花几个小时想到了破解方法,我马上改个算法,把数字变成字符,我想他肯定很郁闷,几个小时的成果白费,又得破解我的算法。呵呵~~~~

    引申:

    从这里可以看出,其实我们的目的就是要让攻击者费点功夫让他自难而退。如果太复杂,太花精力,谁来做啊。当然,还有一个办法,就是伪造成蜘蛛来爬!我这里做了一个测试,其实一般的蜘蛛完全可以不防,因为我的采集程序照样可以访问里面的内容!后来我将cookie打印出来,发现采集程序虽然可以访问内容,但是每次cookie都不相同!而用浏览器访问,每次cookie都相同!何解? 这证明,马上设置cookie,马上获得其实还是在服务器的内容里面!从这个角度来说,是不是无法防止攻击呢?因为别人可以不停的采集这个页面啊!这更本没防住嘛。可是事实证明,2天了,没有出现CPU太高的情况!证明已无攻击或者防住了攻击了!怎么解释呢?

    这里有2种可能:1)正常采集,也就是调用windows的XMLHTTP组件的采集,是可以识别cookie的!虽然不能保存cookie,但是asp的cookie对他同样生效!但这种方式的访问,和正常访问无区别,都属于正常访问的范畴,不会对服务器造成影响!而攻击者用的访问,显然应该属于CC攻击一类的,这种攻击请求,以消耗CPU利用率为目的,不能识别cookie,更不能保存cookie,所以一旦用cookie验证,这种攻击基本失效,因为每次都会response.end()掉,更本不读数据库,性能无损失!如果这样的话,前面蜘蛛识别其实不用了,因为蜘蛛也是用类似xmlhttp的方式访问的,能很好的采集!

    2)我一加上程序,攻击者没发动攻击了,所以一切正常了!(好像不太可能啊,每天都他会攻击几次!)

    此文抛砖引玉,欢迎路过的朋友给点自己的看法。ASP是我一直使用的一种编程技术,虽然语言太不优美,但是结合VB,VC++,很多场合应用都很过得去。

    Tags: ,

  • 06 Nov 2008 /  服务器配置

    今天想在Win2008下虚拟一个CentOS5.2, 结果一启动站点马上Windows就死机!在死机前弹出对话框大概意思是只支持Windows2000,WindowsXP,Windows2003不支持Windows2008。晕死,找了半天都找不到一个好的虚拟机,后来用了以前一个绿色版VM6.0,才20几M,没想到居然可以虚拟成功!

    看来家里的台式机终于可以一直用Windows2008工作了。下次再虚拟一个2003测试代码,当然2003不用虚拟了,用自己的服务器可以测试全部代码。

    其实用了这么久的2008,感觉还是挺好的,稳定,而且开vista效果,界面效果很好。IIS7.0功能也增强很多。大部分软件都兼容,连VB6.0这样的老古董也可以在Win2008下安装,vs.net 2005就更可以装了。自己开发的一套虚拟主机管理软件不用改一行代码就可以运行,不过开出的站点好像有权限问题,估计还得好好研究下Win2008的权限了。2008默认是以RAW格式安装的,并不是ntfs,不知道配置权限是不是有不一样呢?每次都可以创建用户,但是无法把用户加载到制定目录,结果打开网站全是无权限,郁闷!没想到我的软件还没写完,就面临淘汰的厄运啊,5555

    Tags: ,

  • 06 Nov 2008 /  服务器配置

    转载一篇vi 的操作手册,马上要上架一台Linux服务器了,打算用CentOS 5.2 做服务器,装Apache+MySql,先预习下。

    vi和其他编辑器最不一样的地方莫过于它把编辑、处理等等的操作分离开来,形成性质不同的3种操作模式,他们分别为“命令模式”、“插入模式”、“ex模式”。

    但在vi下,为了增强对将要处理的文本的针对性,文本输入、复制等等不同的操作,是被分离开来的,比如文本输入的模式叫做“插入模式”,在插入模式 下,我们可以用和Windows下一样的操作方法来对文本进行输入、编辑等等的操作,但是复制等等非编辑的操作,在插入模式下不能够完成,而需要切换到相 应的模式下用相应的命令来完成。

      在这里,还是首先对重要的vi的模式进行说明。

    1)命令模式:

      在我们刚刚通过vi新建或打开一个已经存在的文件时,首先默认被读取的模式就是“命令模式”,命令模式的特征就是,在编辑器窗口左下角的位置上没有任何的提示标语。在这个模式下,如果不通过相应的命令,我们无法输入新的文本到这个文件中。这里建议新接触刚刚接触vi的朋友在用vi打开一个文件时不要处于心切而乱 按键盘试图输入一些文本到文件中,因为命令模式所谓的“命令”,并不是我们在命令行提时下输入的过程诸如“ls -> 回车”等等形式的命令。确切说vi命令模式下的命令,只是计算机键盘上的某个按键或某些按键的组合,当我们在命令模式下敲下键盘一个按键的时候,相应命令就已经被执行。
     在这里,首先介绍移动光标的命令。通常光标的移动可以通过键盘右边的方向键,但是由于每次移动光标,手都要大幅度的移动到键盘右边,这样使用vi是体现不出效率的,所以建议使用vi固有的命令(键)来控制光标的移动。

    光标的移动命令如下所示: 

     向右移动 –> l
     向左移动 –> h
     向下移动 –> j
     向上移动 –> k

      如上所示,例如要向右移动光标8个字符的距离,只要在键盘上敲 l 键8次即可;向下移动3行的距离,只要在键盘上敲 j 键3次即可……也就是说,在vi命令模式中通过这几个键(命令)来控制光标的移动。

       其次就是文本删除的命令。在Windows下大多数编辑器在删除文本时只要连续按[Backspace]键即可。但由于在vi中,插入模式和命令模式是分离开来的,所以在命令模式下需要通过命令(按键)来删除文本,而不是直接按[Backspace]键。

     文本删除的命令如下所示:  

          删除光标所在位置的字符 –> x
      删除光标所在的行 –> dd(敲 d 两次)

      如上所示,例如要删除从光标位置起向右的3个字符,只要在键盘上敲 x 键3次即可;要删除光标所在的行,只要敲 dd (连续敲d键两次),光标所在行的所有字符以及行将会被删除。

       再次,当编辑完了一个文档,想要保存后退出的时候的命令为“ZZ”(大写、连续敲2次)。

    保存并退出文档:  保存当前修改并退出 –> ZZ

     另外,vi还有一些编辑性质的命令,一并总结如下:

         撤销上一步操作 –> u
      移动光标到行首 –> 0 (数字0)
      移动光标到行首 –> $
      移动光标到当前页最顶行 –> H
      移动光标到当前页最底行 –> L
      向前翻一页(Page Up) –> Ctrl + f
      向后翻一页(Page Down) –> Ctrl + b

    Tags:

  • 05 Nov 2008 /  服务器配置

    昨天调试了下邮件服务器,发现无法发送邮件,开始以为是服务器IP问题,后来发现,竟然和瑞星有关。瑞星的实时检测检测 25及110端口,造成无法发送邮件。在实时监测详细设置里,将25端口去掉,发邮件一切恢复正常!

    不过检测发现,本服务器的IP又被反垃圾邮件组织给禁了!

    检测是否在反垃圾邮件列表中:http://www.spamhaus.org

    Tags: , ,

  • 03 Nov 2008 /  PHP

    因公司项目需要决定研究PHP了,先装个wordpress学习下。结果发现:Warning: Cannot modify header information - headers already sent by (output started at .\wp-config.php:1) in .\wp-login.php on line 267 错误。

    找了半天原因,原来是我改 wp-config.php 的时候出了错。php的默认格式是 utf8格式,可是windows的记事本保存utf8格式的时候会包含utf8的签名BOM,也就是在文件的前面会出现一个类似空格的符号。虽然一般这个符号没什么问题,可是php在解析的时候就会出大错!

    解决办法:1)用记事本将wp-config.php保存为 ANSI 格式的文本,这样会就可以解决问题了;不过这时候文本就变成gb2312的格式了。

    2)用其他的编辑器,比如utraledit,editplus或者是dreamweaver,不过用dreamweaver的时候要注意选择编码格式,一定要取消包含Unicode的签名(BOM),要不然还是会出错的。

    Tags: , ,