燕之庐网站建设 - 优质网站设计公司

Archive for the ‘PHP业界’ Category

PHP业界, 产业新闻

2010/02/23

MySpace宣布CEO范纳塔离职

Tags:

2月11日消息,据国外媒体报道,在担任MySpace的首席执行官职务不到一年 后,MySpace公司CEO欧文范纳塔(Owen Van Natta)离职。

MySpace母公司新闻集团在本周三的一份声明中宣布了这一消息,其职务暂时由迈克琼斯和贾森赫塞豪恩代替,被命名为联席总裁,他们必须把具 体事务的报告交给新闻集团数字媒体部门董事长兼CEO米勒(Jon Miller)。

在公司宣布离职消息后,纳塔表示:对我们已经完成的工作感到骄傲,并期待着公司继续取得不断的增长和成就。但他没有透露具体的离职原因。

欧文万纳塔是目前硅谷最抢手的数字高级管理人员。在担任MySpace首席执行官职务之前,他曾经在Facebook工作,在担任首席运营官职 务之前还担任过首席营收官(chief revenue officer)的职务。纳塔在2008年2月离开Facebook,希望跳槽担任CEO的职务。并最终在2009年4月如愿以偿的担任MySpace的 CEO。

在当时,新闻集团数字媒体部门董事长兼CEO米勒对纳塔寄予厚望,并认为结合纳塔对社交网络的深刻理解和其敏锐的商业意识,再加上 MySpace的业务经验,MySpace可以获得更大的进步。MySpace曾经是世界上最大的社交网络,但是随着Facebook的壮 大,MySpace已经黯然失色。目前,Facebook的页面浏览量是MySpace的11倍(约为2600亿次页面浏览)。

PHP业界, php

2010/02/04

Facebook宣布PHP runtime项目HipHop

Tags: ,

Facebook如期待的那样宣 布了新 的PHP runtime开源项目HipHop for PHP。这个项目由一个PHP到C++的转换程序,一个重新实现的PHP运行库,和许多常用PHP扩展的重写版本构成,目的是旨在加速和优化PHP。

事实上HipHop并不是一个新项目,Facebook已经使用它有数个月之久,目前 Facebook 90%的服务器都运 行着HipHop。Facebook声称它让Web server的CPU占用下降了大约50%,更少的CPU意味 着更少的服务器和更少的系统开销。

用Facebook官方博客上项目负责人赵海平(北大1987届遗传与分子生物专业,普林斯顿计算 机科学博士)的话说,HipHop项目对Facebook影响巨大。它目前已经支撑了Facebook 90%的Web流量。由于HipHop,Facebook Web服务器上的CPU使用平均减少了50%,从而大大减少了服务器的需求。为了让这一改进也惠及社 区,他们决定将之开源,希望能够进一步帮助提高更多大型复杂PHP网站的可伸缩性。

PHP和 Facebook的问题

众所周知,Facebook的前端主要是用PHP写的。赵海平说,过去六年Facebook从 PHP语言的进展上获益良多。PHP非常简单,易学易用,好读好调试,因此新工程师成长很快,有利地促进了Facebook的更快的创新。

PHP是一种脚本语言,其好处是编程效率 高,能够支持产品的快速迭代。但是与传统的编译语言相比,脚本语言的CPU和内存使用效率不好。随着 Ajax技术的广泛采用,加上SNS对动态要求较高,这些缺点更显得突出。对于每月超过4000亿次PV的Facebook来说,如何实现扩展,尤其具有 挑战性。

常见的办法是直接用C++重写PHP应用中比较复杂的部分,作为PHP扩展。实际上,PHP就转变为一种胶水语言,连接前端 HTML和C++应用逻辑。从技术角度讲这也没有问 题,但是增加了技能需求,能够在整个应 用上工作的工程师数量就大大减少了。学习C++只是编写PHP扩展的第一步,接下来还要理解Zend API。由于Facebook的工程团队较小,每个工程师要支持100万以上的用 户。有些代 码不是团队里每个人都能看懂,这对于Facebook是无法接受的。

Facebook网站本身的 可伸缩性更具挑战性,因为几乎每次页面浏览都是有个性化体验的登录用户发起。浏览主页 时,系统需要查询所有朋友、朋友最重要的状态更新、 根据隐私设置筛选结果,然后还要显示评论、照片等等动态,这一切都需要在一秒内完成。

自2007年以来,Facebook曾写过几种不同办法解决这些问题。其中包括用另一种语言重写Facebook,但是由于开发的复杂性和速度等原 因,未能实现。他们还重写了PHP的核心部分Zend引擎,并提交给了PHP项目,但最终还是没有获得所需的性能。最后,他们选择了HipHop,终于得 偿所愿。

有了HipHop,工程师可以编写代码,用PHP编写组合最后页面的逻辑,并能够继续 快速迭代,同时后端服务使用C++, Erlang, Java, Py thon编写,提供新闻提要、搜索、聊天和其他核心功能。

HipHop开发故事

赵海平透露,项目最初是来自几年前Facebook公司一次Hackathon活动(员工在一个晚上自由发挥,实验新的想 法),他手工将PHP转换为C++代码,虽然语法上很类似,但是无论是CPU还是内存使用,转换后的C++代码都大大优于PHP。于是他想,如果构建一个 系统,编程实现转换,会怎么样呢?

在此之前,已经有了不少改善PHP性能的方法。Zend引擎在运行时转换PHP源代码为运行在 Zend虚拟机上的opcode。开源项目APC和 eAccelerator将输出缓存,为大多数PHP网站所使用。此外,还有Zend Server这样的商业产品,通过opcode优化和缓存,提高PHP速度。赵海平选择了另一条道路,将PHP直接转为C++,然后再变成本地机器码。当 然,有许多开源项目也是同样的思路,Roadsend和phc编译为C,Quercus编译为Java,而Phalanger编译为.NET。

Hackathon之后8个月,赵海平拿出了原型,足以说明这条路可以走通,编译后的代码的确更快。不久,Iain Proctor和Minghui Yang加入进来。接下来又开发了10个月,在生产服务器上测试了6个月。然后正式上线部署,6个月之后,Facebook 90%以上的Web流量都使用了HipHop。

按赵海平的说法,凭借HipHop,Facebook Web服务器上的CPU使用平均减少了50%,从而大大减少了服务器的需求。项目对Facebook影响巨大。为了让这一改进也惠及社区,他们决定将之开 源,希望能够进一步帮助提高更多大型复杂PHP网站的可伸缩性。

HipHop的原理

HipHop将PHP代 码转换为高度优化的C++代码,然后再用g++编译器编译。它可以保持语义等效地执行源代码,但为了提高性能,牺牲了一些很少用到的特性,比如 eval()。

HipHop开发中的主要困难在于,在PHP和C++这两种很不一样的语言之间怎么实现转换。虽然PHP也可以写一些 很巧妙的动态特性,但是大多数 PHP代码还是非常简单的。if (…) {…} else {..} 比foo($x) { include $x; } 肯定更常见。这为性能提高提供了机会。HipHop生成的代码尽可能地使用函数和变量的静态绑定。同时,还使用类型推演来选出变量最可能对应的某个类型, 从而节省内存。

转换过程分三步:

1. 静态分析。收集声明关系和依赖关系等信息。

2. 类型推演。选择最合适的类型,是C++的标量?还是String, Array, classes, Object或者Variant。

3. 代码生成。大部分直接将PHP语句和表达式对应为C++的语句和表达式。

在开发过程中,还有一个副产品:HPHPi,是一个 实验性的解释器。通过它,不编译PHP源代码也可以运行。它已经用于HipHop自身的调试中。

HipHop在保持了PHP优点的同 时,也兼得了C++的性能优势。项目总共有30万行代码,5000多个单元测试。所有这些都将以PHP开源许可证形式发布到GitHub。

更多信息,可以申请加入HipHop的邮件列表:http://groups.google.com/group/hiphop-php-dev

网站建设

PHP业界, php

2009/12/28

php优化及高效提速问题小结

Tags: ,

一、 在函数中,传递数组时使用 return 比使用 global 要高效,比如:

function userloginfo($usertemp){

$detail=explode(”|”,$usertemp);

return $detail;

}

$login=userloginfo($userdb);

function userloginfo($usertemp){

global $detail;

$detail=explode(”|”,$usertemp);

}

userloginfo($userdb);

要高效

二、 (这个代码用于得到程序目录对应的网址,推荐使用)

$urlarray=explode(’/',$HTTP_SERVER_VARS['REQUEST_URI']);

$urlcount=count($urlarray);unset($urlarray[$urlcount-1]);

$ofstarurl=’http://’.$HTTP_SERVER_VARS['HTTP_HOST'].implode(’/',$urlarray);

这段代码比

$pre_urlarray=explode(’/',$HTTP_SERVER_VARS['HTTP_REFERER']);

$pre_url=array_pop($pre_urlarray);

要高效

三、 在循环中判断时,数值判断使用恒等要比等于高效

$a=2;$b=2;

比如

if($a==$b)$c=$a;

if($a===$b)$c=$a;

高效

四、 mysql 查询时尽量使用where in 少用 limit

limit查多记录的前几条, 速度很快, 但是查询最面几条就会慢

使用in .在查询连续性记录,非常快, 非连续性记录第一次运行会稍微慢一点,但是之后将比较快!

五、 NT服务器数据操作稳定性不及unix/linux

六、 输出前使用尽量使用 ob_start(); 可以加快输出速度,适用NT或nuli/linux,对unlix类服务器 如果使用 ob_start(’ob_gzhandler’);输出效率将更高

七、 判断的时候尽量使用if($a==他的值) 否定的时候尽量使用if(empty($a)),因为这样程序运行更快速

八、 使用不等时 != 与 <> 效率相当

九、 个人经验得 使用 $a=”11111111111111″; 的效率和 $a=’11111111111111′; 相当.并不象书本说的相差很大

十、 使用规范的SQL语句, 会有利于MySQL的解析

十一、 使用

if($online){

$online1=$online;

setcookie(’online1′,$online,$cookietime,$ckpath,$ckdomain,$secure);

}

COOKIE将马上生效

使用

if($online)

setcookie(’online1′,$online,$cookietime,$ckpath,$ckdomain,$secure);

COOKIE需要再刷新一次才能生效

十二、 使用

$handle=fopen($filename,wb);

flock($handle,LOCK_SH);

$filedata=fread($handle,filesize($filename));

fclose($handle);

file($filename);

无论在速度还是稳定上都要优秀

十三、 截断字符串优化函数(可避免?字符出现)

function substrs($content,$length) {

if(strlen($content)>$length){

$num=0;

for($i=0;$i<$length-3;$i++) {

if(ord($content[$i])>127)$num++;

}

$num%2==1 ? $content=substr($content,0,$length-4):$content=substr($content,0,$length-3);

$content.=’ …’;

}

return $content;

}

比如 $newarray[1]=substrs($newarray[1],25);

十四、 程序中屏蔽大小写

for ($asc=65;$asc<=90;$asc++)

{ //strtolower() 此函数在一些服务器会产生乱码!

if (strrpos($regname,chr($asc))!==false)

{

$error=”为了避免用户名混乱,用户名中禁止使用大写字母,请使用小写字母”;

$reg_check=0;

}

}

十五、 不使用 file();和不使用 fget();(不稳定或速度慢) 取一数组函数

function openfile($filename,$method=”rb”)

{

$handle=@fopen($filename,$method);

@flock($handle,LOCK_SH);

@$filedata=fread($handle,filesize($filename));

@fclose($handle);

$filedata=str_replace(”\n”,”\n”,$filedata);

$filedb=explode(”",$filedata);

//array_pop($filedb);

$count=count($filedb);

if($filedb[$count-1]==”){unset($filedb[$count-1]);}

return $filedb;

}

这个函数虽然代码比较多,不过在速度和稳定性上优势很大!

网站建设

PHP业界

2009/12/14

微软发布Doloto工具 加速优化AJAX程序

Tags:

据国外媒体报道,微软发布了一个名为”Doloto”的小工具(1.56MB),能够对AJAX互动程序的下载进行优化加速,从而提高复杂的Web 2.0网页的浏览和响应速度。

图1 “Download Time Optimizer”

来自微软研究中心的Doloto -“Download Time Optimizer”,首先通过分析AJAX应用程序工作量,然后自动对较大的程序进行代码分割,经过这样的处理之后,执行Web 2.0程序的时候就不再一次性全部下载,而是优先下载初始化所必需的部分代码,其余代码则在后台。

图2 安装界面

由于代码下载和程序执行是交互进行的,用户就可以更快地执行Web程序中所需要的功能,不必等待额外非必要功能的更多代码。

根据测试,Doloto能将JavaScript代码的初期下载量减少40-50%或者数百KB,AJAX Web 2.0程序能因此提速20-40%,具体幅度根据网络状况而不同。

图3 应用分析比较

Doloto下载 (注意需要首先安装.NET Framework 3.5)

更多资源:http://research.microsoft.com/en-us/projects/doloto/

北京网站建设公司

PHP业界, php

2009/11/28

面向普通人加密 使用PHP应用程序保护数据

Tags: ,

在这个日渐虚拟的互联网世界中,您必须小心保护自已的数据。本文将介绍编码和加密一些重要信息(比如密码、信用卡号、甚至整个消息)的基础知识。并通过使用 PHP 的内置功能,了解加密和解密信息的意义,并且将了解一些涉及密码和其他数据的实际示例。
了解当今现实世界与 20 年前的现实世界的不同。在 20 世纪 80 年代,加密是一种特工人员的行为 —— 是您在 Tom Clancy 的侦探小说中才可以读到的情节。如果某人想保持少量私有信息,那么他必须使用密码、密码短语或其他基本方法对数据进行加密。

而现在,加密遍布各个领域。密码也被加密保存在数据库中。电脑空间中的加密的通道可能是通过 SSL、SSH 和其他技术加密的 —— 更不必说拟虚专用网络。人们平常可以而且一定能够使用 Pretty Good Privacy (PGP) 来保护敏感的文件和电子邮件。

作 为一名 PHP 开发人员,您应该知道,强有力的安全做法并不是只将安全保护用于独特的应用程序 —— 还可以将其用于您当前从事的项目。用户要树立从一般加密方法(例如,在登录页上的密码字段中不显示明文)过渡到各种高级加密方法(如 DES、MD5、SHA1 和 Blowfish)的意识。

因时间和篇幅所限,这里无法讨论加密的各个方面,但是您将从这里了解涵盖适用于 您的多数情况的基本内容。我们通过使用 PHP 内置功能先了解加密和解密信息的意义,进而了解涉及密码和其他数据的一些实际示例。在本文中,加密是在更大的安全上下文中进行讨论的。最后,将介绍其他 PHP 扩展和插件。

加密技术的初级读本

作为希腊的词根资产,加密技术是一种 “神秘编写” 艺术。凯撒密码 是最古老的一种密码,形式也最为简单。它采用明文消息,将字母移动 n 个位置,从而产生暗文。例如:

明文:Veni Vidi Vici
暗文:Xgpk Xkfk Xkek
通 过检查暗文并借助一些启发式的技巧,您可以知道,明文实际上是移动了两个字符。凯撒密码很容易破解。例如:检查上述信息,可知 X 重复了多次,且 k 也是如此。这就变成猜迷,确定多少个四字母的词有那样多的元音。知道了这些带元音的词后,您就知道了移动其余字的方法。它还可以帮助您判断明文是否为拉丁 文,让您对其有大致的了解。

现代加密技术的功能非常强大,使用了超越统一移动字母和符号的算法。本文不打算详细介绍这些算法,仅介绍一些 PHP 安装,它包括您需要适度(或特别)保持数据安全的所有内容。

不存在 100% 不受攻击的绝对完整的加密方法。大概每隔一个月,一些黑客及其朋友就会集合 1,000 台计算机,在最初的几天里强力进行计算破坏,从而使最新的加密方法崩溃。不过,您可以密封您的系统和数据,不让黑客干扰和非法闯入。他们将在其他地方寻找可乘之机。

了解这些内容之后,让我们转而了解那些受简单登录形式保护的示例 PHP 应用程序。

没有安全保障或加密的 PHP 形式处理

假 定您是一位新的 Web 应用程序开发人员,没有更多的机会使用安全功能。您创建了您的第一个应用程序,它可以在专用用户表中存储用户名和密码,但是,您没有对这些密码进行加密。 这些密码以一眼就看明白的形式存在,任何人都可以使用它们访问数据库。您可以构建一个如下所示的登录页面。

清单 1. 简单的登录页面

<form action=”verify.php” method=”post”>
<p><label for=’username’>Username</label>
<input type=’text’ name=’username’ id=’username’/>
</p>

<p><label for=’password’>Password</label>
<input type=’text’ name=’password’ id=’password’/>
</p>
<p><input type=”submit” name=”submit” value=”log in”/>
</p>
</form>

HTML 标记存在什么问题?为密码字段选择的输入类型为 text,这意味着用户键入该字段的任何内容都会以明文形式显示在屏幕上。

您 可以方便地将该类型更改为 password,并将该字段中的用户输入替换为一串星号。可靠吗?绝对可靠。不过,这一步骤在很多应用程序中会被忽略。事情虽小,但在安全方面会使人们 感到不安。您愿意将钱存入休息大厅的窗口被严重毁坏的银行吗?也许您会。但是您可能更期望银行是完好无损的。对于应用程序来说,道理相同。

让我们继续介绍处理表单提交的 verify.php 文件。

清单 2. 简单的 PHP 登录验证

<?php
$user = $_POST['user'];
$pw = $_POST['password'];

$sql = “select user,password from users
where user=’$user’
and password=’$pw’
limit 1′;
$result = mysql_query($sql);

if (mysql_num_rows($result)){
//we have a match!
}else{
//no match
}

?>

读阅到此,您会露出满意的微笑。等待阅读本文加密部分的部分读者可能变得不耐烦了,但是加密仅为安全问题的一部分。您还必须聪明地处理引入的用户数据。developerWorks 教程 “锁定您的 PHP 应用程序”(请参阅参考资料)讨论了 SQL 注射:将不正常的数据发送到数据库可导致有害或无根据的访问。无论您使用多少个加密,公开弱点没有一点好处。

您应遵循下面的传统安全原则:“不信任用户提供的数据” 和 “深层防御”;清除传入数据并通过转义传入的字符串保护数据库(参见清单 3)。深层防御是将多余的安全方法都妥善保管 —— 不仅包括加密,还包括用户所提供数据的智能处理。

清单 3. 保护 PHP 形式解析免受用户数据操作的影响

<?php
$user = strip_tags(substr($_POST['user'],0,32));
$pw = strip_tags(substr($_POST['password'],0,32));

$sql = “select user,password from users
where user=’”. mysql_real_escape_string($user).”‘
and password=’”. mysql_real_escape_string($pw).”‘
limit 1′;
$result = mysql_query($sql);

if (mysql_num_rows($result)){
//we have a match!
}else{
//no match
}
?>
通过合理使用 strip_tags()、substr() 和 mysql_real_escape_string(),可以删除任何潜在的有害命令,将字符串减少到 32 个字符,并去掉所有特殊字符,数据库可能将这些字符解释为非预期命令字符串的一部分。

在这一过程结束时,数据库中仍有一个明文密码。您不能显示它。最容易的修复方法是使用 PHP 的内置 crypt() 功能。

使用 crypt()

PHP 的内置 crypt() 功能可实现单向加密 或单向散列。它只所以是单向的,是因为在对某内容进行加密后,您永远不能将其反转为明文。乍一看,此想法似乎很荒谬。使用加密主要是保护信息,随后能够使用该信息,后者通常意味着能够对它进行解密。

不要绝望。单向加密方案和 crypt() 特别受欢迎。可以使保护信息的方法更安全。如果您的用户密码列表落入不法之徒之手,他们实际上没有将密码解密为明文的方法。

让我们返回到密码示例。注释 (notational) PHP 应用程序可能包括让系统管理员创建、编辑和删除用户的模块。例如,在将用户记录存储到用户表之前,PHP 脚本可以使用 crypt() 对密码加密。

清单 4. 使用 crypt() 加密密码

<?php
$user = strip_tags(substr($_POST['user'],0,32));
$pw = strip_tags(substr($_POST['password'],0,32));

$cleanpw = crypt($pw);

$sql = “insert into users (username,password)
values(’”.mysql_real_escape_string($user).”‘,
‘”.mysql_real_escape_string($cleanpw).”‘)”;
//…..etc….
?>

crypt() 将一串明文作为它的第一个参数字,对它应用 salt 会影响加密算法的随机性,并生成输入明文的单向暗文。如果不提供 salt,则 PHP 通常默认其系统 salt,它可以是以下值和长度之一:

算法 Salt
CRYPT_STD_DES 2 个字符(默认)
CRYPT_EXT_DES 9 个字符
CRYPT_MD5 12 个字符,以 $1$开头
CRYPT_BLOWFISH 16 个字符,以 $2$开头
许多现代 PHP 安装使用 MD5 或更高的 salt,它们使用强大的 12 个字符的 salt,但是,不要对任何事情想当然。您最好知道系统正在使用哪一个值。您可以使用以下 PHP 代码片段检查服务器的设置:

<?php echo “System salt size: “. CRYPT_SALT_LENGTH; ?>

返 回的答案将是 2、9、12 或 16,它告诉您系统正在使用的值。要使用 MD5 或更高版本的 salt,您可以显式调用明文和 salt 参数中的 crypt() 函数以及 md5() 函数,以获取随机暗文(参见清单 5)。md5() 函数可以散列反馈的任何字符串,并将其转变为固定长度为 32 个字符的字符串。您可能更喜欢其他方法,具体的使用取决于安全需求和个人爱好。

清单 5. 使用 crypt() 和 md5() 加密密码

<?php
$user = strip_tags(substr($_POST['user'],0,32));
$pw = strip_tags(substr($_POST['password'],0,32));

$cleanpw = crypt(md5($pw),md5($user));

$sql = “insert into users (username,password)
values(’”.mysql_real_escape_string($user).”‘,
‘”.mysql_real_escape_string($cleanpw).”‘)”;
//…..etc….
?>

现在数据库中已经拥有一个已加密的密码,但是没有对其进行解密的方法。如何使之有用?一个比较容易的方法是:对用户提供的任何传入密码都使用相同的加密方法,并将结果与您存储的密码比较。

清单 6. 重访 verify.php

<?php
$user = strip_tags(substr($_POST['user'],0,32));
$pw = strip_tags(substr($_POST['password'],0,32));
$cleanpw = crypt(md5($pw),md5($user));

$sql = “select user,password from users
where user=’”. mysql_real_escape_string($user).”‘
and password=’”. mysql_real_escape_string($cleanpw).”‘
limit 1′;
$result = mysql_query($sql);

if (mysql_num_rows($result)){
//we have a match!
}else{
//no match
}
?>
例 如,如果存储的加密密码是 i83Uw28jKzBrZF,则加密存储传入的密码,并将它与存储的密码进行比较。攻击者破坏加密的惟一方法是将一个非常长的字符串列表与您的加密密码 进行比较,每次比较一个,直到找到匹配项。这也称为字典攻击,因此您的密码最好不应该是密码 或 Star Trek 字符名,甚至您的呢称。因为在加密 Fido 后,它会变成一堆乱语,但这并不表明它对于此种攻击是安全的。确保您的密码具有某一长度(八个或更多字符),并包含大写字母、数字和特定的字符,如 ! 和 $,这样猜测您的数据会更加困难。在短语中,f1D0! 是一个较好的密码,它胜于 GandalftheGray 之类的长密码,由于后者使用小写字母,并且是 “Lord of the Rings” 的字符名称。

使用 crypt() 的一种不太好的方法

还有使用 crypt() 的另一种方法,这种方法不太好:将明文的前 n 个字符用作 salt。

清单 7. 将明文字符用于 salt

<?php
$user = strip_tags(substr($_POST['user'],0,32));
$pw = strip_tags(substr($_POST['password'],0,32));
$cleanpw =crypt($pw, substr($user,0,2));

$sql = “select user,password from users
where user=’”. mysql_real_escape_string($user).”‘
and password=’”. mysql_real_escape_string($cleanpw).”‘
limit 1′;
$result = mysql_query($sql);

if (mysql_num_rows($result)){
//we have a match!
}else{
//no match
}
?>

如果您的用户名是 tmyer,则 salt 预置为 tm,它会使某人很容易推断 salt 的内容。这不是一个好方法。

使用 PHP 进行加密和解密

本文的大部分篇幅讨论了使用 crypt() 的单向加密。但是,如果您要将消息发送给某人,并提供对该消息解密的方法,又该如何办呢?请使用 PHP 支持的公钥加密技术。

使 用公钥加密的用户拥有一个私钥和一个公钥,并且他们与其他用户共享公钥。如果您要将一封私有短信发送给您的朋友 John Doe,您可以使用 John Doe 的公钥(您已经将其存储在自已的 keyring 中)加密该消息。John Doe 收到该消息后,只有他可以使用他的私钥对其解密。任何给定用户的公钥和私钥在数学上是不能相关的。对于 PGP 和其他公钥加密方法,不存在从公钥推断某人私钥的方法。

PGP 的附加特性是:私钥的密码实际上不是密码,它是一个密码短语。它可以是整句话,包括标点符号、空格和所有字符样式。

使 用基于 PGP 的公钥加密的一种方法是使用 GNU Privacy Guard (GPG)。使用 GPG 加密的任何消息都可以使用 GPG、PGP 或支持任一程序的任何数量的电子邮件客户机插件来解密。在示例中,联机表接受用户输入(包括消息);使用 GPG 为特定的接收方加密消息;然后发送消息。
清单 8. 使用 GPG

<?php
//set up users
$from = “webforms@example.com“;
$to = “you@example.com“;

//cut the message down to size, remove HTML tags
$messagebody = strip_tags(substr($_POST['msg'],0,5000));
$message_body = escapeshellarg($messagebody);

$gpg_path = ‘/usr/local/bin/gpg’;
$home_dir = ‘/htdocs/www’;
$user_env = ‘web’;

$cmd = “echo $message_body | HOME=$home_dir USER=$user_env $gpg_path” .
“–quiet –no-secmem-warning –encrypt –sign –armor ” .
“–recipient $to –local-user $from”;

$message_body = `$cmd`;

mail($to,’Message from Web Form’, $message_body,”From:$from\r\n”);

?>

在 此示例中,PHP 调用 /usr/local/bin/gpg(此位置因服务器而异),以便使用发送方的私钥和接收方的公钥加密消息。结果,只有接收方可以解密该消息,并且知道 来自发送方的消息。此外,还可以设置 HOME 和 USER 环境变量,以通知 GPG 在何处查找存储这些密钥的 keyring。其他标志的功能如下:

–quiet 和 –no-secmem-warning 抑制来自 GPG 的警告。
–encrypt 执行加密。
–sign 添加签名,以验证发送方的身份。
–armor 产生非二进制的 ASCII 输出,这样,易于通过电子邮件将其发送。
正 常情况下,正如前面提到的,机密密钥受密码短语的保护。本特定实例没有使用密码短语,因为在每次表单提交时它都需要手工输入。当然,在下列情况下您还可以 选择其他选项:在单独文件中提供短语,或使用它自已的身份验证方案防止表单公用(例如,如果它是一个只能由公司销售代表访问的表单)。

另请注意,除非您正在对允许用户输入电子邮件消息的表使用 SSL,否则键入的任何内容都是明文形式的。换句话说,客户机和服务器之间的任何人都可以看见它。不过,这是另一个主题。

结束语

我 们对安全性、加密技术,甚至公钥加密技术介绍了很多,目的是帮助您成功开发下一个 PHP 项目。使用加密和其他加密方法的要点不是创建 100% 可靠的无缝系统。关闭的计算机才是不可攻击的系统,但是也不能完全保证,因为某人可能会走上前走,打开它,然后攻击它。加密的要点是使获取敏感数据变得非 常困难,以致黑客不再尝试攻击,或尝试攻击失败后离去。

所有安全性考虑必须兼顾方便和保护。使用强大的算法密钥将所有数据都进行单向加密意 味着您的数据非常安全,但是使用时很不方便。这带来的相应缺陷也很严重,如同使用非加密的内容一样,为您带来的任何方便也为其他人获取数据带来了可怕的方 便。通过加密重要的机密数据(如密码、信用卡号和秘密消息)和添加好的安全措施(如深层防御、过滤用户提供的数据和传统的一般常识)可以达到最佳平衡。

网站设计

PHP业界

2009/10/23

最简便的MySql数据库备份方法

Tags:

使用MYSQL进行数据库备份,又很正规的数据库备份方法,同其他的数据库服务器有相同的概念,但有没有想过,MySQL会有更简捷的使用文件目录的备份方法,而且又快有好。

一、数据备份捷径

因为这个方法没有得到官方正式文档的验证,我们暂称为试验吧。

目的:备份hostA主机中一个mysql数据库TestA,并恢复到到hostB机中

试验环境:

操作系统:WinNT4.0,Mysql3.22.34,phpMyAdmin 2.1.0

在hostA中安装mysql数据库并建立TestA数据库

hostB机安装mysql数据库,没有TestA数据库

方法步骤:

启动phpMyAdmin察看HostA和HostB中的数据库列表,在HostB中没有TestA数据库

找到HostA中mysql的安装目录,并找到数据库目录data

在我的试验环境中,这个目录是

C:mysqldata

找到对应数据库名称的子目录

C:mysqldataTestA

粘贴拷贝到HostB的Data目录下,是HostA同HostB Mysql数据目录下的文件相同

刷新HostB的phpMyAdmin察看一下数据库列表,我们看到TestA已经出现,并且作查询修改等操作都正常,备份恢复恢复成功

试验结论:Mysql的数据库可以通过文件形式保存,备份,恢复只要将相应文件目录恢复即可,无需使用其它工具备份。

二、正规的方法(官方建议):

导出要用到MySQL的mysqldump工具,基本用法是:

mysqldump [OPTIONS]database[tables]

如果你不给定任何表,整个数据库将被导出。

通过执行mysqldump –help,你能得到你mysqldump的版本支持的选项表。

注意,如果你运行mysqldump没有–quick或–opt选项,mysqldump将在导出结果前装载整个结果集到内存中,如果你正在导出一个大的数据库,这将可能是一个问题。

mysqldump支持下列选项:

–add-locks

在每个表导出之前增加LOCK TABLES并且之后UNLOCKTABLE。(为了使得更快地插入到MySQL)。

–add-drop-table

在每个create语句之前增加一个drop table。

–allow-keywords

允许创建是关键词的列名字。这由在列名前面加表名的方法做到。

-c, –complete-insert

使用完整的insert语句(用列名字)。

-C, –compress

如果客户和服务器均支持压缩,压缩两者间所有的信息。

–delayed

用INSERT DELAYED命令插入行。

-e, –extended-insert

使用全新多行INSERT语法。(给出更紧缩并且更快的插入语句)

-#, –debug[=option_string]

跟踪程序的使用(为了调试)。

–help

显示一条帮助消息并且退出。

–fields-terminated-by=…

–fields-enclosed-by=…

–fields-optionally-enclosed-by=…

–fields-escaped-by=…

–fields-terminated-by=…

这些选择与-T选择一起使用,并且有相应的LOADDATAINFILE子句相同的含义。

LOAD DATA INFILE语法。

-F, –flush-logs

在开始导出前,洗掉在MySQL服务器中的日志文件。

-f, –force,

即使我们在一个表导出期间得到一个SQL错误,继续。

-h, –host=..

从命名的主机上的MySQL服务器导出数据。缺省主机是localhost。

-l, –lock-tables.

为开始导出锁定所有表。

-t, –no-create-info

不写入表创建信息(CREATETABLE语句)

-d, –no-data

不写入表的任何行信息。如果你只想得到一个表的结构的导出,这是很有用的!

–opt

同–quick –add-drop-table –add-locks –extended-insert –lock-tables。

应该给你为读入一个MySQL服务器的尽可能最快的导出。

-pyour_pass, –password[=your_pass]

与服务器连接时使用的口令。如果你不指定“=your_pass”部分,mysqldump需要来自终端的口令。

-P port_num, –port=port_num

与一台主机连接时使用的TCP/IP端口号。(这用于连接到localhost以外的主机,因为它使用 Unix套接字。)

-q, –quick

不缓冲查询,直接导出至stdout;使用mysql_use_result()做它。

-S /path/to/socket, –socket=/path/to/socket

与localhost连接时(它是缺省主机)使用的套接字文件。

-T, –tab=path-to-some-directory

对于每个给定的表,创建一个table_name.sql文件,它包含SQL CREATE 命令,和一个table_name.txt文件,它包含数据。 注意:这只有在mysqldump运行在mysqld守护进程运行的同一台机器上的时候才工作。.txt文件的格式根据–fields-xxx和–lines–xxx选项来定。

-u user_name, –user=user_name

与服务器连接时,MySQL使用的用户名。缺省值是你的Unix登录名。

-O var=option, –set-variable var=option

设置一个变量的值。可能的变量被列在下面。

-v, –verbose

冗长模式。打印出程序所做的更多的信息。

-V, –version

打印版本信息并且退出。

-w, –where=’where-condition’

只导出被选择了的记录;注意引号是强制的!

“–where=user=’jimf’” “-wuserid>1″ “-wuserid<1″

最常见的mysqldump使用可能制作整个数据库的一个备份:

mysqldump –optdatabase> backup-file.sql

但是它对用来自于一个数据库的信息充实另外一个MySQL数据库也是有用的:

mysqldump –opt database | mysql –host=remote-host -C database

由于mysqldump导出的是完整的SQL语句,所以用mysql客户程序很容易就能把数据导入了:

mysqladmin create target_db_name

mysql target_db_name < backup-file.sql

PHP业界, php

2009/10/20

PHP程序员一般都忽略了的几点精华

Tags: ,

我发现很多的PHP程序员,尤其是学习还不是很久的,都不知道PHP的精华所在。Perl当年如何在商界出名?其强大的正则表达式。而PHP呢?他是一门 从Unix下发展起来的语言,当然也就继承了Perl的很多特点,同时C的优点都有。快速、简洁、明了,尤其是C程序员,PHP是至爱,我就是深爱着 “PHP”(都忘了女友了:))。这里,我想来写一篇PHP的变量、数组应用技巧和PHP的正则表达式、PHP的模板应用,以后有时间再写PHP与 COM、PHP与XML的完全结合。

1、变量、数组的应用技巧
(1)很多人用得不多的数组函数。foreach、list、each。分别举几个例子,应该就能知道了。例:
<?php
$data = array(’a’ => ‘data1′, ‘b’ => ‘data2′, ‘c’ => ‘data3′);
while(list($subscript, $value) = each($data))
{
echo “$subscript => $value ::“;
echo “$subscript => $value\n
“;
}

reset($data);
foreach($data as $subscript => $value)
{
echo “$subscript => $value :: “;
echo “$subscript => $value\n
“;
}
(2)函数的变量、变量的变量、变量的“指针”:看下例:
<?php
//变量的变量
$var = “this is a var”;
$varname = “var”;
echo $$varname;
//函数的变量
function fun1($str) {
echo $str;
}
$funname = “fun1″;
$funname(”This is a function !”);
?>
变量的“指针”。这个指针加上了双引号,表明他不是真正的指针。看看下例:
<?php
function($a) {
$a ;
}
$c = 0;
function($c);
echo $c; //$c仍为0
function(&$a) {
$a ;
}
$c = 0;
echo $c; //$c为1
?>
之所以称其为“指针”,就是因为他有了和C语言中指针相同的功能。但这又不是真正的指针,只能够是这样的去理解。

2、正则表达式
正则表达式是一个非常大的题目,Perl的正则表达式的强大是闻了名的。而PHP也不弱,他继承了Perl的正则表达式法则,还有自己的一套法则。这里只说PHP自己的正则表达式。
正则表达式是最基本的元素。简单地说就是一套规则,用于去判定其它的元素是不是符合自身的规则,或者说是不是有相同的特征描述。
正则表达式的开始符:^,结尾符$,这两个符号间的是匹配的元素。如检查一个电话号码是不是打往北京的号,用正则表达式表示就是“^010$”。只要前3位区号是010,就是北京的号,后面的电话号码就不用管了。然后,用正则表达式匹配函数ereg来判断,例:
<?php
$pattern = “^010$”;
$phone = “01080718828″;
if(ereg($pattern, $phone))
echo “打往北京的号”;
else
echo “不是打往北京的号”;
?>
这 就是正则表达式。北京的电话都是8位数字的,那我要知道这个号码是不是正确了?假如他按了9位号呢?如果判断正误?这就要用到正则表达式的字符簇。那么上 例的正则表达式就要这样写:^010[0-9]{8}$,就能同时判断号码是不是符合规则。正则表达式有很多的应用,像LBB、VBB论坛在发贴时的所谓 VBB代码LBB代码的解析,都是用正则表达式完成的。

3、模板
知道了正则表达式的功能,那么就可以知道模板了。什么是模板?举个例子吧?一般写网页用到了后台程序的时候,都是在网页里面插入程序代码。如PHP。这就是HTML和PHP的混写。这样的优点是读取速度快,缺点是如果大家分工合作做网站,那么非程序员就不会改网了。
而 用模板,则可以达到分工的最合理化。美工只做页面,程序只写后台,然后再合起来。优秀的Jsp提供了自定义标签的功能很好地完成了模板功能。而主流的 PHP如何做到呢?就是利用正则表达式来做到的。可以去网上下载一个PHPLIB,里面的PHP目录下有一个template.inc的源代码文件,那就 是用PHP实现模板套用的类。

由于篇幅有限,这里只是简单地说一说这些内容,如果真的想学的话,还请看专门的教材。如光要讲清楚正则表达式就可以写上一本小书。

PHP业界, php

2009/10/19

PHP5在Apache下的两种模式的安装

Tags: ,

我也在第一时间用上了PHP5,下面简要介绍一下我的安装过程(只讲述apache服务器下的安装),与喜爱PHP的朋友分享。

其实,PHP5的安装过程也没有什么新意,与PHP4差不多。

一、CGI模式

1、解压PHP-5.0.0-Win32.zip到x:\PHP,重命名PHP.ini-dist为PHP.ini,copy至x:\winnt(x:\windows)或apache的安装文件夹。copy x:\PHP\PHP5ts.dll至winnt(windows)、或winnt\system32或apache的安装文件夹。

2、修改Apache的httpd.conf文件。加上以下几行:
ScriptAlias /PHP/ “x:/PHP/”
AddType application/x-httpd-PHP.PHP
Action application/x-httpd-PHP”/PHP/PHP-CGI.exe”

3、修改PHP.ini。设置CGI.force_redirect = 0
二、模块方式

1、与上1同。

2、以上2中改为:
LoadModulePHP5_modulePHP5apache.dll
AddModule mod_PHP5.c
AddType application/x-httpd-PHP.PHP

不要上面的步骤3

注意:如果是Apache2,不需要在http.conf中加上面的AddModule mod_PHP5.c亦可。
三、模块扩展

完成以上过程,基本上就安装完成了,不过如果你还要使用它的扩展功能,就得再配置一下。例如使用mysql。

1、设置PHP.ini。一般要设置“include_path = ”和“extension_dir =”,尤其是后者,路径自定,一般至少要包含x:\PHP和x:\PHP\ext。设置“extension=”一般去掉前面的;号即可。

2、copy相应的dll文件到winnt(windows)、或winnt\system32或apache的安装文件夹。

以加载mysql为例讲解一下:修改PHP.ini,配置extension_dir = “x:\PHP\ext”,去掉extension=PHP_mysql.dll前面“;”,copy x:\PHP\libmysql.dll至winnt(windows)、或winnt\system32或apache的安装文件夹。

注意,配置好后或任意时刻修改后要重启web服务器方可生效。PHP4程序都能运行。以上路径中有x代表分区,请自行替换。

本人是在win2k、apache1.3.31下安装的。

PHP业界, php, 网站建设

2009/10/16

康盛创想核心产品Discuz! 7.1正式开源发布

Tags: , , , ,

10月16日上午,中国领先的社区平台与服务提供商康盛创想(Comsenz)核心产品Discuz! 7.1版本正式开源发布。该产品在创新性的引入社交化互动元素的同时,进一步改进了社区论坛系统的插件开发机制,降低了网络社区应用与二次开发的门槛。

Discuz! 7.1版本创新性引入了更多社交网络(SNS)互动元素,提醒系统、新编辑器、新手任务、社区热点、主题关注等功能的推出,成为主流网络社区创新应用的新趋势。在经典的Discuz! 7.0版本基础之上,进一步完善了社区论坛系统的功能。

PHP业界

2009/10/15

在MySQL 中,ORDER BY的两种排序实现方式

Tags: ,

总的来说,在 MySQL 中的ORDER BY有两种排序实现方式,一种是利用有序索引获取有序数据,另一种则是通过相应的排序算法,将取得的数据在内存中进行排序。

下面将通过实例分析两种排序实现方式及实现图解:

假设有TableA 和 B 两个表结构分别如下:

1   sky@localhost : example 01:48:21> show create table A\G
2
3   *************************** 1. row ***************************
4
5   Table: A
6
7   Create Table: CREATE TABLE `A` (
8
9   `c1` int(11) NOT NULL default ’0′,
10
11   `c2` char(2) default NULL,
12
13   `c3` varchar(16) default NULL,
14
15   `c4` datetime default NULL,
16
17   PRIMARY KEY (`c1`)
18
19   ) ENGINE=MyISAM DEFAULT CHARSET=utf8
20
21   sky@localhost : example 01:48:32> show create table B\G
22
23   *************************** 1. row ***************************
24
25   Table: B
26
27   Create Table: CREATE TABLE `B` (
28
29   `c1` int(11) NOT NULL default ’0′,
30
31   `c2` char(2) default NULL,
32
33   `c3` varchar(16) default NULL,
34
35   PRIMARY KEY (`c1`),
36
37   KEY `B_c2_ind` (`c2`)
38
39   ) ENGINE=MyISAM DEFAULT CHARSET=utf8

1、利用有序索引进行排序,实际上就是当我们 Query 的 ORDER BY 条件和 Query 的执行计划中所利用的 Index 的索引键(或前面几个索引键)完全一致,且索引访问方式为 rang、 ref 或者 index 的时候,MySQL 可以利用索引顺序而直接取得已经排好序的数据。这种方式的 ORDER BY 基本上可以说是最优的排序方式了,因为 MySQL 不需要进行实际的排序操作。

假设我们在TableA 和 B 上执行如下SQL

1   sky@localhost : example 01:44:28> EXPLAIN SELECT A.* FROM A,B
2
3   -> WHERE A.c1 > 2 AND A.c2 < 5 AND A.c2 = B.c2 ORDER BY A.c1\G
4
5   *************************** 1. row ***************************
6
7   id: 1
8
9   select_type: SIMPLE
10
11   table: A
12
13   type: range
14
15   possible_keys: PRIMARY
16
17   key: PRIMARY
18
19   key_len: 4
20
21   ref: NULL
22
23   rows: 3
24
25   Extra: Using where
26
27   *************************** 2. row ***************************
28
29   id: 1
30
31   select_type: SIMPLE
32
33   table: B
34
35   type: ref
36
37   possible_keys: B_c2_ind
38
39   key: B_c2_ind
40
41   key_len: 7
42
43   ref: example.A.c2
44
45   rows: 2
46
47   Extra: Using where; Using index

我们通过执行计划可以看出,MySQL实际上并没有进行实际的排序操作,实际上其整个执行过程如下图所示:

2、通过相应的排序算法,将取得的数据在内存中进行排序方式,MySQL 比需要将数据在内存中进行排序,所使用的内存区域也就是我们通过 sort_buffer_size 系统变量所设置的排序区。这个排序区是每个Thread独享的,所以说可能在同一时刻在 MySQL 中可能存在多个 sort buffer 内存区域。

第二种方式在 MySQL Query Optimizer 所给出的执行计划(通过 EXPLAIN 命令查看)中被称为 filesort。在这种方式中,主要是由于没有可以利用的有序索引取得有序的数据,MySQL只能通过将取得的数据在内存中进行排序然后再将数据返回给 客户端。在 MySQL 中 filesort 的实现算法实际上是有两种的,一种是首先根据相应的条件取出相应的排序字段和可以直接定位行数据的行指针信息,然后在 sort buffer 中进行排序。另外一种是一次性取出满足条件行的所有字段,然后在 sort buffer 中进行排序。

在 MySQL4.1 版本之前只有第一种排序算法,第二种算法是从 MySQL4.1开始的改进算法,主要目的是为了减少第一次算法中需要两次访问表数据的 IO 操作,将两次变成了一次,但相应也会耗用更多的 sort buffer 空间。当然,MySQL4.1开始的以后所有版本同时也支持第一种算法,MySQL 主要通过比较我们所设定的系统参数 max_length_for_sort_data 的大小和 Query 语句所取出的字段类型大小总和来判定需要使用哪一种排序算法。如果 max_length_for_sort_data 更大,则使用第二种优化后的算法,反之使用第一种算法。所以如果希望 ORDER BY 操作的效率尽可能的高,一定要主义 max_length_for_sort_data 参数的设置。曾经就有同事的数据库出现大量的排序等待,造成系统负载很高,而且响应时间变得很长,最后查出正是因为 MySQL 使用了传统的第一种排序算法而导致,在加大了 max_length_for_sort_data 参数值之后,系统负载马上得到了大的缓解,响应也快了很多。

我们再看看 MySQL 需要使用 filesort 实现排序的实例。

假设我们改变一下我们的 Query,换成通过A.c2来排序,再看看情况:

1   sky@localhost : example 01:54:23> EXPLAIN SELECT A.* FROM A,B
2
3   -> WHERE A.c1 > 2 AND A.c2 < 5 AND A.c2 = B.c2 ORDER BY A.c2\G
4
5   *************************** 1. row ***************************
7   id: 1
8
9   select_type: SIMPLE
10
11   table: A
12
13   type: range
14
15   possible_keys: PRIMARY
16
17   key: PRIMARY
18
19   key_len: 4
20
21   ref: NULL
22
23   rows: 3
24
25   Extra: Using where; Using filesort
26
27   *************************** 2. row ***************************
28
29   id: 1
30
31   select_type: SIMPLE
32
33   table: B
34
35   type: ref
36
37   possible_keys: B_c2_ind
38
39   key: B_c2_ind
40
41   key_len: 7
42
43   ref: example.A.c2
44
45   rows: 2
46
47   Extra: Using where; Using index

MySQL 从TableA 中取出了符合条件的数据,由于取得的数据并不满足 ORDER BY 条件,所以 MySQL 进行了 filesort 操作,其整个执行过程如下图所示:

在 MySQL 中,filesort 操作还有一个比较奇怪的限制,那就是其数据源必须是来源于一个 Table,所以,如果我们的排序数据如果是两个(或者更多个) Table 通过 Join所得出的,那么 MySQL 必须通过先创建一个临时表(Temporary Table),然后再将此临时表的数据进行排序,如下例所示:

1   sky@localhost : example 02:46:15> explain select A.* from A,B
2
3   -> where A.c1 > 2 and A.c2 < 5 and A.c2 = B.c2 order by B.c3\G
4
5   *************************** 1. row ***************************
6
7   id: 1
8
9   select_type: SIMPLE
10
11   table: A
12
13   type: range
14
15   possible_keys: PRIMARY
16
17   key: PRIMARY
18
19   key_len: 4
20
21   ref: NULL
22
23   rows: 3
24
25   Extra: Using where; Using temporary; Using filesort
26
27   *************************** 2. row ***************************
28
29   id: 1
30
31   select_type: SIMPLE
32
33   table: B
34
35   type: ref
36
37   possible_keys: B_c2_ind
38
39   key: B_c2_ind
40
41   key_len: 7
42
43   ref: example.A.c2
44
45   rows: 2
46
47   Extra: Using where

这个执行计划的输出还是有点奇怪的,不知道为什么,MySQL Query Optimizer 将 “Using temporary” 过程显示在第一行对 Table A 的操作中,难道只是为让执行计划的输出少一行?

实际执行过程应该是如下图所示: