2012-1-30 17:58 Monday  
function Serialize(obj){   

switch(obj.constructor){   
        case Object:   
            var str = "{";   
            for(var o in obj){   
                str += o + ":" + Serialize(obj[o]) +",";   
            }   
            if(str.substr(str.length-1) == ",")   
                str = str.substr(0,str.length -1);   
             return str + "}";   
             break;   
         case Array:               
             var str = "[";   
             for(var o in obj){   
                 str += Serialize(obj[o]) +",";   
             }   
             if(str.substr(str.length-1) == ",")   
                 str = str.substr(0,str.length -1);   
             return str + "]";   
             break;   
         case Boolean:   
             return "\"" + obj.toString() + "\"";   
             break;   
         case Date:   
             return "\"" + obj.toString() + "\"";   
             break;   
         case Function:   
             break;   
         case Number:   
             return "\"" + obj.toString() + "\"";   
             break;    
         case String:   
             return "\"" + obj.toString() + "\"";   
             break;       
     }   
}

MySQL 当记录不存在时插入,当记录存在时更新
网上基本有三种解决方法。

第一种:

示例一:插入多条记录

假设有一个主键为 client_id 的 clients 表,可以使用下面的语句:

INSERT INTO clients
(client_id, client_name, client_type)
SELECT supplier_id, supplier_name, 'advertising'
FROM suppliers
WHERE not exists (select * from clients
where clients.client_id = suppliers.supplier_id);
示例一:插入单条记录

INSERT INTO clients
(client_id, client_name, client_type)
SELECT 10345, 'IBM', 'advertising'
FROM dual
WHERE not exists (select * from clients
where clients.client_id = 10345);
使用 dual 做表名可以让你在 select 语句后面直接跟上要插入字段的值,即使这些值还不存在当前表中。

第二种:

INSERT 中 ON DUPLICATE KEY UPDATE的使用

如果您指定了ON DUPLICATE KEY UPDATE,并且插入行后会导致在一个UNIQUE索引或PRIMARY KEY中出现重复值,则执行旧行UPDATE。例如,如果列a被定义为UNIQUE,并且包含值1,则以下两个语句具有相同的效果:mysql> INSERT INTO table (a,b,c) VALUES (1,2,3)
         -> ON DUPLICATE KEY UPDATE c=c+1;

mysql> UPDATE table SET c=c+1 WHERE a=1;
如果行作为新记录被插入,则受影响行的值为1;如果原有的记录被更新,则受影响行的值为2。
注释:如果列b也是唯一列,则INSERT与此UPDATE语句相当:
mysql> UPDATE table SET c=c+1 WHERE a=1 OR b=2 LIMIT 1;
如果a=1 OR b=2与多个行向匹配,则只有一个行被更新。通常,您应该尽量避免对带有多个唯一关键字的表使用ON DUPLICATE KEY子句。
您可以在UPDATE子句中使用VALUES(col_name)函数从INSERT...UPDATE语句的INSERT部分引用列值。换句话说,如果 没有发生重复关键字冲突,则UPDATE子句中的VALUES(col_name)可以引用被插入的col_name的值。本函数特别适用于多行插入。 VALUES()函数只在INSERT...UPDATE语句中有意义,其它时候会返回NULL。
示例:
mysql> INSERT INTO table (a,b,c) VALUES (1,2,3),(4,5,6)
         -> ON DUPLICATE KEY UPDATE c=VALUES(a)+VALUES(b);
本语句与以下两个语句作用相同:
mysql> INSERT INTO table (a,b,c) VALUES (1,2,3)
         -> ON DUPLICATE KEY UPDATE c=3;
mysql> INSERT INTO table (a,b,c) VALUES (4,5,6)
         -> ON DUPLICATE KEY UPDATE c=9;
当您使用ON DUPLICATE KEY UPDATE时,DELAYED选项被忽略。

第三种:
REPLACE语句

  我们在使用数据库时可能会经常遇到这种情况。如果一个表在一个字段上建立了唯一索引,当我们再向这个表中使用已经存在的键值插入一条记录,那将会抛出 一个主键冲突的错误。当然,我们可能想用新记录的值来覆盖原来的记录值。如果使用传统的做法,必须先使用DELETE语句删除原先的记录,然后再使用 INSERT插入新的记录。而在MySQL中为我们提供了一种新的解决方案,这就是REPLACE语句。使用REPLACE插入一条记录时,如果不重 复,REPLACE就和INSERT的功能一样,如果有重复记录,REPLACE就使用新记录的值来替换原来的记录值。

  使用REPLACE的最大好处就是可以将DELETE和INSERT合二为一,形成一个原子操作。这样就可以不必考虑在同时使用DELETE和INSERT时添加事务等复杂操作了。

  在使用REPLACE时,表中必须有唯一索引,而且这个索引所在的字段不能允许空值,否则REPLACE就和INSERT完全一样的。

  在执行REPLACE后,系统返回了所影响的行数,如果返回1,说明在表中并没有重复的记录,如果返回2,说明有一条重复记录,系统自动先调用了 DELETE删除这条记录,然后再记录用INSERT来插入这条记录。如果返回的值大于2,那说明有多个唯一索引,有多条记录被删除和插入。

  REPLACE的语法和INSERT非常的相似,如下面的REPLACE语句是插入或更新一条记录。

  REPLACE INTO users (id,name,age) VALUES(123, '赵本山', 50);
 
  插入多条记录:

  REPLACE INTO users(id, name, age)
  VALUES(123, '赵本山', 50), (134,'Mary',15);

  REPLACE也可以使用SET语句

  REPLACE INTO users SET id = 123, name = '赵本山', age = 50;

  上面曾提到REPLACE可能影响3条以上的记录,这是因为在表中有超过一个的唯一索引。在这种情况下,REPLACE将考虑每一个唯一索引,并对每 一个索引对应的重复记录都删除,然后插入这条新记录。假设有一个table1表,有3个字段a, b, c。它们都有一个唯一索引。

  CREATE TABLE table1(a INT NOT NULL UNIQUE,b INT NOT NULL UNIQUE,c INT NOT NULL UNIQUE);

  假设table1中已经有了3条记录

  a b c
  1 1 1
  2 2 2
  3 3 3

  下面我们使用REPLACE语句向table1中插入一条记录。

  REPLACE INTO table1(a, b, c) VALUES(1,2,3);

  返回的结果如下

  Query OK, 4 rows affected (0.00 sec)

  在table1中的记录如下

  a b c
  1 2 3

  我们可以看到,REPLACE将原先的3条记录都删除了,然后将(1, 2, 3)插入。
总结:虽然没有具体测试,感觉第一种最费资源了(只是感觉),不过你要是没有主键的话也只能用他了。第二种和第三种的区别是:1)insert是先尝试插 入,若主键存在则更新。REPLACE是先尝试插入,若主键存在则删除原纪录再插入。2)如果有多个唯一关键字发生冲突(不同关键字的冲突发生在不同记 录),比如现在有2个字段2条记录冲突了(没条记录冲突一个字段),则insert是选择排序后在前面的一条进行更新,REPLACE是删除那两条记录, 然后插入新记录。本人的一点小见解,如有错误,欢迎指正。
<script>

var start=0;

var end=0;

function add(){

var textBox = document.getElementById("ta");

var pre = textBox.value.substr(0, start);

var post = textBox.value.substr(end);

textBox.value = pre + document.getElementById("inputtext").value + post;

}

function savePos(textBox){

//如果是Firefox(1.5)的话,方法很简单

if(typeof(textBox.selectionStart) == "number"){

start = textBox.selectionStart;

end = textBox.selectionEnd;

}

//下面是IE(6.0)的方法,麻烦得很,还要计算上'\n'

else if(document.selection){

var range = document.selection.createRange();

if(range.parentElement().id == textBox.id){

// create a selection of the whole textarea

var range_all = document.body.createTextRange();

range_all.moveToElementText(textBox);

//两个range,一个是已经选择的text(range),一个是整个textarea(range_all)

//range_all.compareEndPoints()比较两个端点,如果range_all比range更往左(further to the left),则 //返回小于0的值,则range_all往右移一点,直到两个range的start相同。

// calculate selection start point by moving beginning of range_all to beginning of range

for (start=0; range_all.compareEndPoints("StartToStart", range) < 0; start++)

range_all.moveStart('character', 1);

// get number of line breaks from textarea start to selection start and add them to start

// 计算一下\n

for (var i = 0; i <= start; i ++){

if (textBox.value.charAt(i) == '\n')

start++;

}

// create a selection of the whole textarea

var range_all = document.body.createTextRange();

range_all.moveToElementText(textBox);

// calculate selection end point by moving beginning of range_all to end of range

for (end = 0; range_all.compareEndPoints('StartToEnd', range) < 0; end ++)

range_all.moveStart('character', 1);

// get number of line breaks from textarea start to selection end and add them to end

for (var i = 0; i <= end; i ++){

if (textBox.value.charAt(i) == '\n')

end ++;

}

}

}

document.getElementById("start").value = start;

document.getElementById("end").value = end;

}

</script>

<form action="a.cgi">

<table border="1" cellspacing="0" cellpadding="0">

<tr>

<td>start: <input type="text" id="start" size="3"/></td>

<td>end: <input type="text" id="end" size="3"/></td>

</tr>

<tr>

<td colspan="2">

<textarea id="ta" onKeydown="savePos(this)"

onKeyup="savePos(this)"

onmousedown="savePos(this)"

onmouseup="savePos(this)"

onfocus="savePos(this)"

rows="14" cols="50"></textarea>

</td>

</tr>

<tr>

<td><input type="text" id="inputtext" /></td>

<td><input type="button" onClick="add()" value="Add Text"/></td>

</tr>

</table>

</form> 

select uid,username,title_template,title_data,feedid from uc_feeds as a
where feedid in(select max(feedid) from uc_feeds as b where a.uid=b.uid) order by feedid desc limit 10

这样就可以了

2012-1-30 17:56 Monday  

网上转的

今天遇到了一个Jquery提交数据量过大的时候后台获得的时候会截掉一部分,这个找了很久,在网上看到了这样的解释和方式:

采用Ajax传递数据时,通常会将数据整理为data="var1=abc&var2=def"。而当数据中存在加号(+)或是连接符(& amp; amp;)时,服务器端接收数据时会有部分数据丢失现象。分析一下Ajax传递数据的格式与Javascript的语法不难发现:

1. "+"号:JavaScript解析为字符串连接符,所以服务器端接收数据时"+"会丢失。

2. "&":JavaScript解析为变量连接符,所以服务器端接收数据时&符号以后的数据都会丢失。

解决办法也相当简单,只需要为+与&符号编码即可:

function vchar(str) {
str = str.replace(/\+/g, "%2B");
str = str.replace(/\&/g, "%26");
return str;
}
var1 = "abc+kef";
var2 = "abc&kef";
var1 = vchar(var1);
var2 = vchar(var2);
alert(var1);
alert(var2);
使用jquery的话可以使用如下方式提交

var params = $('input, textarea').serialize();
$.ajax({
type: 'post',
url: 'xxxx.php',
data: params,
success: function(response){
       ......
}
});
上面的这个方法我试过了,不是很好用,之后我想到了JSON的方式提交,结果可以实现,效果很好,但是用JSON提交的时候要注意到这样的一个问题,JSON提交的数据时经过编码的,所以在后台要进行解码,我的后台是java,所以我用了这样的方式:
$.ajax({
type: 'post',
url: 'xxxx.action',
data: {arr1:arr1,arr2:arr2},//arr1就是你传递到后台的参数,用request获得,
success: function(response){
       ......
}
});
下面是对中文数据进行解码的代码
/**
   * Ajax数据解码
   * @return
   */
public String decodeAjax(String str) {
   if (MUtil.checkString(str)) {
try {
return java.net.URLDecoder.decode(str, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
return null;
}
   }
   return null;
}

var val = $('#form1 input,#form1 textarea,#form1 select').serialize(),

post的时候,再直接 data:val,   就行了

这是编码问题,在utf-8页面下无问题, 只要在载入google时加入&oe=gb2312 就可以了
2012-1-30 17:54 Monday  

服务器是win2003+apache+php+mysql
前一段时间重装apache后,现在就不能使用curl模块了,
php.ini的配置是正确的。

百度一下,大家的解决方法都是复制 libeay32.dll 和 ssleay32.dll到/windows/system32/,有的甚至说要复制4个,再加上php5ts.php,php_curl.php我也做过,还是不行。

在csdn上提问后,在网友的提醒下,我查看了一下日志,提示php_curl.dll载入错误,

于是在修改php.ini里面的dll路径后,还是提示相同的错误

PHP Warning: PHP Startup: Unable to load dynamic library 'c:/php5/ext/php_curl.dll' - \xca\xd4\xcd\xbc\xb7\xc3\xce\xca\xce\xde\xd0\xa7\xb5\xc4\xb5\xd8\xd6\xb7\xa1\xa3\r\n in Unknown on line 0

我以为是路径的问题,结果发现不是。

在更深的百度之后,找到一个答案就是在apache的配置文件中载入libeay32.dll 和 ssleay32.dll

于是,在加了下面两段话之后

LoadFile "c:/php5/ssleay32.dll"
LoadFile "c:/php5/libeay32.dll"

问题解决~
2012-1-30 17:54 Monday  
如果是用的smarty,出现页面空白不报错的话,在$smarty->display("index.tpl");前输出正常的话,有可能是编译文件的问题,删除编译的文件就好了。
2012-1-30 17:53 Monday  

PclZip简介与使用

PclZip介绍
PclZip library能够压缩与解压缩Zip格式的压缩档(WinZip、PKZIP);且能对此类类档案进行处理,包括产生压缩档、列出压缩档的内容以及解压缩档案等等。由于能够在伺服器端进行压缩与解压缩的动作,所以相当方便使用。
PclZip定义一个PclZip类别,其类别物件可视为一个ZIP档案,亦提供method来进行处理。

如何使用PclZip
1.基础
所有的功能都由pclzip.lib.php这个档案提供,PclZip library可于其首页(www.phpconcept.net/pclzip/index.en.php)下载。所有的PKZIP档案其实就是一个 PclZip的类别物件。当产生一个PclZip档案(ie, PclZip类别物件),就会先产生一个压缩档,且档名已经指定,但此压缩档的内容尚未存在:

< ?PHP
require_once('pclzip.lib.php');
$archive = new PclZip("archive.zip");
?>

此物件提供了一些public method可用来处理此档案。

2.参数
每一个method有其各自可使用的参数,包括有必须与非必须的参数:

< ?PHP
require_once('pclzip.lib.php');
$archive = new PclZip('archive.zip');

$v_list = $archive->add('dev/file.txt',
PCLZIP_OPT_REMOVE_PATH, 'dev');
?>

上例中的’dev/file.txt’就是必须参数;’PCLZIP_OPT_REMOVE_PATH’则为非必须参数。当然有些method也可以只包含非必须的参数:

< ?PHP
$list = $archive->extract(PCLZIP_OPT_PATH, "folder",
PCLZIP_OPT_REMOVE_PATH, "data",
PCLZIP_CB_PRE_EXTRACT, "callback_pre_extract",);
?>

上例中原本压缩档内档案存放的路径为/data,不过你可以指定解压缩至/folder中。此外,在解压缩之前,会呼叫callback function(’callback_pre_extract()’),此function可让使用者在解压缩的过程中变更档案存放路径与档名,或是选 择某些档案不解压缩。
所有可用的非必要参数可参考网址(www.phpconcept.net/pclzip/man/en/index.php)。

3.回传值
每个method所回传的值可能会不同,将会在每个method中说明。不过大部分的method回传0、error或是阵列。

4.错误处理
从版本1.3之后,错误处理已经整合至PclZip类别中,当一个method回传错误码,可以得知一些额外的讯息以方便错误处理:
* errorName():回传错误名称
* errorCode():回传错误码
* errorInfo():回传错误的描述

接下来会举几个例子来说明如何使用PclZip。

PclZip实例1、产生ZIP压缩档
PclZip($zipname):为PclZip constructor,$zipname为PKZIP压缩档的档名。
主要是产生一个PclZip物件,即一个PKZIP压缩档;但此时,只有压缩档产生出来,并做一些检查(例如是否有开启zlib extension…等),除此之外,并没有做其他动作。
create($filelist, [optional arguments list]):将参数$filelist指定的档案或目录(包含当中所有档案与子目录)加入上述所产生的压缩档中。
而非必要的参数则能够修改压缩档内的档案存放路径。
此method可用的参数可以参考网志(www.phpconcept.net/pclzip/man/en/index.php)。

下面的示例说明如何产生PKZIP压缩档(档名为archive.zip),并将file.txt、data/text.txt以及目录folder(包含当中的档案与子目录)加入刚刚产生的archive.zip中:

< ?PHP
include_once('pclzip.lib.php');
$archive = new PclZip('archive.zip');
$v_list = $archive->create('file.txt,data/text.txt,folder');
if ($v_list == 0) {
die("Error : ".$archive->errorInfo(true));
}
?>

下面的示例说明基本上与上例一样产生archive.zip,但在将file.txt与text.txt压缩于其中时,将路径由data/改为 install/ ;因此,在archive.zip中这两个档案的路径会是install/file.txt与install/text.txt

< ?PHP
include_once('pclzip.lib.php');
$archive = new PclZip('archive.zip');
$v_list = $archive->create('data/file.txt,data/text.txt',
PCLZIP_OPT_REMOVE_PATH, 'data',
PCLZIP_OPT_ADD_PATH, 'install');
if ($v_list == 0) {
die("Error : ".$archive->errorInfo(true));
}
?>

PclZip实例2、列出压缩档内容
listContent( ) :列出压缩档中的内容,包括档案的属性与目录:

< ?PHP
include_once('pclzip.lib.php');
$zip = new PclZip("test.zip");

if (($list = $zip->listContent()) == 0) {
die("Error : ".$zip->errorInfo(true));
}

for ($i=0; $i<sizeof ($list); $i++) {
for(reset($list[$i]); $key = key($list[$i]); next($list[$i])) {
echo "File $i / [$key] = ".$list[$i][$key]."<br>";
}
echo "<br />";
}
?></sizeof>

上例将会回传结果:
File 0 / [filename] = data/file1.txt
File 0 / [stored_filename] = data/file1.txt
File 0 / [size] = 53
File 0 / [compressed_size] = 36
File 0 / [mtime] = 1010440428
File 0 / [comment] =
File 0 / [folder] = 0
File 0 / [index] = 0
File 0 / [status] = ok

File 1 / [filename] = data/file2.txt
File 1 / [stored_filename] = data/file2.txt
File 1 / [size] = 54
File 1 / [compressed_size] = 53
File 1 / [mtime] = 1011197724
File 1 / [comment] =
File 1 / [folder] = 0
File 1 / [index] = 1
File 1 / [status] = ok

PclZip实例3、解压缩档案
extract([options list]) :解压缩PKZIP中的档案或目录。
[options list]可用的参数可参考网址(www.phpconcept.net/pclzip/man/en/index.php)。这些参数能让使用者在解压 缩的时候有更多的选项,譬如指定变更解压缩档案的路径、指定只解压缩某些档案或不解压缩某些档案或者是将档案解压缩成字串输出(可用于readme档)。

下例是一个简单的解压缩档案示例,将压缩档archive.zip内的档案解压缩至目前的目录:

< ?PHP
require_once('pclzip.lib.php');
$archive = new PclZip('archive.zip');


if ($archive->extract() == 0) {
die("Error : ".$archive->errorInfo(true));
}
?>

下例是进阶的解压缩档案使用,archive.zip中所有档案都解压缩于data/中,而特别指明在install/release中的所有档案也直接丢于data/中,而非data/install/ release:

< ?PHP
include('pclzip.lib.php');
$archive = new PclZip('archive.zip');
if ($archive->extract(PCLZIP_OPT_PATH, 'data',
PCLZIP_OPT_REMOVE_PATH, 'install/release') == 0) {
die("Error : ".$archive->errorInfo(true));
}
?>

相关文档:
PclZip官方地址:http://www.phpconcept.net/pclzip/index.php
PclZip手册地址:http://www.phpconcept.net/pclzip/man/en/index.php
PEAR类创建ZIP档案文件:http://www.ccvita.com/10.html
PclZip简介与使用:http://www.ccvita.com/59.html
PclZip:强大的PHP压缩与解压缩zip类:http://www.ccvita.com/330.html

转帖 (1):

这几天遇到了一个很多人都遇到过的问题,这个问题在google上有太多的人都遇到,但很少有指出最终的解决方案, 大部分是解决了AcceptEx failed,但引起了内存的疯狂增加(“memory leak”)。这几天遇到这个问题后也费了不少功夫,但没有从网上找到最根本的解决办法,幸运的是,最终探索出了一个解决方案,在这里写出来,希望能帮助 后来遇到问题的难友们尽早解决问题。

遇到的问题比较曲折,大体经过是:

某天,不能访问apache的页面,检查得知,apache在疯狂写日志,而且大部分是一句 话:“winnt_accept: Asynchronous AcceptEx failed”,最多的时候写到了200M以上。经各方探索,最终在apache的手册上找到了一个解决方法:

在http.conf配置中设置Win32DisableAcceptEx参数。这样做的原因是,apache在某些Windows版本上可能兼容性不足,在调用AcceptEx接收请求时可能有问题,使用上面的参数禁用后,apache会使用另一套方案替代(BSD),这种方案效率稍微低些。详见:

http://httpd.apache.org/docs/2.0/mod/mpm_winnt.html#win32disableacceptex

当时修改完该设置后,重启apache,测试了一段时间,感觉原来的问题确实消除了,不过当时感觉内存占用量非常明显,但测试一段时间没有问题就放过去了,直到今天下午:

今天下午发现又不能访问页面了,然后检查apache发现它已经crash了。然后打开日志发现最后一句:“Out of memory!”--内存不足了。

然后对内存进行测试,发现一直按住F5键不停,apache的内存就不停上涨,似乎有一直吃光内存的意思,停止刷新 后只能下降到500M左右了(刚启动时是20M)。如果不使用Win32DisableAcceptEx参数则明显没有这个问题,停止刷新后能回落到 20M。看来是这个参数的原因。

于是从google上寻找答案,但可惜的是没有太多有价值的东西。只能看到apache的官方网站已经把这个问题列 为了一个bug,甚至有些人又退回到不使用那个参数(忍受AcceptEx failed的风险?)。最后看到了一个说法,将ThreadsPerChild 设为170以下就可以,可为什么是170以下呢?作者没有很多描述。于是自己探索如下,使用一个简单的页面,不停的按住F5刷新:

如果将Threadsperchild 设为50,无论怎么刷新内存最多到150M左右,但不会再长了。停止刷新后,会降到55M左右;如果将ThreadsPerChild 设为100, 内存峰值:282M,能降到92M左右;如果将ThreadsPerChild设为550,内存峰值2G,停止后到500M左右……。

按照上述规律,基本上找到了问题的原因,因为我的配置中原来使用的是ThreadsPerChild 550,这样也就是内存很可能会长到2G以上(复杂页面比简单页面耗用量大),而机器的内存设置不能支持这么大,因此应该就是这个问题了。

所以最终的解决方法就是保留Win32DisableAcceptEx的同时修改了ThreadsPerChild 150。解决完成后我推测内存疯狂增长的原因:

首先,ThreadsPerChild的意思是系统启动时默认启动的等待线程数,用来等待处理客户的请求。在使用 AcceptEx时内存增长不明显并且可以降回20M左右,可能是因为用户来了请求线程分配了一些资源,此时内存增长,但用户访问完成后,这些资源都释放 了(这些资源很可能都和用户相关,没法留着下个用户使用,所以都释放了)。但禁用了AcceptEx后,由于apache每个线程需要处理网络事件,因此 每个线程的资源需要就多了,并且处理完一个用户的请求后,有些资源不想释放,是可以对下个用户重用的,这样就留在了里面。由于我的线程数设了550(估计 网上很多人遇到这个类似于“memory leak”问题的可能也都设的比较大或者机器虚拟内存较小),这样当线程较多时就会出现达到最大内存的情况,而且这种现象给人的感觉就是有内存泄漏,因为 初始时是20M,来一个请求后线程分配一些资源(暂时不释放的),这样可能就变成了21M,如果同时有10个人访问,可能等他们访问完后就变成了50M, 感觉是有内存泄漏。

这样也就解释了为什么有人说设到170以下就不再出现内存不足了,可能因为他的机器这个配置比较合适。不过知道了上述的规律和一些推测,这个结论应该是根据自己机器的情况合理调配。

我很少接触apache等linux上的东西,所知较少,只是遇到了问题才开始了解的上述信息,可能有很多的理解错误。如果能给别人一些帮助我会比较欣慰,如果误导甚至帮了倒忙,也希望能够理解!

如果在Win下使用Apache,而你又必须要开防火墙之类的软件,那么如果你的Apache运行有问题,比如文件下载不完全或者损坏、未知错误信息、防火墙冲突等等,请参考如下:

打开你的 httpd.conf 配置文件,看是否如下修改可以解决问题:

    EnableSendfile Off
    EnableMMAP Off
    Win32DisableAcceptEx

转帖 (2):

现象:】


访问apache静态的http内容,有时候比较慢,有时候“找不到网页”404错误;另外在error.log里也报错:

[Mon May 26 10:11:47 2008] [warn] (OS 64)指定的网络名不再可用。 : winnt_accept: Asynchronous AcceptEx failed.

原因:】

winnt(MPM) - Apache 2.2 参考手册有下列描述

Apache MPM winnt

说明 专门为Windows NT优化过的MPM
状态 MPM
模块名 mpm_winnt_module
源文件 mpm_winnt.c

概述

该多路处理模块(MPM)是Windows NT上的默认值。它使用一个单独的父进程产生一个单独的子进程,在这个子进程中轮流产生多个线程来处理请求。

Win32DisableAcceptEx 指令

说明 使用accept()代替AcceptEx()接受网络链接
语法 Win32DisableAcceptEx
默认值 AcceptEx()是默认的,使用这个指令将禁用它。
作用域 server config
状态 MPM
模块 mpm_winnt
兼容性 仅在 Apache 2.0.49 及以后的版本中可用

AcceptEx()是一个微软的WinSock2 API ,通过使用BSD风格的accept() API提供了性能改善。一些流行的Windows产品,比如防病毒软件或虚拟专用网络软件,会干扰AcceptEx()的正确操作。如果你遇到类似于如下的错误:

[error] (730038)An operation was attempted on something that is not a socket.: winnt_accept: AcceptEx failed. Attempting to recover.

你就需要使用这个指令来禁止使用AcceptEx()

【解决办法:】

在httpd.conf文件中添加 Win32DisableAcceptEx 标记,如下:

<IfModule mpm_winnt.c>
ThreadsPerChild 150
MaxRequestsPerChild 10000
Win32DisableAcceptEx
</IfModule>

这样可以允许并发连接更大一些。同时性能上也不会有明显的降低。

如果Apache的 error.log还是出现大量的:Sat Dec 24 17:21:28 2006] [warn] (OS 64)指定的网络名不再可用。 : winnt_accept: Asynchronous AcceptEx failed。可以参考下列配置:

1、网上邻居->本地连接->属性->internet协议(TCP/IP)->属性->高级->wins标签->去掉启用LMhosts查询前的勾.
2、控制面版->windows防火墙->高级标签->本地连接设置->服务的标签里勾选安全Web服务器(HTTPS)。
3、然后退出Apache,再打开启动就可以了 ,一开始我没有退出,直接在那重启,就是不可以,一定要先停止,在开启即可

转帖 (3):

[warn] (OS 64)指定的网络名不再可用。 : winnt_accept: Asynchronous AcceptEx failed.

   以前也看到,但忽略了。这回不能再放过她了。

   看了几篇(winnt(MPM) - Apache 2.2 中文版参考手册),说是因为一些流行的视窗系统产品,比如防病毒软件或虚拟专用网络软件,会干扰AcceptEx()的正确操作。于是在apache设置文件中添加如下语句:

<IfModule mpm_winnt.c>
ThreadsPerChild 1000
MaxRequestsPerChild 10000
Win32DisableAcceptEx
</IfModule>

   停止Apache,再启动。确实新设置起作用了:

[notice] Disabled use of AcceptEx() WinSock2 API
[notice] mod_python: Creating 8 session mutexes based on 0 max processes and 1000 max threads.
[notice] Child 2380: Child process is running
[notice] Child 2380: Acquired the start mutex.
[notice] Child 2380: Starting 1000 worker threads.

   okay,似乎错误不再来了。

问题一、
Apache日志中“指定的网络名不再可用”问题的解决
现象:
[Sat Mar 03 13:29:49 2007] [warn] (OS 64)指定的网络名不再可用。   : winnt_accept: Asynchronous AcceptEx failed.
出现这个故障时硬盘灯狂闪,内存占用极大,访问极慢。
分析:
AcceptEx() 是 Microsoft WinSock v2 API 一组提升网路效率 API 中的指令。而且在 Windows 上似乎蛮有可能出问题的。
   注:可能為了效能还是预设為开啟 AcceptEx()
解决:
    如果无预警的发生问题,我猜可能是 Windows Update 或是防火墙、防毒软体更新了某些网路原件,造成 Microsoft WinSock v2 API 动作不正常,这时可以把这个功能先给关掉。
   依照官方说明 , Win32DisableAcceptEx 这个功能,只有 2.0.49 版以后的才可以使用,所以我猜测 AcceptEx() 这个指令大概也是 2.0.49 才会开始支援(目前最新的就是 2.0.49)。
   关掉 AcceptEx() 的方式只要在 httpd.conf 找到   区段,加入 Win32DisableAcceptEx 就可以了。
Win32DisableAcceptEx #加入这一行
ThreadsPerChild 250
MaxRequestsPerChild 0

疑问:如果把AcceptEx()这个关掉了,是否会影响访问的速度;如果影响速度,又怎样不让速度慢下来。
问题二、
apache错误日志里面出现"connection reset by peer"
分析:
这个问题一般是客户端在连接还没有完全建立的时候就取消连接,比如用户按了浏览器上面的“停止”按钮,一般来说没有什么问题。但是如果频繁出现,就表示很多客户端连接到Apache服务器的响应时间太长了,可能是网络的问题或者服务器性能问题。
问题三、
apache错误日志里面提示default.ida或者cmd.exe不存在
分析:
这个说明Internet上面的某些机器中了蠕虫病毒比如Nimda或者Code Red。 你可以略过这些错误,因为这些病毒对Apache无效。
问题四、
apache错误日志里面出现"fcntl: F_SETLKW: No record locks available
现象:
服务器挂起,或者不能启动,错误日志里面出现"fcntl: F_SETLKW: No record locks available"或者类似的信息。
分析:
这个是文件锁定问题,表示Apache服务器在尝试使用一个NFS文件系统上面的同步文件。由于使用并行操作模式,Apache服务器在访问某些特定资源 的时候需要一些同步机制。其中一种同步机制就是文件锁定,这个需要被锁定文件那端的文件系统要支持锁定机制,所以使用NFS文件系统上面的文件会出现这种 问题。
解决:
为了解决NFS文件系统的局限性,可以在配置文件里面加入一行:
  LockFile /var/run/apache-lock
  这个文件对其他人必须是不能写入的。
  注意:Redhat Linux7.x版本以后已经提供了NFS锁定机制,应该不会出现此问题。
2012-1-30 17:52 Monday  

PHP常用函数手册

PHP常用函数手册判断一个编程语言的功能强弱,可以从他的库函数入手。一个较好的编程语言,必然有较强的库函数。
I/O函数
Flush
函数描述:flush();
说明:函数Flush刷新PHP的输出缓存,它尽量将缓和存中的内容输出到用户的浏览器。
返回值:无
Print
函数描述:print(string arg,string[arg],…);
说明:函数print输入所有的参数。
返回值:若输出成功,返回true(1);否则返回false(0)。
Printf
函数描述:printf(string format,mixed[string]);
说明:函数printf根据所给格式format,输出string。格式以一个%开头,以一个字母结尾,该字母决定输出的数据类型。PHP的类型说明符如表所示。
PHP的类型说明符
类型说明符   说         明
b   输出二进制整数
o   输出八进制整数
x,X   输出十六进制整数,“x”使用小写字母,“X”使用大写字母
d   输出十进制整数
c   输出由整数ASCII代码说明的字符
s   输出字符串
f   输出浮点数
e   输出用科学计数法表示的浮点数
%   输出一个百分号
返回值:无
正规表达式函数
Ereg
函数描述:int ereg (string pattern ,string string ,array[regs]);
说明:函数ereg在参数string中寻找pattern中给出的正规表达式相匹配的项。如果提供了可选reg数组,则每一项匹配将顺序存储在数组 regs[1]开始的各项中。在regs[0]中存储整个正规表达式的匹配项。在函数ereg中,匹配的辨别是区分大小写的。请参看以下程序
返回值:若至少有一处匹配则函数ereg返回true(1);否则返回false(0)。
例子:
<?
$date=”2000-5-4”;
if (ereg(“([0-9]){4})-([0-9]{1,2}-([0-9]){1,2})”,$date,$regs))
{
print(“$regs[3].$regs[2].$regs[1]”);
}
else
{
print(“输出时间格式有误:$date”);
}
?>
该程序输出结果:14.5.2000
Ereg_replace
函数描述:string Ereg_replace(string pattern,string replacement,string string);
说明:函数Ereg_replace可用于替换文本,当参数pattern与参数string中的字串匹配时,他就被参数replacement的内容所 替换。若参数pattern中包含有圆括号的子表达式,则在参数replacement中可以用包含特定的代码来说明哪个子表达式被替换,最多可以有九个 子表达式。其具体形式是用两个反斜杠后跟一个从0~9的单数字,0表示与整个表达式相匹配,1~9表示相应的与前1~9个子表达式相匹配。注意,参数 pattern中的圆括号是可以嵌套的,其表达式序号等于该表达式前的圆括号的数目。
返回值:函数ereg_eplace返回替换后的字符串pattern。
Eregi
函数描述:int eregi(string pattern , string string , array[regs]);
说明:函数eregi与ereg相类似,不同之处是函数eregi进行匹配时不区分大小写。
返回值:若至少有一处相匹配,函数eregi返回true(1),否则返回false(0)。
Eregi_replace
函数描述:string Eregi_replace(string pattern,string replacement,string string);
说明:函数eregi_replace与ereg_replace相类似,不同之处就是函数eregi_replace进行匹配时不区分大小写。
返回值:函数eregi_eplace返回替换后的字符串pattern。
Split
函数描述:array split(string pattern,string string , int[limit]);
说明:函数split以参数pattern作为分界符从参数string 中取行一系列子串,并将它们存入一字符串数组。参数limit限定生成数组的大小,数组中的最后一个元素为参数string中还未分组的所有内容。
返回值:函数split返回生成的字符串数组,如果有一个错误,返回false(0)。
Sql_regcase
函数描述:string sql_regcase(string string);
说明:函数sql_regcase生成一个字符串数组,数组中的各个元素依次为参数string中各个字符的大小写;若在参数string中有一个空格,其对应数组元素的内容为一个空格。
返回值:函数sql_regcase返回所生成字符串数组。
例:
<?
print(sql_regcase(“Hello PHP”));
?>
此程序结果为:[Hh][Ee][Ll][Ll][Oo][ ][Pp][Hh][Pp]
数学函数
Abs
函数描述:mixed abs(mixed number);
返回值:函数abs返回参数number的绝对值。
Acos
函数描述:double acos(double number);
返回值:函数acos返回参数number的反余弦值。如果参数number大于1或小于1,则其反余弦值无意义。
Asin
函数描述;double asin(double number);
返回值:函数asin返回参数number的反正弦值。如果参数number大于1或小于1,则其反正弦值无意义。
Atan
函数描述:double atan(double number);
函数atan返回参数number的反正切值。
Atan2
函数描述:Double atan2(double x , double y);
返回值:函数atan2返回由直角坐标系指定的座标点在极座标系中的角度的弧度值。
BinDec
函数描述:int bindec(string binary_number);
返回值:函数bindec返回一个用二进制数写成的字符串binary_number的整数值。PHP使用32位带符号的整数,其二进制数的第一位是符号位。
Ceil
函数描述:int ceil(double number);
返回值:函数ceil返回大于参数number 的最小整数;若number为整数。,则返回其本身。
Cos
函数描述:double cos(double angle);
返回值:函数cos返回以弧度的大小为参数angle的角的余弦值。
DecBin
与bindec相反,将十进制转为二进制。
DecHex(<->HexDec)
返回十六进制值
DecOct(<->OctDec)
返回八进制值
Deg2rad(<->Rad2reg)
函数描述:double deg2red(double angle);
返回值:函数deg2red返回角度数angle相对应的弧度值。
Exp
函数描述:double exp(double power);
返回值:函数exp返回自然对数的power次幂。
Floor
函数描述:int floor(double number);
返回值:返回参数number的整数部分。
Getrandmax
函数描述:int getrandmax();
返回值;返回由函数rand所能返回的最大值
Log(Log10)
函数描述:Double log(double number);
返回值:返回参数number的自然对数(返回以10为底的对数)
Max (<->Min)
函数描述:mixed max(mixed arg1, mixed arg2, …,mixed argn);
返回值:返回此数组中的最大值(最小值),若参数中有浮点数,则所有参数转化成浮点数,返回值也为浮点数;否则所有参数转化成整数,返回值为整数。
pi
函数描述:double pi();
返回值:函数pi返回圆周率的近似值。
Pow
函数描述:double pow(double base,double power);
返回值:函数pow返回参数base的power次幂。
Rand
函数描述:int rand(int lowest,int longest);
说明:函数rand使用前要用srand激活。
返回值:函数rand返回可选参数lowest和longest之间的一个数(包含两个参数);若无参数,则返回值的范围从零到getrandmax返回的整数。
Round
函数描述:double round(double number);
返回值:函数round返回最接近参数number的整数。
Sin
函数描述:double sin(double angle);
返回值:函数sin返回一个用弧度表示的角的正弦值。
Sqrt
函数描述:double sqrt(double number);
说明:在函数sqrt中,参数number不能小于0。
返回值:函数sqrt返回参数number的平方根。
Srand
函数描述:srand(int seed);
说明:函数srand激活随机数发生器。参数seed是随机产生的种子,即所得的随机数是由参数经过一系列计算所的。
返回值:无。
Tan
函数描述:double tan(duoble angle);
返回值:函数tan返回以弧度表示的角的正切值。
时间函数
CheckDate
函数描述:int checkdate(int month,int date,int year);
说明:在PHP中谔谔所谓合法日期,指的是参数year介于1900~32767之间,month介于1~12之间,day处于当前月的有效日期之间的日期。
返回值:若输入的日期合法,返回true(1);否则返回false(0)。
Date
函数描述:string date(string format, int [timestamp]);
说明:函数date根据参数format生成一个描述日期timestamp的字符串。参数timestamp可选,若给定,则为所需的时间戳,即从1970年1月1日开始的秒数;若为空白,则使用当前日期。Format代码如下表:
返回值:函数date返回生成的日期描述字符串。
函数date的format代码表
代     码   描     述
a   am/pm
A   AM/PM
d   有前导零的月份中的日期
D   三字母简写形式的星期几
F   月份名
h   用1~12表示的小时
H   用0~23表示的小时
I   分钟
j   没有前导零的月份中的日期
l   星期几
m   用1~12表示的月份
M   简写月份名
S   月份中日期的正序后缀
U   从纪元开始的秒数
y   两位的年份
Y   四位的年份
Z   一年之中的日期
Getdate
函数描述:array getdate(int[timnestamp]);
说明:函数生成一个带有所给日期信息的关联数组。参数timestamp为所需的时间戳,若为空,则使用当前日期。关联数组元素如下表所示:
返回值:函数getdate返回生成的关联数组。
函数getdate生成的关联数组元素表
元     素   描     述
hours   24小时格式的小时
mday   月份中的日期
minutes   分钟
mon   数字形式的月份
month   月份的全称
seconds   秒数
wday   从0~6数字形式的星期几
weekday   星期几的名称
yday   一年中数字形式的日期
year   年份
0   日期戳
MkTime
函数描述:int mktime(int hour, int minute, int second, int month, int day, int year);
返回值:函数mktime返回给出日期的时间戳,即从1970年1月1日开始的秒数。所有参数都可选,若为空,则使用当前值。若某参数超过范围,函数mktime也可以正确解释。例如,用13作为月份就等于第二年的一月份。
GmmkTime
函数描述:int gmmktime(int hour, int minute, int second, int month, int day, int year);
返回值:函数gmmktime与函数mktime相类似,但不同的是他的各参数均被认为是格林威治时间。
Time
函数描述:int time();
返回值:函数time返回当前的时间戳。
MicroTime
函数描述:string microtime();
返回值:函数microtime返回一个字符串,其组成为两个由空格隔开的成员,第一个成员是系统时间的毫秒数,第二个成员是从1970年1月1日开始计的秒数,即系统时间的时间戳。
6.2.5字符串操作函数
AddSlashes
函数描述:string addslashes(string string);
说明:函数addslashes在参数string中的单引号(‘)、双引号(“)、反斜杠(\)和空格前添加反斜杠(\)。
返回值:函数addslashes返回添加后的字符串参数string。
Chop
函数描述:string chop(string string);
返回值:函数chop去除参数string中最后一个非空字符后的所有空格,并返回生成的新字符串。
Chr
函数描述:string chr(int ascii);
返回值:函数chr根据所给的ASCII码返回相对应的字符。
Eval
函数描述:eval(string phpcode);
说明:函数eval将参数phpcode作为PHP脚本中的一行代码执行,括号内应用单引号或退格美元符。
返回值:无。
Explode
函数描述:array explode(string separator,string string);
返回值:函数explode返回一个字符串数组,数组元素是由参数separator分隔的参数string的各段内容。
Htmlspecialchars
函数描述:string htmlspecialchars(string string);
说明:在HTML中,某些字符与特殊意义,为保留其原意,则将他们用HTLM语言描述。
‘&’转换为“&”
‘ ” ’转换为‘&qout’
‘<’转换为’ < ’
‘>’转换为‘>’
返回值:函数htmlspecialchars返回转变后的字符串。

Implode
函数描述:string implode(array pieces ,string glue);
返回值:将数组pieces依次用参数glue联结并返回生成的字符串
Jion
函数描述:string join(array pieces ,string glue);
说明:函数jion与函数implode作用完全相同。
Ltrim
函数描述:string ltrim(string string);
返回值:去除参数string中第一个非空字符前的所有空格,并返回生成的新字符串。
Nl2br
函数描述:string nl2br(string string);
返回值:在所有的新行前插入“<br>”,并生成新的字符串。
Ord
函数描述:int ord(string string);
返回值:返回所有字符的ASCII码。
QuoteMeta
函数描述:string quotemeta(string string);
返回值:此函数返回一个字符串,该字符串在参数string中的下列元素前加反斜杠:“.”“+”“\\”“*”“?”“[”“]”“^”“(”“)”“$”
RawurldeCode
函数描述:string rawurldecode(string string);
返回值:将原参数字符串string中的百分号(%)及其后的两位十六进制数替换成对应的文本字符,并返回替换后的字符串。
Sprintf
函数描述:string sprintf(string format,mixed[string]);
返回值:与函数printf作用类似,不同之处是他不将原需输出的字符串发送给浏览器,而是返回该字符串。
Strchr
函数描述:string strchr(string string ,string needle);
说明:与函数strstr的作用相同。
Strcmp
函数描述:int strcmp(string str1,string str2);
说明:函数strcmp比较参数Str1与str2的大小,比较过程区分大小写。
返回值:如果str1大于str2,则函数strcmp返回1;如果str1小于str2,则返回-1;如果两者相等,则返回0。
Strcspn
函数描述:int strcspn(string str1 ,string str2);
返回值:从参数str1的首字符开始,不包括参数str 2中任意一个字符的最短字符串的长度。
(即str2在str1中的位置,返回的位置从0开始。)
StripSlashes
函数描述:string stripslashes(string string);
说明:删除参数string中的反斜杠字符。
返回值:返回经过上述操作的字符串。
Strlen
函数描述:int strlen(string string);
返回值:返回参数字符串string的长度。
Strpos
函数描述:int strops(string string ,string needle);
说明:函数strpos中参数needle以整个字符串起作用。若参数needle为一个数字,则函数自动将其转化成整数并作为相对应的ASCII码使用。
返回值:函数strpos返回参数needle在字符串参数string中的最先位置,位置数从0开始。若在字符串string中不包含needle,则返回false(0)。
Strrpos
函数描述:int strrpos(string string ,string needle);
说明:与函数strpos不同,函数strrpos中,参数needle中起作用的只是其首字符。若参数needle为一个数字,则函数自动将其转化成整数并作为相对应的ASCII码使用。
返回值:函数strrpos返回参数needle在字符串参数string中的最后位置,位置数从0开始。若在字符串string中不包含needle,则返回false(0)。
Strrchr
函数描述:string strrchr(string string ,string needle);
说明:在函数strrchr中,参数needle中起作用的只是其首字符。若参数needle为一个数字,则函数自动将其转化成整数并作为相对应的ASCII码使用。
返回值:函数strrchr返回string中由最后一个needle字符开始及其之后的所有部分。若在字符串string中不包含needle,则返回false(0)。
Strrev
函数描述:string strrev(string string);
返回值:函数strrev将参数string倒置并返回。
StrStr
函数描述:string strstr(string string ,string needle);
说明:若参数needle为一个数字,则函数自动将其转化成整数并作为相对应的ASCII码使用。
返回值:函数strstr返回参数string中从参数needle开始及其之后的部分,包括参数needle。
Strtok
函数描述:string strtok(string str1,string str2);
返回值:返回参数str1中在参数str2首字母前的字符串。
Strtolower(<-> Strtoupper)
函数描述:string strtolower(string string);
说明:jiang参数string中的大写字母替换成小写字母。
返回值:替换后的字符串。
Strtr
函数描述:string strtr(string string ,string from ,string to);
说明:函数strtr将参数string中字符from替换成字符to,若参数from和参数to的长度不同,则较长字符串中超过较短字符串长度的部分将被丢弃。
返回值:返回替换后的字符串。
Substr
函数描述:string substr(string string,int start,int [length]);
说明:函数substr从参数string中的第start个字符开始,提取出一个长度为length的字符串。如果参数start是正数,则返回字符串 将从参数string首部起第start个字符开始;若为负数,则返回字符串将从参数string尾部逆推的第start个字符开始。如果参数给出并为 正,,则返回的是一个从start开始的长度为length的字符串;如果参数length给出且为负,则返回的字符串以正数第start位字符为首,以 从参数string尾部开始逆推(-length)个字符为结束的字符串;若返回的字符串长度为负,则返回值为NULL。
返回值:返回所提取出的字符串。

mysql中一个表的一个时间列是int类型,现在想修改这个字段的值,打算可读日期时间格式转成int,然后修改那个值。

这个转换函数就是UNIX_TIMESTAMP,将可读的时间转换成int类型,具体用法:

update xxx_table set xxx_time=UNIX_TIMESTAMP('2006-11-13 13:24:22') where ......

同时介绍一个另一个转换函数:FROM_UNIXTIME,将将时间戳转成常用时间格式



select FROM_UNIXTIME(xxx_time) from xxx_table



mysql将时间戳转成常用时间格式
在mysql中,一个时间字段的存储类型是int(11),怎么转化成字符类型,比方存储为13270655222,需要转化为yyyy -mm-dd的形式

使用 FROM_UNIXTIME函数,具体如下:

FROM_UNIXTIME(unix_timestamp,format)
返回表示 Unix 时间标记的一个字符串,根据format字符串格式化。format可以包含与DATE_FORMAT()函数列出的条目同样的修饰符。
根据format字符串格式化date值。下列修饰符可以被用在format字符串中: %M 月名字(January……December)
%W 星期名字(Sunday……Saturday)
%D 有英语前缀的月份的日期(1st, 2nd, 3rd, 等等。)
%Y 年, 数字, 4 位
%y 年, 数字, 2 位
%a 缩写的星期名字(Sun……Sat)
%d 月份中的天数, 数字(00……31)
%e 月份中的天数, 数字(0……31)
%m 月, 数字(01……12)
%c 月, 数字(1……12)
%b 缩写的月份名字(Jan……Dec)
%j 一年中的天数(001……366)
%H 小时(00……23)
%k 小时(0……23)
%h 小时(01……12)
%I 小时(01……12)
%l 小时(1……12)
%i 分钟, 数字(00……59)
%r 时间,12 小时(hh:mm:ss [AP]M)
%T 时间,24 小时(hh:mm:ss)
%S 秒(00……59)
%s 秒(00……59)
%p AM或PM
%w 一个星期中的天数(0=Sunday ……6=Saturday )
%U 星期(0……52), 这里星期天是星期的第一天
%u 星期(0……52), 这里星期一是星期的第一天
%% 一个文字“%”。

所有的其他字符不做解释被复制到结果中。


如:

SELECT FROM_UNIXTIME(1234567890, '%Y-%m-%d %H:%i:%S')
可以自己指定格式。
原来是McAfee的访问保护阻止了,将例外的进程httpd.exe添加进去就行了。。
2012-1-30 17:50 Monday  

1) 笨方法:重新安装

2) 修改注册表
McAfee 8.0
HKEY_LOCAL_MACHINE\SOFTWARE\Network Associates\TVD\VirusScan Enterprise\CurrentVersion
UIP就是MD5加密过的密码.
直接清除掉,再回到卖咖啡那里重新设置密码就OK了.

其实控制台的密码设置相关信息就保存在
HKEY_LOCAL_MACHINE\SOFTWARE\Network Associates\TVD\VirusScan Enterprise\CurrentVersion下的UIP、UIPMode、UIPpages这三个子键里

UIP为具体的密码内文
mode为加密状况,0为锁定、1则相反
pages就对应的是相关的页面锁定范围


McAfee 8.5
注册表位置改在:HKEY_LOCAL_MACHINE\SOFTWARE\McAfee\DesktopProtection