<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>LuoYe &#187; PHP</title>
	<atom:link href="http://www.luoye.org/blog/category/source/php/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.luoye.org/blog</link>
	<description>又一个 WordPress 博客</description>
	<lastBuildDate>Wed, 11 Jan 2012 05:51:01 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>PHP网站MVC架构模式中的种种误区</title>
		<link>http://www.luoye.org/blog/2011/06/php-mvc-mistakes/</link>
		<comments>http://www.luoye.org/blog/2011/06/php-mvc-mistakes/#comments</comments>
		<pubDate>Wed, 15 Jun 2011 14:36:42 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[mvc]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[php mvc]]></category>

		<guid isPermaLink="false">http://www.luoye.org/blog/?p=330</guid>
		<description><![CDATA[MVC架构模式已不再是新技术，也不再是新名词。但是，如果你能大概看一看因内的开源的PHP开发框架，或者国内的PHP开源软件。我们不难发现，很多这们的代码与其说是MVC，还不如称其为东施效颦。很多是为MVC而MVC。或者，只提供MVC的部分功能。而不是真正意义上的MVC。这其中，很多原因当然是软件开发者不懂得设计模式，不了解MVC的根本目的。     由此，我们先明确一下，MVC的根本目的有哪些：     1、分工：使用MVC可以把数据库开发，程序业务逻辑开发，页面开发分开。      多数人说起MVC的好处，仅限于这一点。认为，MVC不外乎是利于大型团队合作。其实是大错特错了。     2、松耦合。如果不懂得设计模式，根本不知松耦合是什么意思。当然，可以简单说明一下：      我们把模块部分，分为数据库抽象层，数据操作层，和业务逻辑层。这是最简单的业务架构。这样分开的好处是什么？      数据库抽象层，一般会支持多种数据库。这样做的目的，是可以让你的应用快速更换数据库。也能方便你的应用与其它类型数据库交互。      同时，更强大的，还会有链接管理器，从而对大型网站的分库操作，分表操作的支持。      一般，数据库抽象层可以通过向导生成静成的ORM层，或直接提供动态的ORM层（这是最新的DRYSQL模式）。      但除了ORM，CRUD，还有其它的查询。MVC中仍是要求将其写到专门的数据操作模块中的。      为什么要这样做呢？这就是松耦合。当一部分改动，不会影响另一部分。      试想，如果将数据模块与业务模块混合在一起，那么，如果某一日更换数据库，则，你要修改的是庞大的模块部分的代码。但将数据模块独立出来，只要修改数据模块部分的SQL语句即可以了。      对于视图部分，实际也是一样。因为，本来是给PC浏览器用的，如果哪一天要加上手机页面，则只要添加就可以了，其它的都可以共用，但若不分开，就得重新做一套。      从这一点看，有人说，PHP不适合于使用框架，实际上，不用框架，很多是行不通的。      可以看出其目标：这也就实现了，出现问题只要修改一处。而不是修改多处。     3、共享与集中处理。控制器，是一个完全将流程按面向对象方式设计的程序流程中的组件。我们应当能够记得，最普通的PHP程序写法，页头包含 SESSION模块，然后是访问控制。但若想，增加对主机名，子域名控制，则每一个包含的页面，都要再次增加包含。或要在SESSION模块，或访问控制模块增加一个包含文件。于是，程序逻辑变得相当混乱。如果其中有出错与跳转，那么，势必会出现在不需要加载的页面跳来跳去。     控制器的目的，就是让页面请求最终到达所需要的页面。并且是基于面向对象的流程的。     通常：控制器，必须要有Host， SubDomain， IP，URL，ACL的路由检测。由于现在一个网站，同时有浏览器与手机的，所以，还要有UserAgent检测。控制器要能做到最为方便地将一个请求映射到一个模块类的一个方法（事件）中。     4、完全面向对象，MVC程序，多数只有一个客户端请求入口——bootstrap，应用往往基于这个文件进行配置或修改。其它的全部都是class。即实现客户端到服务器端的事件映射。这样做的目的，是将应用的流程规范到了一个完全面向对象的流程中。保证程序的可读性，从而保证与程序员的无关性。     5、目前流行的开放API，如果是良好的MVC架构，开放API只要直接调用数据操作层接口就能实现，这也大大节省了程序的开发量，同时增加了代码的公用与集中处理的能力。这也就实现了，出现问题只要修改一处。     6、视图问题：因为界面的需求是多样的，不断变化的，往往对于WEB模式的企业应用更加显示出这样的变化。目前，可悲的是，PHP仍没有象.net,或 flex相似的视图模式。只有JAVA，有Typstray,JFS这样的面向部件的视图模式，PHP目前均没有成熟的开源产品可用。虽说，Smarty 抄袭了struts,phpFACES抄袭了JFS，但是本质上，均没有完全体充分利用PHP的语言的长处。phpFACES则更是无人问津，国内几乎无人使用。而FLAX RIA的冲击，以及JS框架带来的RIA新技术，也没有能与后端PHP相结合。JSP落后，PHP一样也是落后。人们需要新的开源。当然，phpFACES可以说是这方面的先驱，因为，它是基于DOJO创建的组件库。     7、插件技术：一个好的开发框架。所有的扩展应当均是由插件式方来完成的。但现在有多少框架支持插件？官方的Zend可以说是大全，而不是插件式配置，这纯属是技术误导。当然，最好的，插件最多的，则是symfony. 而symfony的ORM还在使用Propel，没能用上最新的DRYSQL技术。就插件而言，很多情况下限制了软件的应用，推广与发展，比如，大名鼎鼎的WordPress,提供了完美的应用插件，但底层开发框架极为混乱。最简单的，只能用于Mysql数据库，谁要是想用Oracle，那你的恶梦就开始了。所以，一个好的框架，应当在任何一个层面均支持插件。插件由此可以大概分为：数据库驱动插件，数据模块插件，缓存驱动插件，图型库插件等功能类插件，同时还有应用类插件。现时代，没有插件技术，就没有成功可言。也只有支持插件，才能够实现无限扩展，通用性才不是空话。但是，从国内行业论坛上来看，没有专门讨论插件接口实现技术的相关的话题，高处不胜寒！！     8、开发框架的架构：一个WEB应用架构，其内核应当是一个好的开发框架，这一个框架，必须要有的核心是：App对象，一个给入口文件用来完成一切事务的聚合类，AutoLoader 装载器，uxConfig 配置文件读取，uxLocale 本地化管理，Model 模型，View 视图，Controller 控制器（主机，子域名，URI，UA，IP，ACL均需要支持），Exception ErrorHandle错误与异常管理，Security 安全管理（Validator 数据验证，Filter 数据过滤器）状态管理（Session 会话管理，Cache 缓存管理）。然后是应用必须的基本类库，其中，数据库排第一位。架构中所以把数据库放到类库而不是放到内核，主要是两个方面，其一，让用户有选择权，用户可以选择用框架本身的，也可以去选ADODB，DOCTRINE，PEOPEL等第三方的。其次，网站规模的变化，数据库层面变化是最快的。但现在有多少开发框架有这样的规范的架构？     由此，我们发现：MVC架构模式中的种种误区不外乎来源于两个方面：     其一是：人们的认识造成的。PHP开发队伍技术落后，素质差是一大本质原因。对软件架构的不了解，特别是面向对象，设计模式的不了解，从而无法深入理解MVC。 [...]]]></description>
			<content:encoded><![CDATA[<p>MVC架构模式已不再是新技术，也不再是新名词。但是，如果你能大概看一看因内的开源的PHP开发框架，或者国内的PHP开源软件。我们不难发现，很多这们的代码与其说是MVC，还不如称其为东施效颦。很多是为MVC而MVC。或者，只提供MVC的部分功能。而不是真正意义上的MVC。这其中，很多原因当然是软件开发者不懂得设计模式，不了解MVC的根本目的。<span id="more-330"></span><br />
    由此，我们先明确一下，MVC的根本目的有哪些：<br />
    1、分工：使用MVC可以把数据库开发，程序业务逻辑开发，页面开发分开。<br />
     多数人说起MVC的好处，仅限于这一点。认为，MVC不外乎是利于大型团队合作。其实是大错特错了。<br />
    2、松耦合。如果不懂得设计模式，根本不知松耦合是什么意思。当然，可以简单说明一下：<br />
     我们把模块部分，分为数据库抽象层，数据操作层，和业务逻辑层。这是最简单的业务架构。这样分开的好处是什么？<br />
     数据库抽象层，一般会支持多种数据库。这样做的目的，是可以让你的应用快速更换数据库。也能方便你的应用与其它类型数据库交互。<br />
     同时，更强大的，还会有链接管理器，从而对大型网站的分库操作，分表操作的支持。<br />
     一般，数据库抽象层可以通过向导生成静成的ORM层，或直接提供动态的ORM层（这是最新的DRYSQL模式）。<br />
     但除了ORM，CRUD，还有其它的查询。MVC中仍是要求将其写到专门的数据操作模块中的。<br />
     为什么要这样做呢？这就是松耦合。当一部分改动，不会影响另一部分。<br />
     试想，如果将数据模块与业务模块混合在一起，那么，如果某一日更换数据库，则，你要修改的是庞大的模块部分的代码。但将数据模块独立出来，只要修改数据模块部分的SQL语句即可以了。<br />
     对于视图部分，实际也是一样。因为，本来是给PC浏览器用的，如果哪一天要加上手机页面，则只要添加就可以了，其它的都可以共用，但若不分开，就得重新做一套。<br />
     从这一点看，有人说，PHP不适合于使用框架，实际上，不用框架，很多是行不通的。<br />
     可以看出其目标：这也就实现了，出现问题只要修改一处。而不是修改多处。<br />
    3、共享与集中处理。控制器，是一个完全将流程按面向对象方式设计的程序流程中的组件。我们应当能够记得，最普通的PHP程序写法，页头包含 SESSION模块，然后是访问控制。但若想，增加对主机名，子域名控制，则每一个包含的页面，都要再次增加包含。或要在SESSION模块，或访问控制模块增加一个包含文件。于是，程序逻辑变得相当混乱。如果其中有出错与跳转，那么，势必会出现在不需要加载的页面跳来跳去。<br />
    控制器的目的，就是让页面请求最终到达所需要的页面。并且是基于面向对象的流程的。<br />
    通常：控制器，必须要有Host， SubDomain， IP，URL，ACL的路由检测。由于现在一个网站，同时有浏览器与手机的，所以，还要有UserAgent检测。控制器要能做到最为方便地将一个请求映射到一个模块类的一个方法（事件）中。<br />
    4、完全面向对象，MVC程序，多数只有一个客户端请求入口——bootstrap，应用往往基于这个文件进行配置或修改。其它的全部都是class。即实现客户端到服务器端的事件映射。这样做的目的，是将应用的流程规范到了一个完全面向对象的流程中。保证程序的可读性，从而保证与程序员的无关性。<br />
    5、目前流行的开放API，如果是良好的MVC架构，开放API只要直接调用数据操作层接口就能实现，这也大大节省了程序的开发量，同时增加了代码的公用与集中处理的能力。这也就实现了，出现问题只要修改一处。<br />
    6、视图问题：因为界面的需求是多样的，不断变化的，往往对于WEB模式的企业应用更加显示出这样的变化。目前，可悲的是，PHP仍没有象.net,或 flex相似的视图模式。只有JAVA，有Typstray,JFS这样的面向部件的视图模式，PHP目前均没有成熟的开源产品可用。虽说，Smarty 抄袭了struts,phpFACES抄袭了JFS，但是本质上，均没有完全体充分利用PHP的语言的长处。phpFACES则更是无人问津，国内几乎无人使用。而FLAX RIA的冲击，以及JS框架带来的RIA新技术，也没有能与后端PHP相结合。JSP落后，PHP一样也是落后。人们需要新的开源。当然，phpFACES可以说是这方面的先驱，因为，它是基于DOJO创建的组件库。<br />
    7、插件技术：一个好的开发框架。所有的扩展应当均是由插件式方来完成的。但现在有多少框架支持插件？官方的Zend可以说是大全，而不是插件式配置，这纯属是技术误导。当然，最好的，插件最多的，则是symfony. 而symfony的ORM还在使用Propel，没能用上最新的DRYSQL技术。就插件而言，很多情况下限制了软件的应用，推广与发展，比如，大名鼎鼎的WordPress,提供了完美的应用插件，但底层开发框架极为混乱。最简单的，只能用于Mysql数据库，谁要是想用Oracle，那你的恶梦就开始了。所以，一个好的框架，应当在任何一个层面均支持插件。插件由此可以大概分为：数据库驱动插件，数据模块插件，缓存驱动插件，图型库插件等功能类插件，同时还有应用类插件。现时代，没有插件技术，就没有成功可言。也只有支持插件，才能够实现无限扩展，通用性才不是空话。但是，从国内行业论坛上来看，没有专门讨论插件接口实现技术的相关的话题，高处不胜寒！！<br />
    8、开发框架的架构：一个WEB应用架构，其内核应当是一个好的开发框架，这一个框架，必须要有的核心是：App对象，一个给入口文件用来完成一切事务的聚合类，AutoLoader 装载器，uxConfig 配置文件读取，uxLocale 本地化管理，Model 模型，View 视图，Controller 控制器（主机，子域名，URI，UA，IP，ACL均需要支持），Exception ErrorHandle错误与异常管理，Security 安全管理（Validator 数据验证，Filter 数据过滤器）状态管理（Session 会话管理，Cache 缓存管理）。然后是应用必须的基本类库，其中，数据库排第一位。架构中所以把数据库放到类库而不是放到内核，主要是两个方面，其一，让用户有选择权，用户可以选择用框架本身的，也可以去选ADODB，DOCTRINE，PEOPEL等第三方的。其次，网站规模的变化，数据库层面变化是最快的。但现在有多少开发框架有这样的规范的架构？<br />
    由此，我们发现：MVC架构模式中的种种误区不外乎来源于两个方面：<br />
    其一是：人们的认识造成的。PHP开发队伍技术落后，素质差是一大本质原因。对软件架构的不了解，特别是面向对象，设计模式的不了解，从而无法深入理解MVC。<br />
    这与PHP自身发展也有关系，PHP4以前，是不支持面向对象的。PHP是以简易吸引了大量用户。但一旦用于大型网站开发，对于这此嫌JSP烦锁的人，恶梦就开始了。<br />
    其二是：PHP开发框架发以及开源技术发展密切相关的，开发框架对MVC不能提供足够好的MVC架构支持，同时，没有足够好的开源组件，使得人们不能进一步理解MVC。如同，你用了PHP的ADODB，但它也不会要求你在程序中，要把数据模块与业务模块分开。这是架构师的责任。然而，中国PHP行业有多少网络应用架构师？比如，敏捷之履上海活动时，杭州某大公司的某外籍CTO大讲特讲PHP根本不需要框架，云云，这不能不反映出国内PHP行业技术的落后。现实是如此残酷。唯有正视软件产业的现状。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.luoye.org/blog/2011/06/php-mvc-mistakes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP压缩解压缩类：PclZip</title>
		<link>http://www.luoye.org/blog/2011/01/pclzip/</link>
		<comments>http://www.luoye.org/blog/2011/01/pclzip/#comments</comments>
		<pubDate>Fri, 21 Jan 2011 08:11:52 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.luoye.org/blog/?p=281</guid>
		<description><![CDATA[PclZip是一个强大的压缩与解压缩zip文件的PHP类，PclZip library不仅能够压缩与解压缩Zip格式的文件；还能出压缩档的内容。同时也可以对现有的ZIP包进行添加或删除文件。 官方网站：http://www.phpconcept.net/pclzip/index.php 以下为一个简单的压缩全站进行备份的代码： &#60;?php require_once('pclzip.lib.php'); $zip = new PclZip(&#34;archive.zip&#34;); $v_list = $zip-&#62;create($_SERVER['DOCUMENT_ROOT'] ,PCLZIP_OPT_REMOVE_PATH,$_SERVER['DOCUMENT_ROOT']); if($v_list == 0){ echo '异常：'.$z-&#62;errorInfo(true); } else { echo '备份成功'; } ?&#62; 其他使用方法： &#60;?php //解压缩到extract/folder/这个目录中 $list = $archive-&#62;extract(PCLZIP_OPT_PATH, &#34;extract/folder/&#34;); //增加这个目录在压缩档中，完成以后压缩档里面会有backup这个目录，backup里面会有这两个档案 $list = $archive-&#62;create(&#34;file.txt,image.gif&#34;,PCLZIP_OPT_ADD_PATH, &#34;backup&#34;); //去掉部份的路径，这里完成后会变成test/file.txt $list = $archive-&#62;add(&#34;/usr/local/user/test/file.txt&#34;,PCLZIP_OPT_REMOVE_PATH, &#34;/usr/local/user&#34;); //把所有路径都去掉，这个压缩档建立完后，里面就只会有file.txt跟image.gif，不会有目录了 $list = $archive-&#62;create(&#34;data/file.txt images/image.gif&#34;,PCLZIP_OPT_REMOVE_ALL_PATH); //把解压缩出来的档案的CHMOD设成0777 $list = $archive-&#62;extract(PCLZIP_OPT_SET_CHMOD, 0777); //解压缩部份的档案，这个参数是使用档案名称判别 //引数可以用下面这样的阵列 [...]]]></description>
			<content:encoded><![CDATA[<p>PclZip是一个强大的压缩与解压缩zip文件的PHP类，PclZip library不仅能够压缩与解压缩Zip格式的文件；还能出压缩档的内容。同时也可以对现有的ZIP包进行添加或删除文件。 官方网站：http://www.phpconcept.net/pclzip/index.php 以下为一个简单的压缩全站进行备份的代码：<span id="more-281"></span></p>
<pre class="brush: php; title: ;">
&lt;?php
require_once('pclzip.lib.php');
$zip = new PclZip(&quot;archive.zip&quot;);
$v_list = $zip-&gt;create($_SERVER['DOCUMENT_ROOT'] ,PCLZIP_OPT_REMOVE_PATH,$_SERVER['DOCUMENT_ROOT']);
if($v_list == 0){ echo '异常：'.$z-&gt;errorInfo(true); }
else { echo '备份成功'; }
?&gt;
</pre>
<p>其他使用方法：</p>
<pre class="brush: php; title: ;">
&lt;?php
//解压缩到extract/folder/这个目录中
$list = $archive-&gt;extract(PCLZIP_OPT_PATH, &quot;extract/folder/&quot;);

//增加这个目录在压缩档中，完成以后压缩档里面会有backup这个目录，backup里面会有这两个档案
$list = $archive-&gt;create(&quot;file.txt,image.gif&quot;,PCLZIP_OPT_ADD_PATH, &quot;backup&quot;);

//去掉部份的路径，这里完成后会变成test/file.txt
$list = $archive-&gt;add(&quot;/usr/local/user/test/file.txt&quot;,PCLZIP_OPT_REMOVE_PATH, &quot;/usr/local/user&quot;);

//把所有路径都去掉，这个压缩档建立完后，里面就只会有file.txt跟image.gif，不会有目录了
$list = $archive-&gt;create(&quot;data/file.txt images/image.gif&quot;,PCLZIP_OPT_REMOVE_ALL_PATH);

//把解压缩出来的档案的CHMOD设成0777
$list = $archive-&gt;extract(PCLZIP_OPT_SET_CHMOD, 0777);

//解压缩部份的档案，这个参数是使用档案名称判别
//引数可以用下面这样的阵列
$rule_list[0] = 'test/aaa.txt';
$rule_list[1] = 'test/ddd.txt';
//或是下面这样，一个字串中，用逗号分隔每个要解压缩的档案
$rule_list = &quot;test/aaa.txt,test/ddd.txt&quot;;
$list = $archive-&gt;extract(PCLZIP_OPT_BY_NAME,$rule_list);

//解压缩部份的档案，使用php的ereg()函式，档案名称有比对成功的都会被解压缩
$list = $archive-&gt;extract(PCLZIP_OPT_BY_EREG, &quot;aa&quot;);

//解压缩部份的档案，使用php的preg_match()函式，档案名称有比对成功的都会被解压缩
$list = $archive-&gt;extract(PCLZIP_OPT_BY_PREG, &quot;/^bb/&quot;);
//上面这两个函式如果不懂的话，请先研究正规表示法(Regular Expression)

//依照阵列中元素的索引解压缩，可是我不太懂index啥 = =a
$list = $archive-&gt;extract(PCLZIP_OPT_BY_INDEX, array('0-1','6-7'));

//将一个档案内容解压缩成一个字串
$list = $archive-&gt;extract(PCLZIP_OPT_BY_NAME, &quot;data/readme.txt&quot;,PCLZIP_OPT_EXTRACT_AS_STRING);

//将一个档案内容解压缩完后直接输出(echo)
$list = $archive-&gt;extract(PCLZIP_OPT_BY_NAME, &quot;data/readme.txt&quot;,PCLZIP_OPT_EXTRACT_IN_OUTPUT);

//将一个档案加入一个压缩档中，但不会对此档案压缩
$list = $archive-&gt;add(&quot;data/file.txt&quot;, PCLZIP_OPT_NO_COMPRESSION);

//对此压缩档增加一个注解，如果原本就有注解的话会被覆盖掉
$list = $archive-&gt;create(&quot;data&quot;, PCLZIP_OPT_COMMENT, &quot;Add a comment&quot;);

//对此压缩档增加一个注解，如果原本就有注解的话会接在后面
$list = $archive-&gt;add(&quot;data&quot;, PCLZIP_OPT_ADD_COMMENT, &quot;Add a comment after the existing one&quot;);

//对此压缩档增加一个注解，如果原本就有注解的话会放在原本的注解前面
$list = $archive-&gt;add(&quot;data&quot;, PCLZIP_OPT_PREPEND_COMMENT, &quot;Add a comment before the existing one&quot;);
?&gt;
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.luoye.org/blog/2011/01/pclzip/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MYSQL时间函数</title>
		<link>http://www.luoye.org/blog/2010/12/mysqltime/</link>
		<comments>http://www.luoye.org/blog/2010/12/mysqltime/#comments</comments>
		<pubDate>Wed, 22 Dec 2010 07:06:07 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[mysql时间函数]]></category>

		<guid isPermaLink="false">http://www.luoye.org/blog/?p=246</guid>
		<description><![CDATA[当前时间NOW() SYSDATE() CURRENT_DATE 以&#8217;YYYY-MM-DD&#8217;或YYYYMMDD格式返回今天日期值，取决于函数是在一个字符串还是数字上下文被使用。 mysql&#62; select CURDATE();　-&#62; &#8217;1997-12-15&#8242; mysql&#62; select CURDATE() + 0; -&#62; 19971215 CURRENT_TIME 以&#8217;HH:MM:SS&#8217;或HHMMSS格式返回当前时间值，取决于函数是在一个字符串还是在数字的上下文被使用。 mysql&#62; select CURTIME(); -&#62; &#8217;23:50:26&#8242; mysql&#62; select CURTIME() + 0; -&#62; 235026 CURRENT_TIMESTAMP 以&#8217;YYYY-MM-DD HH:MM:SS&#8217;或YYYYMMDDHHMMSS格式返回当前的日期和时间，取决于函数是在一个字符串还是在数字的上下文被使用。 mysql&#62; select NOW();-&#62; &#8217;1997-12-15 23:50:26&#8242; mysql&#62; select NOW() + 0; -&#62; 19971215235026 时间格式DATE_FORMAT(date,format) 根据format字符串格式化date值。 TIME_FORMAT(time,format) 根据format字符串格式化time值。format字符串只能包含处理小时、分钟和秒的那些格式修饰符。其他修饰符产生一个NULL值或0。 　 mysql&#62; select DATE_FORMAT(&#8217;1997-10-04 22:23:00&#8242;, &#8216;%W %M [...]]]></description>
			<content:encoded><![CDATA[<p>当前时间NOW()</p>
<p>SYSDATE()</p>
<p>CURRENT_DATE 以&#8217;YYYY-MM-DD&#8217;或YYYYMMDD格式返回今天日期值，取决于函数是在一个字符串还是数字上下文被使用。</p>
<p>mysql&gt; select CURDATE();　-&gt; &#8217;1997-12-15&#8242;</p>
<p>mysql&gt; select CURDATE() + 0; -&gt; 19971215</p>
<p>CURRENT_TIME 以&#8217;HH:MM:SS&#8217;或HHMMSS格式返回当前时间值，取决于函数是在一个字符串还是在数字的上下文被使用。 <span id="more-246"></span></p>
<p>mysql&gt; select CURTIME(); -&gt; &#8217;23:50:26&#8242;</p>
<p>mysql&gt; select CURTIME() + 0; -&gt; 235026</p>
<p>CURRENT_TIMESTAMP 以&#8217;YYYY-MM-DD HH:MM:SS&#8217;或YYYYMMDDHHMMSS格式返回当前的日期和时间，取决于函数是在一个字符串还是在数字的上下文被使用。</p>
<p>mysql&gt; select NOW();-&gt; &#8217;1997-12-15 23:50:26&#8242;</p>
<p>mysql&gt; select NOW() + 0; -&gt; 19971215235026</p>
<p>时间格式DATE_FORMAT(date,format) 根据format字符串格式化date值。</p>
<p>TIME_FORMAT(time,format) 根据format字符串格式化time值。format字符串只能包含处理小时、分钟和秒的那些格式修饰符。其他修饰符产生一个NULL值或0。</p>
<p>　 mysql&gt; select DATE_FORMAT(&#8217;1997-10-04 22:23:00&#8242;, &#8216;%W %M %Y&#8217;);</p>
<p>-&gt; &#8216;Saturday October 1997&#8242;</p>
<p>mysql&gt; select DATE_FORMAT(&#8217;1997-10-04 22:23:00&#8242;, &#8216;%H:%i:%s&#8217;);</p>
<p>-&gt; &#8217;22:23:00&#8242;</p>
<p>mysql&gt; select DATE_FORMAT(&#8217;1997-10-04 22:23:00&#8242;, &#8216;%D %y %a %d %m %b %j&#8217;);</p>
<p>-&gt; &#8217;4th 97 Sat 04 10 Oct 277&#8242;</p>
<p>mysql&gt; select DATE_FORMAT(&#8217;1997-10-04 22:23:00&#8242;, &#8216;%H %k %I %r %T %S %w&#8217;);</p>
<p>-&gt; &#8217;22 22 10 10:23:00 PM 22:23:00 00 6&#8242;</p>
<p>下列修饰符可以被用在format字符串中，所有的其他字符不做解释被复制到结果中。</p>
<p>　　%M 月名字(January……December)</p>
<p>　　%W 星期名字(Sunday……Saturday)</p>
<p>　　%D 有英语前缀的月份的日期(1st, 2nd, 3rd, 等等。）</p>
<p>　　%Y 年, 数字, 4 位</p>
<p>　　%y 年, 数字, 2 位</p>
<p>　　%a 缩写的星期名字(Sun……Sat)</p>
<p>　　%d 月份中的天数, 数字(00……31)</p>
<p>　　%e 月份中的天数, 数字(0……31)</p>
<p>　　%m 月, 数字(01……12)</p>
<p>　　%c 月, 数字(1……12)</p>
<p>　　%b 缩写的月份名字(Jan……Dec)</p>
<p>　　%j 一年中的天数(001……366)</p>
<p>　　%H 小时(00……23)</p>
<p>　　%k 小时(0……23)</p>
<p>　　%h 小时(01……12)</p>
<p>　　%I 小时(01……12)</p>
<p>　　%l 小时(1……12)</p>
<p>　　%i 分钟, 数字(00……59)</p>
<p>　　%r 时间,12 小时(hh:mm:ss [AP]M)</p>
<p>　　%T 时间,24 小时(hh:mm:ss)</p>
<p>　　%S 秒(00……59)</p>
<p>　　%s 秒(00……59)</p>
<p>　　%p AM或PM</p>
<p>　　%w 一个星期中的天数(0=Sunday ……6=Saturday ）</p>
<p>　　%U 星期(0……52), 这里星期天是星期的第一天</p>
<p>　　%u 星期(0……52), 这里星期一是星期的第一天</p>
<p>　　%% 一个文字&#8221;%&#8221;。</p>
<p>DAYTO_DAYS(date) 给出一个日期date，返回一个天数(从0年的天数)。</p>
<p>mysql&gt; select TO_DAYS(&#8217;1997-10-07&#8242;); -&gt; 729669</p>
<p>FROM_DAYS(N) 给出一个天数N，返回一个DATE值。</p>
<p>mysql&gt; select FROM_DAYS(729669); -&gt; &#8217;1997-10-07&#8242;</p>
<p>DAYOFWEEK(date) 返回日期date的星期索引(1=星期天，2=星期一, ……7=星期六)。这些索引值对应于ODBC标准。</p>
<p>WEEKDAY(date) 返回date的星期索引(0=星期一，1=星期二, ……6= 星期天)。</p>
<p>DAYOFMONTH(date) 返回date的月份中日期，在1到31范围内。</p>
<p>DAYOFYEAR(date) 返回date在一年中的日数, 在1到366范围内。</p>
<p>MONTH(date) 返回date的月份，范围1到12。</p>
<p>DAYNAME(date) 返回date的星期名字。</p>
<p>MONTHNAME(date) 返回date的月份名字。</p>
<p>QUARTER(date) 返回date一年中的季度，范围1到4。</p>
<p>WEEK(date),WEEK(date,first) 对于星期天是一周的第一天的地方，有一个单个参数，返回date的周数，范围在0到52。2个参数形式WEEK()允许你指定星期是否开始于星期天或星期一。如果第二个参数是0，星期从星期天开始，如果第二个参数是1，从星期一开始。</p>
<p>YEAR(date) 返回date的年份，范围在1000到9999。</p>
<p>HOUR(time) 返回time的小时，范围是0到23。</p>
<p>MINUTE(time) 返回time的分钟，范围是0到59。</p>
<p>SECOND(time) 回来time的秒数，范围是0到59。</p>
<p>SECONDSEC_TO_TIME(seconds) 返回seconds参数，变换成小时、分钟和秒，值以&#8217;HH:MM:SS&#8217;或HHMMSS格式化，取决于函数是在一个字符串还是在数字上下文中被使用。</p>
<p>mysql&gt; select SEC_TO_TIME(2378);-&gt; &#8217;00:39:38&#8242;</p>
<p>mysql&gt; select SEC_TO_TIME(2378) + 0;-&gt; 3938</p>
<p>TIME_TO_SEC(time) 返回time参数，转换成秒。</p>
<p>mysql&gt; select TIME_TO_SEC(&#8217;22:23:00&#8242;);-&gt; 80580</p>
<p>TIMESTAMP　 UNIX_TIMESTAMP(date) 如果没有参数调用，返回一个Unix时间戳记(从&#8217;1970-01-01 00:00:00&#8242;GMT开始的秒数)。如果UNIX_TIMESTAMP()用一个date参数被调用，它返回从&#8217;1970-01-01 00:00:00&#8242; GMT开始的秒数值。date可以是一个DATE字符串、一个DATETIME字符串、一个TIMESTAMP或以YYMMDD或YYYYMMDD格式的本地时间的一个数字。</p>
<p>mysql&gt; select UNIX_TIMESTAMP(&#8217;1997-10-04 22:23:00&#8242;); -&gt; 875996580</p>
<p>*当UNIX_TIMESTAMP被用于一个TIMESTAMP列，函数将直接接受值，没有隐含的&#8221;string-to-unix- timestamp&#8221;变换。 FROM_UNIXTIME(unix_timestamp) 以&#8217;YYYY-MM-DD HH:MM:SS&#8217;或YYYYMMDDHHMMSS格式返回unix_timestamp参数所表示的值，取决于函数是在一个字符串还是或数字上下文中被使用。</p>
<p>mysql&gt; select FROM_UNIXTIME(875996580); -&gt; &#8217;1997-10-04 22:23:00&#8242;</p>
<p>mysql&gt; select FROM_UNIXTIME(875996580) + 0; -&gt; 19971004222300</p>
<p>FROM_UNIXTIME(unix_timestamp,format) 返回表示 Unix 时间标记的一个字符串，根据format字符串格式化。format可以包含与DATE_FORMAT()函数列出的条目同样的修饰符。</p>
<p>mysql&gt; select FROM_UNIXTIME(UNIX_TIMESTAMP(),&#8217;%Y %D %M %h:%i:%s %x&#8217;);　</p>
<p>-&gt; &#8217;1997 23rd December 03:43:30 x&#8217;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.luoye.org/blog/2010/12/mysqltime/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHPCMS的PHP编码规范</title>
		<link>http://www.luoye.org/blog/2010/12/phpcms-php/</link>
		<comments>http://www.luoye.org/blog/2010/12/phpcms-php/#comments</comments>
		<pubDate>Thu, 16 Dec 2010 02:20:26 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[phpcms]]></category>
		<category><![CDATA[php编码规范]]></category>

		<guid isPermaLink="false">http://www.luoye.org/blog/?p=222</guid>
		<description><![CDATA[1. 引言 本规范由编程原则组成，融合并提炼了开发人员长时间积累下来的成熟经验，意在帮助形成良好一致的编程风格。以达到事半功倍的效果，如果有需要本文档会不定期更新。 2. 适用范围 如无特殊说明，以下规则要求完全适用于phpcms项目，同时也可大部分适用于公司其他PHP项目。 3. 标准化的重要性和好处 当一个软件项目尝试着遵守公共一致的标准时，可以使参与项目的开发人员更容易了解项目中的代码、弄清程序的状况。使新的参与者可以很快的适应环境，防止部 分参与者出于节省时间的需要，自创一套风格并养成终生的习惯，导致其它人在阅读时浪费过多的时间和精力。而且在一致的环境下，也可以减少编码出错的机会。 缺陷是由于每个人的标准不同，所以需要一段时间来适应和改变自己的编码风格，暂时性的降底了工作效率。从使项目长远健康的发展以及后期更高的团队工作效率 来考虑暂时的工作效率降低是值得的，也是必须要经过的一个过程。标准不是项目成功的关键，但可以帮助我们在团队协作中有更高的效率并且更加顺利的完成既定 的任务。  程序员可以了解任何代码，弄清程序的状况 新人可以很快的适应环境 防止新接触PHP的人出于节省时间的需要，自创一套风格并养成终生的习惯 防止新接触PHP的人一次次的犯同样的错误 在一致的环境下，人们可以减少犯错的机会 程序员们有了一致的敌人 4. PHP编码规范与原则 4.1.代码标记 PHP程序可以使用&#60;?php ?&#62;或&#60;? ?&#62;来界定PHP 代码，在HTML页面中嵌入纯变量时，可以使用&#60;?=$variablename?&#62;这样的形式。 近年来PHP开发组一直倡导代码规范化和标准化，未来版本PHP可能会开始不建议使用甚至取消&#60;? ?&#62;和&#60;?=$variablename?&#62;这种速记形式，因此为了加强程序兼容性，在发布之前我们将统一把&#60;?=标记替换为 &#60;?php echo 。 4.2.注释 注释是对于那些容易忘记作用的代码添加简短的介绍性内容。请使用 C 样式的注释“/* */”和标准 C++ 注释“//”。 程序开发中难免留下一些临时代码和调试代码，此类代码必须添加注释，以免日后遗忘。所有临时性、调试性、试验性的代码，必须添加统一的注释标记“//debug”并后跟完整的注释信息，这样可以方便在程序发布和最终调试前批量检查程序中是否还存在有疑问的代码。例如： 4.3.书写规则 4.3.1. 缩进 每个缩进的单位约定是一个TAB(8个空白字符宽度)，需每个参与项目的开发人员在编辑器(UltraEdit、EditPlus、Zend Studio等)中进行强制设定，以防在编写代码时遗忘而造成格式上的不规范。 本缩进规范适用于PHP、JavaScript中的函数、类、逻辑结构、循环等。 4.3.2. 大括号{}、if和switch 首括号与关键词同行，尾括号与关键字同列； if结构中，if和elseif与前后两个圆括号同行，左右各一个空格，所有大括号都单独另起一行。另外，即便if后只有一行语句，仍然需要加入大括号，以保证结构清晰； switch结构中，通常当一个case块处理后，将跳过之后的case块处理，因此大多数情况下需要添加break。break的位置视程序逻辑，与case同在一行，或新起一行均可，但同一switch体中，break的位置格式应当保持一致。 以下是符合上述规范的例子： 4.3.3. 运算符、小括号、空格、关键词和函数 每个运算符与两边参与运算的值或表达式中间要有一个空格，唯一的特例是字符连接运算符号两边不加空格； 左括号“(” [...]]]></description>
			<content:encoded><![CDATA[<p><strong>1. 引言</strong></p>
<p>本规范由编程原则组成，融合并提炼了开发人员长时间积累下来的成熟经验，意在帮助形成良好一致的编程风格。以达到事半功倍的效果，如果有需要本文档会不定期更新。</p>
<p><strong>2. 适用范围</strong></p>
<p>如无特殊说明，以下规则要求完全适用于phpcms项目，同时也可大部分适用于公司其他PHP项目。<span id="more-222"></span></p>
<p><strong>3. 标准化的重要性和好处</strong></p>
<p>当一个软件项目尝试着遵守公共一致的标准时，可以使参与项目的开发人员更容易了解项目中的代码、弄清程序的状况。使新的参与者可以很快的适应环境，防止部 分参与者出于节省时间的需要，自创一套风格并养成终生的习惯，导致其它人在阅读时浪费过多的时间和精力。而且在一致的环境下，也可以减少编码出错的机会。 缺陷是由于每个人的标准不同，所以需要一段时间来适应和改变自己的编码风格，暂时性的降底了工作效率。从使项目长远健康的发展以及后期更高的团队工作效率 来考虑暂时的工作效率降低是值得的，也是必须要经过的一个过程。标准不是项目成功的关键，但可以帮助我们在团队协作中有更高的效率并且更加顺利的完成既定 的任务。</p>
<ol>
<li> 程序员可以了解任何代码，弄清程序的状况</li>
<li>新人可以很快的适应环境</li>
<li>防止新接触PHP的人出于节省时间的需要，自创一套风格并养成终生的习惯</li>
<li>防止新接触PHP的人一次次的犯同样的错误</li>
<li>在一致的环境下，人们可以减少犯错的机会</li>
<li>程序员们有了一致的敌人</li>
</ol>
<p><strong>4. PHP编码规范与原则</strong></p>
<p>4.1.代码标记</p>
<p>PHP程序可以使用<em>&lt;?php ?&gt;</em>或<em>&lt;? ?&gt;</em>来界定PHP 代码，在HTML页面中嵌入纯变量时，可以使用<em>&lt;?=$variablename?&gt;</em>这样的形式。</p>
<p>近年来PHP开发组一直倡导代码规范化和标准化，未来版本PHP可能会开始不建议使用甚至取消<em>&lt;? ?&gt;</em>和<em>&lt;?=$variablename?&gt;</em>这种速记形式，因此为了加强程序兼容性，在发布之前我们将统一把<em>&lt;?=</em>标记替换为 <em>&lt;?php echo</em> 。</p>
<p><strong>4.2.注释</strong></p>
<p>注释是对于那些容易忘记作用的代码添加简短的介绍性内容。请使用 C 样式的注释“/* */”和标准 C++ 注释“//”。</p>
<p>程序开发中难免留下一些临时代码和调试代码，此类代码必须添加注释，以免日后遗忘。所有临时性、调试性、试验性的代码，必须添加统一的注释标记“//debug”并后跟完整的注释信息，这样可以方便在程序发布和最终调试前批量检查程序中是否还存在有疑问的代码。例如：</p>
<p><img class="alignnone size-full wp-image-2718" title="debug" src="http://www.luoye.org/blog/wp-content/uploads/2010/12/debug.png" alt="" width="446" height="86" /></p>
<p><strong>4.3.书写规则</strong></p>
<p>4.3.1. 缩进</p>
<p>每个缩进的单位约定是一个TAB(8个空白字符宽度)，需每个参与项目的开发人员在编辑器(UltraEdit、EditPlus、Zend Studio等)中进行强制设定，以防在编写代码时遗忘而造成格式上的不规范。</p>
<p>本缩进规范适用于PHP、JavaScript中的函数、类、逻辑结构、循环等。</p>
<p>4.3.2. 大括号{}、if和switch</p>
<p>首括号与关键词同行，尾括号与关键字同列；</p>
<p>if结构中，if和elseif与前后两个圆括号同行，左右各一个空格，所有大括号都单独另起一行。另外，即便if后只有一行语句，仍然需要加入大括号，以保证结构清晰；</p>
<p>switch结构中，通常当一个case块处理后，将跳过之后的case块处理，因此大多数情况下需要添加break。break的位置视程序逻辑，与case同在一行，或新起一行均可，但同一switch体中，break的位置格式应当保持一致。</p>
<p>以下是符合上述规范的例子：</p>
<p><img class="alignnone size-full wp-image-2719" title="switch" src="http://www.luoye.org/blog/wp-content/uploads/2010/12/switch.png" alt="" width="426" height="356" /></p>
<p>4.3.3. 运算符、小括号、空格、关键词和函数</p>
<p>每个运算符与两边参与运算的值或表达式中间要有一个空格，唯一的特例是字符连接运算符号两边不加空格；</p>
<p>左括号“(” 应和函数关键词紧贴在一起，除此以外应当使用空格将“(”同前面内容分开；</p>
<p>右括号“)”除后面是“)”或者“.”以外，其他一律用空格隔开它们；</p>
<p>除字符串中特意需要，一般情况下，在程序以及HTML中不出现两个连续的空格；</p>
<p>任何情况下，PHP程序中不能出现空白的带有TAB或空格的行，即：这类空白行应当不包含任何TAB或空格。同时，任何程序行尾也不能出现多余的TAB或空格。多数编辑器具有自动去除行尾空格的功能，如果习惯养成不好，可临时使用它，避免多余空格产生；</p>
<p>每段较大的程序体，上、下应当加入空白行，两个程序块之间只使用1个空行，禁止使用多行。</p>
<p>程序块划分尽量合理，过大或者过小的分割都会影响他人对代码的阅读和理解。一般可以以较大函数定义、逻辑结构、功能结构来进行划分。少于15行的程序块，可不加上下空白行；</p>
<p>说明或显示部分中，内容如含有中文、数字、英文单词混杂，应当在数字或者英文单词的前后加入空格。</p>
<p>根据上述原则，以下举例说明正确的书写格式：</p>
<p><img class="alignnone size-full wp-image-2720" title="br" src="http://www.luoye.org/blog/wp-content/uploads/2010/12/br.png" alt="" width="383" height="188" /></p>
<p>4.3.4. 函数定义</p>
<ul>
<li>参数的名字和变量的命名规范一致；</li>
<li>函数定义中的左小括号，与函数名紧挨，中间无需空格；</li>
<li>开始的左大括号另起一行；</li>
<li>具有默认值的参数应该位于参数列表的后面；</li>
<li>函数调用与定义的时候参数与参数之间加入一个空格；</li>
<li>必须仔细检查并切实杜绝函数起始缩进位置与结束缩进位置不同的现象。</li>
</ul>
<p>例如，符合标准的定义：</p>
<p><img class="alignnone size-full wp-image-2721" title="function" src="http://www.luoye.org/blog/wp-content/uploads/2010/12/function.png" alt="" width="392" height="135" /></p>
<p>不符合标准的定义：</p>
<p><img class="alignnone size-full wp-image-2722" title="function_wrong" src="http://www.luoye.org/blog/wp-content/uploads/2010/12/function_wrong.png" alt="" width="395" height="50" /></p>
<p>4.3.5. 引号</p>
<p>PHP中单引号和双引号具有不同的含义，最大的几项区别如下：</p>
<p>单引号中，任何变量($var)、特殊转义字符(如“\t \r \n”等)不会被解析，因此PHP的解析速度更快，转义字符仅仅支持“\’”和“\\”这样对单引号和反斜杠本身的转义；</p>
<p>双引号中，变量($var)值会代入字符串中，特殊转义字符也会被解析成特定的单个字符，还有一些专门针对上述两项特性的特殊功能性转义，例如“\$”和“{$array[‘key’]}。这样虽然程序编写更加方便，但同时PHP的解析也很慢；</p>
<p>数组中，如果下标不是整型，而是字符串类型，请务必用单引号将下标括起，正确的写法为$array[‘key’]，而不是$array[key]，因为不 正确的写法会使PHP解析器认为key是一个常量，进而先判断常量是否存在，不存在时才以“key”作为下标带入表达式中，同时出发错误事件，产生一条 Notice级错误。</p>
<p>因此，在绝大多数可以使用单引号的场合，禁止使用双引号。依据上述分析，可以或必须使用单引号的情况包括但不限于下述：</p>
<ul>
<li>字符串为固定值，不包含“\t”等特殊转义字符；</li>
<li>数组的固定下标，例如$array[‘key’]；</li>
<li>表达式中不需要带入变量，例如$string = ‘test’;，而非$string = “test$var”；</li>
</ul>
<p>例外的，在正则表达式(用于preg_系列函数和ereg系列函数)中，phpcms全部使用双引号，这是为了人工分析和编写的方便，并保持正则表达式的统一，减少不必要的分析混淆。</p>
<p>数据库SQL语句中，所有数据都不得加单引号，但是在进行sql查询之前都必须经过intval函数处理；所有字符串都必须加单引号，以避免可能的注入漏洞和SQL错误。正确的写法为：</p>
<p><img class="alignnone size-full wp-image-2723" title="sql" src="http://www.luoye.org/blog/wp-content/uploads/2010/12/sql.png" alt="" width="659" height="33" /></p>
<p>所有数据在插入数据库之前，均需要进行addslashes()处理，以免特殊字符未经转义在插入数据库的时候出现错误。phpcms中如果已经引 入了文件 common.inc.php，则所有通过 GET, POST, FILE,取得的变量默认情况下已经使用了addslashes()进行了转义，不必重复进行。如果数据处理必要(例如用于直接显示)，可以使用 stripslashes() 恢复，但数据在插入数据库之前必须再次进行转义。</p>
<p>缓存文件中，一般对缓存数据的值采用 addcslashes($string, ‘\’\\’)进行转义。</p>
<p><strong>4.4.命名原则</strong></p>
<p>命名是程序规划的核心。古人相信只要知道一个人真正的名字就会获得凌驾于那个人之上的不可思议的力量。只要你给事物想到正确的名字，就会给你以及后来的人带来比代码更强的力量。</p>
<p>名字就是事物在它所处的生态环境中一个长久而深远的结果。总的来说，只有了解系统的程序员才能为系统取出最合适的名字。如果所有的命名都与其自然相适合，则关系清晰，含义可以推导得出，一般人的推想也能在意料之中。</p>
<p>就一般约定而言，类、函数和变量的名字应该总是能够描述让代码阅读者能够容易的知道这些代码的作用。形式越简单、越有规则，就越容易让人感知和理解。应该避免使用模棱两可，晦涩不标准的命名。</p>
<p>4.4.1. 变量、对象、函数名</p>
<p>变量、对象、函数名一律为小写格式，除非必要，单词之间一般不使用下划线“_”进行分割；</p>
<p>以标准计算机英文为蓝本，杜绝一切拼音、或拼音英文混杂的命名方式；</p>
<p>变量命名只能使用项目中有据可查的英文缩写方式，例如可以使用$data而不可使用$data1、$data2这样容易产生混淆的形式，应当使用$articledata、$userdata这样一目了然容易理解的形式；</p>
<p>可以合理的对过长的命名进行缩写，例如$bio($biography)，$tpp($threadsPerPage)，前提是英文中有这样既有的缩写形式，或字母符合英文缩写规范；</p>
<p>必须清楚所使用英文单词的词性，在权限相关的范围内，大多使用$enable***、$is*** 、的形式，前者后面接动词，后者后面接形容词。</p>
<p>4.4.2. 常量</p>
<p>常量应该总是全部使用大写字母命名，少数特别必要的情况下，可使用划线来分隔单词；</p>
<p>PHP 的内建值 TRUE、FALSE 和NULL必须全部采用大写字母书写。</p>
<p><strong>4.5.变量的初始化与逻辑检查</strong></p>
<p>任何变量在进行累加、直接显示或存储前必需进行初使化，例如：</p>
<p><img class="alignnone size-full wp-image-2724" title="init" src="http://www.luoye.org/blog/wp-content/uploads/2010/12/init.png" alt="" width="284" height="59" /></p>
<p>判断一个无法确定（不知道是否已被赋值）的变量时，可用empty()或isset()，而不要直接使用if($switch)的形式，除非你确切的知道此变量一定已经被初始化并赋值。</p>
<p>empty()和isset()的区别为：</p>
<p><em>bool empty(mixed var)</em><strong> </strong>如果 var 是非空或非零的值，则 empty() 返回 FALSE。换句话说，”&#8221;、0、”0″、NULL、FALSE、array()、var $var; 以及没有任何属性的对象都将被认为是空的，如果 var 为空，则返回 TRUE。</p>
<p><em>bool isset(mixed var[, mixed var[, ...]]) </em>如果 var 存在则返回 TRUE，否则返回 FALSE。如果已经使用 unset() 释放了一个变量之后，它将不再是 isset()。若使用 isset() 测试一个被设置成 NULL 的变量，将返回 FALSE。同时要注意的是一个 NULL 字节（”\0″）并不等同于 PHP 的 NULL 常数。</p>
<p>判断一个变量是否为数组，请使用is_array()，这种判断尤其适用于对数组进行遍历的操作，例如foreach()，因为如果不事先判断，foreach()会对非数组类型的变量报错；</p>
<p>判断一个数组元素是否存在，可使用isset($array[‘key’])，也可使用empty()，两者异同见上。 </p>
<p><strong>4.6.</strong><strong>安全性</strong></p>
<p>PHP中的变量不并不像C语言那样需要事先声明，解释器会在第一次使用时自动创建他们，同样类型也不需要指定，解释器会根据上下文环境自动确定。从 开发人员的角度来看，这无疑是一种极其方便的处理方法。一个变量被创建了，就可以在程序中的任何地方使用。这导致的结果就是开发人员工经常不注意初始化变 量。因此，为了提高程序的安全性，我们不能相信任何没有明确定义的变量。所有的变量在定义使用前要初使化以防止恶意构造提交的变量覆盖程序中使用的变量。</p>
<p>细节可以阅读（<a href="http://www.securereality.com.au/studyinscarlet.txt">http://www.securereality.com.au/studyinscarlet.txt</a>）这篇文档，该文档里罗列了PHP常见的安全问题，阅读该文档是非常有必要的！</p>
<p> <strong>4.7.</strong><strong>兼容性</strong></p>
<p>代码设计应当兼顾PHP 高低版本的特性，当前，应仍然以PHP 4.3.0作为最低通过平台，尽量不使用高版本PHP 新增的函数、常数或者常量。如果使用只在高版本才具备的函数，必须对其进行二次封装，自动判断当前PHP版本，并自行编写低版本下的兼容代码；</p>
<p>对于个别函数，参数要求或者代码要求应当以较为严格的PHP版本为准；</p>
<p>除非必要，不要使用PHP扩展模块中的函数。使用时应当加入必要的判断，当服务器环境不支持此函数的时候，进行必要的处理。文档和程序中的功能说明中，也应加上兼容性说明。</p>
<p><strong>4.8.</strong><strong>代码重用</strong></p>
<p>代码的有效重用可以减少效率的损失与资源的浪费。在开发软件项目时为了避免重复劳动和浪费时间。开发人员应尽量提高现有代码的重用率，同时将更多的精力用在新技术的应用和新功能的创新开发上面。</p>
<ul>
<li>在需要多次使用代码，并且对于您希望实现的任务没有可用的内置 PHP 函数时，不吝啬定义函数或类。开发者须根据功能、调用情况，将函数放置于include目录并以.func.php作为函数文件后缀，将类放置于 include/class目录。超过3行，实现相同功能的程序切勿在不同程序中多次出现，这是无法容忍和回避的问题；</li>
<li>在任何时候都不要出现同一个程序中出现两段或更多的相似代码或相同代码，即便在不同程序中，也应尽力避免。开发者应当总是有能力找到避免代码大段(超过10行)重复或类似的情况。</li>
</ul>
<p>需要强调的是，本部分虽然篇幅较短，但却是十分需要经验，并将花费开发者大量时间和精力去进行优化的部分，任何产品开发者必须时刻清楚和理解代码重用的重要性和必要性，切实在增强产品效率、逻辑性和可读性上下功夫，这是一名优秀软件开发者所必须具备的基本素质。</p>
<p><strong>4.9.</strong><strong>其他细节问题</strong></p>
<p>4.9.1.   包含调用</p>
<p>包含调用程序文件，请全部使用require_once，以避免可能的重复包含问题；</p>
<p>包含调用缓存文件，由于缓存文件无法保证100%正确打开，请使用include_once或include。在必要时，可以使用@include_once或@include的方式，以忽略错误提示；</p>
<p>包含和调用代码中，须以PHPCMS_ROOT.’/’开头，应避免直接写程序文件名(例如：require_once ‘x.php’;)的做法；</p>
<p>所有被包含和调用的程序文件，包括但不限于程序、缓存或模板，通常其不能被直接URL请求。phpcms通过在./include /common.inc.php中定义一个标记性常量IN_PHPCMS，来判断程序是否被合法调用。因此，在除了./include /common.inc.php以外的任何一个被包含和调用的程序文件中，需要包含以下内容，以使得访问者无法直接通过URL请求该文件：</p>
<p><img class="alignnone size-full wp-image-2725" title="IN_PHPCMS" src="http://www.luoye.org/blog/wp-content/uploads/2010/12/IN_PHPCMS.png" alt="" width="375" height="20" /></p>
<p>4.9.2.   错误报告级别</p>
<p>在软件开发和调试阶段，请使用error_reporting(E_ALL);作为默认的错误报告级别，此级别最为严格，能够报告程序中所有的错 误、警告和提示信息，以帮助开发者检查和核对代码，避免大多数安全性问题和逻辑错误、拼写错误。error_reporting()可以 在./include/common.inc.php的头几行进行设置。</p>
<p>在软件发布时，请使用error_reporting(E_ERROR | E_WARNING | E_PARSE);作为默认的错误报告级别，以利于用户使用并将无谓错误提示信息降至最低。</p>
<p><strong>5.</strong><strong>数据库设计</strong></p>
<p><strong>5.1.</strong><strong>字段</strong></p>
<p>5.1.1.   表和字段命名</p>
<p>表和字段的命名以前面《4.4命名原则》的约定为基本准则。</p>
<p>所有数据表名称，只要其名称是可数名词，则必须以复数方式命名，例如：phpcms_member(用户表)；存储多项内容的字段，或代表数量的字段，也应当以复数方式命名，例如：hits(查看次数)、items(内容数量)。</p>
<p>当几个表间的字段有关连时，要注意表与表之间关联字段命名的统一，如phpcms_article_1表中的articleid与phpcms_article_data_1表中的articleid。</p>
<p>代表id自增量的字段，通常用以下几种形式：</p>
<ul>
<li> 一般情况下，使用全称的形式，例如userid、articleid；</li>
<li>没有功能性作用，只为管理和维护方便而设的id，可以使用全称的形式，也可只将其命名为id。</li>
</ul>
<p>篇幅所限，无法一一赘述，但所有与表、字段相关的命名，请务必大量参考phpcms现有字段的命名方式，以保证命名的系统性和统一性。</p>
<p>5.1.2.   字段结构</p>
<p>允许NULL值的字段，数据库在进行比较操作时，会先判断其是否为NULL，非NULL时才进行值的必对。因此基于效率的考虑，所有字段均不能为空，即全部NOT NULL；</p>
<p>预计不会存储非负数的字段，例如各项id、发帖数等，必须设置为UNSIGNED类型。UNSIGNED类型比非UNSIGNED类型所能存储的正整数范围大一倍，因此能获得更大的数值存储空间；</p>
<p>存储开关、选项数据的字段，通常使用tinyint(1)非UNSIGNED类型，少数情况也可能使用enum()结果集的方式。tinyint作 为开关字段时，通常1为打开；0为关闭；-1为特殊数据，例如N/A(不可用)；高于1的为特殊结果或开关二进制数组合(详见phpcms中相关代码)；</p>
<p>MEMORY/HEAP类型的表中，要尤其注意规划节约使用存储空间，这将节约更多内存。例如cdb_sessions表中，就将IP地址的存储拆分为4个tinyint(3) UNSIGNED类型的字段，而没有采用char(15)的方式；</p>
<p>任何类型的数据表，字段空间应当本着足够用，不浪费的原则，数值类型的字段取值范围见下表：</p>
<p><img class="alignnone size-full wp-image-2726" title="int" src="http://www.luoye.org/blog/wp-content/uploads/2010/12/int.png" alt="" width="534" height="271" /></p>
<p><strong>5.2.SQL</strong><strong>语句</strong></p>
<p>所有SQL语句中，除了表名、字段名称以外，全部语句和函数均需大写，应当杜绝小写方式或大小写混杂的写法。例如select * from phpcms_member;是不符合规范的写法。</p>
<p>很长的SQL语句应当有适当的断行，依据JOIN、FROM、ORDER BY等关键字进行界定。</p>
<p>通常情况下，在对多表进行操作时，要根据不同表名称，对每个表指定一个1~2个字母的缩写，以利于语句简洁和可读性。</p>
<p>如下的语句范例，是符合规范的：</p>
<p><img class="alignnone size-full wp-image-2727" title="query" src="http://www.luoye.org/blog/wp-content/uploads/2010/12/query.png" alt="" width="425" height="53" /></p>
<p><strong>5.3.</strong><strong>性能与效率</strong></p>
<p>5.3.1.   定长与变长表</p>
<p>包含任何varchar、text等变长字段的数据表，即为变长表，反之则为定长表。</p>
<ul>
<li>对于变长表，由于记录大小不同，在其上进行许多删除和更改将会使表中的碎片更多。需要定期运行OPTIMIZE TABLE以保持性能。而定长表就没有这个问题；</li>
<li>如果表中有可变长的字段，将它们转换为定长字段能够改进性能，因为定长记录易于处理。但在试图这样做之前，应该考虑下列问题：</li>
<li>使用定长列涉及某种折衷。它们更快，但占用的空间更多。char(n) 类型列的每个值总要占用n 个字节(即使空串也是如此)，因为在表中存储时，值的长度不够将在右边补空格；</li>
<li>而varchar(n)类型的列所占空间较少，因为只给它们分配存储每个值所需要的空间，每个值再加一个字节用于记录其长度。因此，如果在char和varchar类型之间进行选择，需要对时间与空间作出折衷；</li>
<li>变长表到定长表的转换，不能只转换一个可变长字段，必须对它们全部进行转换。而且必须使用一个Alter TABLE语句同时全部转换，否则转换将不起作用；</li>
<li>有时不能使用定长类型，即使想这样做也不行。例如对于比255字符更长的串，没有定长类型；</li>
<li>在设计表结构时如果能够使用定长数据类型尽量用定长的，因为定长表的查询、检索、更新速度都很快。必要时可以把部分关键的、承担频繁访问的表拆 分，例如定长数据一个表，非定长数据一个表。例如phpcms的phpcms_member表等。因此规划数据结构时需要进行全局考虑；</li>
</ul>
<p>进行表结构设计时，应当做到恰到好处，反复推敲，从而实现最优的数据存储体系。</p>
<p>5.3.2.   运算与检索</p>
<p>数值运算一般比字符串运算更快。例如比较运算，可在单一运算中对数进行比较。而串运算涉及几个逐字节的比较，如果串更长的话，这种比较还要多。</p>
<p>如果串列的值数目有限，应该利用普通整型或emum类型来获得数值运算的优越性。</p>
<p>更小的字段类型永远比更大的字段类型处理要快得多。对于字符串，其处理时间与串长度直接相关。一般情况下，较小的表处理更快。对于定长表，应该选择 最小的类型，只要能存储所需范围的值即可。例如，如果mediumint够用，就不要选择bigint。对于可变长类型，也仍然能够节省空间。一个 TEXT 类型的值用2 字节记录值的长度，而一个LONGTEXT 则用4字节记录其值的长度。如果存储的值长度永远不会超过64KB，使用TEXT 将使每个值节省2字节。</p>
<p>5.3.3.   结构优化与索引优化</p>
<p>索引能加快查询速度，而索引优化和查询优化是相辅相成的，既可以依据查询对索引进行优化，也可以依据现有索引对查询进行优化，这取决于修改查询或索引，哪个对现有产品架构和效率的影响最小。</p>
<p>索引优化与查询优化是多年经验积累的结晶，在此无法详述，但仍然给出几条最基本的准则。</p>
<p>首先，根据产品的实际运行和被访问情况，找出哪些SQL语句是最常被执行的。最常被执行和最常出现在程序中是完全不同的概念。最常被执行的SQL语 句，又可被划分为对大表(数据条目多的)和对小表(数据条目少的)的操作。无论大表或小表，有可分为读(Select)多、写 (Update/Insert)多或读写都多的操作。</p>
<p>对常被执行的SQL语句而言，对大表操作需要尤其注意：</p>
<ul>
<li>写操作多的，通常可使用写入缓存的方法，先将需要写或需要更新的数据缓存至文件或其他表，定期对大表进行批量写操作。同时，应尽量使得常被读写的 大表为定长类型，即便原本的结构中大表并非定长。大表定长化，可以通过改变数据存储结构和数据读取方式，将一个大表拆成一个读写多的定长表，和一个读多写 少的变长表来实现；</li>
<li>读操作多的，需要依据SQL查询频率设置专门针对高频SQL语句的索引和联合索引。</li>
</ul>
<p>而小表就相对简单，加入符合查询要求的特定索引，通常效果比较明显。同时，定长化小表也有益于效率和负载能力的提高。字段比较少的小定长表，甚至可以不需要索引。</p>
<p>其次，看SQL语句的条件和排序字段是否动态性很高(即根据不同功能开关或属性，SQL查询条件和排序字段的变化很大的情况)，动态性过高的SQL语句是无法通过索引进行优化的。惟一的办法只有将数据缓存起来，定期更新，适用于结果对实效性要求不高的场合。</p>
<p>MySQL索引，常用的有PRIMARY KEY、INDEX、UNIQUE几种，详情请查阅MySQL文档。通常，在单表数据值不重复的情况下，PRIMARY KEY和UNIQUE索引比INDEX更快，请酌情使用。</p>
<p>事实上，索引是将条件查询、排序的读操作资源消耗，分布到了写操作中，索引越多，耗费磁盘空间越大，写操作越慢。因此，索引决不能盲目添加。对字段索引与否，最根本的出发点，依次仍然是SQL语句执行的概率、表的大小和写操作的频繁程度。</p>
<p>5.3.4.   查询优化</p>
<p>MySQL中并没有提供针对查询条件的优化功能，因此需要开发者在程序中对查询条件的先后顺序人工进行优化。例如如下的SQL语句：</p>
<p><img class="alignnone size-full wp-image-2728" title="table" src="http://www.luoye.org/blog/wp-content/uploads/2010/12/table.png" alt="" width="501" height="18" /></p>
<p> 事实上无论a&gt;’0’还是b&lt;’1’哪个条件在前，得到的结果都是一样的，但查询速度就大不相同，尤其在对大表进行操作时。</p>
<p>开发者需要牢记这个原则：最先出现的条件，一定是过滤和排除掉更多结果的条件；第二出现的次之；以此类推。因而，表中不同字段的值的分布，对查询速度有着很大影响。而ORDER BY中的条件，只与索引有关，与条件顺序无关。</p>
<p>除了条件顺序优化以外，针对固定或相对固定的SQL查询语句，还可以通过对索引结构进行优化，进而实现相当高的查询速度。原则是：在大多数情况下， 根据Where条件的先后顺序和ORDER BY的排序字段的先后顺序而建立的联合索引，就是与这条SQL语句匹配的最优索引结构。尽管，事实的产品中不能只考虑一条SQL语句，也不能不考虑空间占 用而建立太多的索引。</p>
<p>同样以上面的SQL语句为例，最优的当table表的记录达到百万甚至千万级后，可以明显的看到索引优化带来的速度提升。</p>
<p>依据上面条件优化和索引优化的两个原则，当table表的值为如下方案时，可以得出最优的条件顺序方案：</p>
<p><img class="alignnone size-full wp-image-2729" title="table2" src="http://www.luoye.org/blog/wp-content/uploads/2010/12/table2.png" alt="" width="538" height="251" /></p>
<p>EXPLAIN语句是检测索引和查询能否良好匹配的简便方法。在phpMyAdmin或其他MySQL客户端中运行EXPLAIN+查询语句，例如 EXPLAIN select * FROM table Where a&gt;’0’ AND b&lt;’1’ orDER BY c;这种形式，即使得开发者无需模拟上百万条数据，也可以验证索引是否合理，相关细节请参考MySQL说明。</p>
<p>值得提出的是，Using filesort是最不应当出现的情况，如果EXPLAIN得出此结果，说明数据库为这个查询专门建立了一个用以缓存结果的临时表文件，并在查询结束后删 除。众所周知，硬盘I/O速度始终是计算机存储的瓶颈，因此，查询中应当尽全力避免高执行频率的SQL语句使用filesort。尽管，开发者永远都不可 能保证产品中的全部SQL语句都不会使用filesort。</p>
<p>限于篇幅，本文档远远没有涵盖数据库优化的方方面面，例如：联合索引与普通索引的可重用性、JOIN连接的索引设计、MEMORY/HEAP表等。 数据库优化实际上就是在很多因素和利弊间不断权衡、修改，惟有在成功与失败经验中反复推敲才能得出的经验，这种经验往往就是最难能可贵和价值连城的。</p>
<p>5.3.5.   兼容性问题</p>
<p>由于MySQL 3.23至5.0的变化很大，因此程序中尽量不使用特殊的SQL语句，以免带来兼容性问题，并给数据库移植造成困难。</p>
<p>通常在MySQL 4.1以上版本，phpcms应使用相当的字符集来存储，例如GBK/BIG5/UTF-8。传统的latin1编码虽然有一定的兼容性，但仍然不是推荐 的选择。使用相应非默认字符集时，程序每次运行时需要使用SET NAMES ‘character_set’;来规定连接、传输和结果的字符集。</p>
<p>Mysql 5.0以上新增了数种SQL_MODE，默认的SQL_MODE依服务器安装设置不同而不同，因此程序每次运行时需要使用SET SQL_MODE=’’;来规定当前的SQL模式。</p>
<p><strong>6.</strong><strong> </strong><strong>模板设计</strong></p>
<p><strong>6.1.</strong><strong>代码标记</strong></p>
<p>HTML代码标记一律采用小写字母形式，杜绝任何使用大写字母的方式</p>
<p>模板中所有的逻辑体，如{if}、{loop}等，必须前后使用HTML注释(&lt;!– –&gt;)，即类似&lt;!–{if expr}–&gt;的形式。事实上，phpcms模板编译器是支持不加HTML注释的逻辑体写法的，但加入注释可以使得模板可读性更好，同时方便用户使 用DreamWeaver或FrontPage等对模板进行修改。</p>
<p><strong>6.2.</strong><strong>书写规则</strong></p>
<p>6.2.1.   HTML</p>
<p>所有HTML标记参数赋值需使用双引号包含，例如，应当使用&lt;input type=”text” name=”test” value=”ok”&gt;,而绝对不能使用&lt;input value=ok&gt;。</p>
<p>在任何情况下，产品中的模板文件必须采用手写HTML代码的方式，而绝对不能使用DreamWeaver、FrontPage等自动网页制作工具进行撰写或修改。</p>
<p>6.2.2.   变量</p>
<p>模板中使用的变量，依据作用和出现位置不同，分为几种方式：</p>
<p>逻辑体中，即被&lt;!–{ }–&gt;包围起来的部分，例如&lt;!–{if isset($array[‘key’])}–&gt;这种形式，其中的变量书写规范与PHP程序中完全一致；</p>
<p>开发者需要使用{}将变量括起来，以免出现模板编译错误，可能的情况如下：</p>
<ul>
<li>变量前后含有中括号的或其他敏感字符的(包括但不限于“$”、“’”等)，正确的写法为descriptionnew[{$buddy[buddyid]}]；</li>
<li>数组的下标为变量的，正确的写法为{$extcredits[$creditstrans][title]}；</li>
<li>其他变量十分复杂的情况。</li>
</ul>
<p>6.2.3.   语言元素</p>
<p>6.2.4.   缩进</p>
<p>在phpcms的*.html模板文件中，由于具备逻辑结构，故不考虑任何HTML本身的缩进，所有缩进均意为着逻辑上的缩进结构。缩进采用TAB方式，不使用空格作为缩进符号，仅需适当断行即可。例如</p>
<p><img class="alignnone size-full wp-image-2730" title="tab" src="http://www.luoye.org/blog/wp-content/uploads/2010/12/tab.png" alt="" width="442" height="85" /></p>
<p><strong>7.</strong><strong>文件与目录</strong></p>
<p><strong>7.1.</strong><strong>文件命名</strong></p>
<p>所有包含PHP代码的程序文件或半程序文件，应以小写.php作为扩展名，而不要使用.phtml、.php3、.inc、.class等作为扩展名。</p>
<ul>
<li>普通程序 能够被URL直接调用的程序，例如list.php、index.php，直接使用程序名+.php的方式命名</li>
<li>函数库和类库程序 分别以小写.func.php和.class.php作为扩展名。函数库和类库程序只能被其他程序引用，而不能独立运行。其中不能包含任何流程性的、不属于任何函数或类的程序代码。</li>
<li>流程性程序<strong> </strong>以小写.inc.php作为扩展名。只能被其他程序引用，而不能独立运行。其中不能包含任何函数或类代码的程序代码。</li>
<li>模板源文件 以小写.html作为扩展名。模板源文件按照phpcms模板编码规则进行编写，不是可以执行的程序，而只能被phpcms模板编译器所解析，放置于./templates/default或./templates下的其他模板目录下。</li>
<li>模板目标文件<strong> </strong>模板文件被编译后自动生成的目标程序，以小写. php作为扩展名，存放于./data/templates目录下。</li>
<li>语言包文件 以小写.lang.php作为扩展名，只能存放模板或程序使用的语言包信息。</li>
<li>缓存文件<strong> </strong>此类文件为系统自动生成，以cache_xxx.php、usergroup_xxx.php、style_xxx.php等类似形式命名，存放于./data/cache目录下。</li>
</ul>
<p><strong>7.2.</strong><strong>目录命名</strong></p>
<p>phpcms目录命名以前面《4.4命名原则》的约定为基本准则。在可能的情况下，多以复数形式出现，如./templates、./images等。</p>
<p>由于目录数量较少，因此目录命名大多是一些习惯和约定俗成，开发人员如需新建目录，应与项目组成员进行磋商，达成一致后方可实施。</p>
<p><strong>7.3.</strong><strong>空目录索引</strong></p>
<p>请在所有不包含普通程序(即能够被URL直接调用的程序)的目录中放置一个1字节的index.htm文件，内容为一个空格。几乎除phpcms根 目录以外，所有目录都属于这一类型，因此开发者需要在这些目录全部放入空index.htm文件，以避免当http服务器的Directory Listing打开时，服务器文件被索引和列表。</p>
<p>附件目录等敏感目录，要在程序中实现相应功能，当新建下级目录时，必须自动写入一个空的index.htm文件，以避免新建目录被索引的问题。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.luoye.org/blog/2010/12/phpcms-php/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>php之一致性hash</title>
		<link>http://www.luoye.org/blog/2010/12/php%e4%b9%8b%e4%b8%80%e8%87%b4%e6%80%a7hash/</link>
		<comments>http://www.luoye.org/blog/2010/12/php%e4%b9%8b%e4%b8%80%e8%87%b4%e6%80%a7hash/#comments</comments>
		<pubDate>Thu, 16 Dec 2010 02:09:27 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[php hash]]></category>

		<guid isPermaLink="false">http://www.luoye.org/blog/?p=220</guid>
		<description><![CDATA[一致性hash大多用于缓存集群中，为了使在缓存中由于一台或多台服务器宕机，导致后端数据库压力过大而崩溃，他对添加和减少缓存服务器迁移的数据量最小化 相关资料可参考一下网站： http://blog.sunyixing.com/?p=87 http://weblogs.java.net/blog/2007/11/27/consistent-hashing 上面有一个 java 版本的例子，可以参考。 http://blog.csdn.net/mayongzhan/archive/2009/06/25/4298834.aspx 转载了一个 PHP 版的实现代码。 http://www.codeproject.com/KB/recipes/lib-conhash.aspx C语言版本 一些参考资料地址： http://portal.acm.org/citation.cfm?id=258660 http://en.wikipedia.org/wiki/Consistent_hashing http://www.spiteful.com/2008/03/17/programmers-toolbox-part-3-consistent-hashing/ http://weblogs.java.net/blog/2007/11/27/consistent-hashing http://tech.idv2.com/2008/07/24/memcached-004/ http://blog.csdn.net/mayongzhan/archive/2009/06/25/4298834.aspx http://code.google.com/p/flexihash/]]></description>
			<content:encoded><![CDATA[<p>一致性hash大多用于缓存集群中，为了使在缓存中由于一台或多台服务器宕机，导致后端数据库压力过大而崩溃，他对添加和减少缓存服务器迁移的数据量最小化</p>
<p>相关资料可参考一下网站：<br />
<a href="http://blog.sunyixing.com/?p=87">http://blog.sunyixing.com/?p=87</a><br />
<a href="http://weblogs.java.net/blog/2007/11/27/consistent-hashing">http://weblogs.java.net/blog/2007/11/27/consistent-hashing</a> 上面有一个 java 版本的例子，可以参考。<span id="more-220"></span></p>
<p><a href="http://blog.csdn.net/mayongzhan/archive/2009/06/25/4298834.aspx">http://blog.csdn.net/mayongzhan/archive/2009/06/25/4298834.aspx</a> 转载了一个 PHP 版的实现代码。</p>
<p><a href="http://www.codeproject.com/KB/recipes/lib-conhash.aspx">http://www.codeproject.com/KB/recipes/lib-conhash.aspx</a> C语言版本</p>
<p>一些参考资料地址：</p>
<p><a href="http://portal.acm.org/citation.cfm?id=258660">http://portal.acm.org/citation.cfm?id=258660</a></p>
<p><a href="http://en.wikipedia.org/wiki/Consistent_hashing">http://en.wikipedia.org/wiki/Consistent_hashing</a></p>
<p><a href="http://www.spiteful.com/2008/03/17/programmers-toolbox-part-3-consistent-hashing/">http://www.spiteful.com/2008/03/17/programmers-toolbox-part-3-consistent-hashing/</a></p>
<p><a href="http://weblogs.java.net/blog/2007/11/27/consistent-hashing">http://weblogs.java.net/blog/2007/11/27/consistent-hashing</a></p>
<p><a href="http://tech.idv2.com/2008/07/24/memcached-004/">http://tech.idv2.com/2008/07/24/memcached-004/</a></p>
<p><a href="http://blog.csdn.net/mayongzhan/archive/2009/06/25/4298834.aspx">http://blog.csdn.net/mayongzhan/archive/2009/06/25/4298834.aspx</a></p>
<p><a href="http://code.google.com/p/flexihash/">http://code.google.com/p/flexihash/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.luoye.org/blog/2010/12/php%e4%b9%8b%e4%b8%80%e8%87%b4%e6%80%a7hash/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>php函数之file_get_contents模拟post和get</title>
		<link>http://www.luoye.org/blog/2010/12/php-file_get_contents-post-get/</link>
		<comments>http://www.luoye.org/blog/2010/12/php-file_get_contents-post-get/#comments</comments>
		<pubDate>Thu, 16 Dec 2010 02:00:50 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[file_get_contents]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.luoye.org/blog/?p=213</guid>
		<description><![CDATA[&#60;?php $postdata = array('name'=&#62;'niutian365','pass'=&#62;'123456***') ;/*要访问的页面上的form内的input名称参数或者get参数*/ $post_string = http_build_query($postdata); $opts = array( 'http'=&#62;array( 'protocol_version'=&#62;'1.1',/*http协议版本(若不指定php5.2系默认为http1.0)*/ 'method'=&#62;&#34;POST&#34;,/*获取方式这里可改成GET*/ 'timeout' =&#62; 5 ,/*超时时间*/ 'header'=&#62; &#34;User-Agent:Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.2.8) Gecko/20100722 Firefox/3.6.8\r\n&#34;. &#34;Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n&#34;. &#34;Accept-language: zh-cn,zh;q=0.5\r\n&#34; . &#34;Accept-Charset: GB2312,utf-8;q=0.7,*;q=0.7\r\n&#34;. &#34;Content-length: &#34;.strlen($post_string),/*模拟的header头*/ 'content'=&#62; $post_string /*访问时传递的数据内容*/ ) ); /*创建并返回一个文本数据流并应用各种选项, 可用于fopen(),file_get_contents()等过程的超时设置, 代理服务器,请求方式,头信息设置的特殊过程 */ $context = stream_context_create($opts); $content = file_get_contents('http://www.niutian365.com/index.php',false,$context ); ?&#62; 其他方式(来自网络未验证)： [...]]]></description>
			<content:encoded><![CDATA[<p><span id="more-213"></span></p>
<pre class="brush: php; title: ;">
&lt;?php

  $postdata = array('name'=&gt;'niutian365','pass'=&gt;'123456***') ;/*要访问的页面上的form内的input名称参数或者get参数*/

  $post_string =  http_build_query($postdata);
  $opts = array(
'http'=&gt;array(
  'protocol_version'=&gt;'1.1',/*http协议版本(若不指定php5.2系默认为http1.0)*/
  'method'=&gt;&quot;POST&quot;,/*获取方式这里可改成GET*/
  'timeout' =&gt; 5 ,/*超时时间*/
  'header'=&gt;
          &quot;User-Agent:Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.2.8) Gecko/20100722 Firefox/3.6.8\r\n&quot;.
          &quot;Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n&quot;.
          &quot;Accept-language: zh-cn,zh;q=0.5\r\n&quot; .
      &quot;Accept-Charset: GB2312,utf-8;q=0.7,*;q=0.7\r\n&quot;.
      &quot;Content-length: &quot;.strlen($post_string),/*模拟的header头*/
   'content'=&gt; $post_string /*访问时传递的数据内容*/
    )
  );

  /*创建并返回一个文本数据流并应用各种选项,
      可用于fopen(),file_get_contents()等过程的超时设置,
      代理服务器,请求方式,头信息设置的特殊过程
  */
  $context = stream_context_create($opts);

  $content = file_get_contents('http://www.niutian365.com/index.php',false,$context );
?&gt;
</pre>
<p>
其他方式(来自网络未验证)：</p>
<pre class="brush: php; title: ;">
&lt;?php
/**
* Socket版本
* 使用方法：
* $post_string = &quot;app=socket&amp;version=beta&quot;;
* request_by_socket('facebook.cn','/restServer.php',$post_string);
*/
function request_by_socket($remote_server,$remote_path,$post_string,$port = 80,$timeout = 30){
    $socket = fsockopen($remote_server,$port,$errno,$errstr,$timeout);
    if (!$socket) die(&quot;$errstr($errno)&quot;);

    fwrite($socket,&quot;POST $remote_path HTTP/1.0\r\n&quot;);
    //fwrite($socket,&quot;User-Agent: Socket Example\r\n&quot;);
    fwrite($socket,&quot;User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.1.2) Gecko/20090729 Firefox/3.5.2\r\n&quot;);
    fwrite($socket,&quot;HOST: $remote_server\r\n&quot;);
    fwrite($socket,&quot;Content-type: application/x-www-form-urlencoded\r\n&quot;);
    fwrite($socket,&quot;Content-length: &quot;.strlen($post_string) .&quot;\r\n&quot;);
    fwrite($socket,&quot;Accept:*/*\r\n&quot;);
    fwrite($socket,&quot;\r\n&quot;);
    fwrite($socket,$post_string.&quot;\r\n&quot;);
    fwrite($socket,&quot;\r\n&quot;);

    $header = &quot;&quot;;//去除头部
    while ($str = trim(fgets($socket,4096))) {
        $header.=$str;
    }

    $data = &quot;&quot;;
    while (!feof($socket)) {
        $data .= fgets($socket,4096);
    }

    return $data;
}

/**
* Curl版本
* 使用方法：
* $post_string = &quot;app=request&amp;version=beta&quot;;
* request_by_curl('http://facebook.cn/restServer.php',$post_string);
*/
function request_by_curl($remote_server,$post_string){
    $ch = curl_init();
    curl_setopt($ch,CURLOPT_URL,$remote_server);
    curl_setopt($ch,CURLOPT_POSTFIELDS,$post_string);
    curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
    curl_setopt($ch,CURLOPT_USERAGENT,'Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.1.2) Gecko/20090729 Firefox/3.5.2');
    $data = curl_exec($ch);
    curl_close($ch);
    return $data;
}
?&gt;
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.luoye.org/blog/2010/12/php-file_get_contents-post-get/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

