<?xml version="1.0" encoding="gb2312" ?>
<rss version="2.0">
	<channel>
		<title><![CDATA[PHP]]></title>
		<link><![CDATA[http://www.phpzixue.cn/articles1.shtml]]></link>
		<description><![CDATA[PHP]]></description>
		<language>zh-CN</language>
	<item>
		<title><![CDATA[php上传文件$_FILES数组为空的解决办法]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail1191.shtml]]></link>
		<description><![CDATA[php上传文件$_FILES数组为空的解决办法：
<br/>用php做上传文件的应用时，在后台打印$_FILES时发现为空数组，出现这个问题可能有以下两个原因：
<br/>表单类型原因或者php设置问题：
<br/>1，表单类型：
<br/>上传文件的表单编码类型必须设置成enctype=&quot;multipart/form-data&quot;，因为要传大数据，一般提交方式用POST。
<br/>
<br/>2，php设置问题：
<br/>php默认的post_max_size为2M.如果POST数据尺寸大于post_max_size$_POST和$_FILES超全局变量便会为空.解决的方法是：
<br/>1.一般的文件上传,除非文件很小.就像一个5M的文件,很可能要超过一分钟才能上传完.但在php中,默认的该页最久执行时间为30秒.就是说超过30秒,该脚本就停止执行.这就导致出现无法打开网页的情况.这时我们可以修改max_execution_time在php.ini里查找max_execution_time默认是30秒.改为max_execution_time=0（可修改范围为PHP_INI_ALL）0表示没有限制
<br/>或者在php文件头设置ini_set('max_execution_time',0);
<br/>2.修改post_max_size设定POST数据所允许的最大大小。此设定也影响到文件上传。查找post_max_size.改为post_max_size=150M（可修改范围为PHP_INI_PHP_INI_PERDIR）
<br/>3.很多人都会改了第二步.但上传文件时最大仍然为8M.为什么呢.我们还要改一个参数upload_max_filesize表示所上传的文件的最大大小。查找upload_max_filesize,默认为8M改为upload_max_filesize=100M（可修改范围为PHP_INI_PHP_INI_PERDIR）
<br/>另外要说明的是post_max_size是整个表达的大小，而upload_max_filesize是上传文件的大小，前者应大于后者.]]></description>
		<pubDate>Mon, 07 May 2012 14:44:57 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[php中在变量和函数前加static关键字之后的区别]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail1190.shtml]]></link>
		<description><![CDATA[static全局变量和普通全局变量，static局部变量和普通局部变量，static函数与普通函数的区别？　　
<br/>1)全局变量(外部变量)的说明之前再冠以static就构成了静态的全局变量。全局变量本身就是静态存储方式，静态全局变量当然也是静态存储方式。这两者在存储方式上并无不同。这两者的区别在于非静态全局变量的作用域是整个源程序，当一个源程序由多个源文件组成时，非静态的全局变量在各个源文件中都是有效的。而静态全局变量则限制了其作用域，即只在定义该变量的源文件内有效，在同一源程序的其它源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内，只能为该源文件内的函数公用，因此可以避免在其它源文件中引起错误。
<br/>2)从以上分析可以看出，把局部变量改变为静态变量后是改变了它的存储方式即改变了它的生存期。把全局变量改变为静态变量后是改变了它的作用域，限制了它的使用范围。　　
<br/>3)static函数与普通函数作用域不同,仅在本文件。只在当前源文件中使用的函数应该说明为内部函数(static)，内部函数应该在当前源文件中说明和定义。对于可在当前源文件以外使用的函数，应该在一个头文件中说明，要使用这些函数的源文件要包含这个头文件　　
<br/>综上所述:
<br/>static全局变量与普通的全局变量有什么区别：
<br/>static全局变量只初使化一次，防止在其他文件单元中被引用;　　
<br/>static局部变量和普通局部变量有什么区别：
<br/>static局部变量只被初始化一次，下一次依据上一次结果值；　　
<br/>static函数与普通函数有什么区别：
<br/>static函数在内存中只有一份，普通函数在每个被调用中维持一份拷贝]]></description>
		<pubDate>Fri, 27 Apr 2012 14:17:15 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[php中判断变量类型常用方法介绍]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail1189.shtml]]></link>
		<description><![CDATA[php中判断变量类型常用方法介绍：
<br/>php中常用的判断变量的函数有如下几个gettype()、is_array()、is_bool()、is_float()、is_integer()、is_null()、is_numeric()、is_object()、is_resource()、is_scalar()和is_string()。
<br/>下面介绍下它们具体的使用方法
<br/>gettype()
<br/>gettype会根据参数类型返回下列值
<br/>boolean（从PHP4起）
<br/>integer
<br/>double（如果是float则返回“double”，而不是“float”）
<br/>string
<br/>array
<br/>object
<br/>resource（从PHP4起）
<br/>NULL”（从PHP4起）
<br/>unknowntype”
<br/>例如:
<br/>gettype('123');返回的是string
<br/>而gettype(123);返回的是integer
<br/>
<br/>is_array()
<br/>is_array()的用法相对简单
<br/>如果参数是数组返回true否则返回false
<br/>
<br/>其他几个函数的用法和返回值与is_array()类似
<br/>这里需要注意的是is_numeric()是用来判断变量是否是数字或者数字符串的
<br/>当is_numeric()的参数是数字或者数字字符串的时候返回true否则返false。]]></description>
		<pubDate>Fri, 27 Apr 2012 11:37:30 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[通过设置nginx的client_max_body_size解决nginx+php上传大文件的问题]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail1184.shtml]]></link>
		<description><![CDATA[通过设置nginx的client_max_body_size解决nginx+php上传大文件的问题：
<br/>用nginx来做webserver的时，上传大文件时需要特别注意client_max_body_size这个参数,否则会中断在nginx的请求中,在php中是无法记录到访问的.
<br/>一般上传大文件流程：
<br/>首先修改php.ini文件：
<br/>参数	设置	说明
<br/>file_uploads	on	是否允许通过HTTP上传文件的开关。默认为ON即是开
<br/>upload_tmp_dir	–	文件上传至服务器上存储临时文件的地方，如果没指定就会用系统默认的临时文件夹
<br/>upload_max_filesize	8m	望文生意，即允许上传文件大小的最大值。默认为2M
<br/>post_max_size	8m	指通过表单POST给PHP的所能接收的最大值，包括表单里的所有值。默认为8M
<br/>说明
<br/>一般来说，设置好上述四个参数后，在网络正常的情况下，上传&lt;=8M的文件是不成问题的
<br/>但如果要上传&gt;8M的大文件的话，只设置上述四项还不一定能行的通。除非你的网络真有100M/S的上传高速，否则你还得继续设置下面的参数。
<br/>max_execution_time	600	每个PHP页面运行的最大时间值(秒)，默认30秒
<br/>max_input_time	600	每个PHP页面接收数据所需的最大时间，默认60秒
<br/>memory_limit	8m	每个PHP页面所吃掉的最大内存，默认8M

<br/>
<br/>但是还是不行，因为的webserver用的是nginx，google了一下，发现在nginx的conf中添加了一个参数：
<br/>默认是1M，需要增大的话。
<br/>在nginx.conf中增加一句
<br/>client_max_body_size30m;
<br/>重启即可
<br/>30m表示最大上传30M，需要多大设置多大。]]></description>
		<pubDate>Fri, 20 Apr 2012 14:56:59 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[用PHP函数memory_get_usage获取当前PHP内存消耗量]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail1182.shtml]]></link>
		<description><![CDATA[用PHP函数memory_get_usage获取当前PHP内存消耗量：
<br/>PHP性能优化过程中避免不了需要获取PHP内存消耗，使用memory_get_usage()函数可获取当前的内存消耗情况，函数使用简单，下面介绍下memory_get_usage()函数的用法与实例。
<br/>
<br/>一，函数原型
<br/>intmemory_get_usage([bool$real_usage=false])
<br/>
<br/>二，版本兼容
<br/>PHP4&gt;=4.3.2,PHP5
<br/>
<br/>三，基础用法与实例
<br/>1，获取当前的内存消耗量
<br/>&lt;?php
<br/>echomemory_get_usage();
<br/>$var=str_repeat(&quot;phpzixue.cn&quot;,10000);
<br/>echomemory_get_usage();
<br/>unset($var);
<br/>echomemory_get_usage();
<br/>?&gt;
<br/>分别输出：6232812250462416
<br/>说明：memory_get_usage()函数输出的数值为bytes单位
<br/>
<br/>2，格式化memory_get_usage()输出
<br/>&lt;?php
<br/>functionconvert($size){
<br/>$unit=array('b','kb','mb','gb','tb','pb');
<br/>return@round($size/pow(1024,($i=floor(log($size,1024)))),2).''.$unit[$i];
<br/>}
<br/>echoconvert(memory_get_usage(true));
<br/>?&gt;
<br/>输出：256kb
<br/>
<br/>3，自定义函数获取数组或变量值大小
<br/>&lt;?php
<br/>functionarray_size($arr){
<br/>ob_start();
<br/>print_r($arr);
<br/>$mem=ob_get_contents();
<br/>ob_end_clean();
<br/>$mem=preg_replace(&quot;/\n+/&quot;,&quot;&quot;,$mem);

<br/>$mem=strlen($mem);
<br/>return$mem;
<br/>}
<br/>$memEstimate=array_size($GLOBALS);
<br/>?&gt;
<br/>可以看出，要想减少内存的占用，可以使用PHPunset()函数把不再需要使用的变量删除。类似的还有：PHPmysql_free_result()函数，可以清空不再需要的查询数据库得到的结果集，这样也能得到更多可用内存。
<br/>
<br/>PHPmemory_get_usage()还可以有个参数，$real_usage，其值为布尔值。默认为FALSE，表示得到的内存使用量不包括该函数（PHP内存管理器）占用的内存；当设置为TRUE时，得到的内存为包括该函数（PHP内存管理器）占用的内存。
<br/>
<br/>所以在实际编程中，可以用PHPmemory_get_usage()比较各个方法占用内存的高低，来选择使用哪种占用内存小的方法。]]></description>
		<pubDate>Tue, 17 Apr 2012 17:36:43 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[用PHP操作http中Etag、lastModified和Expires标签]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail1181.shtml]]></link>
		<description><![CDATA[用PHP操作http中Etag、lastModified和Expires标签：
<br/>1、Etag、Expires中Client端Http，RequestHeader及Server端Http，ReponseHeader工作原理。
<br/>2、静态下Apache、Lighttpd和Nginx中Etag和Expires配置
<br/>3、非实时交互动态页面中Etag和Expires处理
<br/>在客户端通过浏览器发出第一次请求某一个URL时，根据HTTP协议的规定，浏览器会向服务器传送报头(HttpRequestHeader)，服务器端响应同时记录相关属性标记(HttpReponseHeader)，服务器端的返回状态会是200，格式类似如下：
<br/>1.HTTP/1.1200OK
<br/>2.Date:Tue,03Mar201204:58:40GMT
<br/>3.Content-Type:image/jpeg
<br/>4.Content-Length:83185
<br/>5.Last-Modified:Tue,24Feb201208:01:04GMT
<br/>6.Cache-Control:max-age=2592000
<br/>7.Expires:Thu,02Apr201205:14:08GMT
<br/>8.Etag:“5d8c72a5edda8d6a:3239″
<br/>
<br/>客户端第二次请求此URL时，根据HTTP协议的规定，浏览器会向服务器传送报头(HttpRequestHeader)，服务器端响应并记录相关记录属性标记文件没有发生改动,服务器端返回304，直接从缓存中读取：
<br/>
<br/>1.HTTP/1.x304NotModified
<br/>2.Date:Tue,03Mar201205:03:56GMT
<br/>3.Content-Type:image/jpeg
<br/>4.Content-Length:83185
<br/>5.Last-Modified:Tue,24Feb201208:01:04GMT
<br/>6.Cache-Control:max-age=2592000
<br/>7.Expires:Thu,02Apr201205:14:08GMT
<br/>8.Etag:&quot;5d8c72a5edda8d6a:3239&quot;
<br/>9.//其中Last-Modified、Expires和Etag是标记页面缓存标识
<br/>
<br/>一、Last-Modified、Expires和Etag相关工作原理
<br/>　　1、Last-Modified
<br/>　　在浏览器第一次请求某一个URL时，服务器端的返回状态会是200，内容是你请求的资源，同时有一个Last-Modified的属性标记(HttpReponseHeader)此文件在服务期端最后被修改的时间，格式类似这样：
<br/>　　Last-Modified:Tue,24Feb201208:01:04GMT
<br/>　　客户端第二次请求此URL时，根据HTTP协议的规定，浏览器会向服务器传送If-Modified-Since报头(HttpRequestHeader)，询问该时间之后文件是否有被修改过：
<br/>　　If-Modified-Since:Tue,24Feb201208:01:04GMT
<br/>　　如果服务器端的资源没有变化，则自动返回HTTP304（NotChanged.）状态码，内容为空，这样就节省了传输数据量。当服务器端代码发生改变或者重启服务器时，则重新发出资源，返回和第一次请求时类似。从而保证不向客户端重复发出资源，也保证当服务器有变化时，客户端能够得到最新的资源。
<br/>
<br/>　　注：如果If-Modified-Since的时间比服务器当前时间(当前的请求时间request_time)还晚，会认为是个非法请求
<br/>
<br/>　　2、Etag工作原理
<br/>　　HTTP协议规格说明定义ETag为“被请求变量的实体标记”
<br/>　　简单点即服务器响应时给请求URL标记，并在HTTP响应头中将其传送到客户端，类似服务器端返回的格式：
<br/>　　Etag:“5d8c72a5edda8d6a:3239″
<br/>　　客户端的查询更新格式是这样的：
<br/>　　If-None-Match:“5d8c72a5edda8d6a:3239″
<br/>　　如果ETag没改变，则返回状态304。
<br/>　　即:在客户端发出请求后，HttpReponseHeader中包含Etag:“5d8c72a5edda8d6a:3239″
<br/>　　标识，等于告诉Client端，你拿到的这个的资源有表示ID：5d8c72a5edda8d6a:3239。
<br/>
<br/>　　当下次需要发Request索要同一个URI的时候，浏览器同时发出一个If-None-Match报头(HttpRequestHeader)此时包头中信息包含上次访问得到的Etag:“5d8c72a5edda8d6a:3239″标识。
<br/>If-None-Match:“5d8c72a5edda8d6a:3239“
<br/>这样，Client端等于Cache了两份，服务器端就会比对2者的etag。如果If-None-Match为False，不返回200，返回304(NotModified)Response。
<br/>
<br/>3、Expires
<br/>给出的日期/时间后，被响应认为是过时。如Expires:Thu,02Apr201205:14:08GMT
<br/>需和Last-Modified结合使用。用于控制请求文件的有效时间，当请求数据在有效期内时客户端浏览器从缓存请求数据而不是服务器端.当缓存中数据失效或过期，才决定从服务器更新数据。
<br/>
<br/>　　4、Last-Modified和Expires
<br/>　　Last-Modified标识能够节省一点带宽，但是还是逃不掉发一个HTTP请求出去，而且要和Expires一起用。而Expires标识却使得浏览器干脆连HTTP请求都不用发，比如当用户F5或者点击Refresh按钮的时候就算对于有Expires的URI，一样也会发一个HTTP请求出去，所以，Last-Modified还是要用的，而且要和Expires一起用。
<br/>
<br/>　　5、Etag和Expires
<br/>　　如果服务器端同时设置了Etag和Expires时，Etag原理同样，即与Last-Modified/Etag对应的HttpRequestHeader:If-Modified-Since和If-None-Match。我们可以看到这两个Header的值和WebServer发出的Last-Modified,Etag值完全一样；在完全匹配If-Modified-Since和If-None-Match即检查完修改时间和Etag之后，服务器才能返回304.
<br/>
<br/>6、Last-Modified和Etag
<br/>Last-Modified和ETags请求的http报头一起使用，服务器首先产生Last-Modified/Etag标记，服务器可在稍后使用它来判断页面是否已经被修改，来决定文件是否继续缓存
<br/>
<br/>过程如下:
<br/>1.客户端请求一个页面（A）。
<br/>2.服务器返回页面A，并在给A加上一个Last-Modified/ETag。
<br/>3.客户端展现该页面，并将页面连同Last-Modified/ETag一起缓存。
<br/>4.客户再次请求页面A，并将上次请求时服务器返回的Last-Modified/ETag一起传递给服务器。
<br/>5.服务器检查该Last-Modified或ETag，并判断出该页面自上次客户端请求之后还未被修改，直接返回响应304和一个空的响应体。
<br/>
<br/>注：
<br/>1、Last-Modified和Etag头都是由WebServer发出的HttpReponseHeader，WebServer应该同时支持这两种头。
<br/>2、WebServer发送完Last-Modified/Etag头给客户端后，客户端会缓存这些头；
<br/>3、客户端再次发起相同页面的请求时，将分别发送与Last-Modified/Etag对应的HttpRequestHeader:If-Modified-Since和If-None-Match。我们可以看到这两个Header的值和WebServer发出的Last-Modified,Etag值完全一样；
<br/>4、通过上述值到服务器端检查，判断文件是否继续缓存；
<br/>
<br/>二、Apache、Lighttpd和Nginx中针配置Etag和Expires，有效缓存纯静态如css/js/pic/页面/流媒体等文件。
<br/>
<br/>A、Expires
<br/>A.1、ApacheEtag
<br/>使用Apache的mod_expires模块来设置，这包括控制应答时的Expires头内容和Cache-Control头的max-age指令
<br/>
<br/>1.ExpiresActiveOn
<br/>2.ExpiresByTypeimage/gif“accessplus1month”
<br/>3.ExpiresByTypeimage/jpg“accessplus1month”
<br/>4.ExpiresByTypeimage/jpeg“accessplus1month”
<br/>5.ExpiresByTypeimage/x-icon“accessplus1month”
<br/>6.ExpiresByTypeimage/bmp“accessplus1month”
<br/>7.ExpiresByTypeimage/png“accessplus1month”
<br/>8.ExpiresByTypetext/html“accessplus30minutes”
<br/>9.ExpiresByTypetext/css“accessplus30minutes”
<br/>10.ExpiresByTypetext/txt“accessplus30minutes”
<br/>11.ExpiresByTypetext/js”accessplus30minutes”
<br/>12.ExpiresByTypeapplication/x-javascript”accessplus30minutes”
<br/>13.ExpiresByTypeapplication/x-shockwave-flash”accessplus30minutes”
<br/>或
<br/>1.&lt;ifmodulemod_expires.c&gt;
<br/>2.&lt;filesmatch“\.(jpg|gif|png|css|js)$”&gt;
<br/>3.ExpiresActiveon
<br/>4.ExpiresDefault“accessplus1year”
<br/>5.&lt;/filesmatch&gt;
<br/>6.&lt;/ifmodule&gt;
<br/>
<br/>当设置了expires后，会自动输出Cache-Control的max-age信息
<br/>具体关于Expires详细内容可以查看Apache官方文档。
<br/>
<br/>在这个时间段里，该文件的请求都将直接通过缓存服务器获取，当然如果需要忽略浏览器的刷新请求（F5)，缓存服务器squid还需要使用refresh_pattern选项来忽略该请求
<br/>
<br/>1.refresh_pattern-i\.gif$1440100%28800ignore-reload
<br/>2.refresh_pattern-i\.jpg$1440100%28800ignore-reload
<br/>3.refresh_pattern-i\.jpeg$1440100%28800ignore-reload
<br/>4.refresh_pattern-i\.png$1440100%28800ignore-reload
<br/>5.refresh_pattern-i\.bmp$1440100%28800ignore-reload
<br/>6.refresh_pattern-i\.htm$60100%100ignore-reload
<br/>7.refresh_pattern-i\.html$144050%28800ignore-reload
<br/>8.refresh_pattern-i\.xml$144050%28800ignore-reload
<br/>9.refresh_pattern-i\.txt$144050%28800ignore-reload
<br/>10.refresh_pattern-i\.css$144050%28800reload-into-ims
<br/>11.refresh_pattern-i\.js$6050%100reload-into-ims
<br/>12.refresh_pattern.1050%60
<br/>
<br/>有关Squid中Expires的说明，请参考Squid官方中refresh_pattern介绍。
<br/>
<br/>A.2、LighttpdExpires
<br/>和Apache一样Lighttpd设置expire也要先查看是否支持了mod_expire模块，
<br/>下面的设置是让URI中所有images目录下的文件1小时后过期；
<br/>
<br/>1.expire.url=(“/images/”=&gt;“access1hours”)
<br/>
<br/>下面是让作用于images目录及其子目录的文件；
<br/>
<br/>1.$HTTP[&quot;url&quot;]=~“^/images/”{
<br/>2.expire.url=(“”=&gt;“access1hours”)
<br/>3.}
<br/>
<br/>也可以指定文件的类型；
<br/>1.$HTTP[&quot;url&quot;]=~“\.(jpg|gif|png|css|js)$”{
<br/>2.expire.url=(“”=&gt;“access1hours”)
<br/>3.}
<br/>
<br/>具体参考Lighttpd官方Expires解释
<br/>
<br/>A.3、Nginx中Expires
<br/>
<br/>1.location~.*\.(gif|jpg|jpeg|png|bmp|swf)$
<br/>2.{
<br/>3.expires30d;
<br/>4.}
<br/>5.location~.*\.(js|css)?$
<br/>6.{
<br/>7.expires1h;
<br/>8.}
<br/>
<br/>这类文件并不常修改，通过expires指令来控制其在浏览器的缓存，以减少不必要的请求。expires指令可以控制HTTP应答中的“Expires”和“Cache-Control”的头标（起到控制页面缓存的作用）。其他请参考Nginx中Expires
<br/>
<br/>B.1、Apache中Etag设置
<br/>在Apache中设置Etag的支持比较简单，只用在含有静态文件的目录中建立一个文件.htaccess,里面加入：
<br/>FileETagMTimeSize
<br/>这样就行了，详细的可以参考Apache的FileEtag文档页
<br/>
<br/>B.2、LighttpdEtag
<br/>在Lighttpd中设置Etag支持：
<br/>etag.use-inode:是否使用inode作为Etag
<br/>etag.use-mtime:是否使用文件修改时间作为Etag
<br/>etag.use-size:是否使用文件大小作为Etag
<br/>static-file.etags:是否启用Etag的功能
<br/>第四个参数肯定是要enable的，前面三个就看实际的需要来选吧，推荐使用修改时间
<br/>
<br/>B.3、NginxEtag
<br/>Nginx中默认没有添加对Etag标识.IgorSysoev的观点”在对静态文件处理上看不出如何Etag好于Last-Modified标识。”
<br/>Note:
<br/>Yes,it’saddition,andit’seasytoadd,however,IdonotseehowETagisbetterthanLast-Modifiedforstaticfiles.-IgorSysoev
<br/>Aniceshortdescriptionishere:
<br/>http://www.mnot.net/cache_docs/#WORK
<br/>Itlookstomethatitmakessomecachesouttheretocachetheresponsefromtheoriginservermorereliableasinrfc2616(ftp://ftp.rfc-editor.org/in-notes/rfc2616.txt)iswritten.
<br/>3.11EntityTags13.3.2EntityTagCacheValidators14.19ETag
<br/>当然也有第三方nginx-static-etags模块了，请参考
<br/>http://mikewest.org/2008/11/generating-etags-for-static-content-using-nginx
<br/>
<br/>三、对于非实时交互动态页面中Epires和Etag处理
<br/>对数据更新并不频繁、如tag分类归档等等，可以考虑对其cache。简单点就是在非实时交互的动态程序中输出expires和etag标识，让其缓存。但需要注意关闭session，防止httpresponse时httpheader包含sessionid标识；
<br/>
<br/>3.1、Expires
<br/>如expires.php
<br/>
<br/>1.&lt;?php
<br/>2.header(’Cache-Control:max-age=86400,must-revalidate’);
<br/>3.header(’Last-Modified:‘.gmdate(’D,dMYH:i:s’).‘GMT’);
<br/>4.header(”Expires:”.gmdate(’D,dMYH:i:s’,time()+‘86400′).‘GMT’);
<br/>5.?&gt;
<br/>
<br/>以上信息表示该文件自请求后24小时后过期。
<br/>其他需要处理的动态页面直接调用即可。
<br/>
<br/>3.2、Etag
<br/>根据Http返回状态来处理。当返回304直接从缓存中读取
<br/>如etag.php
<br/>1.&lt;?php
<br/>2.cache();
<br/>3.echodate(”Y-m-dH:i:s”);
<br/>4.functioncache()
<br/>5.{
<br/>6.$etag=“http://longrujun.name”;
<br/>7.if($_SERVER['HTTP_IF_NONE_MATCH']==$etag)
<br/>8.{
<br/>9.header(’Etag:’.$etag,true,304);
<br/>10.exit;
<br/>11.}
<br/>12.elseheader(’Etag:’.$etag);
<br/>13.}
<br/>14.?&gt;]]></description>
		<pubDate>Tue, 17 Apr 2012 17:18:37 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[用php操作redis队列实例讲解]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail1179.shtml]]></link>
		<description><![CDATA[用php操作redis队列实例讲解：
<br/>redis简介：
<br/>Redis是一个比较高级的开源key-value存储系统，采用ANSIC实现。其与memcached类似，但是支持持久化数据存储，同时value支持多种类型：字符串（同memcached中的value），列表，集合(Set)，有序集合(OrderSet)和Hash。所有的值类型均支持原子操作，如列表中追加弹出元素，集合中插入移除元素等。Rdids的数据大部分位于内存中，其读写效率非常高，其提供AOF（追加式操作记录文件）和DUMP（定期数据备份）两种持久化方式。Redis支持自定义的VM（虚拟内存）机制，当数据容量超过内存时，可以将部分Value存储到文件中。同时Redis支持Master-Slave机制，可以进行数据复制。
<br/>可以把Redis的list结构当队列来用.
<br/>从上面Redis的场景和作用来说，对于我们现在的开发活动，究竟能把Redis引入在那些场景，而不是把这么好的东东演变成“为了使用Redis，而Redis”的惨烈局面呢？当然，具体问题具体分析，这个真的很重要哈。
<br/>缓存？分布式缓存？队列？分布式队列？
<br/>某些系统应用（例如，电信、银行和大型互联网应用等）都会使用到，当然，现在大行其道的memcache就是很好的证明；但从某一方面来说，memcache是否能把两张囊括其中，而且能做到更好（没有实际的应用过，所以只是抛出）。但从Redis身上，我就能感觉到，Redis，就能把队列和缓存两张都囊括其中，而且都不会产生并发环境下的困扰，因为Redis中的操作都是原子操作来着。
<br/>下面开始说说Redis中的队列（分布式）。
<br/>状况场景：
<br/>现在的项目，都是部署在多个服务器，或者多个IP上，而且前台经由F5分发，所以用户的请求究竟落在那一台的服务器上，是无法确定的。对于项目中，有一秒杀设计，刚开始没有考虑到这种部署，同时也是使用最容易处理的方式，直接给数据库表锁行记录（Oracle上的）。可以说，对于不同的应用部署，而只有一台数据库服务器来说，很“轻松”的就解决了这个并发的问题。所以现在考虑一下，是不是挪到应用上，避免数据库服务器也掺杂到业务上。
<br/>比如，现在有2台应用服务器，1台数据库服务器。想法是，把Redis部署在数据库服务器上，两台服务器在操作并发缓存或者队列时，先从Redis服务器上取得在两台应用服务器的代理对象，再做入列出列的操作。
<br/>入队操作代码
<br/>&lt;?php
<br/>$redis=newRedis();
<br/>$redis-&gt;connect('127.0.0.1',6379);
<br/>while(True){
<br/>try{
<br/>$value='value_'.date('Y-m-dH:i:s');
<br/>$redis-&gt;LPUSH('key1',$value);
<br/>sleep(rand()%3);
<br/>echo$value.&quot;\n&quot;;
<br/>}catch(Exception$e){
<br/>echo$e-&gt;getMessage().&quot;\n&quot;;
<br/>}
<br/>}
<br/>?&gt;
<br/>
<br/>出队操作代码
<br/>&lt;?php
<br/>$redis=newRedis();
<br/>$redis-&gt;pconnect('127.0.0.1',6379);
<br/>while(True){
<br/>try{
<br/>echo$redis-&gt;LPOP('key1').&quot;\n&quot;;
<br/>}catch(Exception$e){
<br/>echo$e-&gt;getMessage().&quot;\n&quot;;
<br/>}
<br/>sleep(rand()%3);
<br/>}?&gt;
<br/>入队列操作文件list_push.php
<br/>&lt;?php
<br/>$redis=getRedisInstance();//从Redis服务器拿到redis实例
<br/>$redis-&gt;connect('Redis服务器IP',6379);
<br/>while(true){
<br/>$redis-&gt;lPush('list1','A_'.date('Y-m-dH:i:s'));
<br/>sleep(rand()%3);
<br/>}
<br/>?&gt;
<br/>
<br/>执行#phplist_push.php&amp;
<br/>出队列操作list_pop.php文件
<br/>&lt;?php
<br/>$redis=getRedisInstance();//从Redis服务器拿到redis实例
<br/>$redis-&gt;pconnect('Redis服务器IP',6379);
<br/>while(true){
<br/>try{
<br/>var_export($redis-&gt;blPop('list1',10));
<br/>}catch(Exception$e){
<br/>//echo$e;
<br/>}
<br/>}
<br/>
<br/>用Python实现：
<br/>1.入队列（write.py）
<br/>#!/usr/bin/envpython
<br/>importtime
<br/>fromredisimportRedis
<br/>redis=Redis(host='127.0.0.1',port=6379)
<br/>whileTrue:
<br/>now=time.strftime(&quot;%Y/%m/%d%H:%M:%S&quot;)
<br/>redis.lpush('test_queue',now)
<br/>time.sleep(1)
<br/>
<br/>2.出队列（read.py）
<br/>#!/usr/bin/envpython
<br/>importsys
<br/>fromredisimportRedis
<br/>redis=Redis(host='127.0.0.1',port=6379)
<br/>whileTrue:
<br/>res=redis.rpop('test_queue')
<br/>ifres==None:
<br/>pass
<br/>else:
<br/>printstr(res)
<br/>在操作时，注意，要操作的是同一个list对象。]]></description>
		<pubDate>Sun, 15 Apr 2012 20:58:38 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[php中exit和return、break和contiue的用法区别]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail1178.shtml]]></link>
		<description><![CDATA[php中exit和return、break和contiue的用法区别：
<br/>exit函数的用法：
<br/>语法：
<br/>voidexit([stringstatus])
<br/>voidexit(intstatus)
<br/>作用：输出一则消息并且终止当前脚本。
<br/>如果一段文本中包括多个以结束的脚本，则exit退出当前所在脚本。
<br/>比如一篇php文本包括一下代码,则输出为world。
<br/>&lt;?php
<br/>echo&quot;hello&quot;;
<br/>exit;
<br/>?&gt;
<br/>echo&quot;world&quot;;
<br/>?&gt;
<br/>语法格式：void表示没有返回值。
<br/>voidexit([string$status])
<br/>voidexit(int$status)
<br/>如果status是一段字符串，这个函数在脚本退出前打印status。
<br/>如果status是一个整数，这个整数会被作为退出状态。退出状态应该从0到254，退出状态255被PHP保留并禁止使用。状态0被用来表示成功的终止程序。
<br/>return语言结构的用法
<br/>作用：终止函数的执行和从函数中返回一个值
<br/>break和continue用在for，foreach，while，do..while或者switch结构中。
<br/>break结束当前for，foreach，while，do..while或者switch结构的执行。
<br/>break可以接受一个可选的数字参数来决定跳出几重循环。
<br/>代码如下：
<br/>&lt;?php
<br/>$arr=array('one','two','three','four','stop','five');
<br/>while(list(,$val)=each($arr)){
<br/>if($val=='stop'){
<br/>break;
<br/>}
<br/>echo&quot;$val&quot;;
<br/>}
<br/>$i=0;
<br/>while(++$i){
<br/>switch($i){
<br/>case5:
<br/>echo&quot;At5&quot;;
<br/>break1;
<br/>case10:
<br/>echo&quot;At10;quitting&quot;;
<br/>break2;
<br/>default:
<br/>break;
<br/>}
<br/>}
<br/>?&gt;
<br/>continue在循环结构用用来跳过本次循环中剩余的代码并开始执行本循环结构的下一次循环。
<br/>注:注意在PHP中switch语句被认为是作为continue目的的循环结构。
<br/>continue接受一个可选的数字参数来决定跳过几重循环到循环结尾。
<br/>代码如下：
<br/>&lt;?php
<br/>while(list($key,$value)=each($arr)){
<br/>if(!($key%2)){//skipoddmembers
<br/>continue;
<br/>}
<br/>do_something_odd($value);
<br/>}
<br/>$i=0;
<br/>while($i++&lt;5){
<br/>echo&quot;Outer&lt;br/&gt;&quot;;
<br/>while(true){
<br/>echo&quot;Middle&lt;br/&gt;&quot;;
<br/>while(true){
<br/>echo&quot;Inner&lt;br/&gt;&quot;;
<br/>continue3;
<br/>}
<br/>echo&quot;Thisnevergetsoutput.&lt;br/&gt;&quot;;
<br/>}
<br/>echo&quot;Neitherdoesthis.&lt;br/&gt;&quot;;
<br/>}
<br/>?&gt;]]></description>
		<pubDate>Thu, 12 Apr 2012 17:59:25 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[MongoDB数据库简介及用PHP连接MongoDB实例详解]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail1176.shtml]]></link>
		<description><![CDATA[MongoDB简介及用PHP连接MongoDB数据库实例详解：
<br/>MongoDB数据库是一个介于关系数据库和非关系数据库之间的产品，是非关系数据库当中功能最丰富，最像关系数据库的。他支持的数据结构非常松散，是类似json的bjson格式，因此可以存储比较复杂的数据类型。Mongo最大的特点是他支持的查询语言非常强大，其语法有点类似于面向对象的查询语言，几乎可以实现类似关系数据库单表查询的绝大部分功能，而且还支持对数据建立索引。
<br/>它的特点是高性能、易部署、易使用，存储数据非常方便。
<br/>主要功能特性有：
<br/>*支持查询。
<br/>*支持复制和故障恢复。
<br/>*面向集合存储，易存储对象类型的数据。
<br/>*模式自由。
<br/>*支持动态查询。
<br/>*支持完全索引，包含内部对象。
<br/>*使用高效的二进制数据存储，包括大型对象（如视频等）。
<br/>*自动处理碎片，以支持云计算层次的扩展性。
<br/>*支持RUBY，PYTHON，JAVA，C++，PHP,C#等多种语言。
<br/>*文件存储格式为BSON（一种JSON的扩展）。
<br/>*可通过网络访问。
<br/>下面介绍下用php操作MongoDB数据库的例子
<br/>&lt;?php
<br/>//这里采用默认连接本机的27017端口，当然你也可以连接远程主机如192.168.0.4:27017,如果端口是27017，端口可以省略
<br/>$m=newMongo();
<br/>//选择comedy数据库，如果以前没该数据库会自动创建，也可以用$m-&gt;selectDB(&quot;comedy&quot;);
<br/>$db=$m-&gt;comedy;
<br/>//选择comedy里面的collection集合，相当于RDBMS里面的表，也-可以使用
<br/>$collection=$db-&gt;collection;
<br/>$db-&gt;selectCollection(&quot;collection&quot;);
<br/>//添加一个元素
<br/>$obj=array(&quot;title&quot;=&gt;&quot;CalvinandHobbes-&quot;.date('i:s'),&quot;author&quot;=&gt;&quot;BillWatterson&quot;);
<br/>//将$obj添加到$collection集合中
<br/>$collection-&gt;insert($obj);
<br/>//添加另一个元素
<br/>$obj=array(&quot;title&quot;=&gt;&quot;XKCD-&quot;.date('i:s'),&quot;online&quot;=&gt;true);
<br/>$collection-&gt;insert($obj);
<br/>//查询所有的记录
<br/>$cursor=$collection-&gt;find();
<br/>//遍历所有集合中的文档
<br/>foreach($cursoras$obj){
<br/>echo$obj[&quot;title&quot;].&quot;\n&quot;;
<br/>}
<br/>//删除所有数据
<br/>$collection-&gt;remove();
<br/>//删除name为hm
<br/>$collection-&gt;remove(array('name'=&gt;'hm'));
<br/>//断开MongoDB连接
<br/>$m-&gt;close();
<br/>?&gt;]]></description>
		<pubDate>Wed, 11 Apr 2012 11:41:11 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[PHP中fopen,file_get_contents,curl函数的区别]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail1172.shtml]]></link>
		<description><![CDATA[PHP中fopen,file_get_contents,curl函数的区别：
<br/>1.fopen/file_get_contents每次请求都会重新做DNS查询，并不对DNS信息进行缓存。但是CURL会自动对DNS信息进行缓存。对同一域名下的网页或者图片的请求只需要一次DNS查询。这大大减少了DNS查询的次数。所以CURL的性能比fopen/file_get_contents好很多。
<br/>2.fopen/file_get_contents在请求HTTP时，使用的是http_fopen_wrapper，不会keeplive。而curl却可以。这样在多次请求多个链接时，curl效率会好一些。
<br/>3.fopen/file_get_contents函数会受到php.ini文件中allow_url_open选项配置的影响。如果该配置关闭了，则该函数也就失效了。而curl不受该配置的影响。
<br/>4.curl可以模拟多种请求，例如：POST数据，表单提交等，用户可以按照自己的需求来定制请求。而fopen/file_get_contents只能使用get方式获取数据。
<br/>file_get_contents获取远程文件时会把结果都存在一个字符串中fiels函数则会储存成数组形式
<br/>因此，我还是比较倾向于使用curl来访问远程url。Php有curl模块扩展，功能很是强大。
<br/>做采集的时候还是推荐使用PHP的采集类Snoopy：
<br/>
<br/><ahref="http://www.phpzixue.cn/detail123.shtml">snoopy—php版的网络客户端，抓页面等</a>]]></description>
		<pubDate>Thu, 15 Mar 2012 09:55:32 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[PHP中调用Lucene包来实现全文检索的方法]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail1167.shtml]]></link>
		<description><![CDATA[PHP中调用Lucene包来实现全文检索的方法：
<br/>需要使用PHP实现对网站内大量数量进行全文检索，而且目前最流行的全文检索的搜索引擎库就是Lucene了，它是ApacheJakarta的一个子项目，并且提供了简单实用的API，用这些API，就可以对任何基本文本的数据(包括数据库)进行全文检索。
<br/>因为PHP本身就支持调用外部Java类，所以先用Java写了一个类，这个类通过调用Lucene的API，实现了两个方法：
<br/>*publicStringcreateIndex(StringindexDir_path,StringdataDir_path)
<br/>*publicStringsearchword(Stringss,Stringindex_path)
<br/>其中createIndex是创建索引方法，传入了两个参数分别是indexDir_path(索引文件的目录)，dataDir_path(被索引的文件目录)，返回被索引的文件列表字符串，另一个是searchword，通过传入的关键字参数(ss)对索引进行检索，index_path就是索引文件的目录。返回所有检索到的文件。
<br/>这里是源代码，很简单，大家可以参考一下：TxtFileIndexer.java
<br/>packageTestLucene;
<br/>importjava.io.File;importjava.io.FileReader;
<br/>importjava.io.Reader;
<br/>importjava.util.Date;
<br/>importorg.apache.lucene.analysis.Analyzer;
<br/>importorg.apache.lucene.analysis.standard.StandardAnalyzer;
<br/>importorg.apache.lucene.document.Document;
<br/>importorg.apache.lucene.document.Field;
<br/>importorg.apache.lucene.index.IndexWriter;
<br/>importorg.apache.lucene.index.Term;
<br/>importorg.apache.lucene.search.Hits;
<br/>importorg.apache.lucene.search.IndexSearcher;
<br/>importorg.apache.lucene.search.TermQuery;
<br/>importorg.apache.lucene.store.FSDirectory;
<br/>publicclassTxtFileIndexer...{
<br/>publicStringtest()...{
<br/>return&quot;testisokhohoho&quot;;
<br/>}
<br/>/**//**
<br/>*@paramargs
<br/>*/
<br/>publicStringcreateIndex(StringindexDir_path,StringdataDir_path)throwsException...{
<br/>Stringresult=&quot;&quot;;
<br/>FileindexDir=newFile(indexDir_path);
<br/>FiledataDir=newFile(dataDir_path);
<br/>AnalyzerluceneAnalyzer=newStandardAnalyzer();
<br/>File[]dataFiles=dataDir.listFiles();
<br/>IndexWriterindexWriter=newIndexWriter(indexDir,luceneAnalyzer,true);

<br/>longstartTime=newDate().getTime();
<br/>for(inti=0;i&lt;dataFiles.length;i++)...{
<br/>if(dataFiles[i].isFile()&amp;&amp;dataFiles[i].getName().endsWith(&quot;.html&quot;))...{
<br/>result+=&quot;Indexingfile&quot;+dataFiles[i].getCanonicalPath()+&quot;&lt;br/&gt;&quot;;

<br/>Documentdocument=newDocument();
<br/>ReadertxtReader=newFileReader(dataFiles[i]);
<br/>document.add(Field.Text(&quot;path&quot;,dataFiles[i].getCanonicalPath()));
<br/>document.add(Field.Text(&quot;contents&quot;,txtReader));
<br/>indexWriter.addDocument(document);
<br/>}
<br/>}

<br/>indexWriter.optimize();
<br/>indexWriter.close();
<br/>longendTime=newDate().getTime();
<br/>
<br/>result+=&quot;Ittakes&quot;+(endTime-startTime)
<br/>+&quot;millisecondstocreateindexforthefilesindirectory&quot;
<br/>+dataDir.getPath();

<br/>returnresult;
<br/>}
<br/>publicStringsearchword(Stringss,Stringindex_path)throwsException...{
<br/>StringqueryStr=ss;
<br/>Stringresult=&quot;Result:&lt;br/&gt;&quot;;
<br/>//ThisisthedirectorythathoststheLuceneindex
<br/>FileindexDir=newFile(index_path);

<br/>FSDirectorydirectory=FSDirectory.getDirectory(indexDir,false);
<br/>IndexSearchersearcher=newIndexSearcher(directory);
<br/>if(!indexDir.exists())...{
<br/>result=&quot;TheLuceneindexisnotexist&quot;;
<br/>returnresult;
<br/>}
<br/>Termterm=newTerm(&quot;contents&quot;,queryStr.toLowerCase());

<br/>TermQueryluceneQuery=newTermQuery(term);
<br/>Hitshits=searcher.search(luceneQuery);
<br/>for(inti=0;i&lt;hits.length();i++)...{
<br/>Documentdocument=hits.doc(i);
<br/>result+=&quot;&lt;br/&gt;&lt;ahref='getfile.php?w=&quot;+ss+&quot;&amp;f=&quot;+document.get(&quot;path&quot;)+&quot;'&gt;File:&quot;+document.get(&quot;path&quot;)+&quot;&lt;/a&gt;\n&quot;;

<br/>}
<br/>returnresult;
<br/>}
<br/>}
<br/>而PHP程序就调用这两个方法，实现对Lucene的调用，从而达到全文检索的目的。
<br/>PHP的调用方法如下：
<br/>先创建一个我们写的TxtFileIndexer类的实例，
<br/>$tf=newJava('TestLucene.TxtFileIndexer');
<br/>然后就按正常PHP类的调用方法的方式进行调用，首先创建索引：
<br/>&lt;?PHP
<br/>$data_path=&quot;F:/test/php_lucene/htdocs/data/manual&quot;;//定义被索引内容的目录
<br/>$index_path=&quot;F:/test/php_lucene/htdocs/data/search&quot;;//定义生成的索引文件存放目录

<br/>$s=$tf-&gt;createIndex($index_path,$data_path);//调用Java类的方法
<br/>print$s;//打印返回的结果
<br/>?&gt;
<br/>这次再试试检索：
<br/>&lt;?PHP
<br/>$index_path=&quot;F:/test/php_lucene/htdocs/data/search&quot;;//定义生成的索引文件存放目录
<br/>$s=$tf-&gt;searchword(&quot;hereiskeywordforsearch&quot;,$index_path);
<br/>print$s;
<br/>?&gt;

<br/>另外要注意Java类的路径，可以在PHP里设置
<br/>java_require(&quot;F:/test/php_lucene/htdocs/lib/&quot;);//这是个例子，我的类和Lucene都放到这个目录下，这样就可以了，是不是很简单。
<br/>PHP源代码：test.php
<br/>&lt;?php
<br/>error_reporting(0);
<br/>java_require(&quot;F:/test/php_lucene/htdocs/lib/&quot;);
<br/>$tf=newJava('TestLucene.TxtFileIndexer');
<br/>$s=$tf-&gt;test();
<br/>print&quot;TestLucene.TxtFileIndexer-&gt;test()&lt;br/&gt;&quot;.$s;

<br/>echo&quot;&lt;hr/&gt;&quot;;
<br/>$data_path=&quot;F:/test/php_lucene/htdocs/data/manual&quot;;
<br/>$index_path=&quot;F:/test/php_lucene/htdocs/data/search&quot;;
<br/>if($_GET[&quot;action&quot;]==&quot;create&quot;)...{
<br/>$s=$tf-&gt;createIndex($index_path,$data_path);
<br/>print$s;

<br/>}else...{
<br/>echo&quot;&lt;formmethod=get&gt;&lt;inputtype=textname=w/&gt;&lt;inputtype=submitvalue=search/&gt;&lt;br/&gt;&quot;;
<br/>if($_GET[&quot;w&quot;]!=&quot;&quot;)...{
<br/>$s=$tf-&gt;searchword($_GET[&quot;w&quot;],$index_path);
<br/>print$s;

<br/>}
<br/>}
<br/>?&gt;
<br/>接下来我把环境配置说一下，先需要有JavaSDK，是必须的，我使用的是1.4.2版的，其它版本应该也没问题。PHP5，试过PHP4，应该可以。由于PHP5带的Java扩展没调通，并且以前用过调用Java效率很低，很慢，所以使用了Php/JavaBridge这个项目。
<br/>1.下载JavaBridgeURL:http://sourceforge.net/projects/php-java-bridge/，目前版本是php-java-bridge_3.0.8_j2ee.zip，解包后把
<br/>a.JavaBridge\WEB-INF\cgi\java-x86-windows.dll
<br/>b.JavaBridge\WEB-INF\lib\JavaBridge.jar
<br/>复制到c:\php\ext目录下，并把java-x86-windows.dll　改名为php_java.dll
<br/>2.修改php.ini(例)
<br/>extension=php_java.dll
<br/>java.class.path=&quot;C:\php\ext\JavaBridge.jar;F:\test\php_lucene\htdocs&quot;
<br/>java.java_home=&quot;C:\j2sdk1.4.2_10&quot;

<br/>java.library.path=&quot;c:\php\ext;F:\test\php_lucene\htdocs&quot;
<br/>3.重启Apache即可。
<br/>4.可以找一些文件进行索引，在test.php里可以修改索引文件和数据文件的路径。TxtFileIndexer.java的37行限制了只索引html后缀的文件，有需要也可以修改。
<br/>根据目前的情况(JavaBridge支持Linux和Freebsd)，完全可以在linux或freebsd/apache2/php4/lucene/JavaBridge环境下运行]]></description>
		<pubDate>Thu, 30 Jun 2011 15:22:58 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[php中mysql_connect和mysql_pconnect的用法区别]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail1163.shtml]]></link>
		<description><![CDATA[php中mysql_connect和mysql_pconnect的用法区别：
<br/>主要区别在于当php以apache模块方式运行时,由于apache有使用进程池,一个httpd进程结束后会被放回进程池,这也就使得用pconnect打开的的那个mysql连接资源不被释放,于是有下一个连接请求时就可以被复用.
<br/>这就使得在apache并发访问量不大的时候,由于使用了pconnect,php节省了反复连接db的时间,使得访问速度加快.这应该是比较好理解的.
<br/>但是在apache并发访问量大的时候,如果使用pconnect,会由于之前的一些httpd进程占用的mysql连接没有close,则可能会因为mysql已经达到最大连接着,使得之后的一些请求永远得不到满足.
<br/>例如:
<br/>若mysql最大连接数设为500,而apache的最大同时访问数设为2000
<br/>假设所有访问都会要求访问db,而且操作时间会比较长
<br/>当前500个请求的httpd都没有结束的时候...之后的httd进程都是无法连接到mysql的(因已经达到mysql最大连接数).只有当前500个httpd进程结束或被复用才可以连接得到了mysql.
<br/>其实这个也很好解释了xgy_p的测试中若操作比较简单,pconnect比connect效率高很多,而且跟使用jsp的连接池的速度比较接近.因为这个时候httpd进程可以不断的给复用.
<br/>而当DB操作复杂,耗时较长时,因httpd会fork很多并发进程处理,而先产生的httpd进程不释放db连接,使得后产生的httpd进程无法连上db.因为这样没有复用其它httpd进程的mysql连接.于是会就产生很多连接超时,像一开始的1000个并发连接测试说几乎都是连接超时就是这个原因.
<br/>(反进来看jsp用的如果是纯粹的db连接池,则不会有因为达到mysql连接上限而连不上的问题,因为jsp的连接池会使得可以等待其它连接使用完毕并复用.)
<br/>因此在并发访问量不高时,使用pconnect可以简单提高访问速度,但在并发量增大后,是否再使用pconnect就要看程序员的选择了.]]></description>
		<pubDate>Wed, 15 Jun 2011 10:21:05 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[优化php性能的五个实用技巧]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail1161.shtml]]></link>
		<description><![CDATA[优化php性能的五个实用技巧：
<br/>以下是五个优化技巧，熟练掌握后对于开发还是很有帮助的。
<br/>1.对字符串使用单引号
<br/>PHP引擎允许使用单引号和双引号来封装字符串变量，但是这个是有很大的差别的！使用双引号的字符串告诉PHP引擎首先去读取字符串内容，查找其中的变量，并改为变量对应的值。一般来说字符串是没有变量的，所以使用双引号会导致性能不佳。最好是使用字符串连接而不是双引号字符串。
<br/>BAD:
<br/>$output=&quot;Thisisaplainstring&quot;;
<br/>GOOD:
<br/>$output='Thisisaplainstring';
<br/>BAD:
<br/>$type=&quot;mixed&quot;;
<br/>$output=&quot;Thisisa$typestring&quot;;

<br/>GOOD:
<br/>$type='mixed';
<br/>$output='Thisisa'.$type.'string';
<br/>2.不要随便就复制变量
<br/>有时候为了使PHP代码更加整洁，一些PHP新手（包括我）会把预定义好的变量复制到一个名字更简短的变量中，其实这样做的结果是增加了一倍的内存消耗，只会使程序更加慢。试想一下，在下面的例子中，如果用户恶意插入512KB字节的文字到文本输入框中，这样就会导致1MB的内存被消耗！
<br/>BAD:
<br/>$description=$_POST['description'];
<br/>echo$description;
<br/>GOOD:
<br/>echo$_POST['description'];
<br/>
<br/>3.使用echo函数来输出字符串
<br/>使用echo()函数来打印结果出了有更容易阅读之外，在下个例子中，你还可以看到有更好的性能。
<br/>BAD:
<br/>print($myVariable);
<br/>GOOD:
<br/>echo$myVariable;

<br/>
<br/>4.不要在echo中使用连接符
<br/>很多PHP程序员（有包括我）不知道在用恶臭输出多个变量的时候，其实可以使用逗号来分开的，而不必用字符串先把他们先连起来，如下面的第一个例子中，由于使用了连接符就会有性能问题，因为这样就会需要PHP引擎首先把所有的变量连接起来，然后在输出，而在第二个例子中，PHP引擎就会按照循序输出他们。
<br/>BAD:
<br/>echo'Hello,mynameis'.$firstName.$lastName.'andIlivein'.$city;
<br/>GOOD:
<br/>echo'Hello,mynameis',$firstName,$lastName,'andIlivein',$city;
<br/>
<br/>5.使用switch/case代替if/else
<br/>对于只有单个变量的判断，使用switch/case语句而不是if/else语句，会有更好的性能，并且代码更加容易阅读和维护。
<br/>BAD:
<br/>if($_POST['action']=='add'){
<br/>addUser();
<br/>}elseif($_POST['action']=='delete'){
<br/>deleteUser();

<br/>}elseif($_POST['action']=='edit'){
<br/>editUser();
<br/>}else{
<br/>defaultAction();
<br/>}
<br/>GOOD:
<br/>switch($_POST['action']){
<br/>case'add':
<br/>addUser();
<br/>break;
<br/>case'delete':
<br/>deleteUser();

<br/>break;
<br/>case'edit':
<br/>editUser();
<br/>break;
<br/>default:
<br/>defaultAction();
<br/>break;
<br/>}]]></description>
		<pubDate>Tue, 31 May 2011 10:05:21 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[php中Socket用法简介]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail1160.shtml]]></link>
		<description><![CDATA[php中Socket用法简介：
<br/>◇Socket基础
<br/>◇产生一个服务器
<br/>◇产生一个客户端
<br/>在这一章里你将了解到迷人而又让人容易糊涂的套接字（Sockets）。Sockets在PHP中是没有充分利用的功能。今天你将看到产生一个能使用客户端连接的服务器，并在客户端使用socket进行连接，服务器端将详细的处理信息发送给客户端。
<br/>当你看到完整的socket过程，那么你将会在以后的程序开发中使用它。这个服务器是一个能让你连接的HTTP服务器，客户端是一个Web浏览器，这是一个单一的客户端/服务器的关系。
<br/>◆　Socket基础
<br/>PHP使用Berkley的socket库来创建它的连接。你可以知道socket只不过是一个数据结构。你使用这个socket数据结构去开始一个客户端和服务器之间的会话。这个服务器是一直在监听准备产生一个新的会话。当一个客户端连接服务器，它就打开服务器正在进行监听的一个端口进行会话。这时，服务器端接受客户端的连接请求，那么就进行一次循环。现在这个客户端就能够发送信息到服务器，服务器也能发送信息给客户端。
<br/>产生一个Socket，你需要三个变量：一个协议、一个socket类型和一个公共协议类型。产生一个socket有三种协议供选择，继续看下面的内容来获取详细的协议内容。
<br/>定义一个公共的协议类型是进行连接一个必不可少的元素。下面的表我们看看有那些公共的协议类型。
<br/>表一：协议
<br/>名字/常量描述
<br/>AF_INET这是大多数用来产生socket的协议，使用TCP或UDP来传输，用在IPv4的地址
<br/>AF_INET6与上面类似，不过是来用在IPv6的地址
<br/>AF_UNIX本地协议，使用在Unix和Linux系统上，它很少使用，一般都是当客户端和服务器在同一台及其上的时候使用
<br/>表二：Socket类型
<br/>名字/常量描述

<br/>SOCK_STREAM这个协议是按照顺序的、可靠的、数据完整的基于字节流的连接。这是一个使用最多的socket类型，这个socket是使用TCP来进行传输。
<br/>SOCK_DGRAM这个协议是无连接的、固定长度的传输调用。该协议是不可靠的，使用UDP来进行它的连接。
<br/>SOCK_SEQPACKET这个协议是双线路的、可靠的连接，发送固定长度的数据包进行传输。必须把这个包完整的接受才能进行读取。
<br/>SOCK_RAW这个socket类型提供单一的网络访问，这个socket类型使用ICMP公共协议。（ping、traceroute使用该协议）
<br/>SOCK_RDM这个类型是很少使用的，在大部分的操作系统上没有实现，它是提供给数据链路层使用，不保证数据包的顺序
<br/>表三：公共协议
<br/>名字/常量描述
<br/>ICMP互联网控制消息协议，主要使用在网关和主机上，用来检查网络状况和报告错误信息
<br/>UDP用户数据报文协议，它是一个无连接，不可靠的传输协议
<br/>TCP传输控制协议，这是一个使用最多的可靠的公共协议，它能保证数据包能够到达接受者那儿，如果在传输过程中发生错误，那么它将重新发送出错数据包。
<br/>现在你知道了产生一个socket的三个元素，那么我们就在php中使用socket_create()函数来产生一个socket。这个socket_create()函数需要三个参数：一个协议、一个socket类型、一个公共协议。socket_create()函数运行成功返回一个包含socket的资源类型，如果没有成功则返回false。
<br/>Resourecesocket_create(intprotocol,intsocketType,intcommonProtocol);
<br/>现在你产生一个socket，然后呢？php提供了几个操纵socket的函数。你能够绑定socket到一个IP，监听一个socket的通信，接受一个socket；现在我们来看一个例子，了解函数是如何产生、接受和监听一个socket。
<br/>&lt;?php
<br/>$commonProtocol=getprotobyname(“tcp”);
<br/>$socket=socket_create(AF_INET,SOCK_STREAM,$commonProtocol);
<br/>socket_bind($socket,‘localhost’,1337);

<br/>socket_listen($socket);
<br/>//Moresocketfunctionalitytocome
<br/>?&gt;
<br/>上面这个例子产生一个你自己的服务器端。例子第一行，
<br/>$commonProtocol=getprotobyname(“tcp”);
<br/>使用公共协议名字来获取一个协议类型。在这里使用的是TCP公共协议，如果你想使用UDP或者ICMP协议，那么你应该把getprotobyname()函数的参数改为“udp”或“icmp”。还有一个可选的办法是不使用getprotobyname()函数而是指定SOL_TCP或SOL_UDP在socket_create()函数中。
<br/>$socket=socket_create(AF_INET,SOCK_STREAM,SOL_TCP);
<br/>例子的第二行是产生一个socket并且返回一个socket资源的实例。在你有了一个socket资源的实例以后，你就必须把socket绑定到一个IP地址和某一个端口上。
<br/>socket_bind($socket,‘localhost’,1337);
<br/>在这里你绑定socket到本地计算机（127.0.0.1）和绑定socket到你的1337端口。然后你就需要监听所有进来的socket连接。
<br/>socket_listen($socket);
<br/>在第四行以后，你就需要了解所有的socket函数和他们的使用。
<br/>表四：Socket函数
<br/>函数名描述
<br/>socket_accept()接受一个Socket连接
<br/>socket_bind()把socket绑定在一个IP地址和端口上

<br/>socket_clear_error()清除socket的错误或者最后的错误代码
<br/>socket_close()关闭一个socket资源
<br/>socket_connect()开始一个socket连接
<br/>socket_create_listen()在指定端口打开一个socket监听
<br/>socket_create_pair()产生一对没有区别的socket到一个数组里
<br/>socket_create()产生一个socket，相当于产生一个socket的数据结构
<br/>socket_get_option()获取socket选项
<br/>socket_getpeername()获取远程类似主机的ip地址
<br/>socket_getsockname()获取本地socket的ip地址
<br/>socket_iovec_add()添加一个新的向量到一个分散/聚合的数组
<br/>socket_iovec_alloc()这个函数创建一个能够发送接收读写的iovec数据结构
<br/>socket_iovec_delete()删除一个已经分配的iovec
<br/>socket_iovec_fetch()返回指定的iovec资源的数据
<br/>socket_iovec_free()释放一个iovec资源
<br/>socket_iovec_set()设置iovec的数据新值
<br/>socket_last_error()获取当前socket的最后错误代码
<br/>socket_listen()监听由指定socket的所有连接
<br/>socket_read()读取指定长度的数据
<br/>socket_readv()读取从分散/聚合数组过来的数据
<br/>socket_recv()从socket里结束数据到缓存
<br/>socket_recvfrom()接受数据从指定的socket，如果没有指定则默认当前socket
<br/>socket_recvmsg()从iovec里接受消息
<br/>socket_select()多路选择
<br/>socket_send()这个函数发送数据到已连接的socket
<br/>socket_sendmsg()发送消息到socket
<br/>socket_sendto()发送消息到指定地址的socket
<br/>socket_set_block()在socket里设置为块模式
<br/>socket_set_nonblock()socket里设置为非块模式
<br/>socket_set_option()设置socket选项
<br/>socket_shutdown()这个函数允许你关闭读、写、或者指定的socket
<br/>socket_strerror()返回指定错误号的详细错误
<br/>socket_write()写数据到socket缓存
<br/>socket_writev()写数据到分散/聚合数组
<br/>(注:函数介绍删减了部分原文内容，函数详细使用建议参考英文原文，或者参考PHP手册)

<br/>以上所有的函数都是PHP中关于socket的，使用这些函数，你必须把你的socket打开，如果你没有打开，请编辑你的php.ini文件，去掉下面这行前面的注释：
<br/>extension=php_sockets.dll
<br/>如果你无法去掉注释，那么请使用下面的代码来加载扩展库：
<br/>&lt;?php
<br/>if(!extension_loaded(sockets)){
<br/>if(strtoupper(substr(PHP_OS,3))==WIN){
<br/>dl(php_sockets.dll);
<br/>}else{
<br/>dl(sockets.so);
<br/>}
<br/>}
<br/>?&gt;

<br/>如果你不知道你的socket是否打开，那么你可以使用phpinfo()函数来确定socket是否打开。你通过查看phpinfo信息了解socket是否打开。如下图：
<br/>查看phpinfo()关于socket的信息
<br/>◆　产生一个服务器
<br/>现在我们把第一个例子进行完善。你需要监听一个指定的socket并且处理用户的连接。
<br/>&lt;?php
<br/>$commonProtocol=getprotobyname(&quot;tcp&quot;);
<br/>$socket=socket_create(AF_INET,SOCK_STREAM,$commonProtocol);
<br/>socket_bind($socket,'localhost',1337);
<br/>socket_listen($socket);
<br/>//Acceptanyincomingconnectionstotheserver

<br/>$connection=socket_accept($socket);
<br/>if($connection){
<br/>socket_write($connection,&quot;Youhaveconnectedtothesocket...\n\r&quot;);
<br/>}
<br/>?&gt;
<br/>你应该使用你的命令提示符来运行这个例子。理由是因为这里将产生一个服务器，而不是一个Web页面。如果你尝试使用Web浏览器来运行这个脚本，那么很有可能它会超过30秒的限时。你可以使用下面的代码来设置一个无限的运行时间，但是还是建议使用命令提示符来运行。
<br/>set_time_limit(0);
<br/>在你的命令提示符中对这个脚本进行简单测试：
<br/>Php.exeexample01_server.php
<br/>如果你没有在系统的环境变量中设置php解释器的路径，那么你将需要给php.exe指定详细的路径。当你运行这个服务器端的时候，你能够通过远程登陆（telnet）的方式连接到端口1337来测试这个服务器。
<br/>
<br/>上面的服务器端有三个问题：1.它不能接受多个连接。2.它只完成唯一的一个命令。3.你不能通过Web浏览器连接这个服务器。
<br/>这个第一个问题比较容易解决，你可以使用一个应用程序去每次都连接到服务器。但是后面的问题是你需要使用一个Web页面去连接这个服务器，这个比较困难。你可以让你的服务器接受连接，然后些数据到客户端（如果它一定要写的话），关闭连接并且等待下一个连接。
<br/>在上一个代码的基础上再改进，产生下面的代码来做你的新服务器端：
<br/>&lt;?php
<br/>//Setupoursocket
<br/>$commonProtocol=getprotobyname(&quot;tcp&quot;);
<br/>$socket=socket_create(AF_INET,SOCK_STREAM,$commonProtocol);
<br/>socket_bind($socket,'localhost',1337);

<br/>socket_listen($socket);
<br/>//Initializethebuffer
<br/>$buffer=&quot;NODATA&quot;;
<br/>while(true){
<br/>//Acceptanyconnectionscominginonthissocket
<br/>$connection=socket_accept($socket);
<br/>printf(&quot;Socketconnected\r\n&quot;);

<br/>//Checktoseeifthereisanythinginthebuffer
<br/>if($buffer!=&quot;&quot;){
<br/>printf(&quot;Somethingisinthebuffer...sendingdata...\r\n&quot;);
<br/>socket_write($connection,$buffer.&quot;\r\n&quot;);
<br/>printf(&quot;Wrotetosocket\r\n&quot;);

<br/>}else{
<br/>printf(&quot;NoDatainthebuffer\r\n&quot;);
<br/>}
<br/>//Gettheinput
<br/>while($data=socket_read($connection,1024,PHP_NORMAL_READ)){
<br/>$buffer=$data;
<br/>socket_write($connection,&quot;InformationReceived\r\n&quot;);

<br/>printf(&quot;Buffer:&quot;.$buffer.&quot;\r\n&quot;);
<br/>}
<br/>socket_close($connection);
<br/>printf(&quot;Closedthesocket\r\n\r\n&quot;);

<br/>}
<br/>?&gt;
<br/>
<br/>这个服务器端要做什么呢？它初始化一个socket并且打开一个缓存收发数据。它等待连接，一旦产生一个连接，它将打印“Socketconnected”在服务器端的屏幕上。这个服务器检查缓冲区，如果缓冲区里有数据，它将把数据发送到连接过来的计算机。然后它发送这个数据的接受信息，一旦它接受了信息，就把信息保存到数据里，并且让连接的计算机知道这些信息，最后关闭连接。当连接关闭后，服务器又开始处理下一次连接。
<br/>◆　产生一个客户端
<br/>处理第二个问题是很容易的。你需要产生一个php页连接一个socket，发送一些数据进它的缓存并处理它。然后你又个处理后的数据在还顿，你能够发送你的数据到服务器。在另外一台客户端连接，它将处理那些数据。
<br/>下面的例子示范了使用socket：
<br/>&lt;?php
<br/>//Createthesocketandconnect
<br/>$socket=socket_create(AF_INET,SOCK_STREAM,SOL_TCP);
<br/>$connection=socket_connect($socket,’localhost’,1337);
<br/>while($buffer=socket_read($socket,1024,PHP_NORMAL_READ))

<br/>{
<br/>if($buffer==“NODATA”)
<br/>{
<br/>echo(“&lt;p&gt;NODATA&lt;/p&gt;”);
<br/>break;
<br/>}
<br/>else

<br/>{
<br/>//Dosomethingwiththedatainthebuffer
<br/>echo(“&lt;p&gt;BufferData:“.$buffer.“&lt;/p&gt;”);
<br/>}
<br/>}
<br/>echo(“&lt;p&gt;WritingtoSocket&lt;/p&gt;”);
<br/>//Writesometestdatatooursocket
<br/>if(!socket_write($socket,“SOMEDATA\r\n”))
<br/>{
<br/>echo(“&lt;p&gt;Writefailed&lt;/p&gt;”);
<br/>}
<br/>//Readanyresponsefromthesocket
<br/>while($buffer=socket_read($socket,1024,PHP_NORMAL_READ))

<br/>{
<br/>echo(“&lt;p&gt;Datasentwas:SOMEDATA&lt;br&gt;Responsewas:”.$buffer.“&lt;/p&gt;”);
<br/>}
<br/>echo(“&lt;p&gt;DoneReadingfromSocket&lt;/p&gt;”);

<br/>?&gt;
<br/>这个例子的代码演示了客户端连接到服务器。客户端读取数据。如果这是第一时间到达这个循环的首次连接，这个服务器将发送“NODATA”返回给客户端。如果情况发生了，这个客户端在连接之上。客户端发送它的数据到服务器，数据发送给服务器，客户端等待响应。一旦接受到响应，那么它将把响应写到屏幕上。
<br/>结合Socket的坦克大战
<br/>（因为是描述游戏和socket结合，跟本文联系不大，所以不翻译，建议参考英文原文）
<br/>翻译文章的初衷是因为我个人对socket非常感兴趣，而且目前国内见php的文章比较少，除了php手册里面的部分内容，所以在我看了《PHPGameProgramming》这本书里有关于socket的内容后毅然决定要翻译，我知道翻译出来的质量不行，还请见谅。
<br/>另外，我在《CorePHPProgramming》ThirdEdition中也发现里面的Socket内容讲的不错，如果有空，我想也许我会把它也给翻译一下。这是我第一次翻译文章，花了我近五个小时，文章可以说是错误百出，如果翻译的不合理请见谅，如果有兴趣提高这个内容可以给我发邮件。这个凌晨时分，竟然无法入眠，不知道是不是在其他角落，也有人同我一样。]]></description>
		<pubDate>Tue, 31 May 2011 09:56:12 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[php下用PHPExcelParser工具读取excel数据]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail1159.shtml]]></link>
		<description><![CDATA[php下用PHPExcelParser工具读取excel数据：
<br/>偶尔发现了一个不错的读取excel的工具PHPExcelParser，现在介绍一下，需要的可以参考一下。
<br/>一，PHPExcelParser有以下3个特点
<br/>1，下载的PHPExcelParser里面有一个，比较详细的使用手册，告诉你什么方法是干什么用的。
<br/>2，不光可能可以把excel文件中的内容，读取出来，而且可以直接入库
<br/>3，含有实例，可以照葫芦画瓢
<br/>二，讲解一下PHPExcelParser实例的一些代码
<br/>requires'excelparser.php';//包括解释excel的核心文件
<br/>$excel=newExcelFileParser(&quot;debug.log&quot;,ABC_NO_LOG);//生成一个读取句柄
<br/>$error_code=$excel-&gt;ParseFromFile($filename)//以文件形势来读取
<br/>//下面这种方法呢是从字符串中读取excel
<br/>$fd=fopen($filename,'rb');
<br/>$content=fread($fd,filesize($name));
<br/>fclose($fd);

<br/>$error_code=$excel-&gt;ParseFromString($content);
<br/>unset($content,$fd);
<br/>//返回的错误编码
<br/>0-没有错误
<br/>1-不能打开文件
<br/>2-文件太小
<br/>3-读取excel头信息出错
<br/>4-文件读取错误
<br/>5-不是excel文件，或者版本早excel5.0
<br/>6-文件已损坏

<br/>7-没有数据
<br/>8-文件版本未知
<br/>array$excel-&gt;worksheet//读取工作薄，就是读取sheet
<br/>$excel-&gt;worksheet['name']//工作薄数组
<br/>boolean$excel-&gt;worksheet['unicode'][$worksheet_number]//工作薄名是不是unicode的形势
<br/>string$excel-&gt;worksheet['name'][$worksheet_number]//得到工作薄名
<br/>array$exc-&gt;worksheet['data'][$worksheet_number]['cell']//工作薄中的大数据块，他由一个小的数据块组成
<br/>int$exc-&gt;worksheet['data'][$worksheet_number]['max_row']//单个工作薄中的最大行数，其他挺像数学里面的X轴的。
<br/>int$exc-&gt;worksheet['data'][$worksheet_number]['max_col']//单个工作薄中的最大列数，其他挺像数学里面的Y轴的。

<br/>int$exc-&gt;worksheet['data'][$worksheet_number]['cell'][$row][$col]['type']//取得数据类型
<br/>0-整型
<br/>1-字符型
<br/>2-浮点弄
<br/>3-日期型
<br/>mixed$exc-&gt;worksheet['data'][$worksheet_number]['cell'][$row][$col]['data']
<br/>int$exc-&gt;worksheet['data'][$worksheet_number]['cell'][$row][$col]['font']//取得字体的类型索引
<br/>$font=$excel-&gt;fonts[$index];//根据索引来得到excel小数据库的字体数据
<br/>$font['size']-//字体大小
<br/>$font['italic']-//是不是斜体
<br/>$font['strikeout']
<br/>$font['bold']//是不是粗体
<br/>$font['script']

<br/>$font['underline']-//下划线
<br/>$font['name']-//字体名称
<br/>array$excel-&gt;sst//包涵数据的数组
<br/>boolean$excel-&gt;sst['unicode'][$ind]//数据是压缩还是没有压缩的
<br/>string$excel-&gt;sst['data'][$ind]//读取数据
<br/>$excel-&gt;xls2tstamp($xlsdate)//将日期转成时间戳
<br/>$ret=$excel-&gt;getDateArray($xlsdate);//取得日期数组
<br/>$ret['day']=天.
<br/>$ret['month']=月.
<br/>$ret['year']=年.
<br/>从excel中读取数据，就像在excel里面扣东西一样。又很像数学里的X轴，Y轴，X，Y轴交叉的地方就是一个数据点，在这里也是。]]></description>
		<pubDate>Tue, 17 May 2011 15:51:50 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[php新手入门的学习方法]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail1155.shtml]]></link>
		<description><![CDATA[php新手入门的学习方法：
<br/>本人经常在QQ群里或论坛上看到有人问如何才能学好php。是自学还是报一些培训班之类的问题。在我看来自学完全可以，本人就是自己的，现在网络这么发达，到网上多搜一些资料，看看别人写的代码都是对自己的一个提高。
<br/>其实每个人的学习方式不同，写这篇文章的目的是分享一下自己的学习过程，仅供参考，不要一味的用别人的学习方法，找对自己有用的学习方式
<br/>经常在某些论坛和QQ群里看到一些朋友会问“怎样才能学好PHP，怎样才能学好***语言”，但别人回答最多的是：从最“简单”的开始。
<br/>这个简单也许真的不简单，呵呵。下面我想分享一下自己学习的一些过程。先说些费话，语言组织能力差，说了不少费话，愿意看的就看，不要骂我就行
<br/>其实学习一门新语言并不是太难，重要的是你有没有准备好去学好它，时间的长短和个人的能力和决心有关。黑客界也流行一句话就是“没有入侵不了的计算机”，这句话大概的意思是说：如果你的技术比维护这台计算机的管理员更胜一筹，那么就能拿下这台计算机甚至能拿下这个管理员管理的所有计算机，如果技不如人，只能继续学习超过对方。我说这些话的意思就是让准备学习陌生语言朋友一定要下决心去学习，只要你下了决心去学了，就一定能学好，千万不要半途而废。（退一万步来说，即使是没学好，但你懂的必然比别人多）
<br/>了解什么是最简单:
<br/>1、网页的基本构成就是html代码,所以必须熟悉HTML/CSS/JS等基本元素
<br/>2、熟悉PHP语法，了解PHP和HTML的运行方式，学习将PHP与HTML结合完成简单页面
<br/>PHP手册是比较好的入门教材
<br/>影响学习进度和程序强大是否的几个可能因素：

<br/>1、记忆力
<br/>一门语言的强大是否，应该看它的函数库和代码执行效率。每门语言都是有自己强大的函数库，要学好它，就必须得花很多的时间去记忆，良好的记忆力能使学习达到事半功倍的效果。
<br/>2、数学和逻辑思维
<br/>这个当然不是绝对影响，因为看开发项目的复杂程度。小的项目不需要太多的数学和逻辑思维能力，但如果是开发类似于财务或大量运算相关项目，这一点就是非常重要了。
<br/>3、有其它语言的基础
<br/>“一通百通”，这句话的道理也是不容置疑。都说有C语言基础的人，学习PHP比较容易，我没学过C语言，所以不知道这句话的效果
<br/>4、多看看别人写的代码
<br/>学习别人的长处，补自己的不足，当然不完全为这个我始终相信：一个有组织的团队写出来的程序不会比个人差我PHP入门就是从看代码开始的，我喜欢看别人写的代码。(入门是从disucz,PHPWind和国外的phpbb看起，还有就是目前最流行的开源BLOG程序)，我尽可能的收集网络上的PHP开源程序，到目前为止，我收集并下载的PHP开源程序有2GB大小,包括BBS，BLOG，CMS等。我下载并不是为了收藏他们，是学习他们的编程方式和实现方法,如果自己想实现的功能不知道怎么去实现，我就会学习他们的实现方法，并不是抄袭代码，最终结果是想通过学习，将技术变成属于自己的ASP我也是以同样的方式学习的(动易和讯的程序及其它ASP开源程序)
<br/>5、恒心

<br/>广告不是有句话是这样说的么：“世界上最高的山是自己”，这句话相信朋友们都能理解
<br/>过自己这关，其它的都好办
<br/>6、实践
<br/>理论固然重要，但实践必不可少。你理论知识再好，如果不实践，就不能看到理论所产生的结果或效果，并不能使你的记忆深刻，所以不能纸上谈兵
<br/>7、找对自己有用的学习方式
<br/>这条可以参照4，我的入门是从看代码开始可能有朋友会问：“一开始看那些强大的代码，你能看懂么？”我的学习方式是从“使用”找“学函数”：PHP的函数太多，短时间不可能记住所有的函数，因为我相信，一个大的项目肯定会使用常见和必须的函数，找到这些函数，才会有重点的学习这些函数，难道你能说写BBS的函数会写BLOG用的函数少么？难道会写BBS还不会写BLOG么？找对学习方式是要经过多种学习方式的尝试，所以这个只有自己把握，毕竟每个人的学习方式不一样
<br/>8、尽可能的找视屏教程看
<br/>别人说十句，还不如一个操作看的明白，这个相信朋友们都有体会吧
<br/>9、从项目开始

<br/>一定要”逼”自己从写项目开始。任何一个高手的“成长”都是要经历一个过程，这个过程是一步步走过来的，来之不易很多朋友学习PHP的第一个作品几乎都是“留言簿”，因为是最简单的程序了会写留言簿，也并不能完全代表你已经入门了，也并不代表就会了PHP，我自己开始想以一个“网络书签”作为自己的第一个作品，但写了基本功能后就没继续了，感觉没多大意思。现在写一个完全正确针对企业的CMS系统，包括针对企业的一些常用功能，我想以这个作为自己PHP入门的第一个作品
<br/>10、了解并学习和PHP有关的技术
<br/>真正的高手必须得学习和PHP关联的技术，要想学好PHP，就必须得学习数据库，PHP+MYSQL被认为是“黄金搭档”所以你必须得接触MYSQL或你认为比较好的数据库，开始设计比较”合理”的数据库，这里的合理就比较广泛了，包括数据库优化和查询优化等等
<br/>最后想说的是：“不要依靠别人”没人愿意理会一个新手的提问，因为新手提问的在他们眼里太简单，不想去解释女性朋友很流行一句话是“男人靠的住，母猪会上树”引用这句话没别的意思，只是让朋友们知道这句话的意思
<br/>还想说的是：“珍惜别人回答的次数”人的忍耐都是有限度的，一定要珍惜这个限度，不要什么问题都去问，有些问题自己花点时间能找到答案的也去问，每问一次，别人的耐心就减去一次，等你真正需要帮助的时候，正好是别人不愿意回答你的时候，可以想像一下，你失去的太多了
<br/>建议的是：“有问题？baidu一下”相信朋友们都已经注意到了，你问的问题，在搜索引擎里都能找到相关的提问，并且有详细的解决方案，你可以使用搜索引擎来找到自己的答案，何必去问别人呢
<br/>目前最大的中文搜索引擎是baidu.com,全球的google,当然还有其它的搜索引擎，一个找不到，多试几个，除非你的问题是第一个提问的，那么你是幸运的，也可能是你“长相”问题，呵呵，说笑的，不要介意，不过这句话倒是挺流行
<br/>祝正准备入门的PHP的朋友能找到适合自己的学习方式，早日成功!!]]></description>
		<pubDate>Thu, 12 May 2011 11:19:34 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[用php实现xml与json之间的相互转换]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail1153.shtml]]></link>
		<description><![CDATA[用php实现xml与json之间的相互转换：
<br/>相关函数请查看php手册。
<br/>一，参考xml如下
<br/>&lt;?xmlversion=&quot;1.0&quot;encoding=&quot;UTF-8&quot;?&gt;
<br/>&lt;humans&gt;
<br/>&lt;zhangying&gt;
<br/>&lt;name&gt;张三&lt;/name&gt;

<br/>&lt;sex&gt;男&lt;/sex&gt;
<br/>&lt;old&gt;26&lt;/old&gt;
<br/>&lt;/zhangying&gt;
<br/>&lt;tank&gt;
<br/>&lt;name&gt;tank&lt;/name&gt;

<br/>&lt;sex&gt;
<br/>&lt;hao&gt;yes&lt;/hao&gt;
<br/>&lt;aaaa&gt;no&lt;/aaaa&gt;
<br/>&lt;/sex&gt;
<br/>&lt;old&gt;26&lt;/old&gt;

<br/>&lt;/tank&gt;
<br/>&lt;/humans&gt;
<br/>二，xml转换成json
<br/>利用simplexml
<br/>publicfunctionxml_to_json($source){
<br/>		if(is_file($source)){//传的是文件，还是xml的string的判断
<br/>			$xml_array=simplexml_load_file($source);
<br/>		}else{
<br/>			$xml_array=simplexml_load_string($source);

<br/>		}
<br/>		$json=json_encode($xml_array);//php5，以及以上，如果是更早版本，请查看JSON.php
<br/>		return$json;
<br/>}
<br/>
<br/>三，json转换成xml
<br/>利用递归函数
<br/>publicfunctionjson_to_xml($source,$charset='utf8'){
<br/>		if(empty($source)){
<br/>			returnfalse;
<br/>		}

<br/>		//php5，以及以上，如果是更早版本，请查看JSON.php
<br/>		$array=json_decode($source);
<br/>		$xml='';
<br/>		$xml.=$this-&gt;change($array);
<br/>		return$xml;
<br/>}
<br/>publicfunctionchange($source){
<br/>		$string=&quot;&quot;;
<br/>		foreach($sourceas$k=&gt;$v){

<br/>			$string.=&quot;&lt;&quot;.$k.&quot;&gt;&quot;;
<br/>			//判断是否是数组，或者，对像
<br/>			if(is_array($v)||is_object($v)){		
<br/>				//是数组或者对像就的递归调用
<br/>				$string.=$this-&gt;change($v);
<br/>			}else{
<br/>				//取得标签数据

<br/>				$string.=$v;
<br/>			}
<br/>			$string.=&quot;&quot;;
<br/>		}
<br/>		return$string;
<br/>}
<br/>上面的方法json_to_xml，可以支持&lt;name&gt;aaaa&lt;/name&gt;，不支持&lt;nametype='test'&gt;aaaaa&lt;/name&gt;看代码就能看明白.]]></description>
		<pubDate>Tue, 26 Apr 2011 11:49:16 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[php程序员应具备的7种能力]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail1152.shtml]]></link>
		<description><![CDATA[php程序员应具备的7种能力：
<br/>一个优秀php程序员应具备什么样的能力，才能更好的完成工作，才会有更好的发展方向呢？下面7种能力希望对您有所帮助。
<br/>一，php能力
<br/>1，了解阶段，您能写一些代码，因为那是在手册和google的帮助下，您才完成的。变量乱定义，N多函数不知道，做起事来很慢，想到什么写什么，代码写的比较乱，后期维护很麻烦。
<br/>2，熟悉阶段，经常查函数，手册估计也看过一，二遍了，常用的函数基本上您都了解了。后期维护给您带来了不少痛苦，您开始发现自己的代码有很多不足，开始思考如果改进自己的代码，如何站在项目的角度来规划自己的代码，而不是想到什么写什么，知道如何来减少冗余代码，使您的代码清晰，知道什么样的代码写出来让人看着舒服，基本的代码规范，已经形成。为了提高自己，会特意的去一些技术性的论坛，学习研究。
<br/>3，很熟悉阶段，本来我想写精通的，到现在我也不知道精通是到什么程度，也没有听到有人说自己精通PHP的，所以就用很熟悉了。这个阶段，我想您已经从面向过程进入了面向对象。个人觉得面向对象的最大好处就是，能使整个项目功能化，模块化，后期维护，改版，升级就很方便了。没有面向对象的时候，不也一样开发吗.这个时期，您已经研究过了一种或者几种框架，结合自己的实际项目经验，在脑子里已经能形成自己的一个框架，这个框架是最适合你的。并且能够将这个框架运用到实际的开发中去，以提高自己的开发效率。
<br/>如果您刚写代码的时候，就有人能约束你按OOP的思想去写代码的话，那您就遇到贵人了。当不好的代码习惯养成时，在想改就不那么容易了。
<br/>二，数据库能力
<br/>用php来做项目的话，用mysql是最多的了，其次是pgsql。因为他们二个是免费的。哈哈，以mysql为例
<br/>1，了解阶段，知道mysql是什么，能写一些简单的sql语句，能设计简单的表，知道如何使用数据库管理工具（如：phpmyadmin）
<br/>2，熟悉阶段，知道如何才能写出高效率的sql语句，了解索引原理，知道如何创建索引，会写一些储存过程，触发器等，能通过各种手段来分析，测试数据库，例如：利用mysqlslap来进行压力测试，通来explain来分析sql语句，通过开启慢查询来分析哪些sql语句真正影响mysql的运行，能利用dbdesigner4,mysqlworkbench为设计数据库，能在命令状态下，查询，分析mysql环境变量，来分析mysql的运行状态等等
<br/>3，很熟悉阶段，对于各有种存储引擎的原理非常熟悉，知道通过修改配置文件来，使存储引擎达到最优化，知道如何来优化数据库的最大连接数，知道怎么样来优化mysql的I/o瓶颈，为了项目的需要，向mysql数据库增加存储引擎或者插件，知道如何搭建数据库集群，并监控数据库的运行状态等等
<br/>三，html，css能力
<br/>php是脚本语言，我们用php大多数情况下是用来做网站的，慨然是网站，那肯定是离不开html,css
<br/>1，了解阶段，知道html标签是干什么用的，通过网络和手册能自主的写一些html，知道css是怎么回事，能在html中写一些简单的style等
<br/>2，熟悉阶段，能利用css来能设计一些简单的布局，可以将css单独的写成文件，熟悉css的语法规则，以及继承性等
<br/>3，很熟悉阶段，能够设计出很好的CSS，并且管理好这些CSS文件，尽量减少冗余代码。知道如何写出有利于搜索引擎搜索的代码，例如：title,h1,h2权重比较高的。等

<br/>对于php程序员来说，并不一定要你去设计页面，但是给你一个页面，你要知道如何来修改CSS文件，html就不要说了肯定要掌握的。
<br/>四，js能力
<br/>如果提高用户体验，是一个网站能留住人的重要标志。这个就要用到JS了
<br/>1，了解阶段，了解JS的基本语法，知道如何去调试这些程序，能写一些简单function等
<br/>2，熟悉阶段，对JS的语法，函数，正则等已经熟悉了，能利用js来写一些特效，并且发现用JS写特效，是比较累人的一件事，开始尝试jquery,prototype，并对jquery,prototype基本语法有所解，个人反对不学JS，直接入手jquery,prototype这样的JS框架。
<br/>3，很熟悉阶段，在框架的帮助下，能熟练的用OOP的思想的来写代码，而不是一个个function累加，熟练运用jquery,prototype的ajax，或者是网上一些ajax框架，如（ajaxrequest），不在直接写active控件了。能够利用网络资源，来完成各种特效。
<br/>对于大型公司来说一般都是有js程序员的，小公司基本上没有，要么交给程序员来做，要么交给美工来做。美工一般都不是程序员，也没有编程基础，所以学JS比较吃力，但是学jquery比较容易的，因为css对html进行控制的方法，和jquery对html的控制方法基本上差不多（css，jquery的相同之处），所以有好多公司把特效交给美工来做。
<br/>五，apache等能力
<br/>个人觉得，到目录为止，跑php的话用apache的人还是最多，前段时间好多网站在吵NGINX有多么多么的好，能比apache好10倍，我觉得还是亲自尝试一下比较好。以apache为例
<br/>1，了解阶段，不管是linux下，还是windows下，能够安装配置apache，知道如何添加php添模，如果面试官问你，apache为什么能解释php代码，你怎么回答呢。对apache的基本配置有所了解，对于启动中遇到的问题能够解决等
<br/>2，熟悉阶段，知道如何向apache中添加新的模块，如果如何进行url重写，防盗链，进行IP限制等
<br/>3，很熟悉阶段，知道如何利用apache来缓存图片，能利用apache来做负载均衡，并且知道利用ab命令来进行压力，通过工具对日志分析，经过分析来对apache进行优化，知道如何搭建多个虚拟主机；对apahce的常用模块都有实际操作经验等
<br/>对apache进行监控和维护，一般是运维人员或者是项目经理来做的，个人觉得最好还是了解一点，因为这样您才不会那么容易被忽悠，对于自己将来的转型也是非常有必要的。
<br/>六，linux系统（shell）
<br/>为什么要掌握linux系统呢？用php写的网站大多数运行在linux或者freebsd下的，掌握linux系统对自己将来的发展还是比较有好处的。借此感谢一下我的好友汪洋，是他将我带进linux世界的，进来后我才发现这里的世界很精彩，现在我基本上不用windows了，偶尔打游戏的时候会进一下，在linux下，不用担心中毒的问题，linux下的病毒很少，也不用担心，XX和XXX扫描你的硬盘了。哈哈
<br/>1，熟悉阶段，会装linux系统，对系统的常用命令能够熟练运用等
<br/>2，运用阶段，在linux系统下，能够安装配置apache,php,mysql,svn,memcache,squid，lvs等一些web项目必要的工具，能够通过日志分析其状态等。对shell要有所了解，并能够写一些简单的shell脚本等

<br/>七，沟通能力
<br/>这一点非常重要，并且被越来越多的人所忽视，其实做程序员挺杯具的，根电脑打交道的时间是最多，也许是因为这样吧，勾通的时候，是比较费劲的，也有可能是被程序的严谨性束缚了大脑，说出来的话，太专业，可能其他人听不懂的。所以平时多和他人交流，特别是根非技术人员多勾通，多站在对方的角度来思想问题，这样的话，我想勾通起来会容易很多。]]></description>
		<pubDate>Tue, 26 Apr 2011 09:37:52 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[php中strstr、strrchr、substr、stristr四个函数用法区别]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail1151.shtml]]></link>
		<description><![CDATA[php中strstr、strrchr、substr、stristr四个函数用法区别：
<br/>php中strstrstrrchrsubstrstristr这四个字符串操作函数特别让人容易混淆，常用的是substr,strstr，基本上可以满足对字符串的操作。
<br/>下面介绍一下这个几个函数的区别。
<br/>一，strstr和strcchr的区别
<br/>strstr显示第一次找到，要查找的字符串，以及后面的字符串。
<br/>strrchr显示最后一次找到，要查找的字符串，以及后面的字符串。
<br/>&lt;?php
<br/>$email='test@test.com@phpzixue.cn';
<br/>$domain=strstr($email,'@');
<br/>echo&quot;strstr测试结果$domain&lt;br&gt;&quot;;
<br/>$domain=strrchr($email,'@');
<br/>echo&quot;strrchr测试结果$domain&lt;br&gt;&quot;;

<br/>?&gt;
<br/>结果如下：
<br/>strstr测试结果@test.com@phpzixue.cn
<br/>strrchr测试结果@phpzixue.cn
<br/>
<br/>二，strstr和stristr的区别
<br/>strstr是大小写敏感的。
<br/>stristr是大小写不敏感的。
<br/>&lt;?php
<br/>$email='zhangYing@phpzixue.cn';
<br/>$domain=strstr($email,'y');
<br/>echo&quot;strstr测试结果$domain&lt;br&gt;&quot;;
<br/>$domain=stristr($email,'y');

<br/>echo&quot;stristr测试结果$domain&lt;br&gt;&quot;;
<br/>?&gt;
<br/>结果如下：
<br/>strstr测试结果phpzixue.cn
<br/>stristr测试结果Ying@phpzixue.cn
<br/>
<br/>三，strstr和substr的区别
<br/>strstr是匹配后截取。
<br/>substr是不匹配，根据起始位置，进行截取。
<br/>&lt;?php
<br/>$email='zhangYing@phpzixue.cn';
<br/>$domain=strstr($email,'y');
<br/>echo&quot;strstr测试结果$domain&lt;br&gt;&quot;;

<br/>$domain=substr($email,-7);
<br/>echo&quot;substr测试结果$domain&lt;br&gt;&quot;;
<br/>?&gt;
<br/>结果如下:
<br/>strstr测试结果phpzixue.cn
<br/>substr测试结果phpzixue.cn
<br/>
<br/>把这个几个字符串截取函数搞明白了，在开发时可以省不少事。]]></description>
		<pubDate>Tue, 26 Apr 2011 09:29:11 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[php中print_r、var_dump和var_export几个函数的用法区别]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail1147.shtml]]></link>
		<description><![CDATA[php中print_r、var_dump和var_export几个函数的用法区别：
<br/>在php中用于调试的有很多方法如：print、echo用来打印普通的变量内容，在这个不做说明，具体请看文章：
<br/><ahref="http://www.phpzixue.cn/detail536.shtml"target="_blank">http://www.phpzixue.cn/detail536.shtml</a><br/>
<br/>下面介绍一下print_r、var_dump、var_export几个函数的用法区别，他们都是用来打印数组对象。
<br/>1、print_r($array/$var)
<br/>print是打印的意思，而r则取自Array的单词，那么该函数的功能就是打印数组内容，它既可以打印数组内容，也可以打印普通的变量。
<br/>print_r($_REQUEST);
<br/>print_r($_GET);/*打印使用GET方法传递的表单内容*/
<br/>print_r($_POST);/*打印使用表单POST方法传递过的数组内容*/
<br/>2、var_dump($object/$array/$var)

<br/>var代表变量（Variable），变量包括对象、数组以及标量变量，dump有倒出之意，加在一块，就是将变量或对象的内容全部输出出来。
<br/>var_dump($DB);/*打印$DB数据库连接对象的内容*/
<br/>var_dump($fileHandle);/*打印文件句柄对象的内容*/
<br/>var_dump($Smarty);/*打印Smarty模板对象*/
<br/>3、var_export($object/$array/$var)
<br/>输出或返回一个变量的字符表示。此函数返回关于传递给函数的变量的结构信息，它和print_r()类似，不同的是其返回的表示是合法的PHP代码。可以通过将函数的第二个参数设置为TRUE，从而返回变量的表示。
<br/>看下面代码：
<br/>&lt;?php
<br/>$a=array(1,2,array(&quot;a&quot;,&quot;b&quot;,&quot;c&quot;));
<br/>var_export($a);
<br/>echo&quot;&lt;br&gt;&quot;;

<br/>$v=var_export($a,TRUE);
<br/>echo$v;
<br/>?&gt;
<br/>上例中，$v=var_export($a,TRUE)表示返回的是PHP的源代码，可以直接用PHP脚本的数组文件中。
<br/>总结说明：
<br/>以上三个函数都可以打印对象的值、系统函数值以及数组的内容；
<br/>1、echo、print、printf可以打印变量内容，但不能显示数组及系统超级变量数组；
<br/>2、print_r和var_dump不仅可以打印数组、标量变量，还可以打印对象的内容；
<br/>3、var_dump语句不仅能打印变量、数组内容，还可以显示布尔变量和资源（Resource）的内容；
<br/>4、var_export函数返回关于传递给该函数的变量的结构信息，和var_dump()函数类似，不同的是其返回的内容是合法的PHP代码。]]></description>
		<pubDate>Mon, 18 Apr 2011 11:52:41 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[PHP5与PHP4的区别小议]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail1143.shtml]]></link>
		<description><![CDATA[PHP5与PHP4的区别小议：
<br/>一、未100%向下兼容
<br/>在php5中尽管大部分PHP4的代码应该不用修改就能运行，还是应该留意以下不向下兼容的改变：
<br/>有了一些新关键字。
<br/>strrpos()和strripos()如今使用整个字符串作为needle。
<br/>非法使用字符串偏移量会导致E_ERROR而不是E_WARNING。一个非法使用的例子：$str=‘abc’;unset($str[0]);.
<br/>array_merge()被改成只接受数组。如果传递入非数组变量，对每个此类参数都会发出一条E_WARNING信息。要小心因为你的代码有可能疯狂发出E_WARNING。
<br/>PATH_TRANSLATED服务器变量在Apache2SAPI中不再暗中设定，这和PHP4中的情形相反，如果Apache没产生此值则其被设为和SCRIPT_FILENAME服务器变量一样的值。此修改是为了遵守CGI规范。更多信息参考手册中$_SERVER['PATH_TRANSLATED']的说明。此问题也影响到PHP&gt;=4.3.2的版本。
<br/>Tokenizer扩展不再定义T_ML_COMMENT常量。如果把error_reporting设为E_ALL，PHP将产生一条消息。尽管T_ML_COMMENT从来都没用到过，还是在PHP4中定义了。在PHP4和PHP5中//和都被解析为T_COMMENT常量。但是PHPDoc风格的注释，自PHP5开始被PHP解析，被识别为T_DOC_COMMENT。
<br/>如果variables_order包括“S”，$_SERVER应该带有argc和argv被产生。如果用户特别配制系统不创建$_SERVER，那此变量当然就不存在了。改变的地方是不管variables_order怎么设定，在CLI版本中argc和argv总是可用的。本来CLI版不是总会产生全局变量$argc和$argv的。
<br/>没有属性的对象不再被当成“empty”。
<br/>有些情况下类必须在使用前被定义。这仅在使用了一些PHP5的新特性（例如interfaces）的时候发生。其它情况下行为都没变。
<br/>get_class()，get_parent_class()和get_class_methods()如今返回的类／方法名和定义时的名字一致（区分大小写），对于依赖以前行为（类／方法名总是返回小写的）的老脚本可能产生问题。一个可能的解决方法是在脚本中搜索所有这些函数并使用strtolower()。
<br/>区分大小写的改变也适用于魔术常量__CLASS__，__METHOD__和__FUNCTION__。其值都会严格按照定义时的名字返回（区分大小写）。
<br/>ip2long()在传递入一个非法IP作为参数时返回FALSE，不再是-1。

<br/>如果有函数定义在包含文件中，则这些函数可以在主文件中使用而与是否在return()指令之前还是之后无关。如果文件被包含两次，PHP5会发出致命错误，因为函数已经被定义，而PHP4不管这个。因此推荐使用include_once()而不要去检查文件是否已被包含以及在包含文件中有条件返回。
<br/>include_once()和require_once()在Windows下先将路径规格化，因此包含A.php和a.php只会把文件包含一次。
<br/>实例：strrpos()和strripos()如今用整个字符串作为needle
<br/>&lt;?php
<br/>var_dump(strrpos(‘ABCDEF’,‘DEF’));//int(3)
<br/>var_dump(strrpos(‘ABCDEF’,‘DAF’));//bool(false)
<br/>?&gt;
<br/>实例：没有属性的对象不再被当成“empty”
<br/>&lt;?php
<br/>classtest{}
<br/>$t=newtest();
<br/>var_dump(empty($t));//echobool(false)
<br/>if($t){
<br/>//Willbeexecuted
<br/>}

<br/>?&gt;
<br/>实例：有些情况下类必须在使用之前定义
<br/>&lt;?php
<br/>//workswithnoerrors:
<br/>$a=newa();
<br/>classa{
<br/>}
<br/>//throwsanerror:
<br/>$a=newb();
<br/>interfacec{
<br/>}

<br/>classbimplementsc{
<br/>}
<br/>?&gt;
<br/>二、CLI和CGI
<br/>PHP5中对CLI和CGI文件名作了些改变。PHP5中，CGI版本被改名为php-cgi.exe（以前是php.exe），现在主目录中的是CLI版本（之前是cli/php.exe）。
<br/>PHP5中引进了一种新模式：php-win.exe。这和CLI版本相同，只除了php-win不输出任何内容，因此不会提供控制台（屏幕上不会闪过“dos窗口”）。此行为类似php-gtk。
<br/>PHP5中，CLI版本总会产生全局变量$argv和$argc而不管php.ini是怎么设的。即使将register_argc_argv设为off也不影响CLI。
<br/>参见命令行模式。
<br/>三、移植配置文件
<br/>由于ISAPI模块的名字改了，从php4xxx改为php5xxx，因此需要对配置文件作些修改。CLI和CGI文件名也改了。更多信息请查看相应章节。
<br/>移植Apache配置极其简单。照下面的例子来检查需要做的修改：
<br/>实例：移植Apache配置文件到PHP5
<br/>#将下面这行：LoadModulephp4_module/php/sapi/php4apache2.dll#改成这一行：LoadModulephp5_module/php/php5apache2.dll
<br/>如果web服务器是以CGI模式运行PHP的，应该注意CGI版本的名字从php.exe改为了php-cgi.exe。在Apache中，应该照这样改：

<br/>实例：移植Apache配置文件到PHP5，CGI模式
<br/>#将下面这行：Actionapplication/x-httpd-php&quot;/php/php.exe&quot;#改成这一行：Actionapplication/x-httpd-php&quot;/php/php-cgi.exe&quot;
<br/>其它的web服务器中，需要修改CGI或者ISAPI模块的名字。
<br/>四、新函数
<br/>PHP5有了些新函数。下面是列表：
<br/>Arrays:
<br/>array_combine()-用一个数组作为键名，另一个数组作为值创建一个新数组
<br/>array_diff_uassoc()-计算数组的差别，并用用户提供的回调函数作附加的索引检查
<br/>array_udiff()-用回调函数比较数据来计算数组的差别
<br/>array_udiff_assoc()-计算数组的差别并作附加的索引检查。用回调函数来比较数据
<br/>array_udiff_uassoc()-计算数组的差别并作附加的索引检查。数据的比较和索引检查都用回调函数来完成
<br/>array_walk_recursive()-对数组的每个成员递归使用用户函数

<br/>array_uintersect_assoc()-计算数组的交集并作附加的索引检查。用回调函数来比较数据
<br/>array_uintersect_uassoc()-计算数组的交集并作附加的索引检查。数据和索引都用回调函数来比较
<br/>array_uintersect()-计算数组的交集。用回调函数来比较数据
<br/>InterBase:
<br/>ibase_affected_rows()-返回前一个查询影响到的行的数目
<br/>ibase_backup()-在服务管理器中发起一个后台任务并立即返回
<br/>ibase_commit_ret()-提交一个事务但不关闭
<br/>ibase_db_info()-请求有关数据库的统计信息
<br/>ibase_drop_db()-删除一个数据库
<br/>ibase_errcode()-返回一个错误代码
<br/>ibase_free_event_handler()-取消一个已注册的事件句柄
<br/>ibase_gen_id()-递增指定的发生器并返回其新值
<br/>ibase_maintain_db()-在数据库服务器上执行一条维护命令
<br/>ibase_name_result()-给结果集指定一个名字
<br/>ibase_num_params()-返回一个准备好的查询的参数数目
<br/>ibase_param_info()-返回一个准备好的查询的参数信息
<br/>ibase_restore()-在服务管理器中发起一个还原任务并立即返回

<br/>ibase_rollback_ret()-回卷一笔事务并保留事务上下文
<br/>ibase_server_info()-请求有关数据库服务器的统计信息
<br/>ibase_service_attach()-连接到服务管理器
<br/>ibase_service_detach()-从服务管理器断开
<br/>ibase_set_event_handler()-注册一个当事件发布时要调用的回调函数
<br/>ibase_wait_event()-等待数据库发布一条事件
<br/>iconv:
<br/>iconv_mime_decode()-解码MIME头信息字段
<br/>iconv_mime_decode_headers()-一次解码多个MIME头信息字段
<br/>iconv_mime_encode()-压缩MIME头信息字段
<br/>iconv_strlen()-返回字符串中的字符计数
<br/>iconv_strpos()-在堆栈中找到第一个出现的子串位置
<br/>iconv_strrpos()-在堆栈中找到最后一个出现的子串位置
<br/>iconv_substr()-从字符串中取出一部分
<br/>Streams:
<br/>stream_copy_to_stream()-把一个流的数据复制到另一个流
<br/>stream_get_line()-根据给定的分隔符中流中读取一行

<br/>stream_socket_accept()-接受一个由stream_socket_server()建立的socket连接
<br/>stream_socket_client()-打开一个Internet或Unix域的socket连接
<br/>stream_socket_get_name()-获取本地或远程的sockets名字
<br/>stream_socket_recvfrom()-从socket获取数据（不管连接是否已经建立）
<br/>stream_socket_sendto()-向socket发送一个消息（不管连接是否已经建立）
<br/>stream_socket_server()-建立一个Internet或Unix域服务器的socket
<br/>Date/Time:
<br/>idate()-将本地进间格式化为整数
<br/>date_sunset()-计算所指定日期和地点的日落时间
<br/>date_sunrise()-T计算所指定日期和地点的日出时间
<br/>time_nanosleep()-廷迟执行程若干秒和若干纳秒
<br/>Strings:
<br/>str_split()-把一个字符串分割为数组
<br/>strpbrk()-在一字符串中搜索给定的字符集合中的任意一个字符
<br/>substr_compare()-以二进制的形式比较两个字符串，从第一个字符串的offset开始，直到到达长度为length时结束，可自定义是否大小写敏感比较
<br/>Other:
<br/>convert_uudecode()-解码uuencoded的字符串

<br/>convert_uuencode()-对字符串进行uuencode
<br/>curl_copy_handle()-复制一个cURL句柄及其所有参数
<br/>dba_key_split()-把一个键分隔为字符串数组
<br/>dbase_get_header_info()-取得dBase数据库的头部信息
<br/>dbx_fetch_row()-获取结果集中被设置为DBX_RESULT_UNBUFFERED的行
<br/>fbsql_set_password()-修改指定用户的密码
<br/>file_put_contents()-向一个文件内写入字符串
<br/>ftp_alloc()-为准备上传的文件分配空间
<br/>get_declared_interfaces()-以数组的形式返回所有已定义的接品
<br/>get_headers()-获取服务器响应HTTP请求时的所有头部信息
<br/>headers_list()-返回所有已发送或准备发送响应头部列表
<br/>http_build_query()-生成一个已经过URL编码的请求字符串
<br/>image_type_to_extension()-根据getimagesize(),exif_read_data(),exif_thumbnail(),exif_imagetype()所返回的image-type取得文件名后缀
<br/>imagefilter()-对图像应用滤镜
<br/>imap_getacl()-获取指定邮箱的ACL
<br/>ldap_sasl_bind()-使用SASL绑定到LDAP目录
<br/>mb_list_encodings()-以数组的形式返回所支持的全部字符集

<br/>pcntl_getpriority()-获得任意一个进程的优先级
<br/>pcntl_wait()-Waitsonorreturnsthestatusofaforkedchildasdefinedbythewaitpid()systemcall
<br/>pg_version()-返回一个包含客户端、协议和服务器版本的数组
<br/>php_check_syntax()-检查指定文件的语法
<br/>php_strip_whitespace()-返回已经去除注释和空白的源代码
<br/>proc_nice()-修改当前进程的优前级
<br/>pspell_config_data_dir()-修改语言文件的位置
<br/>pspell_config_dict_dir()-修改主要单词列表的位置
<br/>setrawcookie()-发送一个没有经过url编码的cookie值
<br/>scandir()-列中指定目录中的所有子目录和文件
<br/>snmp_read_mib()-在一个可用的MIB树中读取和分板一个MIB文件
<br/>sqlite_fetch_column_types()-以数组的形式返回一张表中的列类型
<br/>注意:Tidy扩展库的API也作了重大调整
<br/>五、新指令
<br/>PHP5在php.ini中引进了一些新指令。列表如下：
<br/>mail.force_extra_parameters-强制指定的参数附加值作为额外的参数传递给sendmail库。这些参数总是会替换掉mail()的第5个参数，即使在安全模式下
<br/>register_long_arrays-允许／禁止PHP注册已过时的$HTTP_*_VARS变量

<br/>session.hash_function-选择一种散列函数（MD5或SHA-1）
<br/>session.hash_bits_per_character-定义将二进制散列数据转换为可读格式时每个字符中储存几个位（从4到6）
<br/>zend.ze1_compatibility_mode-启用ZendEngline1代（PHP4）兼容模式
<br/>六、数据库
<br/>关于数据库（MySQL和SQLite）在PHP5中有些改变。
<br/>PHP5中不再绑定MySQL客户端连接库，因为授权和一些其它问题。
<br/>有个新扩展库MySQLi（改良版MySQL），设计用来工作于MySQL4.1及更高版本之下。
<br/>自PHP5起，SQLite扩展库内置在PHP中。SQLite是一个可嵌入SQL数据库引擎，不是客户端连接库用来连接大型数据库服务器（如MySQL或PostgreSQL）的。SQLite库直接读写磁盘上的数据库文件。
<br/>七、新对象模型
<br/>PHP5中有个新对象模型（ObjectModel）。PHP处理对象的方式完全重写了，允许更佳性能和更多特性。之前版本的PHP，对象处理方式和原始类型（例如整型和字符串）相同。此方法的缺点是当变量被赋值或作为参数传递给方法时语义上整个对象都被拷贝。在新方法中，对象通过句柄引用，而不是值（可以将句柄当成是对象的标识符）。
<br/>很多PHP程序员根本没意识到旧的对象模型的这种拷贝怪癖，因此大多数PHP应用程序拿来就能运行，或者只做很小的修改。
<br/>新对象模型的文档见“类与对象”。]]></description>
		<pubDate>Fri, 25 Mar 2011 09:57:09 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[PHP中APC的安装和高级使用讲解]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail1142.shtml]]></link>
		<description><![CDATA[PHP中APC的安装和高级使用讲解：
<br/>PHP中的扩展模块APC,全称是AlternativePHPCache,官方翻译叫”可选PHP缓存”,但我个人觉得应该叫”另一个PHP缓存”。
<br/>因为这个东西如果叫”可选PHP缓存”,容易给人一种可要可不要的,不怎么有用的错觉。
<br/>APC的主页是:http://pecl.php.net/package/apc.目前的版本是3.0.14,通过PECL安装,需要php4.3.0或更高版本.
<br/>PHPAPC的安装:
<br/>一般是下载源代码然后phpize来编译安装,安装完以后在加上php.ini里加上
<br/>extension=apc.so
<br/>这么一行就行了.
<br/>PHPAPC的使用：
<br/>APC的使用其实倒说不上.APC是个优化器,自安装之日起,就默默地在后台为您的PHP应用服务了.您的所有PHP代码会被缓存起来.另外,APC可提供一定的内存缓存功能.但是这个功能并不是十分完美,有报告说如果频繁使用APC缓存的写入功能,会导致不可预料的错误.如果想使用这个功能,可以看看apc_fetch,apc_store等几个与apc缓存相关的函数.从PHP5.2开始,APC引入了一个小甜饼,解决了困扰大家已久的大文件上传的进度条问题.
<br/>PHPAPC的高级使用
<br/>1.缓存期限:APC的缓存分两部分:系统缓存和用户数据缓存.
<br/>系统缓存是自动使用的,是指APC把PHP文件源码的编译结果缓存起来,然后在再次调用时先对比时间标记。如果未过期,则使用缓存代码运行。默认缓存3600s(一小时).但是这样仍会浪费大量CPU时间.因此可以在php.ini中设置system缓存为永不过期(apc.ttl=0).不过如果这样设置,改运php代码后需要restart一下您的web服务器(比如apache…).目前对APC的性能测试一般指的是这一层cache;
<br/>用户数据缓存由用户在编写php代码时用apc_store和apc_fetch函数操作读取、写入的.如果量不大的话我建议可以使用一下.如果量大,我建议使用memcache会更好.如果要享受APC带来的缓存大文件上传进度的特性,需要在php.ini中将apc.rfc1867设为1,并且在表单中加一个隐藏域APC_UPLOAD_PROGRESS,这个域的值可以随机生成一个hash,以确何唯一.
<br/>2.状态控制和分析:PHPAPC的源码包自带了一个apc.php;您可以将这个文件上传到web服务器的某个目录下,用浏览器访问,这会显示当前的状态.我们可以从这里的表格分析当前的缓存状况,作出进一步优化.apc-info-clublocalhost2.png这是某test站点的状态.您可以慢慢分析,这个工具会提供很多有用的工具.比如您可以看到哪些文件经常被包含(访问),您缓存的哪个变量经常被读取,或经常被更新等.最后顺便提一句,有独立报告说,PHPAPC的代码缓存、优化效果要高出zend优化器.就算不是真的,他开源而又免费,实在是一个相当不错的选择]]></description>
		<pubDate>Tue, 22 Mar 2011 16:22:39 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[关于memcache的问题汇总]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail1140.shtml]]></link>
		<description><![CDATA[关于memcache的问题汇总：
<br/>1、memcached是怎么工作的？
<br/>Memcached的神奇来自两阶段哈希（two-stagehash）。Memcached就像一个巨大的、存储了很多&lt;key,value&gt;对的哈希表。通过key，可以存储或查询任意的数据。
<br/>客户端可以把数据存储在多台memcached上。当查询数据时，客户端首先参考节点列表计算出key的哈希值（阶段一哈希），进而选中一个节点；客户端将请求发送给选中的节点，然后memcached节点通过一个内部的哈希算法（阶段二哈希），查找真正的数据（item）。
<br/>举个列子，假设有3个客户端1,2,3，3台memcachedA,B,C：
<br/>Client1想把数据”barbaz”以key“foo”存储。Client1首先参考节点列表（A,B,C），计算key“foo”的哈希值，假设memcachedB被选中。接着，Client1直接connect到memcachedB，通过key“foo”把数据”barbaz”存储进去。Client2使用与Client1相同的客户端库（意味着阶段一的哈希算法相同），也拥有同样的memcached列表（A,B,C）。
<br/>于是，经过相同的哈希计算（阶段一），Client2计算出key“foo”在memcachedB上，然后它直接请求memcachedB，得到数据”barbaz”。
<br/>各种客户端在memcached中数据的存储形式是不同的（perlStorable,phpserialize,javahibernate,JSON等）。一些客户端实现的哈希算法也不一样。但是，memcached服务器端的行为总是一致的。
<br/>最后，从实现的角度看，memcached是一个非阻塞的、基于事件的服务器程序。这种架构可以很好地解决C10Kproblem，并具有极佳的可扩展性。
<br/>可以参考AStoryofCaching，这篇文章简单解释了客户端与memcached是如何交互的。
<br/>2、memcached最大的优势是什么？
<br/>请仔细阅读上面的问题（即memcached是如何工作的）。Memcached最大的好处就是它带来了极佳的水平可扩展性，特别是在一个巨大的系统中。由于客户端自己做了一次哈希，那么我们很容易增加大量memcached到集群中。memcached之间没有相互通信，因此不会增加memcached的负载；没有多播协议，不会网络通信量爆炸（implode）。memcached的集群很好用。内存不够了？增加几台memcached吧；CPU不够用了？再增加几台吧；有多余的内存？在增加几台吧，不要浪费了。
<br/>基于memcached的基本原则，可以相当轻松地构建出不同类型的缓存架构。除了这篇FAQ，在其他地方很容易找到详细资料的。
<br/>看看下面的几个问题吧，它们在memcached、服务器的localcache和MySQL的querycache之间做了比较。这几个问题会让您有更全面的认识。
<br/>3、memcached和MySQL的querycache相比，有什么优缺点？

<br/>把memcached引入应用中，还是需要不少工作量的。MySQL有个使用方便的querycache，可以自动地缓存SQL查询的结果，被缓存的SQL查询可以被反复地快速执行。Memcached与之相比，怎么样呢？MySQL的querycache是集中式的，连接到该querycache的MySQL服务器都会受益。
<br/>*当您修改表时，MySQL的querycache会立刻被刷新（flush）。存储一个memcacheditem只需要很少的时间，但是当写操作很频繁时，MySQL的querycache会经常让所有缓存数据都失效。
<br/>*在多核CPU上，MySQL的querycache会遇到扩展问题（scalabilityissues）。在多核CPU上，querycache会增加一个全局锁（globallock）,由于需要刷新更多的缓存数据，速度会变得更慢。
<br/>*在MySQL的querycache中，我们是不能存储任意的数据的（只能是SQL查询结果）。而利用memcached，我们可以搭建出各种高效的缓存。比如，可以执行多个独立的查询，构建出一个用户对象（userobject），然后将用户对象缓存到memcached中。而querycache是SQL语句级别的，不可能做到这一点。在小的网站中，querycache会有所帮助，但随着网站规模的增加，querycache的弊将大于利。
<br/>*querycache能够利用的内存容量受到MySQL服务器空闲内存空间的限制。给数据库服务器增加更多的内存来缓存数据，固然是很好的。但是，有了memcached，只要您有空闲的内存，都可以用来增加memcached集群的规模，然后您就可以缓存更多的数据。
<br/>4、memcached和服务器的localcache（比如PHP的APC、mmap文件等）相比，有什么优缺点？
<br/>首先，localcache有许多与上面(querycache)相同的问题。localcache能够利用的内存容量受到（单台）服务器空闲内存空间的限制。不过，localcache有一点比memcached和querycache都要好，那就是它不但可以存储任意的数据，而且没有网络存取的延迟。
<br/>*localcache的数据查询更快。考虑把highlycommon的数据放在localcache中吧。如果每个页面都需要加载一些数量较少的数据，考虑把它们放在localcached吧。
<br/>*localcache缺少集体失效（groupinvalidation）的特性。在memcached集群中，删除或更新一个key会让所有的观察者觉察到。但是在localcache中,我们只能通知所有的服务器刷新cache（很慢，不具扩展性），或者仅仅依赖缓存超时失效机制。
<br/>*localcache面临着严重的内存限制，这一点上面已经提到。
<br/>5、memcached的cache机制是怎样的？
<br/>Memcached主要的cache机制是LRU（最近最少用）算法+超时失效。当您存数据到memcached中，可以指定该数据在缓存中可以呆多久Whichisforever,orsometimeinthefuture。如果memcached的内存不够用了，过期的slabs会优先被替换，接着就轮到最老的未被使用的slabs。
<br/>6、memcached如何实现冗余机制？
<br/>不实现！我们对这个问题感到很惊讶。Memcached应该是应用的缓存层。它的设计本身就不带有任何冗余机制。如果一个memcached节点失去了所有数据，您应该可以从数据源（比如数据库）再次获取到数据。您应该特别注意，您的应用应该可以容忍节点的失效。不要写一些糟糕的查询代码，寄希望于memcached来保证一切！如果您担心节点失效会大大加重数据库的负担，那么您可以采取一些办法。比如您可以增加更多的节点（来减少丢失一个节点的影响），热备节点（在其他节点down了的时候接管IP），等等。
<br/>7、memcached如何处理容错的？
<br/>不处理！:)在memcached节点失效的情况下，集群没有必要做任何容错处理。如果发生了节点失效，应对的措施完全取决于用户。节点失效时，下面列出几种方案供您选择：
<br/>*忽略它！在失效节点被恢复或替换之前，还有很多其他节点可以应对节点失效带来的影响。

<br/>*把失效的节点从节点列表中移除。做这个操作千万要小心！在默认情况下（余数式哈希算法），客户端添加或移除节点，会导致所有的缓存数据不可用！因为哈希参照的节点列表变化了，大部分key会因为哈希值的改变而被映射到（与原来）不同的节点上。
<br/>*启动热备节点，接管失效节点所占用的IP。这样可以防止哈希紊乱（hashingchaos）。
<br/>*如果希望添加和移除节点，而不影响原先的哈希结果，可以使用一致性哈希算法（consistenthashing）。您可以百度一下一致性哈希算法。支持一致性哈希的客户端已经很成熟，而且被广泛使用。去尝试一下吧！
<br/>*两次哈希（reshing）。当客户端存取数据时，如果发现一个节点down了，就再做一次哈希（哈希算法与前一次不同），重新选择另一个节点（需要注意的时，客户端并没有把down的节点从节点列表中移除，下次还是有可能先哈希到它）。如果某个节点时好时坏，两次哈希的方法就有风险了，好的节点和坏的节点上都可能存在脏数据（staledata）。
<br/>8、如何将memcached中item批量导入导出？
<br/>您不应该这样做！Memcached是一个非阻塞的服务器。任何可能导致memcached暂停或瞬时拒绝服务的操作都应该值得深思熟虑。向memcached中批量导入数据往往不是您真正想要的！想象看，如果缓存数据在导出导入之间发生了变化，您就需要处理脏数据了；如果缓存数据在导出导入之间过期了，您又怎么处理这些数据呢？
<br/>因此，批量导出导入数据并不像您想象中的那么有用。不过在一个场景倒是很有用。如果您有大量的从不变化的数据，并且希望缓存很快热（warm）起来，批量导入缓存数据是很有帮助的。虽然这个场景并不典型，但却经常发生，因此我们会考虑在将来实现批量导出导入的功能。
<br/>StevenGrimm，一如既往地,，在邮件列表中给出了另一个很好的例子：http://lists.danga.com/pipermail/memcached/2007-July/004802.html。
<br/>9、但是我确实需要把memcached中的item批量导出导入，怎么办？？
<br/>好吧好吧。如果您需要批量导出导入，最可能的原因一般是重新生成缓存数据需要消耗很长的时间，或者数据库坏了让您饱受痛苦。
<br/>如果一个memcached节点down了让您很痛苦，那么您还会陷入其他很多麻烦。您的系统太脆弱了。您需要做一些优化工作。比如处理”惊群”问题（比如memcached节点都失效了，反复的查询让您的数据库不堪重负…这个问题在FAQ的其他提到过），或者优化不好的查询。记住，Memcached并不是您逃避优化查询的借口。
<br/>如果您的麻烦仅仅是重新生成缓存数据需要消耗很长时间（15秒到超过5分钟），您可以考虑重新使用数据库。这里给出一些提示：
<br/>*使用MogileFS（或者CouchDB等类似的软件）在存储item。把item计算出来并dump到磁盘上。MogileFS可以很方便地覆写item，并提供快速地访问。.您甚至可以把MogileFS中的item缓存在memcached中，这样可以加快读取速度。MogileFS+Memcached的组合可以加快缓存不命中时的响应速度，提高网站的可用性。
<br/>*重新使用MySQL。MySQL的InnoDB主键查询的速度非常快。如果大部分缓存数据都可以放到VARCHAR字段中，那么主键查询的性能将更好。从memcached中按key查询几乎等价于MySQL的主键查询：将key哈希到64-bit的整数，然后将数据存储到MySQL中。您可以把原始（不做哈希）的key存储都普通的字段中，然后建立二级索引来加快查询…key被动地失效，批量删除失效的key，等等。
<br/>上面的方法都可以引入memcached，在重启memcached的时候仍然提供很好的性能。由于您不需要当心”hot”的item被memcachedLRU算法突然淘汰，用户再也不用花几分钟来等待重新生成缓存数据（当缓存数据突然从内存中消失时），因此上面的方法可以全面提高性能。
<br/>关于这些方法的细节，详见博客：http://dormando.livejournal.com/495593.html。
<br/>10、memcached是如何做身份验证的？

<br/>没有身份认证机制！memcached是运行在应用下层的软件（身份验证应该是应用上层的职责）。memcached的客户端和服务器端之所以是轻量级的，部分原因就是完全没有实现身份验证机制。这样，memcached可以很快地创建新连接，服务器端也无需任何配置。
<br/>如果您希望限制访问，您可以使用防火墙，或者让memcached监听unixdomainsocket。
<br/>11、memcached的多线程是什么？如何使用它们？
<br/>线程就是定律（threadsrule）！在StevenGrimm和Facebook的努力下，memcached1.2及更高版本拥有了多线程模式。多线程模式允许memcached能够充分利用多个CPU，并在CPU之间共享所有的缓存数据。memcached使用一种简单的锁机制来保证数据更新操作的互斥。相比在同一个物理机器上运行多个memcached实例，这种方式能够更有效地处理multigets。
<br/>如果您的系统负载并不重，也许您不需要启用多线程工作模式。如果您在运行一个拥有大规模硬件的、庞大的网站，您将会看到多线程的好处。
<br/>更多信息请参见：http://code.sixapart.com/svn/memcached/trunk/server/doc/threads.txt。
<br/>简单地总结一下：命令解析（memcached在这里花了大部分时间）可以运行在多线程模式下。memcached内部对数据的操作是基于很多全局锁的（因此这部分工作不是多线程的）。未来对多线程模式的改进，将移除大量的全局锁，提高memcached在负载极高的场景下的性能。
<br/>12、memcached能接受的key的最大长度是多少？
<br/>key的最大长度是250个字符。需要注意的是，250是memcached服务器端内部的限制，如果您使用的客户端支持”key的前缀”或类似特性，那么key（前缀+原始key）的最大长度是可以超过250个字符的。我们推荐使用使用较短的key，因为可以节省内存和带宽。
<br/>13、memcached对item的过期时间有什么限制？
<br/>过期时间最大可以达到30天。memcached把传入的过期时间（时间段）解释成时间点后，一旦到了这个时间点，memcached就把item置为失效状态。这是一个简单但obscure的机制。
<br/>14、memcached最大能存储多大的单个item？
<br/>1MB。如果你的数据大于1MB，可以考虑在客户端压缩或拆分到多个key中。
<br/>15、为什么单个item的大小被限制在1Mbyte之内？
<br/>啊…这是一个大家经常问的问题！
<br/>简单的回答：因为内存分配器的算法就是这样的。
<br/>详细的回答：Memcached的内存存储引擎（引擎将来可插拔…）,使用slabs来管理内存。内存被分成大小不等的slabschunks（先分成大小相等的slabs，然后每个slab被分成大小相等chunks，不同slab的chunk大小是不相等的）。chunk的大小依次从一个最小数开始，按某个因子增长，直到达到最大的可能值。

<br/>如果最小值为400B，最大值是1MB，因子是1.20，各个slab的chunk的大小依次是：slab1-400Bslab2-480Bslab3-576B…
<br/>slab中chunk越大，它和前面的slab之间的间隙就越大。因此，最大值越大，内存利用率越低。Memcached必须为每个slab预先分配内存，因此如果设置了较小的因子和较大的最大值，会需要更多的内存。
<br/>还有其他原因使得您不要这样向memcached中存取很大的数据…不要尝试把巨大的网页放到mencached中。把这样大的数据结构load和unpack到内存中需要花费很长的时间，从而导致您的网站性能反而不好。
<br/>如果您确实需要存储大于1MB的数据，你可以修改slabs.c:POWER_BLOCK的值，然后重新编译memcached；或者使用低效的malloc/free。其他的建议包括数据库、MogileFS等。
<br/>16、我可以在不同的memcached节点上使用大小不等的缓存空间吗？这么做之后，memcached能够更有效地使用内存吗？
<br/>Memcache客户端仅根据哈希算法来决定将某个key存储在哪个节点上，而不考虑节点的内存大小。因此，您可以在不同的节点上使用大小不等的缓存。但是一般都是这样做的：拥有较多内存的节点上可以运行多个memcached实例，每个实例使用的内存跟其他节点上的实例相同。
<br/>17、什么是二进制协议，我该关注吗？
<br/>关于二进制最好的信息当然是二进制协议规范：http://code.google.com/p/memcached/wiki/MemcacheBinaryProtocol。
<br/>二进制协议尝试为端提供一个更有效的、可靠的协议，减少客户端/服务器端因处理协议而产生的CPU时间。
<br/>根据Facebook的测试，解析ASCII协议是memcached中消耗CPU时间最多的环节。所以，我们为什么不改进ASCII协议呢？
<br/>在这个邮件列表的thread中可以找到一些旧的信息：http://lists.danga.com/pipermail/memcached/2007-July/004636.html。
<br/>memcached的内存分配器是如何工作的？为什么不适用malloc/free！？为何要使用slabs？
<br/>实际上，这是一个编译时选项。默认会使用内部的slab分配器。您确实确实应该使用内建的slab分配器。最早的时候，memcached只使用malloc/free来管理内存。然而，这种方式不能与OS的内存管理以前很好地工作。反复地malloc/free造成了内存碎片，OS最终花费大量的时间去查找连续的内存块来满足malloc的请求，而不是运行memcached进程。如果您不同意，当然可以使用malloc！只是不要在邮件列表中抱怨啊:)
<br/>slab分配器就是为了解决这个问题而生的。内存被分配并划分成chunks，一直被重复使用。因为内存被划分成大小不等的slabs，如果item的大小与被选择存放它的slab不是很合适的话，就会浪费一些内存。StevenGrimm正在这方面已经做出了有效的改进。
<br/>邮件列表中有一些关于slab的改进（powerofn还是powerof2）和权衡方案：http://lists.danga.com/pipermail/memcached/2006-May/002163.htmlhttp://lists.danga.com/pipermail/memcached/2007-March/003753.html。
<br/>如果您想使用malloc/free，看看它们工作地怎么样，您可以在构建过程中定义USE_SYSTEM_MALLOC。这个特性没有经过很好的测试，所以太不可能得到开发者的支持。
<br/>更多信息：http://code.sixapart.com/svn/memcached/trunk/server/doc/memory_management.txt。

<br/>18、memcached是原子的吗？
<br/>当然！好吧，让我们来明确一下：
<br/>所有的被发送到memcached的单个命令是完全原子的。如果您针对同一份数据同时发送了一个set命令和一个get命令，它们不会影响对方。它们将被串行化、先后执行。即使在多线程模式，所有的命令都是原子的，除非程序有bug:)
<br/>命令序列不是原子的。如果您通过get命令获取了一个item，修改了它，然后想把它set回memcached，我们不保证这个item没有被其他进程（process，未必是操作系统中的进程）操作过。在并发的情况下，您也可能覆写了一个被其他进程set的item。
<br/>memcached1.2.5以及更高版本，提供了gets和cas命令，它们可以解决上面的问题。如果您使用gets命令查询某个key的item，memcached会给您返回该item当前值的唯一标识。如果您覆写了这个item并想把它写回到memcached中，您可以通过cas命令把那个唯一标识一起发送给memcached。如果该item存放在memcached中的唯一标识与您提供的一致，您的写操作将会成功。如果另一个进程在这期间也修改了这个item，那么该item存放在memcached中的唯一标识将会改变，您的写操作就会失败。
<br/>通常，基于memcached中item的值来修改item，是一件棘手的事情。除非您很清楚自己在做什么，否则请不要做这样的事情。]]></description>
		<pubDate>Fri, 18 Mar 2011 17:09:43 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[memcache中getStats函数返回统计信息用法详解]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail1139.shtml]]></link>
		<description><![CDATA[memcache中getStats函数返回统计信息用法详解：
<br/>getStats函数可以用来统计memcache的命中率、内存使用情况等相关数据。
<br/>说明
<br/>arrayMemcache::getStats([string$type[,int$slabid[,int$limit=100]]])
<br/>Memcache::getStats()返回一个关联数据的服务器统计信息。数组key是统计信息名，值就是统计信息的值。同样你可以使用函数memcache_get_stats()。
<br/>参数
<br/>type
<br/>期望抓取的统计信息类型，可以使用的值有{reset,malloc,maps,cachedump,slabs,items,sizes}。通过memcached协议指定这些附加参数是为了方便memcache开发者(检查其中的变动)。
<br/>slabid
<br/>用于与参数type联合从指定slab分块拷贝数据，cachedump命令会完全占用服务器通常用于比较严格的调试。
<br/>limit
<br/>用于和参数type联合来设置cachedump时从服务端获取的实体条数。
<br/>返回值
<br/>返回关联数组表示的服务器统计信息或在失败时返回FALSE。

<br/>参见
<br/>*Memcache::getVersion()-返回服务器版本信息
<br/>*Memcache::getExtendedStats()-缓存服务器池中所有服务器统计信息
<br/>
<br/>Hereisamemcachestatsanalyzermethodthatcanbeusedtoprintmemcachestatsinaniceinformativetabularformat.
<br/>&lt;?php
<br/>functionprintDetails($status){
<br/>echo&quot;&lt;tableborder='1'&gt;&quot;;
<br/>echo&quot;&lt;tr&gt;&lt;td&gt;MemcacheServerversion:&lt;/td&gt;&lt;td&gt;&quot;.$status[&quot;version&quot;].&quot;&lt;/td&gt;&lt;/tr&gt;&quot;;
<br/>echo&quot;&lt;tr&gt;&lt;td&gt;Processidofthisserverprocess&lt;/td&gt;&lt;td&gt;&quot;.$status[&quot;pid&quot;].&quot;&lt;/td&gt;&lt;/tr&gt;&quot;;
<br/>echo&quot;&lt;tr&gt;&lt;td&gt;Numberofsecondsthisserverhasbeenrunning&lt;/td&gt;&lt;td&gt;&quot;.$status[&quot;uptime&quot;].&quot;&lt;/td&gt;&lt;/tr&gt;&quot;;

<br/>echo&quot;&lt;tr&gt;&lt;td&gt;Accumulatedusertimeforthisprocess&lt;/td&gt;&lt;td&gt;&quot;.$status[&quot;rusage_user&quot;].&quot;seconds&lt;/td&gt;&lt;/tr&gt;&quot;;
<br/>echo&quot;&lt;tr&gt;&lt;td&gt;Accumulatedsystemtimeforthisprocess&lt;/td&gt;&lt;td&gt;&quot;.$status[&quot;rusage_system&quot;].&quot;seconds&lt;/td&gt;&lt;/tr&gt;&quot;;

<br/>echo&quot;&lt;tr&gt;&lt;td&gt;Totalnumberofitemsstoredbythisservereversinceitstarted&lt;/td&gt;&lt;td&gt;&quot;.$status[&quot;total_items&quot;].&quot;&lt;/td&gt;&lt;/tr&gt;&quot;;
<br/>echo&quot;&lt;tr&gt;&lt;td&gt;Numberofopenconnections&lt;/td&gt;&lt;td&gt;&quot;.$status[&quot;curr_connections&quot;].&quot;&lt;/td&gt;&lt;/tr&gt;&quot;;

<br/>echo&quot;&lt;tr&gt;&lt;td&gt;Totalnumberofconnectionsopenedsincetheserverstartedrunning&lt;/td&gt;&lt;td&gt;&quot;.$status[&quot;total_connections&quot;].&quot;&lt;/td&gt;&lt;/tr&gt;&quot;;
<br/>echo&quot;&lt;tr&gt;&lt;td&gt;Numberofconnectionstructuresallocatedbytheserver&lt;/td&gt;&lt;td&gt;&quot;.$status[&quot;connection_structures&quot;].&quot;&lt;/td&gt;&lt;/tr&gt;&quot;;

<br/>echo&quot;&lt;tr&gt;&lt;td&gt;Cumulativenumberofretrievalrequests&lt;/td&gt;&lt;td&gt;&quot;.$status[&quot;cmd_get&quot;].&quot;&lt;/td&gt;&lt;/tr&gt;&quot;;
<br/>echo&quot;&lt;tr&gt;&lt;td&gt;Cumulativenumberofstoragerequests&lt;/td&gt;&lt;td&gt;&quot;.$status[&quot;cmd_set&quot;].&quot;&lt;/td&gt;&lt;/tr&gt;&quot;;

<br/>
<br/>$percCacheHit=((real)$status[&quot;get_hits&quot;]/(real)$status[&quot;cmd_get&quot;]*100);
<br/>$percCacheHit=round($percCacheHit,3);
<br/>$percCacheMiss=100-$percCacheHit;
<br/>
<br/>echo&quot;&lt;tr&gt;&lt;td&gt;Numberofkeysthathavebeenrequestedandfoundpresent&lt;/td&gt;&lt;td&gt;&quot;.$status[&quot;get_hits&quot;].&quot;($percCacheHit%)&lt;/td&gt;&lt;/tr&gt;&quot;;

<br/>echo&quot;&lt;tr&gt;&lt;td&gt;Numberofitemsthathavebeenrequestedandnotfound&lt;/td&gt;&lt;td&gt;&quot;.$status[&quot;get_misses&quot;].&quot;($percCacheMiss%)&lt;/td&gt;&lt;/tr&gt;&quot;;
<br/>
<br/>$MBRead=(real)$status[&quot;bytes_read&quot;]/(1024*1024);

<br/>
<br/>echo&quot;&lt;tr&gt;&lt;td&gt;Totalnumberofbytesreadbythisserverfromnetwork&lt;/td&gt;&lt;td&gt;&quot;.$MBRead.&quot;MegaBytes&lt;/td&gt;&lt;/tr&gt;&quot;;
<br/>$MBWrite=(real)$status[&quot;bytes_written&quot;]/(1024*1024);

<br/>echo&quot;&lt;tr&gt;&lt;td&gt;Totalnumberofbytessentbythisservertonetwork&lt;/td&gt;&lt;td&gt;&quot;.$MBWrite.&quot;MegaBytes&lt;/td&gt;&lt;/tr&gt;&quot;;
<br/>$MBSize=(real)$status[&quot;limit_maxbytes&quot;]/(1024*1024);

<br/>echo&quot;&lt;tr&gt;&lt;td&gt;Numberofbytesthisserverisallowedtouseforstorage.&lt;/td&gt;&lt;td&gt;&quot;.$MBSize.&quot;MegaBytes&lt;/td&gt;&lt;/tr&gt;&quot;;
<br/>echo&quot;&lt;tr&gt;&lt;td&gt;Numberofvaliditemsremovedfromcachetofreememoryfornewitems.&lt;/td&gt;&lt;td&gt;&quot;.$status[&quot;evictions&quot;].&quot;&lt;/td&gt;&lt;/tr&gt;&quot;;

<br/>
<br/>echo&quot;&lt;/table&gt;&quot;;
<br/>}
<br/>
<br/>?&gt;
<br/>Sampleusage:
<br/>&lt;?php
<br/>$memcache_obj=newMemcache;
<br/>$memcache_obj-&gt;addServer('memcache_host',11211);
<br/>printDetails($memcache_obj-&gt;getStats());

<br/>?&gt;
<br/>ThestatsoutputfromthisfunctionandwhatisoutputfromthegetExtendedStats()areidenticalexceptthatgetExtendedStats()providesinformationforallserversused.
<br/>pid-Processidofthisserverprocess
<br/>uptime-Numberofsecondsthisserverhasbeenrunning
<br/>time-CurrentUNIXtimeaccordingtotheserver
<br/>version-Versionstringofthisserver
<br/>rusage_user-Accumulatedusertimeforthisprocess
<br/>rusage_system-Accumulatedsystemtimeforthisprocess
<br/>curr_items-Currentnumberofitemsstoredbytheserver
<br/>total_items-Totalnumberofitemsstoredbythisservereversinceitstarted
<br/>bytes-Currentnumberofbytesusedbythisservertostoreitems
<br/>curr_connections-Numberofopenconnections
<br/>total_connections-Totalnumberofconnectionsopenedsincetheserverstartedrunning
<br/>connection_structures-Numberofconnectionstructuresallocatedbytheserver
<br/>cmd_get-Cumulativenumberofretrievalrequests
<br/>cmd_set-Cumulativenumberofstoragerequests

<br/>get_hits-Numberofkeysthathavebeenrequestedandfoundpresent
<br/>get_misses-Numberofitemsthathavebeenrequestedandnotfound
<br/>bytes_read-Totalnumberofbytesreadbythisserverfromnetwork
<br/>bytes_written-Totalnumberofbytessentbythisservertonetwork
<br/>limit_maxbytes-Numberofbytesthisserverisallowedtouseforstorage.]]></description>
		<pubDate>Thu, 17 Mar 2011 18:05:24 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[php中ignore_user_abort函数的用法]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail1138.shtml]]></link>
		<description><![CDATA[php中ignore_user_abort函数的用法：
<br/>PHP中的ignore_user_abort函数是当用户关掉终端后脚本不停止仍然在执行，可以用它来实现计划任务与持续进程，下面会通过实例讨论ignore_user_abort()函数的作用与用法。
<br/>ignore_user_abort()可以实现当客户端关闭后仍然可以执行PHP代码，可保持PHP进程一直在执行，可实现所谓的计划任务功能与持续进程，只需要开启执行脚本，除非apache等服务器重启或有脚本有输出，该PHP脚本将一直处于执行的状态，初看很实用，不过代价是一个PHP执行脚本的持续进程，开销很大，但却可以实现很多意想不到的功能。
<br/>其描述为设置与客户机断开是否会终止脚本的执行。
<br/>一，函数原型
<br/>intignore_user_abort([boolsetting])
<br/>二，版本兼容
<br/>PHP3&gt;=3.0.7,PHP4,PHP5
<br/>三，函数基础用法与实例
<br/>1，函数基础用法
<br/>1.&lt;?php
<br/>2.ignore_user_abort();
<br/>3.?&gt;
<br/>说明：调用ignore_user_abort()函数声明即使客户机断开不终止脚本的执行。
<br/>2，结合set_time_limit()函数实现一个循环脚本执行任务
<br/>1.&lt;?php
<br/>2.ignore_user_abort();
<br/>3.set_time_limit(0);
<br/>4.$interval=60*15;
<br/>5.do{
<br/>6.//执行的业务
<br/>7.}while(true);
<br/>8.?&gt;
<br/>说明：每隔15分钟循环执行
<br/>3，自定义实现文件输出并跟踪ignore_user_abort()函数的执行结果
<br/>1.&lt;?php
<br/>2.ignore_user_abort(TRUE);
<br/>3.set_time_limit(0);
<br/>4.$interval=10;
<br/>5.$stop=1;
<br/>6.do{
<br/>7.if($stop==10)break;
<br/>8.file_put_contents('phpzixue.php','CurrentTime:'.time().'Stop:'.$stop);
<br/>9.$stop++;
<br/>10.sleep($interval);
<br/>11.}while(true);
<br/>12.?&gt;
<br/>打开liuhui.php文件，文件内容如下：
<br/>CurrentTime:1273735029Stop:9
<br/>其原理是即使客户端终止脚本，仍然每隔10秒钟执行一次，并打印出当前时间与终止点，这样就可以测试出ignore_user_abort()函数的具体效果。
<br/>通过实例发现ignore_user_abort()函数非常实用，实现计划任务，完成后续任务，持续进程等非常有效。更多说明请查看PHP手册。]]></description>
		<pubDate>Tue, 08 Mar 2011 16:36:00 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[Windows下php中Memcache的安装]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail1137.shtml]]></link>
		<description><![CDATA[Windows下php中Memcache的安装：
<br/>1.下载memcache的windows稳定版（http://i.80tvb.com/wp-content/uploads/2010/11/memcached_win.zip），解压放某个盘下面，比如在c:\memcached
<br/>2.在终端（也即cmd命令界面）下输入‘c:\memcached\memcached.exe-dinstall’安装
<br/>3.再输入：‘c:\memcached\memcached.exe-dstart’启动。NOTE:以后memcached将作为windows的一个服务每次开机时自动启动。这样服务器端已经安装完毕了。
<br/>4.下载php_memcache.dll，请自己查找对应的php版本的文件
<br/>5.在C:\winnt\php.ini加入一行‘extension=php_memcache.dll’
<br/>6.重新启动Apache，然后查看一下phpinfo，如果有memcache，那么就说明安装成功！
<br/>
<br/>memcached的基本设置：
<br/>-p监听的端口
<br/>-l连接的IP地址,默认是本机
<br/>-dstart启动memcached服务
<br/>-drestart重起memcached服务
<br/>-dstop|shutdown关闭正在运行的memcached服务
<br/>-dinstall安装memcached服务
<br/>-duninstall卸载memcached服务
<br/>-u以的身份运行(仅在以root运行的时候有效)

<br/>-m最大内存使用，单位MB。默认64MB
<br/>-M内存耗尽时返回错误，而不是删除项
<br/>-c最大同时连接数，默认是1024
<br/>-f块大小增长因子，默认是1.25
<br/>-n最小分配空间，key+value+flags默认是48
<br/>-h显示帮助
<br/>Memcache环境测试：
<br/>运行下面的php文件，如果有输出Thisisatestcache!，就表示环境搭建成功。开始领略Memcache的魅力把！
<br/>&lt;?php
<br/>$mem=newMemcache();
<br/>$mem-&gt;addserver(&quot;127.0.0.1&quot;,11211);
<br/>$mem-&gt;set(&quot;mykey&quot;,&quot;Thisisatestcache!&quot;,0,60);

<br/>$val=$mem-&gt;get(&quot;mykey&quot;);
<br/>echo$val;
<br/>?&gt;
<br/>
<br/>参考文章：
<br/><ahref='http://www.phpzixue.cn/detail386.shtml'target="_blank">php中的memcache函数详解</a>]]></description>
		<pubDate>Mon, 07 Mar 2011 21:57:14 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[Web服务器透明获得客户端的IP地址]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail1135.shtml]]></link>
		<description><![CDATA[Web服务器透明获得客户端的IP地址：
<br/>php中获得客户端IP是一个非常简单的事情，程序里使用$_SERVER[&quot;REMOTE_ADDR&quot;]就可以了，但随着网络结构复杂性越来越高，比如说Apache前有Nginx，或者Nginx前有Squid，这时就复杂了，还得考虑诸如：HTTP_CLIENTADDRESS，HTTP_CLIENT_IP，HTTP_X_FORWARDED_FOR等环境变量，当然可以通过编写程序代码来处理此类逻辑，不过这样的解决方法不够透明，毕竟很多第三方程序并没有考虑这些情况，而且后面服务器的日志里面记录的IP全变成了前面服务器的IP，如此一来，Awstats之类的软件就失效了。下面看看如何透明处理：
<br/>案例1：Apache前有Nginx
<br/>有些网站使用这样的方式来分离静态请求和动态请求，Nginx放在前面处理静态请求，然后再把动态请求转发给后面的Apache，不过如此一来，Apache日志里看到的IP就是Nginx的IP了，为了能让Apache透明获取IP，可以使用mod_rpaf：
<br/>配置很简单，只需在配置文件里加上如下内容：
<br/>LoadModulerpaf_modulelibexec/apache2/mod_rpaf-2.0.so
<br/>RPAFenableOn
<br/>RPAFsethostnameOn
<br/>RPAFproxy_ips127.0.0.1192.168.0.1
<br/>RPAFheaderX-Forwarded-For
<br/>说明：192.168.0.1指的是Nginx内网IP，可以设置多个IP。
<br/>最后确认一下Nginx配置文件里在把动态请求转发给Apache的时候是否设置了如下内容：
<br/>proxy_set_headerHost$host;
<br/>proxy_set_headerX-Real-IP$remote_addr;
<br/>proxy_set_headerX-Forwarded-For$proxy_add_x_forwarded_for;
<br/>重新加载一下服务，差不多就OK了。
<br/>案例2：Nginx前有Squid
<br/>有些网站使用这样的方式来搭建分布式缓存，若干台Squid放在前面提供缓存服务，内容从后面的Nginx获取。不过如此一来，Nginx日志里看到的IP就是Squid的IP了，为了能让Nginx透明获取IP，可以使用NginxHttpRealIpModule。
<br/>NginxHttpRealIpModule缺省并没有激活，可以在编译的时候使用--with-http_realip_module选项激活它。
<br/>配置很简单，只需在配置文件里加上如下内容：
<br/>set_real_ip_from192.168.1.0/24;
<br/>set_real_ip_from192.168.2.1;
<br/>real_ip_header[X-Real-IP|X-Forwarded-For];
<br/>需要说明的地方就是设置IP源的时候可以设置单个IP，也可以设置IP段，另外是使用X-Real-IP还是X-Forwarded-For，取决于前面的服务器有哪个头。
<br/>重新加载一下服务，差不多就OK了。
<br/>另外：Lighttpd有一个类似的模块叫mod_extforward，功能类似，就不多说了。]]></description>
		<pubDate>Wed, 23 Feb 2011 11:28:57 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[php中匿名函数的使用]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail1134.shtml]]></link>
		<description><![CDATA[php中匿名函数的使用：
<br/>php匿名函数的作用就是为了扩大函数的使用功能，在PHP5.3以前，传递Callback的方式，我们只有两种选择：
<br/>1、字符串的函数名
<br/>2、使用create_function的返回
<br/>在PHP5.3以后,我们多了一个选择,也就是Closure。
<br/>1.$func=function(){...};
<br/>2.array_walk($arr,$func);
<br/>从实现上来说,第一种方式:传递函数名字符串是最简单的。而第二种方式create_function,其实和第一种方式本质上一样的,create_function返回一个字符串的函数名,这个函数名的格式是:
<br/>1.&quot;\000_lambda_&quot;.count(anonymous_functions)++
<br/>我们来看看create_function的实现步骤：
<br/>1.获取参数,函数体；
<br/>2.拼凑一个&quot;function__lambda_func(参数){函数体;}&quot;的字符串；
<br/>3.eval；
<br/>4.通过__lambda_func在函数表中找到eval后得到的函数体,找不到就出错；
<br/>5.定义一个函数名:&quot;\000_lambda_&quot;.count(anonymous_functions)++；
<br/>6.用新的函数名替换__lambda_func；
<br/>7.返回新的函数。
<br/>我们来验证下：
<br/>1.&lt;?php
<br/>2.create_function(&quot;&quot;,'echo__FUNCTION__;');
<br/>3.call_user_func(&quot;\000lambda_1&quot;,1);
<br/>4.?&gt;
<br/>5.//输出
<br/>6.__lambda_fun
<br/>因为在eval的时候,函数名是”__lambda_func”,所以匿名函数内会输出__lambda_func,而因为最后用”\000_lambda_”.count(anonymous_functions)++重命名了函数表中的”__lambda_func”函数,所以可通过”\000_lambda_”.count(anonymous_functions)++调用这个匿名函数。为了证实这一点,可以将create_function的返回值dump出来查看。
<br/>而在PHP5.3发布的时候,其中有一条newfeature就是支持闭包/LambdaFunction,我第一反应是以为zval新增了一个IS_FUNCTION,但实际上是构造了一个PHP5.3引入的Closure”类”的实例,Closure类的构造函数是私有的,所以不能被直接实例化,另外Closure类是Final类,所以也不能做为基类派生子类.
<br/>1.//php-5.3.0
<br/>2.$class=newReflectionClass(&quot;Closure&quot;);
<br/>3.var_dump($class-&gt;isInternal());
<br/>4.var_dump($class-&gt;isAbstract());
<br/>5.var_dump($class-&gt;isFinal());
<br/>6.var_dump($class-&gt;isInterface());
<br/>7.//输出:
<br/>8.bool(true)
<br/>9.bool(false)
<br/>10.bool(true)
<br/>11.bool(false)
<br/>12.?&gt;
<br/>而PHP5.3中对闭包的支持,也仅仅是把要保持的外部变量,做为Closure对象的”Static属性”(并不是普通意义上的可遍历/访问的属性).
<br/>1.//php-5.3.0
<br/>2.$b=&quot;laruence&quot;;
<br/>3.$func=function($a)use($b){};
<br/>4.var_dump($func);
<br/>5./*输出:
<br/>6.object(Closure)#1(2){
<br/>7.[&quot;static&quot;]=&gt;
<br/>8.array(1){
<br/>9.[&quot;b&quot;]=&gt;
<br/>10.string(8)&quot;laruence&quot;
<br/>11.}
<br/>12.[&quot;parameter&quot;]=&gt;
<br/>13.array(1){
<br/>14.[&quot;$a&quot;]=&gt;
<br/>15.string(10)&quot;&lt;required&gt;&quot;
<br/>16.}
<br/>17.}
<br/>18.*/
<br/>这个实现,个人认为和JS对闭包的支持比起来,还是有些太简陋了。]]></description>
		<pubDate>Sun, 20 Feb 2011 19:35:51 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[php数组中指针操作的实现代码]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail1133.shtml]]></link>
		<description><![CDATA[php数组中指针操作的实现代码：
<br/>//**
<br/>*将数组的内部指针倒回一位
<br/>*@paramarray&amp;$arr
<br/>*@returnmixed返回前一个单元的值，当没有更多单元时返回FALSE
<br/>*如果数组包含空的单元，或者单元的值是0则本函数碰到这些单元也返回FALSE
<br/>*要正确遍历可能含有空单元或者单元值为0的数组，参见each()函数
<br/>*/
<br/>mixedprev(array&amp;$arr);
<br/>&lt;?php
<br/>$transport=array('foot','bike','car','plane');
<br/>$mode=current($transport);//$mode='foot';
<br/>$mode=next($transport);//$mode='bike';
<br/>$mode=next($transport);//$mode='car';
<br/>$mode=prev($transport);//$mode='bike';
<br/>$mode=end($transport);//$mode='plane';
<br/>$mode=reset($transport);//$mode='foot';
<br/>?&gt;
<br/>array(&quot;key&quot;=&gt;&quot;value&quot;);建立数组
<br/>//显示数组
<br/>print_r($array);
<br/>//使用compact()函数新建数组,并把参数做为新数组的单元;
<br/>$newArray=compact(&quot;red&quot;,&quot;green&quot;,&quot;yellow&quot;,&quot;blue&quot;,&quot;array&quot;);
<br/>//使用extract()函数把数组中的单元转换为变量
<br/>extract($exArray);
<br/>echo&quot;$key1$key2$key3$key4$key5&quot;;
<br/>※检查值、键
<br/>array_key_exists($key,$array);//检查数组键
<br/>in_array($value,$array);//检查值于数组
<br/>※获取值
<br/>//使用array_values()取得数组的值
<br/>$carValues=array_values($car);
<br/>//取出数组的键名
<br/>$twoKeys=array_keys($two);
<br/>key($array);//输出当前单元的键名
<br/>//数组定义后,使用current()取得当前单元的值
<br/>$red=current($array);
<br/>list($red,$green)=$array;//把数组中的值赋与变量,$array=array(&quot;红色&quot;,&quot;绿色&quot;);
<br/>each($two);//返回数组中当前单元的键和值
<br/>※遍历数组
<br/>foreach($twoas$subArray);//遍历数组
<br/>while(list($key,$value)=each($array)){
<br/>echo&quot;$key=&gt;$value,&quot;;//使用each遍历数组
<br/>}
<br/>※填充数组
<br/>//向左、右填充数组
<br/>array_pad($array,+3,&quot;shuzhi&quot;);//2参数为正从左往右填充，数值大于单元数时才填充
<br/>$array1=array_fill(5,5,&quot;test&quot;);//使用array_fill()填充这个数组的值,值为test,从第5个单元开始填充,一共填充5个单元
<br/>//填充数组键名
<br/>$keys=array('string',5,10,'str');
<br/>$array3=array_fill_keys($keys,&quot;数组值&quot;);
<br/>//使用array_filp()函数交换键名与值
<br/>$speed=array_flip($speed);
<br/>//使用array_splice()函数替换第6个单元的值为7
<br/>$output=array_splice($input,6,0,7);
<br/>//使用array_splice()函数删除数组单元,只保留前5个单元
<br/>$output=array_splice($input,5);
<br/>$array1=range(10,100,10);//使用range()函数的第三个参数,设置单元之间的步进值
<br/>※排序
<br/>shuffle($array);//将数组顺序打乱
<br/>//使用array_multisort()对三个数组排序
<br/>array_multisort($sort1,$sort2,$sort3);
<br/>//把这个数组进行排序,并保持索引关系
<br/>asort($array);
<br/>//把测试数组进行逆向排序,并保持索引关系
<br/>arsort($array);
<br/>//使用ksort()对数组按键名排序
<br/>ksort($array);
<br/>//使用krsort()函数按键名逆向排序
<br/>krsort($array);
<br/>//使用sort()对测试数组进行排序[以键名排列]
<br/>sort($array);
<br/>//使用natsort()排序[自然排序,以数值排列]对单元数值大小写敏感
<br/>natsort($array);
<br/>//使用natcasesort()函数排序[自然排序]但是忽略数值大小写
<br/>natcasesort($array);
<br/>//使用array_reverse()函数排序,数组单元按相反排列
<br/>$newArray=array_reverse($array,TRUE);//TRUE设时保留原键名
<br/>※交集、差集
<br/>//使用array_diff()计算三个数组的差集[对数组数值比较]
<br/>$result=array_diff($dog1,$dog2,$dog3);
<br/>//使用array_diff_assoc()计算三个数组的差集[对数值和键名比较]
<br/>$result=array_diff_assoc($dog1,$dog2,$dog3);
<br/>//使用array_diff_key()计算三个数组的差集[比较键名]
<br/>$result=array_diff_key($dog1,$dog2,$dog3);
<br/>//使用array_intersect()计算三个数组的交集[对数组数值比较]
<br/>$result=array_intersect($dog1,$dog2,$dog3);
<br/>//使用array_intersect_assoc()计算三个数组的交集[对数值和键名比较]
<br/>$result=array_intersect_assoc($dog1,$dog2,$dog3);
<br/>//使用array_intersect_key()计算三个数组的交集[比较键名]
<br/>$result=array_intersect_key($dog1,$dog2,$dog3);
<br/>※合并数组
<br/>//使用array_merge()函数合并数组
<br/>$result=array_merge($array1,$array2,$array3,$array4,$array5);
<br/>array_rand($input,10);//随机取出10个单元
<br/>count($array,COUNT_RECURSIVE);//显示数组单元数目，2参数只可为1或者COUNT_RECURSIVE,有时可遍历多维数组
<br/>※出入栈
<br/>//数组出栈,后进先出，数组最后一个单元弹出
<br/>array_pop($array);
<br/>//数组入栈,将7，8两个数值添加到数组尾部
<br/>array_push($array，7，8);
<br/>//将数组开头单元移出数组
<br/>array_shift($array);
<br/>//将7，8添加入数组开头
<br/>array_unshift($array,7,8）;]]></description>
		<pubDate>Sat, 12 Feb 2011 21:16:07 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[用php将短URL转换为实际URL的函数]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail1131.shtml]]></link>
		<description><![CDATA[用php将短URL转换为实际URL的函数：
<br/>现在有很多都是将实际域名转换为短域名，但也有需要反转查看一下实际域名，那么就可以使用下面这个函数。
<br/>&lt;?php
<br/>$url=&quot;http://sinaurl.cn/hbdsU5&quot;;
<br/>echounshorten($url);
<br/>functionunshorten($url){
<br/>$url=trim($url);
<br/>$headers=get_headers($url);
<br/>$location=$url;
<br/>$short=false;
<br/>foreach($headersas$head){
<br/>if($head==&quot;HTTP/1.1302Found&quot;)$short=true;
<br/>if($short&amp;&amp;startwith($head,&quot;Location:&quot;)){
<br/>$location=substr($head,10);
<br/>}
<br/>}
<br/>return$location;
<br/>}
<br/>functionstartwith($Haystack,$Needle){
<br/>returnstrpos($Haystack,$Needle)===0;
<br/>}
<br/>?&gt;]]></description>
		<pubDate>Tue, 25 Jan 2011 16:27:22 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[discuz!中防止sql注入的php函数]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail1130.shtml]]></link>
		<description><![CDATA[discuz!中防止sql注入的php函数：
<br/>防止sql注入的函数，需要的了解一下。
<br/>&lt;?php
<br/>$magic_quotes_gpc=get_magic_quotes_gpc();
<br/>@extract(daddslashes($_COOKIE));
<br/>@extract(daddslashes($_POST));
<br/>@extract(daddslashes($_GET));
<br/>if(!$magic_quotes_gpc){
<br/>$_FILES=daddslashes($_FILES);
<br/>}
<br/>functiondaddslashes($string,$force=0){
<br/>if(!$GLOBALS['magic_quotes_gpc']||$force){
<br/>if(is_array($string)){
<br/>foreach($stringas$key=&gt;$val){
<br/>$string[$key]=daddslashes($val,$force);
<br/>}
<br/>}else{
<br/>$string=addslashes($string);
<br/>}
<br/>}
<br/>return$string;
<br/>}
<br/>?&gt;]]></description>
		<pubDate>Tue, 25 Jan 2011 16:17:56 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[php中strncasecmp字符串比较函数用法说明]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail1127.shtml]]></link>
		<description><![CDATA[php中strncasecmp字符串比较函数用法说明：
<br/>我们通常在进行字符串比较的时候都是先用strtolower或者strtoupper将字符串转换为小写或者大写之后，再进行判断是否相等。
<br/>但是这样就需要转换两次。大多时候，我们是针对字符集转换的时候才会这样，比如判断参数传进来是否utf-8，这5个字符的写法，可就多了，比如UTF-8，Utf-8,utf-8等，那我们怎么办呢？strtolower?strupper?不需要了。。
<br/>strncasecmp($a,$b,$length)就可以了。。
<br/>如果返回是0则相等，那我们怎么判断呢？
<br/>strncasecmp($str,'utf-8',5)==0那么，传入的参数就是utf8的，是否很方便呢？
<br/>只是这些函数我们平时不太用得到，我看到这个函数的用法却是在yiiframework，他在处理事件的时候，判断前两个字符是否为on的时候，就是这样判断的。我也因此学到了一招。
<br/>定义和用法
<br/>strncasecmp()函数的作用是：比较字符串的前n个字符（大小写不敏感）。
<br/>这个函数将返回下列值：
<br/>0–如果字符串相等
<br/>&lt;0–如果string1小于string2
<br/>&gt;0–如果string1大于string2
<br/>Syntax
<br/>语法
<br/>strncasecmp(string1,string2,length)
<br/>Parameter参数	Description描述
<br/>string1	必要参数。指定参与比较的第一个字符串对象
<br/>string2	必要参数。指定参与比较的第二个字符串对象
<br/>length		必要参数。指定每个字符串中参数比较的字符数量
<br/>注意：strncasecmp()函数是二进制精确的，并且它不区分字母大小写。
<br/>实例
<br/>&lt;?php
<br/>echostrncasecmp(&quot;Helloworld!&quot;,&quot;hellophpzixue.cn!&quot;,6);
<br/>?&gt;
<br/>结果如下：
<br/>0]]></description>
		<pubDate>Tue, 11 Jan 2011 09:21:59 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[hessian在php中的使用简介]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail1123.shtml]]></link>
		<description><![CDATA[hessian在PHP中的使用简介：
<br/>hessian是可以通过http的方式和其他的语言交换数据，类似soap。
<br/>一、hessian是什么？
<br/>Hessian是一个轻量级的远程的数据交换工具，使用简单的方法提供了RMI(远程方法调用)的功能.相比WebService，Hessian更简单、快捷。采用的是二进制RPC协议，因为采用的是二进制协议，所以它很适合于发送二进制数据
<br/>hessian是独立于语言的。
<br/>二、在PHP中怎么用的呢？
<br/>你是不是认为这个和soap一样在php.ini中开启一个就可以使用了，我也这么认为的。可
<br/>是我要告诉你的是这样的想法是错误的。
<br/>需要去下载一个HessianPHP的库来使用。
<br/>下载地址http://hessianphp.sourceforge.net/
<br/>三、看看怎么使用。
<br/>1、服务器端。
<br/>&lt;?php
<br/>include_once('HessianPHP/dist/HessianService.php');
<br/>classHelloWorldService{
<br/>publicfunction__construct(){
<br/>}
<br/>publicfunctionadd($a,$b){
<br/>return$a+$b;
<br/>}
<br/>}
<br/>$wrapper=newHessianService();
<br/>$wrapper-&gt;registerObject(newHelloWorldService);
<br/>$wrapper-&gt;displayInfo=true;
<br/>$wrapper-&gt;service();
<br/>?&gt;
<br/>2、客户端
<br/>&lt;?php
<br/>require_once'HessianPHP/dist/HessianClient.php';
<br/>Hessian::errorReporting(HESSIAN_SILENT);
<br/>$url='http://localhost/info.php';
<br/>$proxy=&amp;newHessianClient($url);
<br/>$sum=$proxy-&gt;add(3,5);
<br/>echo$sum;
<br/>if(Hessian::error()){
<br/>$errors=Hessian::error();
<br/>print_r($erros-&gt;message);
<br/>//var_dump($errors);
<br/>}
<br/>?&gt;
<br/>client结果
<br/>8]]></description>
		<pubDate>Wed, 22 Dec 2010 11:50:20 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[用php过滤网页中所有的html,css,js代码]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail1112.shtml]]></link>
		<description><![CDATA[用php过滤网页中所有的html,css,js代码：
<br/>方便做一些采集程序，有需要的朋友可以参考一下
<br/>get.php代码如下：
<tablecellspacing="0"cellpadding="6"width="95%"align="center"border="0"class="page_kuang">
<tr><tdclass="page_kuang_content">
&lt;?php
<br/>$search=array(
<br/>&quot;'&lt;script[^&gt;]*?&gt;.*?&lt;/script&gt;'si&quot;,//去掉javascript
<br/>&quot;'&lt;style[^&gt;]*?&gt;.*?&lt;/style&gt;'si&quot;,//去掉css
<br/>&quot;'&lt;[/!]*?[^&lt;&gt;]*?&gt;'si&quot;,//去掉HTML标记
<br/>&quot;'&lt;!--[/!]*?[^&lt;&gt;]*?&gt;'si&quot;,//去掉注释标记
<br/>&quot;'([rn])[s]+'&quot;,//去掉空白字符
<br/>&quot;'&amp;(quot|#34);'i&quot;,//替换HTML实体
<br/>&quot;'&amp;(amp|#38);'i&quot;,
<br/>&quot;'&amp;(lt|#60);'i&quot;,
<br/>&quot;'&amp;(gt|#62);'i&quot;,
<br/>&quot;'&amp;(nbsp|#160);'i&quot;,
<br/>&quot;'&amp;(iexcl|#161);'i&quot;,
<br/>&quot;'&amp;(cent|#162);'i&quot;,
<br/>&quot;'&amp;(pound|#163);'i&quot;,
<br/>&quot;'&amp;(copy|#169);'i&quot;,
<br/>&quot;'&amp;#(d+);'e&quot;);//作为PHP代码运行
<br/>$replace=array(&quot;&quot;,
<br/>&quot;&quot;,
<br/>&quot;&quot;,
<br/>&quot;&quot;,
<br/>&quot;\1&quot;,
<br/>&quot;\&quot;&quot;,
<br/>&quot;&amp;&quot;,
<br/>&quot;&lt;&quot;,
<br/>&quot;&gt;&quot;,
<br/>&quot;&quot;,
<br/>chr(161),
<br/>chr(162),
<br/>chr(163),
<br/>chr(169),
<br/>&quot;chr(\1)&quot;);
<br/>//$document为需要处理字符串，如果来源为文件可以$document=file_get_contents('http://www.phpzixue.cn/');
<br/>$out=preg_replace($search,$replace,$document);
<br/>echo$out;
<br/>?&gt;</td></tr></table>]]></description>
		<pubDate>Fri, 15 Oct 2010 10:42:25 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[给php初学者的一点建议]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail1111.shtml]]></link>
		<description><![CDATA[给php初学者的一点建议：
<br/>下面几点是给php初学者一些建议，当然也其它语言也类似,真正理解和体会到了你很快就可以变为一个php达人。
<br/>1.概要：学习任何语言都需要多看多想多写多问！！写编程是一种熟能生巧的东西！因为知识就那么多，你看多了就会觉得怎么都一样。
<br/>程序员就是炒冷饭的，一遍又一遍。代码多敲几遍就可以闭着眼睛写了，所以企业招聘都会问你写过多少行代码的！！程序员最忌讳浮躁，有时候发现一段程序完全找不出错误，仅仅是因为少了或多了一个符号，程序员需要的是细心，粗心的人当不了程序员！
<br/>2.php参考手册是必须熟知的，有的初学者会问一些很基础的问题，其实手册上面都有，所以建议初学者先把手册看了，最好把常用函数抄几遍！！再敲几遍手册里的代码。
<br/>当你把手册里的东西都熟悉了，你遇到问题的可能性就很小了。当然mysql手册，也要看一下，但可以不先看的那么细！至少要知道常用的sql语句，这是必须的！
<br/>3.觉得php最好的东西就是，网上能找的开源项目很多，而且一些都是大项目的。所以建议初学者可以看留言板代码，先熟悉常用的数据操作，然后可以去看一下简单的企业网站或者博客，然后可以去研究一下ecshop之类，当你看懂这些，你可以去看看discuz，phpwind论坛源码，里面的架构都是相当强悍的，当然这不是初学者需要去做的，但是总要有个做将军的理想！
<br/>4.要习惯，遇到问题自己先解决，在网络时代，要学会用百度谷歌，这是必须的。当你实在没法解决的时候再去寻求别人的帮助！！
<br/>5.记住，学了php你要不只是学会php，你要学会分析一个项目的实现方式或者一个程序的实现方式。都说算法是语言的基础，要学好php，你还得去学习和运用算法去实现你的程序，学会用算法可以用于任何语言，学会用php你只能用php.
<br/>6.当你写完一个程序的时候，要学会分享出去，因为你是初学者，你的程序也许会有很多不完善的地方，所以分享你写的程序对你更有益！！多分享多交流！才会让你写的程序更精！！]]></description>
		<pubDate>Fri, 15 Oct 2010 10:33:59 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[用php批量更改目录及子目录下所有文件后缀名的方法]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail1102.shtml]]></link>
		<description><![CDATA[用php批量更改目录及子目录下所有文件后缀名的方法：
<br/>更改文件的后缀名，要是少量的还可以手动的改，要是大量的手动改起来就麻烦了，于是写了一些脚本来批量的更改文件的后缀名，使用php递归的方法，代码如下：
<br/>&lt;?php
<br/>//本文件和要改变的目录下的文件放在同一文件夹下
<br/>define(&quot;STA&quot;,&quot;.gif&quot;);//原来的图片格式
<br/>define(&quot;END&quot;,&quot;.jpg&quot;);//要改变的格式
<br/>$dir=&quot;./&quot;;

<br/>$arr=allfile($dir);
<br/>foreach($arras$t)
<br/>{
<br/>$t=str_replace(&quot;.//&quot;,&quot;&quot;,$t);
<br/>if(substr_count($t,STA)&gt;0)
<br/>{
<br/>$f2=str_replace(STA,&quot;&quot;,$t);
<br/>rename($t,$f2.END);
<br/>}
<br/>}
<br/>//获取目录下所有文件的函数
<br/>functionallfile($dir)

<br/>{
<br/>$files=array();
<br/>if(is_file($dir))
<br/>{
<br/>return$dir;
<br/>}
<br/>$handle=opendir($dir);
<br/>if($handle){
<br/>while(false!==($file=readdir($handle))){
<br/>if($file!='.'&amp;&amp;$file!='..'){
<br/>$filename=$dir.&quot;/&quot;.$file;
<br/>if(is_file($filename)){

<br/>$files[]=$filename;
<br/>}else{
<br/>$files=array_merge($files,allfile($filename));
<br/>}
<br/>}
<br/>}//endwhile
<br/>closedir($handle);
<br/>}
<br/>return$files;
<br/>}
<br/>?&gt;]]></description>
		<pubDate>Sun, 26 Sep 2010 10:57:36 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[php中magic_quotes_gpc的使用详解]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail1098.shtml]]></link>
		<description><![CDATA[php中magic_quotes_gpc的使用详解：
<br/>PHP中有一个特殊的函数魔术函数，它在引用的过程中只有在传递$_GET,$_POST,$_COOKIE时才会发生作用。
<br/>对其中的数据有单引号的数据做转义处理。
<br/>第一种情况：
<br/>条件：PHPmagic_quotes_gpc=off
<br/>写入数据库的字符串未经过任何过滤处理。从数据库读出的字符串也未作任何处理。
<br/>数据：$data=”snow”’’sun”;(snow和sun之间是四个连续的单引号).
<br/>操作：将字符串:”snow”’’sun”写入数据库，
<br/>结果：出现sql语句错误，mysql不能顺利完成sql语句，写入数据库失败。
<br/>数据库保存格式：无数据。
<br/>输出数据格式：无数据。
<br/>说明：对于未经处理的单引号在写入数据库时会使sql语句发生错误。
<br/>第二种情况：
<br/>条件：PHPmagic_quotes_gpc=off
<br/>写入数据库的字符串经过函数addlashes()处理。从数据库读出的字符串未作任何处理。
<br/>数据：$data=”snow”’’sun”;(snow和sun之间是四个连续的单引号).
<br/>操作：将字符串:”snow”’’sun”写入数据库，

<br/>结果：sql语句顺利执行，数据成功写入数据库
<br/>数据库保存格式：snow”’’sun(和输入一样)
<br/>输出数据格式：snow”’’sun(和输入一样)
<br/>说明：addslashes()函数将单引号转换为\’的转义字符使sql语句成功执行，
<br/>但\’并未作为数据存入数据库，数据库保存的是snow”’’sun而并不是我们想象的snow\’\’\’\’sun
<br/>第三种情况：
<br/>条件：PHPmagic_quotes_gpc=on
<br/>写入数据库的字符串未经过任何处理。从数据库读出的字符串未作任何处理。
<br/>数据：$data=”snow”’’sun”;(snow和sun之间是四个连续的单引号).
<br/>操作：将字符串:”snow”’’sun”写入数据库，
<br/>结果：sql语句顺利执行，数据成功写入数据库
<br/>数据库保存格式：snow”’’sun(和输入一样)
<br/>输出数据格式：snow”’’sun(和输入一样)
<br/>说明：PHPmagic_quotes_gpc=on将单引号转换为\’的转义字符使sql语句成功执行，
<br/>但\’并未作为数据入数据库，数据库保存的是snow”’’sun而并不是我们想象的snow\’\’\’\’sun。
<br/>第四种情况：
<br/>条件：PHPmagic_quotes_gpc=on

<br/>写入数据库的字符串经过函数addlashes()处理。从数据库读出的字符串未作任何处理。
<br/>数据：$data=”snow”’’sun”;(snow和sun之间是四个连续的单引号).
<br/>操作：将字符串:”snow”’’sun”写入数据库，
<br/>结果：sql语句顺利执行，数据成功写入数据库
<br/>数据库保存格式：snow\’\’\’\’sun(添加了转义字符)
<br/>输出数据格式：snow\’\’\’\’sun(添加了转义字符)
<br/>说明：PHPmagic_quotes_gpc=on将单引号转换为\’的转义字符使sql语句成功执行，
<br/>addslashes又将即将写入数据库的单引号转换为\’,后者的转换被作为数据写入
<br/>数据库，数据库保存的是snow\’\’\’\’sun
<br/>总结如下：
<br/>1.对于PHPmagic_quotes_gpc=on的情况，
<br/>我们可以不对输入和输出数据库的字符串数据作
<br/>addslashes()和stripslashes()的操作,数据也会正常显示。
<br/>如果此时你对输入的数据作了addslashes()处理，
<br/>那么在输出的时候就必须使用stripslashes()去掉多余的反斜杠。
<br/>2.对于PHPmagic_quotes_gpc=off的情况
<br/>必须使用addslashes()对输入数据进行处理，但并不需要使用stripslashes()格式化输出

<br/>因为addslashes()并未将反斜杠一起写入数据库，只是帮助mysql完成了sql语句的执行。
<br/>补充：
<br/>PHPmagic_quotes_gpc作用范围是：web客户服务端；作用时间：请求开始时，例如当脚本运行时．
<br/>magic_quotes_runtime作用范围：从文件中读取的数据或执行exec()的结果或是从sql查询中得到的；作用时间：每次当脚本访问运行状态中产生的数据.]]></description>
		<pubDate>Wed, 15 Sep 2010 09:48:51 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[php中使用curl模拟用户登录实例详解]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail1097.shtml]]></link>
		<description><![CDATA[php中使用curl模拟用户登录实例详解：
<br/>要使用curl需要php开启curl模块。默认不支持。
<br/>函数语法：
<br/>boolcurl_setopt(intch,stringoption,mixedvalue)
<br/>curl_setopt()函数将为一个CURL会话设置选项。option参数是你想要的设置，value是这个选项给定的值。
<br/>下列选项的值将被作为长整形使用(在option参数中指定)：　
<br/>*CURLOPT_INFILESIZE:当你上传一个文件到远程站点，这个选项告诉PHP你上传文件的大小。
<br/>*CURLOPT_VERBOSE:如果你想CURL报告每一件意外的事情，设置这个选项为一个非零值。
<br/>*CURLOPT_HEADER:如果你想把一个头包含在输出中，设置这个选项为一个非零值。
<br/>*CURLOPT_NOPROGRESS:如果你不会PHP为CURL传输显示一个进程条，设置这个选项为一个非零值。
<br/>注意：PHP自动设置这个选项为非零值，你应该仅仅为了调试的目的来改变这个选项。
<br/>*CURLOPT_NOBODY:如果你不想在输出中包含body部分，设置这个选项为一个非零值。
<br/>*CURLOPT_FAILONERROR:如果你想让PHP在发生错误(HTTP代码返回大于等于300)时，不显示，设置这个选项为一人非零值。默认行为是返回一个正常页，忽略代码。
<br/>*CURLOPT_UPLOAD:如果你想让PHP为上传做准备，设置这个选项为一个非零值。
<br/>*CURLOPT_POST:如果你想PHP去做一个正规的HTTPPOST，设置这个选项为一个非零值。这个POST是普通的application/x-www-from-urlencoded类型，多数被HTML表单使用。
<br/>*CURLOPT_FTPLISTONLY:设置这个选项为非零值，PHP将列出FTP的目录名列表。
<br/>*CURLOPT_FTPAPPEND:设置这个选项为一个非零值，PHP将应用远程文件代替覆盖它。
<br/>*CURLOPT_NETRC:设置这个选项为一个非零值，PHP将在你的~./netrc文件中查找你要建立连接的远程站点的用户名及密码。
<br/>*CURLOPT_FOLLOWLOCATION:设置这个选项为一个非零值(象&quot;Location:&quot;)的头，服务器会把它当做HTTP头的一部分发送(注意这是递归的，PHP将发送形如&quot;Location:&quot;的头)。
<br/>*CURLOPT_PUT:设置这个选项为一个非零值去用HTTP上传一个文件。要上传这个文件必须设置CURLOPT_INFILE和CURLOPT_INFILESIZE选项.
<br/>*CURLOPT_MUTE:设置这个选项为一个非零值，PHP对于CURL函数将完全沉默。
<br/>*CURLOPT_TIMEOUT:设置一个长整形数，作为最大延续多少秒。
<br/>*CURLOPT_LOW_SPEED_LIMIT:设置一个长整形数，控制传送多少字节。
<br/>*CURLOPT_LOW_SPEED_TIME:设置一个长整形数，控制多少秒传送CURLOPT_LOW_SPEED_LIMIT规定的字节数。
<br/>*CURLOPT_RESUME_FROM:传递一个包含字节偏移地址的长整形参数，(你想转移到的开始表单)。
<br/>*CURLOPT_SSLVERSION:传递一个包含SSL版本的长参数。默认PHP将被它自己努力的确定，在更多的安全中你必须手工设置。
<br/>*CURLOPT_TIMECONDITION:传递一个长参数，指定怎么处理CURLOPT_TIMEVALUE参数。你可以设置这个参数为TIMECOND_IFMODSINCE或TIMECOND_ISUNMODSINCE。这仅用于HTTP。
<br/>*CURLOPT_TIMEVALUE:传递一个从1970-1-1开始到现在的秒数。这个时间将被CURLOPT_TIMEVALUE选项作为指定值使用，或被默认TIMECOND_IFMODSINCE使用。
<br/>下列选项的值将被作为字符串：　
<br/>*CURLOPT_URL:这是你想用PHP取回的URL地址。你也可以在用curl_init()函数初始化时设置这个选项。
<br/>*CURLOPT_USERPWD:传递一个形如[username]:[password]风格的字符串,作用PHP去连接。
<br/>*CURLOPT_PROXYUSERPWD:传递一个形如[username]:[password]格式的字符串去连接HTTP代理。
<br/>*CURLOPT_RANGE:传递一个你想指定的范围。它应该是&quot;X-Y&quot;格式，X或Y是被除外的。HTTP传送同样支持几个间隔，用逗句来分隔(X-Y,N-M)。
<br/>*CURLOPT_POSTFIELDS:传递一个作为HTTP&quot;POST&quot;操作的所有数据的字符串。
<br/>*CURLOPT_REFERER:在HTTP请求中包含一个&quot;referer&quot;头的字符串。
<br/>*CURLOPT_USERAGENT:在HTTP请求中包含一个&quot;user-agent&quot;头的字符串。
<br/>*CURLOPT_FTPPORT:传递一个包含被ftp&quot;POST&quot;指令使用的IP地址。这个POST指令告诉远程服务器去连接我们指定的IP地址。这个字符串可以是一个IP地址，一个主机名，一个网络界面名(在UNIX下)，或是'-'(使用系统默认IP地址)。
<br/>*CURLOPT_COOKIE:传递一个包含HTTPcookie的头连接。
<br/>*CURLOPT_SSLCERT:传递一个包含PEM格式证书的字符串。
<br/>*CURLOPT_SSLCERTPASSWD:传递一个包含使用CURLOPT_SSLCERT证书必需的密码。
<br/>*CURLOPT_COOKIEFILE:传递一个包含cookie数据的文件的名字的字符串。这个cookie文件可以是Netscape格式，或是堆存在文件中的HTTP风格的头。
<br/>*CURLOPT_CUSTOMREQUEST:当进行HTTP请求时，传递一个字符被GET或HEAD使用。为进行DELETE或其它操作是有益的，更PassastringtobeusedinsteadofGETorHEADwhendoinganHTTPrequest.Thisisusefulfordoingoranother,moreobscure,HTTPrequest.
<br/>注意:在确认你的服务器支持命令先不要去这样做。
<br/>下列的选项要求一个文件描述(通过使用fopen()函数获得)：
<br/>*CURLOPT_FILE:这个文件将是你放置传送的输出文件，默认是STDOUT.
<br/>*CURLOPT_INFILE:这个文件是你传送过来的输入文件。
<br/>*CURLOPT_WRITEHEADER:这个文件写有你输出的头部分。
<br/>*CURLOPT_STDERR:这个文件写有错误而不是stderr。
<br/>用来获取需要登录的页面的例子,当前做法是每次或许都登录一次,有需要的人再做改进了。
<br/>实例:
<tablecellspacing="0"cellpadding="6"width="95%"align="center"border="0"class="page_kuang">
<tr><tdclass="page_kuang_content">&lt;?php
<br/>$cookie_jar=tempnam('./tmp','cookie');
<br/>$ch=curl_init();
<br/>curl_setopt($ch,CURLOPT_URL,'http://www.QQView.com');
<br/>curl_setopt($ch,CURLOPT_POST,1);
<br/>$request='email_address=&amp;password=&amp;action=';
<br/>curl_setopt($ch,CURLOPT_POSTFIELDS,$request);
<br/>//把返回来的cookie信息保存在$cookie_jar文件中
<br/>curl_setopt($ch,CURLOPT_COOKIEJAR,$cookie_jar);
<br/>//设定返回的数据是否自动显示
<br/>curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
<br/>//设定是否显示头信息
<br/>curl_setopt($ch,CURLOPT_HEADER,false);
<br/>//设定是否输出页面内容
<br/>curl_setopt($ch,CURLOPT_NOBODY,false);
<br/>curl_exec($ch);
<br/>curl_close($ch);
<br/>//getdataafterlogin
<br/>$ch2=curl_init();
<br/>curl_setopt($ch2,CURLOPT_URL,'http://www.phpzixue.cn/');
<br/>curl_setopt($ch2,CURLOPT_HEADER,false);
<br/>curl_setopt($ch2,CURLOPT_RETURNTRANSFER,1);
<br/>curl_setopt($ch2,CURLOPT_COOKIEFILE,$cookie_jar);
<br/>$orders=curl_exec($ch2);
<br/>echo'&lt;pre&gt;';
<br/>echostrip_tags($orders);
<br/>echo'&lt;/pre&gt;';
<br/>curl_close($ch2);
<br/>?&gt;</td></tr></table>]]></description>
		<pubDate>Tue, 14 Sep 2010 16:11:40 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[php使用zlib扩展实现页面的gzip压缩输出]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail1093.shtml]]></link>
		<description><![CDATA[php使用zlib扩展实现页面的gzip压缩输出：
<br/>php中的GZIP（GNU-ZIP）是一种压缩技术。经过GZIP压缩后页面大小可以变为原来的30%甚至更小。这样用户浏览的时候就会感觉很快。
<br/>要实现GZIP压缩页面需要浏览器和服务器共同支持，实际上就是服务器压缩，传到浏览器后浏览器解压并解析。浏览器那边不需要我们担心，因为现在绝大多数浏览器都支持解析GZIP过的页面。我们只要把页面在服务器端压缩再输出到浏览器就行了。
<br/>要压缩一个页面，首先要获得要输出的内容。PHP中的ob_start()（ob=&gt;outputbuffer）函数可以实现这个功能，它可以把程序里准备输出的内容先放到一个叫做“缓冲区”的地方。这个函数一定要在页面输出之前使用，所以一般把它放在代码的最顶端。
<br/>&lt;?php
<br/>functionob_gzip($content)//$content就是要压缩的页面内容
<br/>{
<br/>if(!headers_sent()&amp;&amp;//如果页面头部信息还没有输出
<br/>extension_loaded(&quot;zlib&quot;)&amp;&amp;//而且zlib扩展已经加载到PHP中

<br/>strstr($_SERVER[&quot;HTTP_ACCEPT_ENCODING&quot;],&quot;gzip&quot;)){//而且浏览器说它可以接受GZIP的页面
<br/>$content=gzencode($content.&quot;此页已压缩&quot;,9);//为准备压缩的内容贴上“此页已压缩”的注释标签，然后用zlib提供的gzencode()函数执行级别为9的压缩，这个参数值范围是0-9，0表示无压缩，9表示最大压缩，当然压缩程度越高越费CPU。
<br/>//然后用header()函数给浏览器发送一些头部信息，告诉浏览器这个页面已经用GZIP压缩过了！
<br/>header(&quot;Content-Encoding:gzip&quot;);

<br/>header(&quot;Vary:Accept-Encoding&quot;);
<br/>header(&quot;Content-Length:&quot;.strlen($content));
<br/>}
<br/>return$content;//返回压缩的内容
<br/>}
<br/>?&gt;
<br/>压缩机做好了之后，我们把压缩机放到工作台上，于是原来的ob_start()变成ob_start('ob_gzip');//没错，就是给ob_start()加一个参数，参数名就是我们刚才做的“压缩机”的函数名。这样当内容进入缓冲区后PHP就会调用ob_gzip函数把它压缩了。
<br/>好了，所有的工作已完成，最后交货：

<br/>ob_end_flush();//结束缓冲区，输出内容。当然，不用这个函数也行，因为程序执行到最后会自动将缓冲区内容输出。
<br/>完整的示例如下：
<br/>&lt;?php
<br/>//启用一个带有ob_gzip压缩机的工作台
<br/>ob_start('ob_gzip');
<br/>//准备一些待压缩的内容
<br/>for($i=0;$i&lt;100;$i++){
<br/>echo('需要压缩的内容');
<br/>}
<br/>//输出压缩成果
<br/>ob_end_flush();
<br/>//这是ob_gzip压缩机
<br/>functionob_gzip($content){
<br/>if(!headers_sent()&amp;&amp;

<br/>extension_loaded(&quot;zlib&quot;)&amp;&amp;
<br/>strstr($_SERVER[&quot;HTTP_ACCEPT_ENCODING&quot;],&quot;gzip&quot;)){
<br/>$content=gzencode($content.&quot;此页已压缩&quot;,9);
<br/>header(&quot;Content-Encoding:gzip&quot;);

<br/>header(&quot;Vary:Accept-Encoding&quot;);
<br/>header(&quot;Content-Length:&quot;.strlen($content));
<br/>}
<br/>return$content;
<br/>}
<br/>?&gt;
<br/>经过实际测试，上面代码中如果不用GZIP，是4.69KB=4802.56B，启用GZIP后缩小为104B，
<br/>另外，下面是用FlashGet获取的日志信息，可以看到我们程序里加的header信息：

<br/>FriJan2517:53:102010HTTP/1.1200OK
<br/>FriJan2517:53:102010Server:Microsoft-IIS/5.1
<br/>FriJan2517:53:102010Date:Fri,25Jan200809:53:10GMT
<br/>FriJan2517:53:102010Connection:close
<br/>FriJan2517:53:102010X-Powered-By:PHP/5.2.5
<br/>FriJan2517:53:102010Content-Encoding:gzip
<br/>FriJan2517:53:102010Vary:Accept-Encoding
<br/>FriJan2517:53:102010Content-Length:104
<br/>FriJan2517:53:102010Content-type:text/html]]></description>
		<pubDate>Wed, 01 Sep 2010 17:50:37 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[php计算用户在线时长的几种方法]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail1092.shtml]]></link>
		<description><![CDATA[php计算用户在线时长的几种方法：
<br/>下面是计算用户在线时长的几种常用的方法，根据不同情况可做相应的选择：
<br/>首先介绍一下所涉及的数据表结构，四个字段：
<br/>uid&lt;int(10)&gt;：用户id
<br/>session_id&lt;varchar(40)&gt;：用户登录后系统产生的session_id，PHP可是使用session_id()函数获取
<br/>login_time&lt;int(10)&gt;：登录时间
<br/>logout_time&lt;int(10)&gt;：登出时间
<br/>1.服务器设定一个定时轮询的脚本。这个方法是在服务器端写一个定时执行的脚本，比如5分钟执行一次，根据数据库中的记录来判断每个会话的session_id是否还存在于服务器上，如果存在就更新logout_time,不存在就跳过。这样也能比较准确的统计在线时间，不过缺点是需要有服务器的控制权，不然无法设定定时脚本，linux系统可以通过crontab实现，windows系统可以通过计划任务来完成。如果你只是买的虚拟主机，那么这个方法也同样不适合你。
<br/>2.客户端定时发送请求到服务器端。实现方法是在用户登录后，将uid,session_id,login_time插入一条记录，然后在客户端js设定一个计时器，比如每10分钟向服务器端发送一个请求，以此来达到更新登出时间的目的，当然这个间隔时间设定的越短，数据可能会越准确，不过相应的系统的负载也会越高，这个可以根据实际情况设定一个合适的值。这种方法广泛应用于webgame上，因为webgame的几乎所有请求都是ajax请求，不用刷新页面，一旦刷新页面，这个计时器就失去了价值，这也是这个方法的局限性。
<br/>3.在用户每次活动时更新一下登出时间。这样在用户不活动或者退出的时候，登出时间就自然而然的存在于数据库里了，这也是本文着重讨论的方案。下面给出实现方法。
<br/>首先，在用户登录成功后，记录下其uid,session_id,并将现在时间作为登陆时间，现在时间+600s作为登出时间，插入数据库。
<br/>&lt;?php
<br/>$uid=$_SESSION['uid']=$info['id'];
<br/>$session_id=$_SESSION['session_id']=session_id();
<br/>$login_time=time();
<br/>$logout_time=time()+600;
<br/>$sql=&quot;INSERTINTOmember_login(uid,session_id,login_time,logout_time)values($uid,'$session_id',$login_time,$logout_time)&quot;;
<br/>mysql_query($sql);
<br/>?&gt;
<br/>然后在用户每次活动，也就是每点击一个页面时，如果session存在也就是处于登录状态时，更新用户登出时间
<br/>&lt;?php
<br/>if($_SESSION['uid']){
<br/>$uid=$_SESSION['uid'];
<br/>$session_id=$_SESSION['session_id'];
<br/>$logout_time=time()+600;
<br/>$sql=&quot;UPDATEmember_loginSETlogout_time=$logout_timeWHEREuid=$uidANDsession_id='$session_id'&quot;;
<br/>mysql_query($sql);
<br/>}
<br/>?&gt;
<br/>这种方法的优点是相对来说实现起来比较简单，能够适用于大多数的网站，没有额外的服务器需求，而且也可以比较准确的统计用户的在线时间。
<br/>缺点也很明显，增加了数据库的更新操作，增加了系统的负载，不过对于中小型网站来说应该不是问题。]]></description>
		<pubDate>Sun, 29 Aug 2010 20:10:37 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[PHP中作用域解析运算符(::)的用法]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail1084.shtml]]></link>
		<description><![CDATA[PHP中作用域解析运算符(::)的用法：
<br/>ScopeResolutionOperator(::)
<br/>本人一直以为作用域解析运算符只能访问类的static方法和static成员变量。
<br/>其实不然，下面有个简单的小测试代码可以证明这个。
<br/>&lt;?php
<br/>classA{
<br/>private$_name='A';
<br/>function__construct(){
<br/>echo'Aconstruct&lt;br/&gt;';
<br/>}
<br/>functiontest(){
<br/>echo'Atest()&lt;br/&gt;';
<br/>}
<br/>}
<br/>classBextendsA{
<br/>private$_name='B';
<br/>function__construct(){
<br/>parent::__construct();
<br/>echo'Bconstruct&lt;br/&gt;';
<br/>}
<br/>functiontest(){
<br/>echo'Btest()';
<br/>}
<br/>}
<br/>A::test();
<br/>echo'#########&lt;br/&gt;';
<br/>B::test();
<br/>?&gt;
<br/>这段代码输入的结果为：
<br/>Atest()
<br/>#########
<br/>Btest()
<br/>虽然A类中的test()和B类中的test都不是static方法，但是一样可以用“类名::方法名称(参数列表)”的样式进行正确调用。他的效果和new一个类的实例，然后用这个实例调用
<br/>test方法是一个样的。
<br/>但是，如果我需要在test方法中打印name属性，直接用::来调用会是怎么个情况那.我们首先来修改下上面的代码。
<br/>&lt;?php
<br/>classA{
<br/>private$_name='A';
<br/>function__construct(){
<br/>echo'Aconstruct&lt;br/&gt;';
<br/>}
<br/>functiontest(){
<br/>echo'Atest()&lt;br/&gt;',$this-&gt;$_name,'&lt;br/&gt;';
<br/>}
<br/>}
<br/>classBextendsA{
<br/>private$_name='B';
<br/>function__construct(){
<br/>parent::__construct();
<br/>echo'Bconstruct&lt;br/&gt;';
<br/>}
<br/>functiontest(){
<br/>echo'Btest()',$this-&gt;_name,'&lt;br/&gt;';
<br/>}
<br/>}
<br/>A::test();
<br/>echo'#########&lt;br/&gt;';
<br/>B::test();
<br/>?&gt;
<br/>上面的代码运行的结果如下：
<br/>Fatalerror:Using$thiswhennotinobjectcontextinD:\www\test\scoperefe.phponline9
<br/>那有的朋友就说了。你压根就没有实例化类A，当然不能直接用$this-&gt;_name的方式来访问成员变量$_name了，那么，是不是修改成self::$_name就行了哪？
<br/>说干就干，下面把上面的代码修改下
<br/>&lt;?php
<br/>classA{
<br/>private$_name='A';
<br/>function__construct(){
<br/>echo'Aconstruct&lt;br/&gt;';
<br/>}
<br/>functiontest(){
<br/>echo'Atest()&lt;br/&gt;',self::$_name,'&lt;br/&gt;';
<br/>}
<br/>}
<br/>classBextendsA{
<br/>private$_name='B';
<br/>function__construct(){
<br/>parent::__construct();
<br/>echo'Bconstruct&lt;br/&gt;';
<br/>}
<br/>functiontest(){
<br/>echo'Btest()',$this-&gt;_name,'&lt;br/&gt;';
<br/>}
<br/>}
<br/>A::test();
<br/>echo'#########&lt;br/&gt;';
<br/>B::test();
<br/>?&gt;
<br/>再运行上面的代码，结果如下：
<br/>Atest()Fatalerror:Accesstoundeclaredstaticproperty:A::$_nameinD:\www\test\scoperefe.phponline9
<br/>哦，原来不能用self关键字访问当前类的非static方法。
<br/>现在，如果想正确的调用这个方法，有2个做法：
<br/>1、首先实例化类，然后用对象调用就可以直接使用$this-&gt;_name进行调用了；
<br/>2、将成员变量$_name设置为static；
<br/>上面的问题，相信大家都能够正确的处理。
<br/>其实我真正想说的是：
<br/>如果一个方法可以不进行实例化就调用，那么我们最好把这个方法使用static关键字修饰下。在实现方法的时候，只调用该类的static成员变量。这样就不会出现上面遇到问题了。
<br/>如果一个方法没有设置为static的方法。那么，最安全的做法还是用实例对象进行调用更为安全，因为，说不定什么时候就需要修改该方法的实现，在修改的时候，说不定就要调用该类中的
<br/>非static成员变量（因为，很大程度上在修改方法的实现的时候，已经忘记还有用类名直接调用这么一说）。]]></description>
		<pubDate>Sun, 01 Aug 2010 21:14:43 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[php中in_array()函数使用注意事项]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail1083.shtml]]></link>
		<description><![CDATA[php中in_array()函数使用注意事项：
<br/>函数原型：
<br/>boolin_array(mixedneedle,arrayhaystack[,boolstrict])
<br/>在haystack中搜索needle，如果找到则返回TRUE，否则返回FALSE。
<br/>如果第三个参数strict的值为TRUE则in_array()函数还会检查needle的类型是否和haystack中的相同。
<br/>其实最关键的还是因为php是弱类型的语言，在使用in_array()的时候最好还是加上strict参数。因为这样不但比较两者的值是否一直，还会比较两者的类型是否一直。
<br/>另外，我们在控制结构比较两个数值是否一直的时候，也应该尽量使用===来代替==（当然，这个也根据具体的业务逻辑选用比较合适的）。
<br/>下面解释一下为什么
<br/>var_dump(in_array(0,array('s'));
<br/>这句话的结果是bool(true)。
<br/>因为in_array会将0和's'进行比较，0是number类型，'s'是string类型，根据phpmanual中“ComparisonOperators”一章的说明可知，number和string进行
<br/>比较的时候，会先将string类型首先转化为number，然后再进行比较操作。's'转化为number的结果为0，而0==0的结果是true，所以in_array(0,array('s','ss'))的结果也是true
<br/>如果把in_array的第三个参数strict设置为true，比较的时候就会判断值和类型是否都相当。如果都相当的话，才会返回true，否则返回false.]]></description>
		<pubDate>Sun, 01 Aug 2010 20:29:36 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[php中register_shutdown_function函数用法详解]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail1082.shtml]]></link>
		<description><![CDATA[php中register_shutdown_function函数用法详解：
<br/>由于程序出现一些不可预知的问题，给用户显示一个致命错误,又或者一个空白页(在display_errors设为off的情况下)，不是一个很好的处理方法.PHP中有一个叫做register_shutdown_function的函数,可以让我们设置一个当执行关闭时可以被调用的另一个函数.也就是说当我们的脚本执行完成或意外死掉导致PHP执行即将关闭时,我们的这个函数将会被调用.所以,我们可以使用在脚本开始处设置一个变量为false,然后在脚本末尾将之设置为true的方法,让PHP关闭回调函数检查脚本完成与否.如果我们的变量仍旧是false,我们就知道脚本的最后一行没有执行,因此它肯定在程序执行到某处死掉了.我准备了一个非常基本的例子,可以演示在一个致命错误需要显示时,你应该怎么给用户一些合适的反馈.你可以通过关闭致命错误的显示(译注:可以设置display_errors和error_reporting),让例子看起来好看些.
<br/>&lt;?php
<br/>$clean=false;
<br/>functionshutdown_func(){
<br/>global$clean;
<br/>if(!$clean){
<br/>die(&quot;notacleanshutdown&quot;);
<br/>}
<br/>returnfalse;
<br/>}
<br/>register_shutdown_function(&quot;shutdown_func&quot;);
<br/>$a=1;

<br/>$a=newFooClass();//将因为致命错误而失败
<br/>$clean=true;
<br/>?&gt;
<br/>正如你所看到,如果关闭回调函数运行时,clean变量没有被设为true,shutdown_func函数将会打印出一些东西.这个东西可以包装成一个类(不使用全局变量).
<br/>PHP提供register_shutdown_function()这个函数，能够在脚本终止前回调注册的函数,也就是当PHP程序执行完成后执行的函数。
<br/>例子:
<br/>&lt;!DOCTYPEhtmlPUBLIC&quot;-//W3C//DTDXHTML1.0Transitional//EN&quot;&quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;
<br/>&lt;htmlxmlns=&quot;http://www.w3.org/1999/xhtml&quot;&gt;
<br/>&lt;head&gt;

<br/>&lt;metahttp-equiv=&quot;Content-Type&quot;content=&quot;text/html;charset=gb2312&quot;/&gt;
<br/>&lt;title&gt;register_shutdown_function示例&lt;/title&gt;
<br/>&lt;/head&gt;
<br/>&lt;body&gt;
<br/>&lt;?php

<br/>$starttime=microtime(true);
<br/>functionTest(){
<br/>$starttime=microtime(true);
<br/>if(!file_exists(&quot;Test.txt&quot;)){//判断如果文件不存在!!
<br/>$Str=fopen(&quot;Test.txt&quot;,&quot;w+&quot;);
<br/>fwrite($Str,&quot;我是在最后写进来的.时间:$starttime&quot;);
<br/>fclose($Str);
<br/>echo&quot;创建完成!创建时间:$starttime&quot;;

<br/>}
<br/>else{//如果存在;
<br/>echo&quot;文件已经存在&quot;;
<br/>}
<br/>}
<br/>register_shutdown_function(&quot;Test&quot;);
<br/>echo&quot;程序开始:&quot;.$starttime.&quot;&lt;br&gt;&quot;;
<br/>for($i=0;$i&lt;1000;$i++){

<br/>echo&quot;Echo&lt;br/&gt;&quot;;
<br/>}
<br/>exit;
<br/>?&gt;
<br/>&lt;/body&gt;
<br/>&lt;/html&gt;
<br/>register_shutdown_function的作用是指定当本页面所有脚本执行完成之后执行的函数。
<br/>&lt;?php
<br/>functionaaa(){
<br/>echo&quot;创建文件&quot;;

<br/>if($ttt=fopen(&quot;D:/web_root/tx.txt&quot;,&quot;w+&quot;))　　//此处要用绝对路径，用相对路径即无效。原因请看后面的解释
<br/>{
<br/>fwrite($ttt,&quot;youarewriteafterexit&quot;);
<br/>fclose($ttt);
<br/>}
<br/>}
<br/>register_shutdown_function(&quot;aaa&quot;);　　//函数名称无需带括号，用引号包住即可。　当本页面所有语句都执行完成，或者超时时aa函数。
<br/>exit();
<br/>?&gt;

<br/>register_shutdown_function　执行机制是：ＰＨＰ把要调用的函数调入内存。当页面所有ＰＨＰ语句都执行完成时，再调用此函数。注意，在这个时候从内存中调用，不是从php页面中调用，所以上面的例子不能使用相对路径，因为php已经当原来的页面不存在了。就没有什么相对路径可言。
<br/>注意：register_shutdown_function　是指在执行完所有ＰＨＰ语句后再调用函数，不要理解成客户端关闭流浏览器页面时调用函数。
<br/>可以这样理解调用条件：
<br/>1、当页面被用户强制停止时
<br/>2、当程序代码运行超时时
<br/>3、当ＰＨＰ代码执行完成时]]></description>
		<pubDate>Wed, 21 Jul 2010 17:06:19 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[Smarty控制页面某一部分不被缓存的三种实现方法]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail1078.shtml]]></link>
		<description><![CDATA[Smarty控制页面某一部分不被缓存的三种实现方法：
<br/>Smarty提供了强大的缓存功能。但有时候我们不希望整篇文档都被缓存，而是选择的缓存某一部分内容或某一部分不被缓存，Smarty提供了三种方法实现:
<br/>看下面的例子
<br/>模块文件test.html:
<br/>使用insert函数使模板一部分不被缓存
<br/>&lt;br&gt;&lt;{$file}&gt;&lt;{$str}&gt;&lt;br&gt;
<br/>&lt;div&gt;这里是insert更新部分&lt;{insertname=&quot;get_current_time&quot;}&gt;&lt;/div&gt;

<br/>&lt;br&gt;
<br/>使用register_function阻止内容从缓存输出
<br/>&lt;div&gt;这里是register_function函数更新部分&lt;{current_time}&gt;&lt;/div&gt;
<br/>&lt;br&gt;
<br/>使用register_block使用整篇页面的某一块区域不被缓存

<br/>&lt;div&gt;
<br/>Pagecreated:&lt;{&quot;0&quot;|date_format:&quot;%D%H:%M:%S&quot;}&gt;
<br/>&lt;{dynamic}&gt;
<br/>Nowis:&lt;{&quot;0&quot;|date_format:&quot;%D%H:%M:%S&quot;}&gt;

<br/>&lt;{/dynamic}&gt;
<br/>&lt;/div&gt;
<br/>test.php:
<br/>&lt;?php
<br/>include_once(&quot;sm_config.php&quot;);
<br/>$smarty-&gt;caching=true;
<br/>functioninsert_get_current_time(){
<br/>returndate(&quot;Y-m-dH:m:s&quot;);

<br/>}
<br/>functionsmarty_function_current_time($params,$smarty){
<br/>returndate(&quot;Y-m-dH:m:s&quot;);
<br/>}
<br/>functionsmarty_block_dynamic($param,$content,$smarty){
<br/>return$content;
<br/>}
<br/>if(!$smarty-&gt;is_cached(&quot;test.html&quot;)){
<br/>$file=&quot;缓存内容:&quot;;

<br/>$str=&quot;HelloWorld!&quot;;
<br/>}
<br/>$smarty-&gt;register_function(&quot;current_time&quot;,&quot;smarty_function_current_time&quot;,false);
<br/>$smarty-&gt;register_block(&quot;dynamic&quot;,&quot;smarty_block_dynamic&quot;,false);

<br/>$smarty-&gt;assign(&quot;str&quot;,$str);
<br/>$smarty-&gt;assign(&quot;file&quot;,$file);
<br/>$smarty-&gt;display(&quot;test.html&quot;);
<br/>?&gt;
<br/>注意每次刷新都会更新时间，这部分就是不被缓存的，其实变量可修改内容后再刷新，也不会变化，因为已经被缓存过了。
<br/>总结:
<br/>insert非常方便，register_function和register_block更灵活，但register_function要在is_cached()前完成注册函数，不然会因找不到注册函数而导致smarty错误。]]></description>
		<pubDate>Fri, 11 Jun 2010 17:01:25 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[腾讯网php程序员面试题]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail1076.shtml]]></link>
		<description><![CDATA[腾讯网php程序员面试题：
<br/>有兴趣的可以看一下
<br/>说在前面：
<br/>１、以下题目，除了编程任务外其他都需要写在给你提供的草纸上。纸张是珍贵的地球资源，请节约使用。编程任务在有相应的环境时，会要求上机书写，实在没有条件，就只能写在草纸上了。
<br/>２、时间：
<br/>基础任务＋进阶任务＋设计任务＝90分钟
<br/>编程任务＝60分钟
<br/>
<br/>基础任务：
<br/>１、请列举你能想到的UNIX信号，并说明信号用途。
<br/>２、请列举、你能想到的所有的字符串查找算法，并加注释简单说明。
<br/>３、有一个IP地址（192.168.0.1），请写出其32位无符号整数形式。
<br/>４、写出、你能想到的所有HTTP返回状态值，并说明用途（比如：返回404表示找不到页面）
<br/>
<br/>基础任务-选作（会得到额外分数）：
<br/>１、画几个你最熟悉的SERVER端模型出来（格式不重要，尽量将图画清楚，说明思路即可）
<br/>

<br/>进阶任务：
<br/>１、PHP的垃圾收集机制是怎样的？
<br/>　　说明：
<br/>　　１）如果，你熟悉PHP源码，那么请从源码入手，回答些问题，会获得额外加分
<br/>　　２）如果，你不熟悉PHP源码，那么尽你所能，多写点东西，包括利用自己的编程直觉得到的信息，都可以。
<br/>　　３）对，则有分，错误不扣，不写无分。
<br/>２、请写出HTTP头，并符合以下要求：
<br/>　　１）这是一个post请求
<br/>　　２）目标：http://www.example.com:8080/test
<br/>　　３）POST变量：
<br/>　　　　username:test
<br/>　　　　pwd:test2
<br/>　　　　intro:Helloworld!
<br/>　　４）包含以下COOKIE信息：
<br/>　　　　cur_query:you&amp;me
<br/>　　说明：

<br/>　　１）如果，你记不得某个HTTP协议中的指令字了，那么，无奈这举是用“汉字”代替。
<br/>　　２）如果，你能记住更多的HTTP协议指令字，那么多写几句，总是没坏处，对吧？
<br/>　　３）最关键的，只需要画出正确的“轮廓”（还记得httpwatch等工具打印出来的头部吗？那就是“轮廓”的含义），也会有分数，但如果，连“轮廓”都写错了，那么就很遗憾了。
<br/>
<br/>设计任务：
<br/>１、最近总有人骚扰我们的投票模块，需要你来设计一个投票限制的东东
<br/>　　要求如下：
<br/>　　１）要求每个QQ号码（假设此QQ号码在UNIT32内可以表示）10分钟这内只能投5票。
<br/>　　２）我们的用户很踊跃，平均每天要有2000万人左右通过此程序投票。
<br/>　　说明：
<br/>　　１）无需写代码，只需要图跟文字即可。
<br/>　　２）对于关键逻辑，请用图加代码表示出来，这也是对你文字表达能力的一个考验。
<br/>　　３）对你能想到的所有的边界条件列出来，这是对你逻辑思维全面与敏捷性的考验。
<br/>　　４）存储部分，尽你所能吧。如果，你需要一个自己设计的存储层，那么把这个存储层的实现，用文字＋图片方式描述清楚，要是设计合理，你会获得华丽的奖分。
<br/>
<br/>编程任务：
<br/>１、我们碰到了大麻烦，一个新来的传教士惹恼了上帝，上帝很愤怒，要求我们把圣经（bbe.txt）背熟，直至他说哪个单词，我们就要飞快的回答出这个单词在第几行第几个单词位置。听说你是个优秀的程序员，那么髟助我们完成这个不可能的任务吧。

<br/>　　要求如下：
<br/>　　１）/myworks/example/bbe.txt，98版本英文圣经一本
<br/>　　２）输入部分要求如下：php./example.php[单词]
<br/>　　３）输出部分如下：[单词]1,22,45,6　表示：此单词在1行2列（第二个单词），2行4列...
<br/>　　说明：
<br/>　　１）此文本4MB之巨...
<br/>　　２）单词的含义：由英文字母（大小写），数字（0-9）组成的串
<br/>　　３）提供给你的机器OS为ubuntu9.10，内存只有1G，而且，很不幸的，其中700M用来做了别的
<br/>　　４）上机考试不允许上网，但我装了man文档以及读取CHM以及PDF的阅读器，在电脑的桌面的CHM文件夹中，有相应的PHP参考手册
<br/>　　５）算法复杂度要求不能大于O（N^2）（就是N的平方）
<br/>　　６）什么？PHP低效且用起来不顺手，好的，你可以用别的语言来实现。但注意：提供给你的机器上只有python2.4/perl5.8/gcc[g++]4.1]]></description>
		<pubDate>Tue, 08 Jun 2010 13:12:54 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[php中session跨域跨服务器的解决方案]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail1073.shtml]]></link>
		<description><![CDATA[php中session跨域跨服务器的解决方案：
<br/>在网上查了一下，除了asp.net外，所有session的保留都必须借助sessionid。Session的保存位置众说风云，主要有：共享文件、数据库、memcache。因此主要的问题就集中在了sessionid的传递。
<br/>Sessionid的传递主要有四个方法：
<br/>1、通过cookie。
<br/>2、设置php.ini中的session.use_trans_sid=1或者编译时打开打开了--enable-trans-sid选项，让PHP自动跨页传递sessionid。
<br/>3、手动通过url或隐藏表单传值。
<br/>4、用文件或数据库方式传递，在通过其他key对应取值。
<br/>以上的2和3其实使用的是同样的方法，只是途径不一样。
<br/>通过以上的分析我们不难看出，通过cookie传递sessionid，将session存储于memcache服务器中是为一个比较合理的选择。当出现跨域的情况是，可以使用p3p跨域设置cookie。而当客户端禁用cookie的情况下，可以设置php.ini，通过url自动传递sessionid。
<br/>以下我们以通行证为例，探讨其逻辑实现过程（视需求而定，而如果要保证接口的一致性，同时对其他服务器屏蔽session服务器，所有的登陆和获取session信息可以都通过登录服务器进行中转，不过这自然会有时间的延误和登录服务器宕机引起的全站瘫痪风险）：
<br/>包含服务和应用：登陆服务器，保存session的memcache服务器，应用服务器，公钥，密钥
<br/>（1）、对于可信任服务器：
<br/>可以通过登陆公钥加密用户提交的用户名、密码等信息，，直接从客户端提交登录服务器，或通过rpc调用提交登陆服务器，进行用户登陆。
<br/>登录服务器将获取登陆用户的相关信息，以session的方式存于session服务器，并以p3p方式在客户端cookie中设置所有域名下的sessionid，sessionid以session加密公钥方式进行加密。如果使用的是rpc调用，则由本台服务器设置客户端cookie。如果没有将所有的域名都进行设置，可能出现的情况是，没有设置的域名下的模块需要单独重新登录。（cookie不可用的情况将全部使用url传递使用session加密公钥加密过的sessionid，也不存在跨域问题。）
<br/>登录之后，客户端通过session解密公钥，解密通过cookie或url传递的sessionid，并通过此id从session服务器获取对应session信息，在各模块间漫游。（也可以统一通过登录服务器读取session信息。Session服务器可以使用多机定时备份，防止宕机或改服务重启引起的用户登陆session丢失问题。）
<br/>（2）、对于非可信任的合作用户：
<br/>可以通过api接口传递用户名，密码或/和验证码等相关参数。验证码可以是双方确认的某一key，或用户资料等信息。登录服务器验证确认来源之后，产生一个一次性使用的密钥，返回调用端。密钥由请求端和登录服务器共同保存和维持，其他相关需要保存和维持的信息由请求端完成。后面实现同（1）。与（1）的主要不同在于：1），必须先确认请求身份；2），使用密钥而不使用公钥；3），读取session必须通过登录服务器.]]></description>
		<pubDate>Tue, 25 May 2010 09:23:24 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[PHP中用Smarty实现静态化HTML页面]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail1072.shtml]]></link>
		<description><![CDATA[PHP中用Smarty实现静态化HTML页面:
<br/>&lt;?php
<br/>require_once(&quot;./config/config.php&quot;);
<br/>ob_start();
<br/>$id=$_GET[id];
<br/>$sql=&quot;select*fromtable_namewhereid='$id'&quot;;
<br/>$result=mysql_query($sql);
<br/>$rs=mysql_fetch_object($result);
<br/>$smarty-&gt;assign(&quot;showtitle&quot;,$rs-&gt;title);
<br/>$smarty-&gt;assign(&quot;showcontent&quot;,$rs-&gt;content);
<br/>$smarty-&gt;display(&quot;content.html&quot;);
<br/>$this_my_f=ob_get_contents();
<br/>ob_end_clean();
<br/>$filename=&quot;$id.html&quot;;
<br/>tohtmlfile_cjjer($filename,$this_my_f);
<br/>//文件生成函数
<br/>functiontohtmlfile_cjjer($file_cjjer_name,$file_cjjer_content){
<br/>if(is_file($file_cjjer_name)){
<br/>@unlink($file_cjjer_name);//存在，就删除
<br/>}
<br/>$cjjer_handle=fopen($file_cjjer_name,&quot;w&quot;);//创建文件
<br/>if(!is_writable($file_cjjer_name)){//判断写权限
<br/>returnfalse;
<br/>}
<br/>if(!fwrite($cjjer_handle,$file_cjjer_content)){
<br/>returnfalse;
<br/>}
<br/>fclose($cjjer_handle);//关闭指针
<br/>return$file_cjjer_name;//返回文件名
<br/>}
<br/>?&gt;
<br/>最后在将生成的静态页面发布到web上。]]></description>
		<pubDate>Wed, 19 May 2010 11:10:08 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[用php实现在文件指定行插入数据的方法]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail1066.shtml]]></link>
		<description><![CDATA[用php实现在文件指定行插入数据的方法：
<br/>用php实现在文件指定行插入数据的方法实现起来比较复杂，看下面的代码
<br/>&lt;?php
<br/>$arrInsert=insertContent(&quot;array.php&quot;,&quot;abcdef&quot;,3,10);
<br/>unlink(&quot;array.php&quot;);
<br/>foreach($arrInsertas$value)
<br/>{
<br/>file_put_contents(&quot;array.php&quot;,$value,FILE_APPEND);
<br/>}
<br/>functioninsertContent($source,$s,$iLine,$index){
<br/>$file_handle=fopen($source,&quot;r&quot;);
<br/>$i=0;
<br/>$arr=array();
<br/>while(!feof($file_handle)){
<br/>$line=fgets($file_handle);
<br/>++$i;
<br/>if($i==$iLine){
<br/>if($index==strlen($line)-1)
<br/>$arr[]=substr($line,0,strlen($line)-1).$s.&quot;n&quot;;
<br/>else
<br/>$arr[]=substr($line,0,$index).$s.substr($line,$index);
<br/>}else{
<br/>$arr[]=$line;
<br/>}
<br/>}
<br/>fclose($file_handle);
<br/>return$arr;
<br/>}
<br/>//在多数据我们存储数据都是用数据库教程来操作，上面我们就是把数据以X格式存在文本中了，现在我要像操作数据库一样的，想删除那行就那行，保存数据也一样，怎么读取第几行就第几行了，所以我就写出来了php在文件指定行插入数据实例。
<br/>?&gt;
<br/>$iLine:为第几行,$index为第几个字符之前]]></description>
		<pubDate>Sun, 09 May 2010 10:00:05 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[php中包含远程文件allow_url_include的解释和用法]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail1057.shtml]]></link>
		<description><![CDATA[php中包含远程文件allow_url_include的解释和用法：
<br/>PHP常常因为它可能允许URLS被导入和执行语句被人们指责。事实上，这件事情并不是很让人感到惊奇，因为这是导致称为RemoteURLIncludevulnerabilities的php应用程序漏洞的最重要的原因之一。
<br/>因为这个原因，许多安全研究人员建议在php.ini配置中禁用指向allow_url_fopen。不幸的是，许多推荐这种方法的人，并没有意识到，这样会破坏很多的应用并且并不能保证100%的解决remoteURLincludes以及他带来的不安全性。
<br/>通常，用户要求在他们使用其他的文件系统函数的时候，php允许禁止URL包含和请求声明支持。
<br/>因为这个原因，计划在PHP6中提供allow_url_include。在这些讨论之后，这些特性在php5.2.0中被backported。现在大多数的安全研究人员已经改变了他们的建议，只建议人们禁止allow_url_include。
<br/>不幸的是，allow_url_fopen和allow_url_include并不是导致问题的原因。一方面来说在应用中包含本地文件仍然是一件足够危险的事情，因为攻击者经常通过sessiondata,fileupload,logfiles,...等方法获取php代码………
<br/>另一方面allow_url_fopen和allow_url_include只是保护了againstURLhandles标记为URL.这影响了http(s)andftp(s)但是并没有影响php或date(newinphp5.2.0)urls.这些url形式，都可以非常简单的进行php代码注入。
<br/>例1:Usephp://inputtoreadthePOSTdata
<br/>&lt;?php
<br/>//InsecureInclude
<br/>//ThefollowingIncludestatementwill
<br/>//includeandexecuteeverythingPOSTed
<br/>//totheserver
<br/>include&quot;php://input&quot;;
<br/>?&gt;
<br/>例2:Usedata:toIncludearbitrarycode
<br/>&lt;?php
<br/>//InsecureInclude
<br/>//ThefollowingIncludestatementwill
<br/>//includeandexecutethebase64encoded
<br/>//payload.Herethisisjustphpinfo()
<br/>include&quot;data:;base64,PD9waHAgcGhwaW5mbygpOz8+&quot;;
<br/>?&gt;
<br/>把这些放到我们的运算里面将会非常明显的发现既不是url_allow_fopen也不是url_allor_include被保障。这些只是因为过滤器很少对矢量进行过滤。能够100%解决这个URLincludevulnerabilities的方法是我们的Suhosin扩展.]]></description>
		<pubDate>Sat, 24 Apr 2010 12:49:03 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[php中文字符写库和显示乱码问题的解决方法]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail1056.shtml]]></link>
		<description><![CDATA[php中文字符写库和显示乱码问题的解决方法：
<br/>这个的问题就出在在php里没有告诉mysql数据库你要插入的数据是gbk类型的，要解决其实很简单。连接数据库后加上这么一句话就OK了。
<br/>大家以后在编写过程中，一定要记得定义字符类型。
<br/>mysql_query(&quot;setnames'gbk'&quot;)
<br/>下面是实例代码：
<br/>&lt;?php
<br/>/*
<br/>filename:query.php
<br/>do:getandshowthedata
<br/>author:www.phpzixue.cn
<br/>*/
<br/>include_once(&quot;conn.php&quot;);
<br/>include_once(&quot;include.php&quot;);
<br/>mysql_query(&quot;setnames'gbk'&quot;)ordie(&quot;设置字符库失败\n&quot;);
<br/>mysql_select_db($db)ordie(&quot;连接数据库失败!\n&quot;);
<br/>$exec=&quot;select*from$table&quot;;
<br/>//echo$exec;
<br/>$result=mysql_query($exec,$conn)ordie(&quot;查询数据库失败\n&quot;);
<br/>echo&quot;&lt;tableborder=2&gt;&quot;;
<br/>for($cout=0;$cout&lt;mysql_numrows($result);$cout++){
<br/>$city=mysql_result($result,$cout,city);
<br/>$name=mysql_result($result,$cout,name);
<br/>$phone=mysql_result($result,$cout,phone);
<br/>echo&quot;&lt;tr&gt;&quot;;
<br/>echo&quot;city:$city&quot;;
<br/>echo&quot;name:$name&quot;;
<br/>echo&quot;phone:$phone&quot;;
<br/>echo&quot;&lt;/tr&gt;&quot;;
<br/>}
<br/>echo&quot;&lt;/table&gt;&quot;;
<br/>?&gt;]]></description>
		<pubDate>Thu, 15 Apr 2010 13:17:35 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[Socket编程在php中的应用]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail1054.shtml]]></link>
		<description><![CDATA[Socket编程在php中的应用：
<br/>下面的代码是一个接收输入字符串,处理并返回这个字符串到客户端的TCP服务.
<br/>代码如下:
<br/>&lt;?php
<br/>//设置一些基本的变量
<br/>$host=&quot;192.168.1.198&quot;;
<br/>$port=1234;
<br/>//设置超时时间
<br/>set_time_limit(0);
<br/>//创建一个Socket
<br/>$socket=socket_create(AF_INET,SOCK_STREAM,0)ordie(&quot;Couldnotcreatesocket\n&quot;);
<br/>//绑定Socket到端口
<br/>$result=socket_bind($socket,$host,$port)ordie(&quot;Couldnotbindtosocket\n&quot;);
<br/>//开始监听链接
<br/>$result=socket_listen($socket,3)ordie(&quot;Couldnotsetupsocketlistener\n&quot;);
<br/>//acceptincomingconnections
<br/>//另一个Socket来处理通信
<br/>$spawn=socket_accept($socket)ordie(&quot;Couldnotacceptincomingconnection\n&quot;);
<br/>//获得客户端的输入
<br/>$input=socket_read($spawn,1024)ordie(&quot;Couldnotreadinput\n&quot;);
<br/>//清空输入字符串
<br/>$input=trim($input);
<br/>//处理客户端输入并返回结果
<br/>$output=strrev($input).&quot;\n&quot;;
<br/>socket_write($spawn,$output,strlen($output))ordie(&quot;Couldnotwriteoutput\n&quot;);
<br/>//关闭sockets
<br/>socket_close($spawn);
<br/>socket_close($socket);
<br/>?&gt;]]></description>
		<pubDate>Sun, 11 Apr 2010 15:25:46 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[php中setcookie函数用法详解]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail1052.shtml]]></link>
		<description><![CDATA[php中setcookie函数用法详解：
<br/>php手册中对setcookie函数讲解的不是很清楚，下面是我做的一些整理，欢迎提出意见。
<br/>语法：
<br/>boolsetcookie(stringname[,stringvalue[,intexpirel[,stringpath[,stringdomain[,intsecure]]]]].
<br/>参数介绍：
<br/>第一个：name,必选参数，这个是cookie的变量名，可以通过$_COOKIE['user']调用变量名为user的cookie.
<br/>第二：value,可选参数，这个cookie变量的值,比如说setcookie(&quot;user&quot;,&quot;php&quot;),我们通过调用$_COOKIE['user']可以得到php值;
<br/>第三个：expire,可选参数，这个是用来设置cookie变量保存的时间，注意是我们设置的的UNIX时间戳减去当前的UNIX时间戳才是cookie变量保存的时间。（UNIX时间戳：是从1970年1月1日（UTC/GMT的午夜）开始所经过的秒数)，一般我们可以通过time()函数获取当前的UNIX时间戳，再加上我们要保存的时间（单位为秒）比如说，setcookie(&quot;user&quot;,&quot;php&quot;,time()+3600),这样我们就可以保存user这个cookie变量的时间为3600秒。另外我们可以通过设置的时间戳小于当前的时间戳来删除cookie变量，比如说setcookie(&quot;user&quot;,&quot;php&quot;,time()-1)这样我们就删除了user这个cookie变量了。
<br/>第四个：path,cookie的有效范围，这个参数是下一个参数domain基础上的有效范围，如果path设置为&quot;/&quot;，那就是在整个domain都有效，比如setcookie(&quot;user&quot;,&quot;php&quot;,time()+3600,&quot;/&quot;),这样我们domain下的任何目录，任何文件都可以通过$_COOKIE['user']来调用这个cookie变量的值。如果path设置为&quot;/test&quot;,那么只在domain下的/test目录及子目录才有效，比如domain下有两个目录:test1,test2,我们设置为setcookie(&quot;user&quot;,&quot;php,time()+3600,&quot;/test1&quot;)，那么只有test1目录下才能通过$_COOKIE['user']调用user这个cookie变量的值，test2目录下获取不到。
<br/>第五个：domain,cookie有效的域名，如果domain,设置为phpzixue.cn，那么在phpzixue.cn下的所有子域都有效。假设phpzixue.cn有两个子域，php.phpzixue.cn，css.phpzixue.cn，我们设置为setcookie(&quot;user&quot;,&quot;php&quot;,time()+3600,&quot;/&quot;,&quot;php.phpzixue.cn&quot;),那么只有在php.phpzixue.cn这个子域下才能获取user这个cookie变量的值.再举一个例子：setcookie(&quot;user&quot;,&quot;php&quot;,time()+3600,&quot;/test&quot;,&quot;php.phpzixue.cn&quot;),那么只有在php.phpzixue.cn这个子域下的test目录下才能获取user这个cookie变量的值.
<br/>第六个：secure，值cookie是否仅通过安全的https,值为0或1，如果值为1，则cookie只能在https连接上有效，默认值为0，表示cookie在http和https连接上都有效。
<br/>使用cookie技术计算网站的月访问量：
<br/>&lt;?php
<br/>header(&quot;Content-type:text/html;charset=utf-8&quot;);//选择utf-8编码
<br/>if(empty($_COOKIE['counter']))//如果cookie不存在
<br/>$counter=1;//设置$counter的初始值为1;
<br/>else//如果cookie存在
<br/>$counter=$_COOKIE['counter']+1;//每刷新一次页面，将$conunter变量的值累计加1.
<br/>//每刷新一次页面,cookie变量的值都重新赋予新的$counter的值，也就是不断累计加1.
<br/>setcookie('counter',$counter,time()+2678400);//time()+2678400就是说保存2678400秒，也就是一个月。
<br/>echo&quot;你是第$_COOKIE[counter]位访客!!&quot;;//通过$_COOKIE['counter']调用cookie变量的值。
<br/>?&gt;]]></description>
		<pubDate>Wed, 07 Apr 2010 11:09:24 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[smarty中往insert中传参数的方法]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail1051.shtml]]></link>
		<description><![CDATA[smarty中往insert中传参数的方法：
<br/>smarty里insert方法传参数的方法介绍如下:
<br/>smarty模板:
<br/>{insertname=&quot;getPara&quot;p1=&quot;php&quot;p2=&quot;zixue&quot;}
<br/>
<br/>php代码:
<br/>functioninsert_getPara($arr)
<br/>{
<br/>return$arr[&quot;p1&quot;].&quot;&quot;.$arr[&quot;p2&quot;];
<br/>}
<br/>
<br/>将输出:phpzixue
<br/>
<br/>用insert方法的时候,代码里的函数名前面一定要有&quot;insert_&quot;否则会出错,当然除了你改了模板规则.
<br/>其中p1,p2,是要传的两个参数名,可以有多个,任意的,只要里外对应就行.$arr表示数组也是随便写的.]]></description>
		<pubDate>Tue, 06 Apr 2010 10:14:17 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[php中设置session永不过期的方法]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail1050.shtml]]></link>
		<description><![CDATA[php中设置session永不过期的方法：
<br/>让PHP的session永不过期，其实很简单，只需修改系统环境配置，打开php.ini设置文件，修改三行如下：
<br/>1、session.use_cookies
<br/>把这个的值设置为1，利用cookie来传递sessionid
<br/>2、session.cookie_lifetime
<br/>这个代表SessionID在客户端Cookie储存的时间，默认是0，代表浏览器一关闭SessionID就作废，就是因为这个数值所以PHP的session不能永久使用！那么我们把它设置为一个我们认为很大的数字吧，如：999999999。
<br/>3、session.gc_maxlifetime
<br/>这个是Session数据在服务器端储存的时间，如果超过这个时间，那么Session数据就自动删除！那么我们也把它设置为如：99999999。
<br/>就这样一切ok了，当然你不相信的话就测试一下看看——设置一个session值过个10天半个月的回来看看，如果你的电脑没有断电或者宕机，你仍然可以看见这个sessionid。
<br/>
<br/>当然也可能你没有控制服务器的权限并不能像我一样幸运的可以修改php.ini设置，一切依靠我们自己也是有办法的，当然就必须利用到客户端存储cookie了，把得到的sessionID存储到客户端的cookie里面，设置这个cookie的值，然后把这个值传递给session_id()这个函数，具体做法如下：
<br/>&lt;?php
<br/>session_start();//启动Session
<br/>$_SESSION['count'];//注册Session变量Count
<br/>isset($PHPSESSID)?session_id($PHPSESSID):$PHPSESSID=session_id();
<br/>//如果设置了$PHPSESSID，就将SessionID赋值为$PHPSESSID，否则生成SessionID
<br/>$_SESSION['count']++;//变量count加1
<br/>setcookie('PHPSESSID',$PHPSESSID,time()+3156000);//储存SessionID到Cookie中
<br/>echo$count;//显示Session变量count的值
<br/>?&gt;
<br/>如果很久以后你回来刷新这个页面，输出的数字比你走的时候大了1那就对了！如果大了很多，估计是谁动你电脑了，这次测试就不准确了！
<br/>注意：在setcookie一行中的’PHPSESSID’并不是一定的，如果你遇到有个患有修改狂疾病的网管员，他可能对其做了修改，最好的方法是用phpinfo()这个函数看看，确认一下session.name一项的值，比较科学。]]></description>
		<pubDate>Wed, 31 Mar 2010 13:42:21 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[php中利用header实现文件下载]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail1049.shtml]]></link>
		<description><![CDATA[php中利用header实现文件下载：
<br/>在PHP帮助文档里面关于PHP通过header触发下载的说明比较简单，而网上对这方面说明的也很少，很多文章都无法实现我们所需要的效果。
<br/>下面以PDF文件格式为例进行说明：
<br/>&lt;?php
<br/>　　//We'llbeoutputtingaPDF
<br/>　　header('Content-type:application/pdf');
<br/>　　//Itwillbecalleddownloaded.pdf
<br/>　　header('Content-Disposition:attachment;filename=&quot;downloaded.pdf&quot;');
<br/>　　//ThePDFsourceisinoriginal.pdf
<br/>　　readfile('original.pdf');
<br/>?&gt;
<br/>这三句是正确的，但是在真正用的过程中很容易出现一些无法预料的问题，如果你是一个很仔细的人的话，也可以很容易的避免这些问题。而我不是，所以我就遇到了这样的问题，这里就以我的问题来简单说一下。
<br/>对于第一句，应该没啥说的，是必须的，只要改一下文档的类型就行，例如是下载txt文件，那就改为header(’Content-type:application/txt’);。
<br/>第二句也没啥说的，就是为你的下载文档起一个名字，如果是txt文件的话，可以改为header(’Content-Disposition:attachment;filename=”downloaded.txt”‘);。
<br/>第三句的问题就比较多了，readfile这个函数的意思就是读取一个文件然后输出，这里文件的路径需要是真实的文件路径，如果是downloads文件夹下面的一个original.txt文件，可以这样写readfile(’downloads/original.txt’);，而如果提交的页面会输出文本等字符，那么下载到的文件会是原文件original.txt和提交的页面输出的文字的混合文件。我在这里就缺少了仔细的观察，一看下面不对就立即去查代码了，而没发现上面的文本就是我需要的内容，发现了这部分内容，你可能就很快想到怎么来解决这个问题了，也就是关闭提交到的页面的文本内容的输出。
<br/>到这里，问题就解决了，从而也就实现了文本文件链接被点击的时候会触发下载对话框的效果。]]></description>
		<pubDate>Wed, 31 Mar 2010 13:19:13 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[PHP中10个不常见却非常有用的函数用法介绍]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail1046.shtml]]></link>
		<description><![CDATA[PHP中10个不常见却非常有用的函数用法介绍：
<br/>以下这10个php函数虽然不是很常见但是要是掌握了还是非常实用的，减少了一些代码量，有特殊需求的朋友可以参考下，充分发挥php的优势。
<br/>1.pack()
<br/>Pack()能将md5()返回的32位16进制字符串转换为16位的二进制字符串，可以节省存储空间。
<br/>2.sys_getloadavg()
<br/>sys_getloadavt()可以获得系统负载情况。该函数返回一个包含三个元素的数组，每个元素分别代表系统再过去的1、5和15分钟内的平均负载。
<br/>与其让服务器因负载过高而宕掉，不如在系统负载很高时主动die掉一个脚本，sys_getloadavg()就是用来帮你实现这个功能的。不过很遗憾，该函数在windows下无效。
<br/>3.cal_days_in_month()
<br/>cal_days_in_month()能够返回指定月份共有多少天。
<br/>4._()
<br/>WordPress开发者经常能见到这个函数，还有_e()。这两个函数功能相同，与gettext()函数结合使用，能实现网站的多语言化。具体可参见PHP手册的相关部分介绍。
<br/>5.get_browser()
<br/>在发送页面前先看看用户的浏览器都能做些什么是不是挺好？get_browser()能获得用户的浏览器类型，以及浏览器支持的功能，不过首先你需要一个php_browscap.ini文件，用来给函数做参考文件。
<br/>要注意，该函数对浏览器功能的判断是基于该类浏览器的一般特性的。例如，如果用户关闭了浏览器对JavaScript的支持，函数无法得知这一点。但是在判断浏览器类型和OS平台方面，该函数还是很准确的。
<br/>6.debug_print_backtrace()
<br/>这是一个调试用的函数，能帮助你发现代码中的逻辑错误。要理解这个函数，还是直接看个例子吧：
<br/>$a=0;
<br/>functioniterate(){
<br/>global$a;
<br/>if($a&lt;10)
<br/>recur();
<br/>echo$a.&quot;,&quot;;
<br/>}
<br/>functionrecur(){
<br/>global$a;
<br/>$a++;
<br/>//howdidIgethere?
<br/>echo&quot;\n\n\n&quot;;
<br/>debug_print_backtrace();
<br/>if($a&lt;10)
<br/>iterate();
<br/>}
<br/>iterate();
<br/>#OUTPUT:
<br/>#0recur()calledat[C:\htdocs\php_stuff\index.php:8]
<br/>#1iterate()calledat[C:\htdocs\php_stuff\index.php:25]
<br/>#0recur()calledat[C:\htdocs\php_stuff\index.php:8]
<br/>#1iterate()calledat[C:\htdocs\php_stuff\index.php:21]
<br/>#2recur()calledat[C:\htdocs\php_stuff\index.php:8]
<br/>#3iterate()calledat[C:\htdocs\php_stuff\index.php:25]
<br/>#0recur()calledat[C:\htdocs\php_stuff\index.php:8]
<br/>#1iterate()calledat[C:\htdocs\php_stuff\index.php:21]
<br/>#2recur()calledat[C:\htdocs\php_stuff\index.php:8]
<br/>#3iterate()calledat[C:\htdocs\php_stuff\index.php:21]
<br/>#4recur()calledat[C:\htdocs\php_stuff\index.php:8]
<br/>#5iterate()calledat[C:\htdocs\php_stuff\index.php:25]
<br/>7.metaphone()
<br/>这个函数返回单词的metaphone值，相同读音的单词具有相同的metaphone值，也就是说这个函数可以帮你判断两个单词的读音是否相同。不过对中文就无效了。。。
<br/>8.natsort()
<br/>natsort()能将一个数组以自然排序法进行排列，直接看个例子吧：
<br/>$items=array(
<br/>&quot;100apples&quot;,&quot;5apples&quot;,&quot;110apples&quot;,&quot;55apples&quot;
<br/>);
<br/>//normalsorting:
<br/>sort($items);
<br/>print_r($items);
<br/>#Outputs:
<br/>#Array
<br/>#(
<br/>#[0]=&gt;100apples
<br/>#[1]=&gt;110apples
<br/>#[2]=&gt;5apples
<br/>#[3]=&gt;55apples
<br/>#)
<br/>natsort($items);
<br/>print_r($items);
<br/>#Outputs:
<br/>#Array
<br/>#(
<br/>#[2]=&gt;5apples
<br/>#[3]=&gt;55apples
<br/>#[0]=&gt;100apples
<br/>#[1]=&gt;110apples
<br/>#)
<br/>9.levenshtein()
<br/>Levenshtein()告诉你两个单词之间的&quot;距离&quot;。它告诉你如果想把一个单词变成另一个单词，需要插入、替换和删除多少字母。
<br/>看个例子吧：
<br/>$dictionary=array(
<br/>&quot;php&quot;,&quot;javascript&quot;,&quot;css&quot;
<br/>);
<br/>$word=&quot;japhp&quot;;
<br/>$best_match=$dictionary[0];
<br/>$match_value=levenshtein($dictionary[0],$word);
<br/>foreach($dictionaryas$w){
<br/>$value=levenshtein($word,$w);
<br/>if($value&lt;$match_value){
<br/>$best_match=$w;
<br/>$match_value=$value;
<br/>}
<br/>}
<br/>echo&quot;Didyoumeanthe'$best_match'category?&quot;;
<br/>10.glob()
<br/>glob()会让你觉得用opendir(),readdir()和closedir()来寻找文件非常蠢。
<br/>foreach(glob(&quot;*.php&quot;)as$file)
<br/>echo&quot;$file\n&quot;;]]></description>
		<pubDate>Mon, 22 Mar 2010 13:13:15 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[用php实现从文本中给url链接地址加超链接标签&lt;a&gt;的方法]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail1038.shtml]]></link>
		<description><![CDATA[用php实现从文本中给url链接地址加超链接标签&lt;a&gt;的方法：
<br/>主要思路就是从文本中用正则找到url，然后加上标签&lt;a&gt;替换成超链接。
<br/>$string=&quot;php自学网，网址：http://www.phpzixue.cn/&quot;;
<br/>//连接后需要有个空格或回车。
<br/>&lt;?php
<br/>$string=eregi_replace(&quot;http://([^,]*)&quot;,&quot;&lt;ahref=\0target=_blank&gt;\0&lt;/a&gt;&quot;,$string);
<br/>$string=eregi_replace(&quot;ftp://([^,]*)&quot;,&quot;&lt;ahref=\0target=_blank&gt;\0&lt;/a&gt;&quot;,$string);
<br/>print$string;
<br/>?&gt;
<br/>输出结果：
<br/>php自学网，网址：&lt;ahref=http://www.phpzixue.cn/target=_blank&gt;]]></description>
		<pubDate>Thu, 04 Mar 2010 13:16:26 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[php5中关于session生存周期设置简介]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail1037.shtml]]></link>
		<description><![CDATA[php5中关于session生存周期设置简介：
<br/>我们都知道Session变量是保存在服务器端的，那么它是如何来判断客户端用户的呢？
<br/>它是通过SessionID来判断的，什么是SessionID，就是那个Session文件的文件名，SessionID是随机生成的，因此能保证唯一性和随机性，确保Session的安全。一般如果没有设置Session的生存周期，则SessionID存储在内存中，关闭浏览器后该ID自动注销，重新请求该页面后，重新注册一个SessionID。
<br/>如果客户端没有禁用Cookie，则Cookie在启动Session会话的时候扮演的是存储SessionID和Session生存期的角色。我们来手动设置Session的生存期：
<br/>&lt;?php
<br/>session_start();
<br/>//保存一天
<br/>$lifeTime=24*3600;
<br/>setcookie(session_name(),session_id(),time()+$lifeTime,&quot;/&quot;);
<br/>?&gt;
<br/>其实PHP5Session还提供了一个函数session_set_cookie_params();来设置PHP5Session的生存期的，该函数必须在session_start()函数调用之前调用：
<br/>&lt;?php
<br/>//保存一天
<br/>$lifeTime=24*3600;
<br/>session_set_cookie_params($lifeTime);
<br/>session_start();
<br/>?&gt;]]></description>
		<pubDate>Tue, 02 Mar 2010 17:16:45 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[php中清除文件状态缓存函数clearstatcache用法详解]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail1036.shtml]]></link>
		<description><![CDATA[php中清除文件状态缓存函数clearstatcache用法详解：
<br/>函数语法如下：
<br/>voidclearstatcache(void)
<br/>当使用stat()，lstat()或者任何列在受影响函数表中的函数时，PHP将缓存这些函数的返回信息以提供更快的性能。然而在某些情况下，你可能想清除被缓存的信息。例如如果在一个脚本中多次检查同一个文件，而该文件在此脚本执行期间有被删除或修改的危险时，你需要清除文件状态缓存。这种情况下，可以用clearstatcache()函数来清除被PHP缓存的该文件信息。
<br/>必须注意的是，对于不存在的文件，PHP并不会缓存其信息。所以如果调用file_exists()来检查不存在的文件，在该文件没有被创建之前，它都会返回FALSE。如果该文件被创建了，就算以后被删除，它都会返回TRUE
<br/>PHP的缓存数据对更快更好的运行函数是非常有利的。如果一个文件在脚本中测试了多次，你也许会禁止对正确的结果进行缓存。为了实现这点，你可以使用clearstatcache()函数。
<br/>提示和注意
<br/>提示：执行缓存的函数：
<br/>stat()
<br/>lstat()
<br/>file_exists()
<br/>is_writable()
<br/>is_readable()
<br/>is_executable()
<br/>is_file()
<br/>is_dir()
<br/>is_link()
<br/>filectime()
<br/>fileatime()
<br/>filemtime()
<br/>fileinode()
<br/>filegroup()
<br/>fileowner()
<br/>filesize()
<br/>filetype()
<br/>fileperms()
<br/>实例
<br/>&lt;?php
<br/>//checkfilesize
<br/>echofilesize(&quot;test.txt&quot;);
<br/>echo&quot;&lt;br/&gt;&quot;;
<br/>$file=fopen(&quot;test.txt&quot;,&quot;a+&quot;);
<br/>//truncatefile
<br/>ftruncate($file,100);
<br/>fclose($file);//Clearcacheandcheckfilesizeagaincle
<br/>arstatcache();
<br/>echofilesize(&quot;test.txt&quot;);
<br/>?&gt;
<br/>以上事例输出结果如下：
<br/>792100]]></description>
		<pubDate>Tue, 02 Mar 2010 17:09:53 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[用PHP实现域名whois信息查询的代码]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail1033.shtml]]></link>
		<description><![CDATA[用PHP实现域名whois信息查询的代码：
<br/>域名whois信息查询，数据来自于万网、新网。代码如下：
<br/>万网whois：
<br/>&lt;?php
<br/>functionwhois_hichina($domain){
<br/>preg_match(&quot;|&lt;pre&gt;(.+?)&lt;/pre&gt;|is&quot;,@file_get_contents('http://whois.hichina.com/cgi-bin/whois?domain='.$domain.''),$whois);
<br/>$whois[0]=str_replace('友情提示：按注册局要求，过期域名可能会处于注册商自动续费期阶段，您在此查询所看到的域名到期日仅供参考&lt;br/&gt;请您&lt;ahref=&quot;http://www.net.cn/has_client/userlogon/user_logon1.asp&quot;target=&quot;_blank&quot;class=&quot;link_gl&quot;&gt;进入会员区&lt;/a&gt;查看该域名的实际到期时间，并请及时进行续费，谢谢！','',($whois[0]));//过滤掉此段文字
<br/>return$whois[0]);
<br/>}
<br/>?&gt;
<br/>新网whois：
<br/>&lt;?php
<br/>functionwhois_xinnet($domain){
<br/>preg_match(&quot;|&lt;divclass=&quot;lyTableInfoWrap&quot;&gt;(.+?)&lt;/div&gt;|is&quot;,@file_get_contents('http://www.xinnet.cn/Modules/agent/serv/pages/domain_whois.jsp?domainNameWhois='.$domain.'&amp;noCode=noCode'),$whois);
<br/>return$whois[0];
<br/>}
<br/>}
<br/>?&gt;]]></description>
		<pubDate>Wed, 24 Feb 2010 17:38:59 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[用PHP伪静态隐藏URL传递参数名的四种方法]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail1032.shtml]]></link>
		<description><![CDATA[用PHP伪静态隐藏URL传递参数名的四种方法：
<br/>PHP中的伪静态主要是为了隐藏传递的参数名，看在url上看不到传递的参数是什么，下面介绍四种方法。
<br/>方法一：
<br/>&lt;?php
<br/>//localhost/php100/test.php/1/2
<br/>$filename=basename($_SERVER['SCRIPT_NAME']);
<br/>echo$_SERVER['SCRIPT_NAME'].&quot;&lt;br&gt;&quot;;///php100/test.php
<br/>echo$filename.&quot;&lt;br&gt;&quot;;//test.php
<br/>if(strtolower($filename)=='test.php'){
<br/>if(!empty($_GET[id])){
<br/>$id=intval($_GET[id]);
<br/>echo$id.&quot;&lt;br&gt;&quot;;
<br/>$action=intval($_GET[action]);
<br/>echo$action.&quot;&lt;br&gt;&quot;;
<br/>}else{
<br/>$nav=$_SERVER['REQUEST_URI'];
<br/>echo&quot;1:&quot;.$nav.&quot;&lt;br&gt;&quot;;///php100/test.php/1/2
<br/>$script=$_SERVER['SCRIPT_NAME'];
<br/>echo&quot;2:&quot;.$script.&quot;&lt;br&gt;&quot;;///php100/test.php
<br/>$nav=ereg_replace(&quot;^$script&quot;,&quot;&quot;,urldecode($nav));
<br/>echo$nav.&quot;&lt;br&gt;&quot;;///1/2
<br/>$vars=explode(&quot;/&quot;,$nav);
<br/>print_r($vars);//Array([0]=&gt;[1]=&gt;1[2]=&gt;2)
<br/>echo&quot;&lt;br&gt;&quot;;
<br/>$id=intval($vars[1]);
<br/>$action=intval($vars[2]);
<br/>}
<br/>echo$id.'&amp;'.$action;
<br/>}
<br/>?&gt;
<br/>方法二：
<br/>&lt;?php
<br/>//localhost/php100/test.php?id|1@action|2
<br/>$Php2Html_FileUrl=$_SERVER[&quot;REQUEST_URI&quot;];
<br/>echo$Php2Html_FileUrl.&quot;&lt;br&gt;&quot;;
<br/>///php100/test.php?id|1@action|2
<br/>$Php2Html_UrlString=str_replace(&quot;?&quot;,&quot;&quot;,str_replace(&quot;/&quot;,&quot;&quot;,strrchr(strrchr($Php2Html_FileUrl,&quot;/&quot;),&quot;?&quot;)));
<br/>echo$Php2Html_UrlString.&quot;&lt;br&gt;&quot;;
<br/>//id|1@action|2
<br/>$Php2Html_UrlQueryStrList=explode(&quot;@&quot;,$Php2Html_UrlString);
<br/>print_r($Php2Html_UrlQueryStrList);
<br/>//Array([0]=&gt;id|1[1]=&gt;action|2)echo&quot;&lt;br&gt;&quot;;
<br/>foreach($Php2Html_UrlQueryStrListas$Php2Html_UrlQueryStr){
<br/>$Php2Html_TmpArray=explode(&quot;|&quot;,$Php2Html_UrlQueryStr);
<br/>print_r($Php2Html_TmpArray);
<br/>//Array([0]=&gt;id[1]=&gt;1);Array([0]=&gt;action[1]=&gt;2)
<br/>echo&quot;&lt;br&gt;&quot;;
<br/>$_GET[$Php2Html_TmpArray[0]]=$Php2Html_TmpArray[1];
<br/>}
<br/>//echo'假静态：$_GET变量&lt;br/&gt;';
<br/>print_r($_GET);
<br/>//Array([id|1@action|2]=&gt;[id]=&gt;1[action]=&gt;2)echo&quot;&lt;br&gt;&quot;;
<br/>echo&quot;&lt;hr&gt;&quot;;
<br/>echo$_GET[id].&quot;&lt;br&gt;&quot;;
<br/>//1echo$_GET[action];
<br/>//2
<br/>?&gt;
<br/>方法三：
<br/>&lt;?php
<br/>functionmod_rewrite(){
<br/>global$_GET;
<br/>$nav=$_SERVER[&quot;REQUEST_URI&quot;];
<br/>echo$nav.&quot;&lt;br&gt;&quot;;
<br/>$script_name=$_SERVER[&quot;SCRIPT_NAME&quot;];
<br/>echo$script_name.&quot;&lt;br&gt;&quot;;
<br/>$nav=substr(ereg_replace(&quot;^$script_name&quot;,&quot;&quot;,urldecode($nav)),1);
<br/>echo$nav.&quot;&lt;br&gt;&quot;;
<br/>$nav=preg_replace(&quot;/^.ht(m){1}(l){0,1}$/&quot;,&quot;&quot;,$nav);//这句是去掉尾部的.html或.htm
<br/>echo$nav.&quot;&lt;br&gt;&quot;;
<br/>$vars=explode(&quot;/&quot;,$nav);
<br/>print_r($vars);
<br/>echo&quot;&lt;br&gt;&quot;;
<br/>for($i=0;$i&lt;Count($vars);$i+=2){
<br/>$_GET[&quot;$vars[$i]&quot;]=$vars[$i+1];
<br/>}
<br/>return$_GET;
<br/>}
<br/>mod_rewrite();
<br/>$year=$_GET[&quot;year&quot;];//结果为'2006'
<br/>echo$year.&quot;&lt;br&gt;&quot;;
<br/>$action=$_GET[&quot;action&quot;];//结果为'_add'
<br/>echo$action;
<br/>?&gt;
<br/>方法四：
<br/>&lt;?php
<br/>//利用server变量取得PATH_INFO信息该例中为/1,100,8630.html也就是执行脚本名后面的部分
<br/>if(@$path_info=$_SERVER[&quot;PATH_INFO&quot;]){
<br/>//正则匹配一下参数
<br/>if(preg_match(&quot;/\/(\d+),(\d+),(\d+)\.html/si&quot;,$path_info,$arr_path)){
<br/>$gid=intval($arr_path[1]);//取得值1
<br/>$sid=intval($arr_path[2]);//取得值100
<br/>$softid=intval($arr_path[3]);//取得值8630
<br/>}elsedie(&quot;Path:Error!&quot;);
<br/>//相当于soft.php?gid=1&amp;sid=100&amp;softid=8630
<br/>}elsedie('Path:Nothing!');
<br/>?&gt;]]></description>
		<pubDate>Tue, 23 Feb 2010 10:21:10 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[php读取文件乱码问题的解决方法]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail1031.shtml]]></link>
		<description><![CDATA[php读取文件乱码问题的解决方法：
<br/>php5中的流读取函数的默认编码貌似是UTF-8，而php4里直接file_get_contents()读取gb2312编码的正常，到了5就乱码了。
<br/>网上的解决办法说抓取后用iconv()转码。看后我就觉得不对劲：一个是不一定编译了iconv库，更大的问题是编码都跟流转换的时候有关（如果用了iconv实际上php转了两次码：流-&gt;UTF-8-&gt;GB2312）
<br/>仔细看了下php的文档（不知道大家都是怎么写代码的，其实文档上很清楚啊），上面关于fopen()及file_get_contents()都提到了“默认是UTF-8，但是用户可以用stream_default_encoding()或者用户自定义上下文属性改变编码”,手册上写道（Ifunicodesemanticsareenabled,thedefaultencodingofthereaddataisUTF-8.Youcanspecifyadifferentencodingbycreatingacustomcontextorbychangingthedefaultusingstream_default_encoding().）。于是用stream_default_encoding('gb2312');测试：但是faint的是，这个函数不存在？！似乎php6才支持。不过天无绝人之路，还有“用户自定义上下文属性”可以用。
<br/>经过更仔细的看文档，最后解决了这个问题：
<br/>代码如下:
<br/>&lt;?php
<br/>//设置流的编码格式，这是文件流(file)，如果是网络访问，file改成http
<br/>$opts=array('file'=&gt;array('encoding'=&gt;'gb2312'));
<br/>$ctxt=stream_context_create($opts);
<br/>file_get_contents(文件名,FILE_TEXT,$ctxt);
<br/>?&gt;]]></description>
		<pubDate>Sun, 21 Feb 2010 09:14:46 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[用php处理百万级以上的数据提高查询速度的方法]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail1029.shtml]]></link>
		<description><![CDATA[用php处理百万级以上的数据提高查询速度的方法：
<br/>1.应尽量避免在where子句中使用!=或&lt;&gt;操作符，否则将引擎放弃使用索引而进行全表扫描。
<br/>2.对查询进行优化，应尽量避免全表扫描，首先应考虑在where及orderby涉及的列上建立索引。
<br/>3.应尽量避免在where子句中对字段进行null值判断，否则将导致引擎放弃使用索引而进行全表扫描，如：
<br/>selectidfromtwherenumisnull
<br/>可以在num上设置默认值0，确保表中num列没有null值，然后这样查询：
<br/>selectidfromtwherenum=0
<br/>4.应尽量避免在where子句中使用or来连接条件，否则将导致引擎放弃使用索引而进行全表扫描，如：
<br/>selectidfromtwherenum=10ornum=20
<br/>可以这样查询：
<br/>selectidfromtwherenum=10
<br/>unionall
<br/>selectidfromtwherenum=20
<br/>5.下面的查询也将导致全表扫描：
<br/>selectidfromtwherenamelike'%abc%'
<br/>若要提高效率，可以考虑全文检索。
<br/>6.in和notin也要慎用，否则会导致全表扫描，如：
<br/>selectidfromtwherenumin(1,2,3)
<br/>对于连续的数值，能用between就不要用in了：
<br/>selectidfromtwherenumbetween1and3
<br/>7.如果在where子句中使用参数，也会导致全表扫描。因为SQL只有在运行时才会解析局部变量，但优化程序不能将访问计划的选择推迟到运行时；它必须在编译时进行选择。然而，如果在编译时建立访问计划，变量的值还是未知的，因而无法作为索引选择的输入项。如下面语句将进行全表扫描：
<br/>selectidfromtwherenum=@num
<br/>可以改为强制查询使用索引：
<br/>selectidfromtwith(index(索引名))wherenum=@num
<br/>8.应尽量避免在where子句中对字段进行表达式操作，这将导致引擎放弃使用索引而进行全表扫描。如：
<br/>selectidfromtwherenum/2=100
<br/>应改为:
<br/>selectidfromtwherenum=100*2
<br/>9.应尽量避免在where子句中对字段进行函数操作，这将导致引擎放弃使用索引而进行全表扫描。如：
<br/>selectidfromtwheresubstring(name,1,3)='abc'--name以abc开头的id
<br/>selectidfromtwheredatediff(day,createdate,'2005-11-30')=0--'2005-11-30'生成的id
<br/>应改为:
<br/>selectidfromtwherenamelike'abc%'
<br/>selectidfromtwherecreatedate&gt;='2005-11-30'andcreatedate&lt;'2005-12-1'
<br/>10.不要在where子句中的“=”左边进行函数、算术运算或其他表达式运算，否则系统将可能无法正确使用索引。
<br/>11.在使用索引字段作为条件时，如果该索引是复合索引，那么必须使用到该索引中的第一个字段作为条件时才能保证系统使用该索引，否则该索引将不会被使用，并且应尽可能的让字段顺序与索引顺序相一致。
<br/>12.不要写一些没有意义的查询，如需要生成一个空表结构：
<br/>selectcol1,col2into#tfromtwhere1=0
<br/>这类代码不会返回任何结果集，但是会消耗系统资源的，应改成这样：
<br/>createtable#t(...)
<br/>13.很多时候用exists代替in是一个好的选择：
<br/>selectnumfromawherenumin(selectnumfromb)
<br/>用下面的语句替换：
<br/>selectnumfromawhereexists(select1frombwherenum=a.num)
<br/>14.并不是所有索引对查询都有效，SQL是根据表中数据来进行查询优化的，当索引列有大量数据重复时，SQL查询可能不会去利用索引，如一表中有字段sex，male、female几乎各一半，那么即使在sex上建了索引也对查询效率起不了作用。
<br/>15.索引并不是越多越好，索引固然可以提高相应的select的效率，但同时也降低了insert及update的效率，因为insert或update时有可能会重建索引，所以怎样建索引需要慎重考虑，视具体情况而定。一个表的索引数最好不要超过6个，若太多则应考虑一些不常使用到的列上建的索引是否有必要。
<br/>16.应尽可能的避免更新clustered索引数据列，因为clustered索引数据列的顺序就是表记录的物理存储顺序，一旦该列值改变将导致整个表记录的顺序的调整，会耗费相当大的资源。若应用系统需要频繁更新clustered索引数据列，那么需要考虑是否应将该索引建为clustered索引。
<br/>17.尽量使用数字型字段，若只含数值信息的字段尽量不要设计为字符型，这会降低查询和连接的性能，并会增加存储开销。这是因为引擎在处理查询和连接时会逐个比较字符串中每一个字符，而对于数字型而言只需要比较一次就够了。
<br/>18.尽可能的使用varchar/nvarchar代替char/nchar，因为首先变长字段存储空间小，可以节省存储空间，其次对于查询来说，在一个相对较小的字段内搜索效率显然要高些。
<br/>19.任何地方都不要使用select*fromt，用具体的字段列表代替“*”，不要返回用不到的任何字段。
<br/>20.尽量使用表变量来代替临时表。如果表变量包含大量数据，请注意索引非常有限（只有主键索引）。
<br/>21.避免频繁创建和删除临时表，以减少系统表资源的消耗。
<br/>22.临时表并不是不可使用，适当地使用它们可以使某些例程更有效，例如，当需要重复引用大型表或常用表中的某个数据集时。但是，对于一次性事件，最好使用导出表。
<br/>23.在新建临时表时，如果一次性插入数据量很大，那么可以使用selectinto代替createtable，避免造成大量log，以提高速度；如果数据量不大，为了缓和系统表的资源，应先createtable，然后insert。
<br/>24.如果使用到了临时表，在存储过程的最后务必将所有的临时表显式删除，先truncatetable，然后droptable，这样可以避免系统表的较长时间锁定。
<br/>25.尽量避免使用游标，因为游标的效率较差，如果游标操作的数据超过1万行，那么就应该考虑改写。
<br/>26.使用基于游标的方法或临时表方法之前，应先寻找基于集的解决方案来解决问题，基于集的方法通常更有效。
<br/>27.与临时表一样，游标并不是不可使用。对小型数据集使用FAST_FORWARD游标通常要优于其他逐行处理方法，尤其是在必须引用几个表才能获得所需的数据时。在结果集中包括“合计”的例程通常要比使用游标执行的速度快。如果开发时间允许，基于游标的方法和基于集的方法都可以尝试一下，看哪一种方法的效果更好。
<br/>28.在所有的存储过程和触发器的开始处设置SETNOCOUNTON，在结束时设置SETNOCOUNTOFF。无需在执行存储过程和触发器的每个语句后向客户端发送DONE_IN_PROC消息。
<br/>29.尽量避免向客户端返回大数据量，若数据量过大，应该考虑相应需求是否合理。
<br/>30.尽量避免大事务操作，提高系统并发能力。]]></description>
		<pubDate>Mon, 08 Feb 2010 16:11:02 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[php中date与gmdate格式化日期函数的使用区别]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail1028.shtml]]></link>
		<description><![CDATA[php中date与gmdate格式化日期函数的使用区别：
<br/>PHP中格式化日期有2个函数：date()和gmdate()，在php手册中描述为：
<br/>date--格式化一个本地时间／日期
<br/>gmdate--格式化一个GMT/UTC日期／时间，返回的是格林威治标准时（GMT）。
<br/>举个例子，我们现在所在的时区是+8，那么服务器运行以下脚本返回的时间应该是这样的：
<br/>当前时间假定是2010-02-0812:15:27
<br/>echodate('Y-m-dH:i:s',time());输出为：2010-02-0812:15:27
<br/>echogmdate('Y-m-dH:i:s',time());输出为：2010-02-0804:15:27
<br/>第二个函数比第一个函数少了8个小时。但这只是在Linux+Apache下运行PHP所得的结果，如果在Windows下运行，则2个函数返回都是：2010-02-0804:15:27。
<br/>所以，我们应该给一个兼容性的写法，统一使用gmdate，并手工设置当前时区，写法改进如下：
<br/>echogmdate('Y-m-dH:i:s',time()+3600*8);
<br/>这样不管在Linux+Apache下还是Windows下都得到了正确的结果，当然这样写还有一个好处，当网站是面向全世界的时候，那么网站用户只要设置所在的时区，程序自动根据用户设置的时区进行时间计算，数据库中信息发布时间只存当前的time()所生成的时间，那么在中国+8时区看到的发布时间是：2010-02-0812:15:27，那么在欧洲+2时区用户看到这个信息的发布时间是：2010-02-0806:15:27，这样信息的时间就全部对应正确了。]]></description>
		<pubDate>Mon, 08 Feb 2010 15:54:33 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[用PHP实现手机归属地查询api接口]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail1027.shtml]]></link>
		<description><![CDATA[用PHP实现手机归属地查询api接口：
<br/>主要使用curl实现，需要开启php对curl的支持.
<br/>&lt;?php
<br/>header(&quot;Content-Type:text/html;charset=utf-8&quot;);
<br/>if(isset($_GET['number'])){
<br/>$url='http://webservice.webxml.com.cn/WebServices/MobileCodeWS.asmx/getMobileCodeInfo';
<br/>$number=$_GET['number'];
<br/>$ch=curl_init();
<br/>curl_setopt($ch,CURLOPT_URL,$url);
<br/>curl_setopt($ch,CURLOPT_POST,true);
<br/>curl_setopt($ch,CURLOPT_POSTFIELDS,&quot;mobileCode={$number}&amp;userId=&quot;);
<br/>curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
<br/>$data=curl_exec($ch);
<br/>curl_close($ch);
<br/>$data=simplexml_load_string($data);
<br/>if(strpos($data,'http://')){
<br/>echo'手机号码格式错误!';
<br/>}else{
<br/>echo$data;
<br/>}
<br/>}
<br/>?&gt;
<br/>&lt;formaction=&quot;mobile.php&quot;method=&quot;get&quot;&gt;
<br/>手机号码:&lt;inputtype=&quot;text&quot;name=&quot;number&quot;/&gt;&lt;inputtype=&quot;submit&quot;value=&quot;提交&quot;/&gt;
<br/>&lt;/form&gt;]]></description>
		<pubDate>Mon, 08 Feb 2010 15:27:16 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[php中在数组中搜索给定值函数array_search使用方法]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail1026.shtml]]></link>
		<description><![CDATA[php中在数组中搜索给定值函数array_search使用方法：
<br/>语法
<br/>mixedarray_search(mixedneedle,arrayhaystack[,boolstrict])
<br/>用法
<br/>array_search()函数的作用是在数组中查找一个值所对应的键，否则返回false。
<br/>注:如果needle是字符串，则比较以区分大小写的方式进行。
<br/>注:在PHP4.2.0之前，array_search()在失败时返回NULL而不是FALSE。
<br/>如果可选的第三个参数strict为TRUE，则array_search()还将在haystack中检查needle的类型。
<br/>如果needle在haystack中出现不止一次，则返回第一个匹配的键。要返回所有匹配值的键，应该用array_keys()加上可选参数search_value来代替。
<br/>例1
<br/>&lt;?php
<br/>$a=array(&quot;a&quot;=&gt;&quot;Dog&quot;,&quot;b&quot;=&gt;&quot;Cat&quot;,&quot;c&quot;=&gt;&quot;Horse&quot;);
<br/>echoarray_search(&quot;Dog&quot;,$a);
<br/>?&gt;
<br/>上述代码将输出下面的结果：
<br/>a
<br/>例2
<br/>&lt;?php
<br/>$a=array(&quot;a&quot;=&gt;&quot;5&quot;,&quot;b&quot;=&gt;5,&quot;c&quot;=&gt;&quot;5&quot;);
<br/>echoarray_search(5,$a,true);
<br/>?&gt;
<br/>上述代码将输出下面的结果：
<br/>b]]></description>
		<pubDate>Fri, 05 Feb 2010 14:47:02 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[php中mysql_real_escape_string和addslashes函数用法区别]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail1016.shtml]]></link>
		<description><![CDATA[php中mysql_real_escape_string和addslashes函数用法区别:
<br/>往数据库中插入数据之前是要先转义的,在插入数据库.
<br/>本文主要介绍的是用mysql_real_escape_string对用户提交的表单数据进行转义处理和通过addslashes以及mysql_escape_string这3个类似功能的函数用法区别。
<br/>本文很好的说明了addslashes和mysql_real_escape_string的区别，虽然国内很多PHPcoder仍在依靠addslashes防止SQL注入，我还是建议大家加强中文防止SQL注入的检查。addslashes的问题在于黑客可以用0xbf27来代替单引号，而addslashes只是将0xbf27修改为0xbf5c27，成为一个有效的多字节字符，其中的0xbf5c仍会被看作是单引号，所以addslashes无法成功拦截。
<br/>当然addslashes也不是毫无用处，它是用于单字节字符串的处理，多字节字符还是用mysql_real_escape_string吧。
<br/>另外对于php手册中get_magic_quotes_gpc的举例：
<br/>&lt;?php
<br/>if(!get_magic_quotes_gpc()){
<br/>$lastname=addslashes($_POST[&quot;lastname&quot;]);
<br/>}else{
<br/>$lastname=$_POST['lastname'];
<br/>}
<br/>?&gt;
<br/>最好对magic_quotes_gpc已经开放的情况下，还是对$_POST['lastname']进行检查一下。
<br/>再说下mysql_real_escape_string和mysql_escape_string这2个函数的区别：
<br/>mysql_real_escape_string必须在(PHP4&gt;=4.3.0,PHP5)的情况下才能使用。否则只能用mysql_escape_string，两者的区别是：
<br/>mysql_real_escape_string考虑到连接的当前字符集，而mysql_escape_string不考虑。
<br/>总结一下：
<br/>addslashes()是强行加；
<br/>mysql_real_escape_string()会判断字符集，但是对PHP版本有要求；
<br/>mysql_escape_string不考虑连接的当前字符集。]]></description>
		<pubDate>Thu, 28 Jan 2010 15:13:48 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[php中smarty使用缓存操作技巧介绍]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail1015.shtml]]></link>
		<description><![CDATA[php中smarty使用缓存操作技巧介绍:
<br/>smarty中缓存cache的用法.
<br/>一、使用缓存
<br/>开启smarty缓存,只需将caching设为true,并指定cache_dir即可.
<br/>使用cache_lefetime指定缓存生存时间,单位为秒
<br/>要对相同页面生成多个不同的缓存,在display或fetch中加入第二参数cache_id,如$smarty-&gt;display('index.tpl',$my_cache_id);此特性可用于对不同的$_GET进行不同的缓存
<br/>二、清除缓存
<br/>clear_all_cache();//清除所有缓存
<br/>clear_cache('index.tpl');//清除index.tpl的缓存
<br/>clear_cache('index.tpl',cache_id);//清除指定id的缓存
<br/>三、使用自定义缓存方式
<br/>设置cache_handler_func使用自定义的函数处理缓存
<br/>如:
<br/>$smarty-&gt;cache_handler_func=&quot;myCache&quot;;
<br/>functionmyCache($action,&amp;$smarty_obj,&amp;$cache_content,$tpl_file=null,$cache_id=null,$compile_id=null){
<br/>}
<br/>该函数的一般是根椐$action来判断缓存当前操作:
<br/>switch($action){
<br/>case&quot;read&quot;://读取缓存内容
<br/>case&quot;write&quot;://写入缓存
<br/>case&quot;clear&quot;://清空
<br/>}
<br/>一般使用md5($tpl_file.$cache_id.$compile_id)作为唯一的cache_id
<br/>如果需要,可使用gzcompress和gzuncompress来压缩和解压
<br/>四、局部关闭缓存
<br/>要在某些区域使缓存失效(只对需要的缓存),有几种方法:
<br/>insert:
<br/>定义一个insert标签要使用的处理函数,函数名格式为:insert_xx(array$params,object&amp;$smarty)其中的xx是insert的name,也就是说,如果你定义的函数为insert_abc,则模板中使用方法为{insertname='abc'}
<br/>参数通过$params传入
<br/>也可以做成insert插件,文件名命名为:insert.xx.php,函数命名为:smarty_insert_aa($params,&amp;$smarty),xx定义同上
<br/>register_block:
<br/>定义一个block:smarty_block_name($params,$content,&amp;$smarty){return$content;}//name表示区域名
<br/>注册block:$smarty-&gt;register_block('name','smarty_block_name',false);//第三参数false表示该区域不被缓存
<br/>模板写法:{name}内容{/name}
<br/>写成block插件:
<br/>1)定义一件插件函数:block.cacheless.php,放在smarty的plugins目录
<br/>block.cacheless.php的内容如下:
<br/>&lt;?php
<br/>functionsmarty_block_cacheless($param,$content,&amp;$smarty){
<br/>return$content;
<br/>}
<br/>?&gt;
<br/>2)编写程序及模板
<br/>testCacheLess.php文件
<br/>&lt;?php
<br/>include('Smarty.class.php');
<br/>$smarty=newSmarty;
<br/>$smarty-&gt;caching=true;
<br/>$smarty-&gt;cache_lifetime=6;
<br/>$smarty-&gt;display('cache.tpl');
<br/>?&gt;
<br/>所用的模板:cache.tpl
<br/>已经缓存的:{$smarty.now}&lt;br&gt;
<br/>{cacheless}
<br/>没有缓存的:{$smarty.now}
<br/>{/cacheless}]]></description>
		<pubDate>Wed, 27 Jan 2010 16:07:00 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[php中超全局(预定义)变量的使用]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail1014.shtml]]></link>
		<description><![CDATA[php中超全局变量的使用:
<br/>php中超级全局变量也叫做预定义变量，是PHP中自带的变量，它可让你的程序设计更加的方便快捷,它主要包括：
<br/>$_SERVER
<br/>变量由web服务器设定或者直接与当前脚本的执行环境相关联。类似于旧数组
<br/>$GLOBALS
<br/>包含一个引用指向每个当前脚本的全局范围内有效的变量。该数组的键名为全局变量的名称。从PHP3开始存在$GLOBALS数组。
<br/>$_GET
<br/>经由URL请求提交至脚本的变量。
<br/>$_POST
<br/>经由HTTPPOST方法提交至脚本的变量。
<br/>$_COOKIE
<br/>经由HTTPCookies方法提交至脚本的变量。
<br/>$_FILES
<br/>经由HTTPPOST文件上传而提交至脚本的变量。
<br/>$_ENV
<br/>执行环境提交至脚本的变量。
<br/>$_REQUEST
<br/>经由GET，POST和COOKIE机制提交至脚本的变量。
<br/>$_SESSION
<br/>当前注册给脚本会话的变量。
<br/>具体这些信息在这里就不一一的交待了，大家可以新建一个PHP文件phpinfo.php，在文件中写上以下代码。
<br/>&lt;?php
<br/>phpinfo();
<br/>?&gt;
<br/>在浏览器中执行http://localhost/phpinfo.php
<br/>在这个页面当中，你就可以查看到系统当中存在的各种类型的超级全局变量，从而也可以去应用它了。
<br/>下面介绍一个例子，用一个PHP文件显示当前文件及当前服务器的IP地址。
<br/>代码如下：
<br/>&lt;?php
<br/>echo&quot;当前文件为&quot;.$_SERVER[&quot;PHP_SELF&quot;];
<br/>echo&quot;&lt;br&gt;&quot;;
<br/>echo&quot;当前的IP地址是：&quot;.$_SERVER[&quot;SERVER_ADDR&quot;];
<br/>?&gt;
<br/>通过上面的例子，我们发现，预定义变量也就是超级全局变量在使用时无需定义（你可以通过phpinfo去查询），且以&quot;$_&quot;开头，变量名都是大写字母，&quot;[]&quot;括号中是相应的参数。]]></description>
		<pubDate>Tue, 26 Jan 2010 13:44:36 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[php中静态变量(static)与自定义常量的使用]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail1013.shtml]]></link>
		<description><![CDATA[php中静态变量(static)与自定义常量的使用:
<br/>1.php中静态变量是指用static声明的变量，这种变量与局部变量的区别是，当静态变量离开了它的作用范围后，它的值不会自动消亡，而是继续存在，当下次再用到它的时候，可以保留最近一次的值。
<br/>例如:
<br/>&lt;?php
<br/>functionadd()
<br/>{
<br/>static$i=0;
<br/>$i++;
<br/>echo$i;
<br/>}
<br/>add();
<br/>echo&quot;&quot;;
<br/>add();
<br/>?&gt;
<br/>上面的代码中，定义了一个函数add()，然后分两次调用add()。
<br/>如果用局部变量的方式来分工这段代码，两次的输出应该都是1。但实际输出却是1和2。
<br/>这是因为，变量i在声明的时候被加上了一个修饰符static，这就标志着i变量在add()函数内部就是一个静态变量了，具备记忆自身值的功能，当第一次调用add时，i由于自加变成了1，这个时候，i就记住自己不再是0，而是1了，当我们再次调用add时，i再一次自加，由1变成了2。由此，我们就可以看出静态变量的特性了。
<br/>2.php中的自定义常量，就是指用一个字符标识来代表另外一个对象，这个对象可以是一个数值，一个字符串，一个布尔值等等。它的定义与变量有着许多相似之处。只有一点不一样，那就是变量的值在程序运行过程中可以任意更改，而自定义常量一旦定义下来后，在程序运行中就再也不能修改了。
<br/>定义方式如下：
<br/>define(&quot;YEAR&quot;,&quot;2010&quot;);
<br/>使用define关键字来将2010这个字符串绑定到YEAR上来，以后在程序当中出现YEAR的地方就用2010来代替。一般情况下，我们定义常量时，常量名都使用大写字母。
<br/>例：
<br/>复制代码代码如下:
<br/>&lt;?php
<br/>define(&quot;YEAR&quot;,&quot;2010&quot;);
<br/>define(&quot;MONTH&quot;,&quot;10&quot;);
<br/>define(&quot;DATE&quot;,&quot;21&quot;);
<br/>define(&quot;THING&quot;,&quot;Doomsday&quot;);
<br/>echoYEAR.&quot;-&quot;.MONTH.&quot;-&quot;.DATE.&quot;&quot;.THING;
<br/>?&gt;
<br/>这段程序中，定义了四个常量，分别是YEAR，MONTH，DATE，THING，它们对应的值分别是2010，10，21，Doomsday，当我们用echo将它们连起来显示时，与变量不同的地方就在于没有使用“$”。
<br/>它的运行结果是：2010-10-21Doomsday。]]></description>
		<pubDate>Tue, 26 Jan 2010 12:52:04 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[在命令行下执行带参数的php脚本的方法]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail1005.shtml]]></link>
		<description><![CDATA[在命令行下执行带参数的php脚本的方法:
<br/>php本身就是一种脚本语言,不过我们一般都是通过apache来执行php,当然php也是可以通过命令行来执行的.和perl等语言类似.
<br/>主要还是用到了php.exe这个可执行文件,所以需要设置环境变量。
<br/>看下面这个最简单的代码,phphello.php:
<br/>&lt;?php
<br/>echo&quot;Hellophp!&quot;;
<br/>?&gt;
<br/>现在，试着在命令行提示符下运行这个程序，方法是调用CLI可执行文件并提供脚本的文件名：
<br/>#phpphphello.php
<br/>输出Hellophp!
<br/>使用标准的输入和输出
<br/>你可以在自己的PHP脚本里使用这三个常量，以接受用户的输入，或者显示处理和计算的结果。要更好地理解这一点，可以看看下面的脚本:
<br/>&lt;?php
<br/>//askforinput
<br/>fwrite(STDOUT,&quot;Enteryourname:&quot;);
<br/>//getinput
<br/>$name=trim(fgets(STDIN));
<br/>//writeinputback
<br/>fwrite(STDOUT,&quot;Hello,$name!&quot;);
<br/>?&gt;
<br/>shell&gt;phphello.php
<br/>Enteryourname:Joe
<br/>Hello,Joe!
<br/>在这个脚本里，fwrite()函数首先会向标准的输出设备写一条消息，询问用户的姓名。然后它会把从标准输入设备获得的用户输入信息读
<br/>取到一个PHP变量里，并它把合并成为一个字符串。然后就用fwrite()把这个字符串打印输出到标准的输出设备上。
<br/>使用命令行自变量
<br/>在命令行里输入程序参数来更改其运行方式是很常见的做法。你也可以对CLI程序这样做。PHPCLI带有两个特殊的变量，专门用来达到这个
<br/>目的：一个是$argv变量，它通过命令行把传递给PHP脚本的参数保存为单独的数组元素；另一个是$argc变量，它用来保存$argv数组里元素的
<br/>个数。
<br/>用PHP脚本编写一段读取$argv并处理它所含参数的代码是很简单的，看看它是如何工作的：
<br/>&lt;?php
<br/>print_r($argv);
<br/>?&gt;
<br/>Runthisscriptbypassingitsomearbitraryvalues,andchecktheoutput:
<br/>shell&gt;phpphptest.phpchocolate276&quot;killertie,dude!&quot;
<br/>Array
<br/>([0]=&gt;test.php
<br/>[1]=&gt;chocolate
<br/>[2]=&gt;276
<br/>[3]=&gt;killertie,dude!
<br/>)
<br/>正如你可以从输出的结果看到的，传递给test.php的值会自动地作为数组元素出现在$argv里。要注意的是，$argvis的第一个自变量总是
<br/>脚本自己的名称。
<br/>下面是一个更加复杂的例子：
<br/>代码
<br/>&lt;?php
<br/>//checkforallrequiredarguments
<br/>//firstargumentisalwaysnameofscript!
<br/>if($argc!=4){
<br/>die(&quot;Usage:book.php&lt;check-in-date&gt;&lt;num-nights&gt;&lt;room-type&gt;&quot;);
<br/>}
<br/>//removefirstargument
<br/>array_shift($argv);
<br/>//getanduseremainingarguments
<br/>$checkin=$argv[0];
<br/>$nights=$argv[1];
<br/>$type=$argv[2];
<br/>echo&quot;Youhaverequesteda$typeroomfor$nightsnights,checkinginon$checkin.Thankyouforyourorder!&quot;;
<br/>?&gt;
<br/>下面是其用法的示例：
<br/>shell&gt;phpphpbook.php21/05/20057single
<br/>Youhaverequestedasingleroomfor7nights,checkinginon21/05/2005.Thankyouforyourorder!
<br/>在这里，脚本首先会检查$argc，以确保自变量的数量符合要求。它然后会从$argv里提取出每一个自变量，把它们打印输出到标准的输出]]></description>
		<pubDate>Fri, 22 Jan 2010 11:58:15 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[php中session过期时间设置及回收机制详解]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail994.shtml]]></link>
		<description><![CDATA[php中session过期时间设置及回收机制详解:
<br/>修改php中的session过期时间可以修改php配置文件php.ini中的session.gc_maxlifetime即可。
<br/>当php每发出一次请求时，会有1/100的概率（默认值）触发&quot;session回收&quot;。如果&quot;session回收&quot;发生，那就会检查/tmp/sess_*的文件，如果最后的修改时间到现在超过了1440秒（gc_maxlifetime的值），就将其删除，意味着这些session过期失效。
<br/>1.session在server端（一般是ApachewithPHPmodule）如何存在的？
<br/>默认的，php会将session保存在/tmp目录下，文件名为这个样子：sess_01aab840166fd1dc253e3b4a3f0b8381。每一个文件对应了一个session（会话）。
<br/>more/tmp/sess_01aab840166fd1dc253e3b4a3f0b8381
<br/>username|s:9:”phpzixue.cn”;admin|s:1:”0″;
<br/>#变量名|类型:长度:值
<br/>删除这里的session文件，就表示对应的session失效了。
<br/>2.session在client端（一般是浏览器）如何存在的？
<br/>session在浏览器端，只需要保存sessionID（由server端生成的唯一ID）就可以了。有两种保存方式：在cookie中、在url里面。如果cookie中保存sessionID，就可以看到浏览器的cookie中有一个PHPSESID变量。如果是URL传递的，就可以看到形如:
<br/>index.php?PHPSESID=01aab840166fd1dc253e3b4a3f0b8381的URL。（在server端通过session.use_cookies来控制使用哪一种方式）
<br/>3.在server端，php如何判断session文件是否过期？
<br/>如果”最后的修改时间”到”现在”超过了gc_maxlifetime（默认是1440）秒，这个session文件就被认为是过期了，在下一次session回收的时候，如果这个文件仍然没有被更改过，这个session文件就会被删除（session就过期了）。
<br/>简单的说，如果我登录到某网站，如果在1440秒（默认值）内没有操作过，那么对应的session就认为是过期了。
<br/>所以，修改php.ini文件中的gc_maxlifetime变量就可以延长session的过期时间了：（例如，我们把过期时间修改为86400秒）
<br/>session.gc_maxlifetime=86400
<br/>然后，重启你的web服务（一般是apache）就可以了。
<br/>注意：php5里面session过期使用了回收机制。这里设置时间为86400秒，如果session在86400秒内没有被修改过，那么在下一次“回收”时才真的被删除。
<br/>4.session“回收”何时发生？
<br/>默认情况下，每一次php请求，就会有1/100的概率发生回收，所以可能简单的理解为“每100次php请求就有一次回收发生”。这个概率是通过以下参数控制的
<br/>#概率是gc_probability/gc_divisor
<br/>session.gc_probability=1
<br/>session.gc_divisor=100
<br/>注意1：假设这种情况gc_maxlifetime=120，如果某个session文件最后修改时间是120秒之前，那么在下一次回收（1/100的概率）发生前，这个session仍然是有效的。
<br/>注意2：如果你的session使用session.save_path中使用别的地方保存session，session回收机制有可能不会自动处理过期session文件。这时需要定时手动（或者crontab）的删除过期的session：cd/path/to/sessions;find-cmin+24|xargsrm
<br/>5.一些特殊情况
<br/>因为回收机制会检查文件的“最后修改时间”，所以如果某个会话是活跃的，但是session的内容没有改变过，那么对应的session文件也就没有改变过，回收机制会认为这是一个长时间没有活跃的session而将其删除。这是我们不愿看到的，可以通过增加如下的简单代码解决这个问题：
<br/>&lt;?php
<br/>if(!isset($_SESSION['last_access'])||(time()-$_SESSION['last_access'])&gt;60)
<br/>	$_SESSION['last_access']=time();
<br/>?&gt;
<br/>代码会每隔60秒，尝试修改修改一次session。
<br/>总结：如果想修改session过期时间，修改变量gc_maxlifetime就可以了。php5的session采用被动的回收机制（garbagecollection）。过期的session文件不会自己消失，而是通过触发“回收”来处理过期的session。]]></description>
		<pubDate>Tue, 19 Jan 2010 11:31:51 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[php中使用接口(interface)实现多重继承]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail993.shtml]]></link>
		<description><![CDATA[php中使用接口(interface)实现多重继承:
<br/>我们都知道PHP中的类(class)是单继承的，那是不是就没有办法实现多重继承了呢?答案是否定的.我们可以通过其它特殊的方式实现类的多重继承，比如使用接口(interface)实现，只要把类的特征抽象为接口，并通过实现接口的方式让对象有多重身份，通过这样就可以模拟多重继承了。
<br/>下面是一个用接口(interface)实现多重继承的例子，源代码如下：
<br/>&lt;?php
<br/>interfaceUserInterface{//定义User的接口
<br/>functiongetname();
<br/>}
<br/>interfaceTeacherInterface{//teacher相关接口
<br/>functiongetLengthOfService();
<br/>}
<br/>classUserimplementsUserInterface{//实现UserInterface接口
<br/>private$name=&quot;tom&quot;;
<br/>publicfunctiongetName(){
<br/>return$this-&gt;name;
<br/>}
<br/>}
<br/>classTeacherimplementsTeacherInterface{//实现TeacherInterface接口
<br/>private$lengthOfService=5;//工龄
<br/>publicfunctiongetLengthOfService(){
<br/>return$this-&gt;lengthOfService;
<br/>}
<br/>}
<br/>//继承自User类,同时实现了TeacherInterface接口.
<br/>classGraduateStudentextendsUserimplementsTeacherInterface{
<br/>private$teacher;
<br/>publicfunction__construct(){
<br/>$this-&gt;teacher=newTeacher();
<br/>}
<br/>publicfunctiongetLengthOfService(){
<br/>return$this-&gt;teacher-&gt;getLengthOfService();
<br/>}
<br/>}
<br/>classAct{
<br/>//注意这里的类型提示改成了接口类型
<br/>publicstaticfunctiongetUserName(UserInterface$_user){
<br/>echo&quot;Nameis&quot;.$_user-&gt;getName().&quot;&lt;br&gt;&quot;;
<br/>}
<br/>//这里的类型提示改成了TeacherInterface类型.
<br/>publicstaticfunctiongetLengthOfService(TeacherInterface$_teacher){
<br/>echo&quot;Ageis&quot;.$_teacher-&gt;getLengthOfService().&quot;&lt;br&gt;&quot;;
<br/>}
<br/>}
<br/>$graduateStudent=newGraduateStudent();
<br/>Act::getUserName($graduateStudent);
<br/>Act::getLengthOfService($graduateStudent);
<br/>//结果正如我们所要的,实现了有多重身份的一个对象.
<br/>?&gt;
<br/>示例运行结果如下：
<br/>Nameistom
<br/>Ageis5]]></description>
		<pubDate>Tue, 19 Jan 2010 10:06:12 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[php中heredoc技术用法详解]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail992.shtml]]></link>
		<description><![CDATA[php中heredoc技术用法详解:
<br/>php中的heredoc技术在一些PHP文档和书籍中一般没有详细讲述，只是提到了这是一种Perl风格的字符串输出技术,没有做过多的介绍,没有介绍不代表它不重要,它能很好的来实现模板与代码的分离.
<br/>看下面的代码：
<br/>&lt;?php
<br/>$name='php自学网';
<br/>print&lt;&lt;&lt;EOT
<br/>&lt;html&gt;
<br/>&lt;head&gt;
<br/>&lt;metahttp-equiv=&quot;Content-Type&quot;content=&quot;text/html;charset=gb2312&quot;/&gt;
<br/>&lt;title&gt;php中heredoc技术用法详解-php自学网&lt;/title&gt;
<br/>&lt;/head&gt;
<br/>&lt;body&gt;
<br/>Hello,$name!
<br/>&lt;/body&gt;
<br/>&lt;/html&gt;
<br/>EOT;
<br/>?&gt;
<br/>1.以&lt;&lt;&lt;End开始标记开始，以End结束标记结束，结束标记必须顶头写，不能有缩进和空格，且在结束标记末尾要有分号。开始标记和开始标记相同，比如常用大写的EOT、EOD、EOF来表示，但是不只限于那几个，只要保证开始标记和结束标记不在正文中出现即可。
<br/>2.位于开始标记和结束标记之间的变量可以被正常解析，但是函数则不可以。
<br/>3.heredoc常用在输出包含大量HTML语法d文档的时候。比如：函数outputhtml()要输出HTML的主页。可以有两种写法。很明显第二种写法比较简单和易于阅读。
<br/>functionoutputhtml(){
<br/>echo&quot;&lt;html&gt;&quot;;
<br/>echo&quot;&lt;head&gt;&lt;title&gt;php自学网首页&lt;/title&gt;&lt;/head&gt;&quot;;
<br/>echo&quot;&lt;body&gt;首页内容&lt;/body&gt;&quot;;
<br/>echo&quot;&lt;/html&gt;;
<br/>}
<br/>functionoutputhtml()
<br/>{
<br/>echo&lt;&lt;&lt;EOT
<br/>&lt;html&gt;
<br/>&lt;head&gt;&lt;title&gt;php自学网首页&lt;/title&gt;&lt;/head&gt;
<br/>&lt;body&gt;首页内容&lt;/body&gt;
<br/>&lt;/html&gt;
<br/>EOT;
<br/>}
<br/>outputhtml();]]></description>
		<pubDate>Mon, 18 Jan 2010 18:28:21 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[php中文件锁函数flock函数用法简介]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail991.shtml]]></link>
		<description><![CDATA[php中文件锁函数flock函数用法简介:
<br/>语法:
<br/>boolflock(int$handle,int$operation[,int&amp;$wouldblock])
<br/>flock()操作的handle必须是一个已经打开的文件指针。operation可以是以下值之一：
<br/>1.要取得共享锁定（读取程序），将operation设为LOCK_SH（PHP4.0.1以前的版本设置为1）
<br/>2.要取得独占锁定（写入程序），将operation设为LOCK_EX（PHP4.0.1以前的版本中设置为2）
<br/>3.要释放锁定（无论共享或独占），将operation设为LOCK_UN（PHP4.0.1以前的版本中设置为3）
<br/>4.如果你不希望flock()在锁定时堵塞，则给operation加上LOCK_NB（PHP4.0.1以前的版本中设置为4）
<br/>看下面代码:
<br/>a.php
<br/>&lt;?php
<br/>$file=&quot;temp.txt&quot;;
<br/>$fp=fopen($file,'w');
<br/>if(flock($fp,LOCK_EX)){
<br/>fwrite($fp,&quot;abc&quot;);
<br/>sleep(10);
<br/>fwrite($fp,&quot;123&quot;);
<br/>flock($fp,LOCK_UN);
<br/>}
<br/>fclose($fp);
<br/>?&gt;
<br/>b.php
<br/>&lt;?php
<br/>$file=&quot;temp.txt&quot;;
<br/>$fp=fopen($file,'r');
<br/>echofread($fp,100);
<br/>fclose($fp);
<br/>?&gt;
<br/>运行a.php后，马上运行b.php，可以看到输出：
<br/>abc
<br/>等a.php运行完后运行b.php，可以看到输出：
<br/>abc
<br/>123
<br/>显然，当a.php写文件时数据太大，导致时间比较长时，这时b.php读取数据不完整,在对b.php做修改
<br/>修改b.php为：
<br/>&lt;?php
<br/>$file=&quot;temp.txt&quot;;
<br/>$fp=fopen($file,'r');
<br/>if(flock($fp,LOCK_EX)){
<br/>echofread($fp,100);
<br/>flock($fp,LOCK_UN);
<br/>}else{
<br/>echo&quot;Lockfilefailed...&quot;;
<br/>}
<br/>fclose($fp);
<br/>?&gt;
<br/>运行a.php后，马上运行b.php，可以发现b.php会等到a.php运行完成后(即10秒后)才显示：
<br/>abc
<br/>123
<br/>读取数据完整，但时间过长，他要等待写锁释放,再对b.php做修改。
<br/>修改b.php为：
<br/>&lt;?php
<br/>$file=&quot;temp.txt&quot;;
<br/>$fp=fopen($file,'r');
<br/>if(flock($fp,LOCK_SH|LOCK_NB)){
<br/>echofread($fp,100);
<br/>flock($fp,LOCK_UN);
<br/>}else{
<br/>echo&quot;Lockfilefailed...&quot;;
<br/>}
<br/>fclose($fp);
<br/>?&gt;
<br/>运行a.php后，马上运行b.php，可以看到输出：
<br/>Lockfilefailed…
<br/>证明可以返回锁文件失败状态，而不是向上面一样要等很久。
<br/>结论：
<br/>建议作文件缓存时，选好相关的锁，不然可能导致读取数据不完整，或重复写入数据。
<br/>file_get_contents好像选择不了锁，不知道他默认用的什么锁，反正和不锁得到的输出一样，是不完整的数据。]]></description>
		<pubDate>Mon, 18 Jan 2010 18:17:09 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[php中字符串格式化函数sprintf用法简介]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail988.shtml]]></link>
		<description><![CDATA[php中字符串格式化函数sprintf用法简介:
<br/>语法:stringsprintf(stringformat,mixed[args]...);
<br/>返回值:字符串
<br/>函数说明
<br/>本函数用来将字符串格式化。参数format是转换的格式，以百分比符号%开始到转换字符为止。而在转换的格式间依序包括了
<br/>1.填空字元。0的话表示空格填0；空格是内定值，表示空格就放着。
<br/>2.对齐方式。内定值为向右对齐，负号表向左对齐。
<br/>3.栏位宽度。为最小宽度。
<br/>4.精确度。指在小数点后的浮点数位数。
<br/>型态，见下表
<br/>转换字符
<br/>%印出百分比符号，不转换。
<br/>b整数转成二进位。
<br/>c整数转成对应的ASCII字元。
<br/>d整数转成十进位。
<br/>f倍精确度数字转成浮点数。
<br/>o整数转成八进位。
<br/>s整数转成字串。
<br/>x整数转成小写十六进位。
<br/>X整数转成大写十六进位。
<br/>例子:
<br/>&lt;?php
<br/>$money1=68.25;
<br/>$money2=54.35;
<br/>$money=$money1+$money2;
<br/>//此时变数$money值为&quot;123.1&quot;;
<br/>$formatted=sprintf(&quot;%01.2f&quot;,$money);
<br/>//此时变数$formatted值为&quot;123.10&quot;
<br/>?&gt;
<br/>这个%01.2f是什么意思呢？
<br/>首先这个%符号是开始的意思,他写在最前面表示指定格式要开始了。也就是&quot;起始字符&quot;,直到出现&quot;转换字符&quot;为止,就算格式终止。
<br/>然后跟在%符号后面的是0这个零是&quot;填空字元&quot;表示,如果位置空着就用0来填满。
<br/>在0后面的是1这个1是规定,小数点前面的数字占位要有1位以上。
<br/>如果把1改成2如果$money的值为1.23,则$formatted的值将为01.23
<br/>因为,在小数点前面的数字只占了1位,按照上面所规定的格式,小数点前数字应该占2位,现在只有1位,所以,用0来填满。
<br/>到目前,在%01后面的.2(点2)就很好理解了,它的意思是,规定,小数点后的数字,必需占2位.如果这时候,$money的值为1.234,则$formatted的值将为1.23。
<br/>为什么4不见了呢?因为,在小数点后面按照上面的规定,必需且仅能占2位。可是$money的值中,小数点占了3位,所以,4被去掉了,只剩下23。
<br/>最后,以f&quot;转换字符&quot;结尾,其他转换字符请自行参考上面的转换字符列表。
<br/>关于对齐
<br/>如果在%起始符号后面加上-(负号)则,将会把数字以向右对齐的方式进行处理。
<br/>看下面实例:
<br/>&lt;?php
<br/>$money=1.4;
<br/>$formatted=sprintf(&quot;%-02.2f&quot;,$money);
<br/>echo$formatted;
<br/>?&gt;
<br/>这时候,$formatted将不会再是01.40而是1.400]]></description>
		<pubDate>Fri, 15 Jan 2010 09:47:43 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[linux中列出打开文件进程lsof命令用法详解]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail986.shtml]]></link>
		<description><![CDATA[linux中列出打开文件进程lsof命令用法详解:
<br/>Linux下lsof命令的功能是列出打开文件的进程，LINUX下，所有的设备都是以文件的行式存在的.一般root用户才能执行lsof命令，普通用户可以看见/usr/sbin/lsof命令，但是普通用户执行会显示&quot;permissiondenied&quot;,无权限访问.
<br/>sof命令的用法如下：
<br/>lsof-cabc显示abc进程现在打开的文件
<br/>lsofabc.txt显示开启文件abc.txt的进程
<br/>lsof-i:22知道22端口现在运行什么程序
<br/>lsof-ggid显示归属gid的进程情况
<br/>lsof+d/usr/local/显示目录下被进程开启的文件
<br/>lsof+D/usr/local/同上，但是会搜索目录下的目录，时间较长
<br/>lsof-d4显示使用fd为4的进程
<br/>lsof-i用以显示符合条件的进程情况
<br/>语法:
<br/>lsof-i[46][protocol][@hostname|hostaddr][:service|port]
<br/>46–&gt;IPv4orIPv6
<br/>protocol–&gt;TCPorUDP
<br/>hostname–&gt;Internethostname
<br/>hostaddr–&gt;IPv4位置
<br/>service–&gt;/etc/service中的servicename(可以不只一个)
<br/>port–&gt;端口号(可以不只一个)
<br/>例子1:TCP:25–TCPandport25
<br/>@1.2.3.4–InternetIPv4hostaddress1.2.3.4
<br/>tcp@ohaha.ks.edu.tw:ftp–TCPprotocolhosthaha.ks.edu.twservicename:ftp
<br/>lsof-n不将IP转换为hostname，缺省是不加上-n参数
<br/>例子2:lsof-itcp@ohaha.ks.edu.tw:ftp-n
<br/>lsof-p12看进程号为12的进程打开了哪些文件
<br/>lsof+|-r[t]控制lsof不断重复执行，缺省是15s刷新
<br/>-r，lsof会永远不断的执行，直到收到中断信号
<br/>+r，lsof会一直执行，直到没有档案被显示
<br/>例子3：不断查看目前ftp连接的情况：lsof-itcp@ohaha.ks.edu.tw:ftp-r
<br/>lsof-s列出打开文件的大小，如果没有大小，则留下空白
<br/>lsof-uusername以UID，列出打开的文件]]></description>
		<pubDate>Thu, 14 Jan 2010 13:13:21 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[用php中的ignore_user_abort函数实现计划任务]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail983.shtml]]></link>
		<description><![CDATA[用php中的ignore_user_abort函数实现计划任务:
<br/>用php的ignore_user_abort函数可以帮助我们实现像linux中的crontab一样的计划任务，下面看一下是如何来实现的。
<br/>语法:
<br/>手册上的说明
<br/>Description
<br/>intignore_user_abort([bool$setting])
<br/>Setswhetheraclientdisconnectshouldcauseascripttobeaborted.
<br/>也就是说无论客户端是否关闭浏览器，下面的程序都会执行.
<br/>参数说明:
<br/>Parameters
<br/>setting
<br/>Ifnotset,thefunctionwillonlyreturnthecurrentsetting.
<br/>这个函数接受一个参数，来决定是否启用ignore_user_abort的功能。
<br/>返回值：
<br/>ReturnValues
<br/>Returnstheprevioussetting,asaboolean.
<br/>这里说返回前一次的设置，并且是bool值得，经过我的测试，这个说法是不对的，返回的明明是int型的，不相信的话大家可以写一个php文件来测试下。
<br/>
<br/>实现定时器的功能还需借助set_time_limit函数，通过set_time_limit(0)可以设置程序的执行时间为无限制，php默认的执行时间是30秒，通过set_time_limit(0)可以让程序无限制的执行下去。在程序执行之前加上ignore_user_abort(1)和set_time_limit(0)即可以了,看下面的例子。
<br/>&lt;?php
<br/>ignore_user_abort();//runscriptinbackground
<br/>set_time_limit(0);//runscriptforever
<br/>$interval=60*15;//doevery15minutes...
<br/>do{
<br/>//addthescriptthathastoberanevery15minuteshere
<br/>//...
<br/>sleep($interval);//wait15minutes
<br/>}while(true);
<br/>?&gt;]]></description>
		<pubDate>Wed, 13 Jan 2010 10:20:26 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[用php的chr和ord函数实现字符串和ASCII码互转]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail982.shtml]]></link>
		<description><![CDATA[用php的chr和ord函数实现字符串和ASCII码互转:
<br/>chr和ord函数是用来字符串和ASCII码互转的.
<br/>ASCII码是计算机所能显示字符的编码，它的取值范围是0-255，其中包括标点、字母、数字、汉字等。在编程过程中，经常把指定的字符转化为ASCII码进行比较。
<br/>下面是PHP提供的转换ASCII码和字符的函数。
<br/>1．chr()函数
<br/>该函数用于将ASCII码值转化为字符串。其函数声明如下：
<br/>stringchr(intascii);
<br/>2．ord()函数
<br/>该函数用于将字符串转化为ASCII码值。其函数声明如下：
<br/>intord(stringstr);
<br/>例子：
<br/>使用chr()函数和ord()函数进行字符串与ASCII码之间的转换，程序代码如下：
<br/>&lt;?php
<br/>$str1=chr(88);
<br/>echo$str1;//返回值为X
<br/>echo&quot;\t&quot;;
<br/>$str2=ord('S');
<br/>echo$str2;//返回值为83
<br/>?&gt;
<br/>运行结果：X83]]></description>
		<pubDate>Tue, 12 Jan 2010 15:45:28 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[php实现工商银行在线支付接口]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail981.shtml]]></link>
		<description><![CDATA[php实现工商银行在线支付接口:
<br/>实现工商银行的在线支付功能,主要是根据工商银行提供的在线支付的接口，将订单中的数据以表单的形式提交到工行指定的网站中接口中，具体详细的参数设置可以参考工行提供的文档说明书和实现的实例程序。
<br/>在实现与工商银行接口之前，首先要在工行提供的说明书中找到如下两个文件。
<br/>1.开发api接口\lib\windows\win32\infosecapi.dll(windowsxp系统使用的文件).
<br/>2.开发api接口\asp\icbcebankutil.dll
<br/>将其复制到系统文件夹下的windows\system32目录下，运行命令&quot;regsvr32icbcebankutil.dll&quot;加载服务。
<br/>通过php实现网站与工行接口交互的方法如下
<br/>首先，通过com类中的init方法对订单签名数据和商城的公钥进行加密处理，并且将指定的数据以表单的形式提交到工行指定的页面，代码如下:
<br/>$src=&quot;ICBC_PERBANK_B2C1.0.0.0&quot;.$infomer[&quot;merid&quot;].$infomer[&quot;meracct&quot;].$returnaddress.&quot;HS&quot;.$ddnumber.$amount.&quot;0010&quot;.$nowtime.&quot;0&quot;;
<br/>$com=newcom('ICBCEBANKUTIL.B2CUtil');
<br/>$rc=$com-&gt;init(&quot;c:\WINDOWS\user.crt&quot;,&quot;c:\WINDOWS\user.crt&quot;,&quot;c:\WINDOWS\user.key&quot;,&quot;11111111&quot;);
<br/>$ssrc=$com-&gt;signC($src,strlen($src));//订单签名数据
<br/>$rc=$com-&gt;verifySignC($src,strlen($src),$ssrc,strlen($ssrc));
<br/>$cert=$com-&gt;getCert(1);//商城证书公钥
<br/>完成订单签名数据和商城证书公钥的加密处理，这里将商户的测试证书存储到c:\windows目录下，设置商户的密钥口令是00.
<br/>然后创建form表单，将制定的数据提交到工行指定的网站中，关键代码如下：
<br/>需要提交的表单数据:
<tablecellspacing="0"cellpadding="6"width="95%"align="center"border="0"class="page_kuang">
<tr><tdclass="page_kuang_content">&lt;formaction=&quot;https://mybank.icbc.com.cn/&quot;method=&quot;post&quot;name=&quot;form_bank&quot;&gt;
<br/>&lt;inputname=&quot;interfaceName&quot;type=&quot;hidden&quot;value=&quot;ICBC_PERBANK_B2C&quot;/&gt;
<br/>&lt;inputname=&quot;interfaceVersion&quot;type=&quot;hidden&quot;value=&quot;1.0.0.0&quot;/&gt;
<br/>&lt;inputname=&quot;orderid&quot;type=&quot;hidden&quot;value=&quot;&lt;{$ddnumber}&gt;&quot;/&gt;
<br/>&lt;inputname=&quot;amount&quot;type=&quot;hidden&quot;value=&quot;&lt;{$amount}&gt;&quot;/&gt;
<br/>&lt;inputname=&quot;curType&quot;type=&quot;hidden&quot;value=&quot;001&quot;/&gt;
<br/>&lt;inputname=&quot;merID&quot;type=&quot;hidden&quot;value=&quot;&lt;{$merid}&gt;&quot;/&gt;
<br/>&lt;inputname=&quot;merAcct&quot;type=&quot;hidden&quot;value=&quot;&lt;{$meracct}&gt;&quot;/&gt;
<br/>&lt;inputname=&quot;verifyJoinFlag&quot;type=&quot;hidden&quot;value=&quot;0&quot;/&gt;
<br/>&lt;inputname=&quot;notifyType&quot;type=&quot;hidden&quot;value=&quot;HS&quot;/&gt;
<br/>&lt;inputname=&quot;merURL&quot;type=&quot;hidden&quot;value=&quot;&lt;{$returnaddress}&gt;&quot;/&gt;
<br/>&lt;inputname=&quot;resultType&quot;type=&quot;hidden&quot;value=&quot;0&quot;/&gt;
<br/>&lt;inputname=&quot;orderDate&quot;type=&quot;hidden&quot;value=&quot;&lt;{$nowtime}&gt;&quot;/&gt;
<br/>&lt;inputname=&quot;merSignMsg&quot;type=&quot;hidden&quot;value=&quot;&lt;{$ssrc}&gt;&quot;/&gt;
<br/>&lt;inputname=&quot;merCert&quot;type=&quot;hidden&quot;value=&quot;&lt;{$cert}&gt;&quot;/&gt;
<br/>&lt;/form&gt;</td></tr></table>]]></description>
		<pubDate>Tue, 12 Jan 2010 15:19:53 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[php中循环冗余校验函数crc32用法详解]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail980.shtml]]></link>
		<description><![CDATA[php中循环冗余校验函数crc32用法详解:
<br/>语法:
<br/>intcrc32(stringstr)
<br/>必要参数。选择需要计算的字符串
<br/>生成str的32位循环冗余校验码多项式。这通常用于检查传输的数据是否完整,用来验证一个整数的有效性的。
<br/>由于PHP的整数是带符号的，许多crc32校验码将返回负整数，因此你需要使用sprintf()或printf()的“%u”格式符来获取表示无符号crc32校验码的字符串。
<br/>实例:
<br/>在下面这个案例中，我们将使用/不使用“%u”格式来输出crc32()的结果（注意：返回的结果是相同的）：
<br/>&lt;?php
<br/>$str=crc32(&quot;php自学网!&quot;);
<br/>echo'Without%u:'.$str.&quot;&lt;br/&gt;&quot;;
<br/>echo'With%u:';printf(&quot;%u&quot;,$str);
<br/>?&gt;
<br/>结果：
<br/>Without%u:-726583907%u:3568383389]]></description>
		<pubDate>Tue, 12 Jan 2010 15:10:59 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[php版支付宝接口源代码]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail979.shtml]]></link>
		<description><![CDATA[php版支付宝接口源代码:
<br/>首先在使用支付宝支付的时候，必须先注册一个支付宝的账户，然后再下载支付宝提供的接口文件，通过支付宝提供的接口文件，实现电子商务与支付宝的交互。
<br/>在支付宝提供的接口文件中，提供了完整的实例程序，只要依照实例程序中的操作方法，将电子商务网站中指定的数据提交到支付宝提供的数组参数中，然后支付宝通过自己的定义的方法将数据提交到指定的网站中。实现代码如下,具体见代码注释：
<tablecellspacing="0"cellpadding="6"width="95%"align="center"border="0"class="page_kuang">
<tr><tdclass="page_kuang_content">
&lt;?php
<br/>require_once(&quot;alipay_service.php&quot;);
<br/>require_once(&quot;alipay_config.php&quot;);
<br/>$array=explode(&quot;@&quot;,$info[&quot;spc&quot;]);
<br/>$arraynum=explode(&quot;@&quot;,$info[&quot;slc&quot;]);
<br/>$arrayinfo=array();//创建数组
<br/>$arrayinfo_count=array();//创建数组
<br/>for($i=0;$i&lt;count($array);$i++){
<br/>if($array[$i]!=&quot;&quot;){
<br/>$m=$i+1;
<br/>$sqlcart=mysql_query(&quot;select*fromtb_commoditywheretb_commodity_id='&quot;.$array[$i].&quot;'&quot;,$conn);
<br/>$infocart=mysql_fetch_array($sqlcart);//读取数据库中数据
<br/>array_push($arrayinfo,$infocart[tb_commodity_name]);//将购物商品的名称写入到数组中
<br/>array_push($arrayinfo_count,&quot;商品$m：$infocart[tb_commodity_name]数量：$arraynum[$i]&quot;);//将购物商品的数量写入到数组中
<br/>}
<br/>}
<br/>$commodity_name=implode(',',$arrayinfo);//获取商品名称
<br/>$commodity_count=implode(',',$arrayinfo_count);//获取商品描述信息
<br/>$parameter=array(
<br/>&quot;service&quot;=&gt;&quot;trade_create_by_buyer&quot;,//交易类型，必填实物交易＝trade_create_by_buyer（需要填写物流）
<br/>&quot;partner&quot;=&gt;$partner,//合作商户号
<br/>&quot;return_url&quot;=&gt;$return_url,//同步返回
<br/>&quot;notify_url&quot;=&gt;$notify_url,//异步返回
<br/>&quot;_input_charset&quot;=&gt;$_input_charset,//字符集，默认为GBK
<br/>&quot;subject&quot;=&gt;$commodity_name,//商品名称，必填
<br/>&quot;body&quot;=&gt;$commodity_count,//商品描述，必填
<br/>&quot;out_trade_no&quot;=&gt;$ddnumber,//商品外部交易号，订单号，必填,每次测试都须修改
<br/>&quot;logistics_fee&quot;=&gt;$yprice,//物流配送费用
<br/>&quot;logistics_payment&quot;=&gt;'BUYER_PAY',//物流配送费用付款方式：BUYER_PAY(买家支付)
<br/>&quot;logistics_type&quot;=&gt;'EXPRESS',//物流配送方式：POST(平邮)、EMS(EMS)、EXPRESS(其他快递)
<br/>&quot;price&quot;=&gt;$amount,//商品单价，必填
<br/>&quot;payment_type&quot;=&gt;&quot;1&quot;,//默认为1,不需要修改
<br/>&quot;quantity&quot;=&gt;&quot;1&quot;,//商品数量，必填
<br/>&quot;show_url&quot;=&gt;$show_url,//商品相关网站
<br/>&quot;seller_email&quot;=&gt;$seller_email//卖家邮箱，必填
<br/>);
<br/>$alipay=newalipay_service($parameter,$security_code,$sign_type);
<br/>$link=$alipay-&gt;create_url();
<br/>$smarty-&gt;assign(&quot;link&quot;,$link);
<br/>?&gt;</td></tr></table>
这里介绍的知识通过php来实现电子商务网站与支付宝进行交互的方法。其中涉及到支付宝提供的参数和设置都是个人虚拟的，真实的参数将在实际的运作中由支付宝提供，使用支付宝时，需要向支付宝申请一个账户，然后由支付宝提供相应的参数，就可以应用此功能了。]]></description>
		<pubDate>Tue, 12 Jan 2010 14:50:37 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[php中header函数用法实例总结]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail962.shtml]]></link>
		<description><![CDATA[php中header函数用法实例总结:
<br/>1.页面没找到NotFound
<br/>header('HTTP/1.1404NotFound');
<br/>2.用这个header指令来解决URL重写产生的404header
<br/>header('HTTP/1.1200OK');
<br/>3.访问受限
<br/>header('HTTP/1.1403Forbidden');
<br/>//Thepagemovedpermanentlyshouldbeusedfor
<br/>//allredrictions,becausesearchenginesknow
<br/>//what'sgoingonandcaneasilyupdatetheirurls.
<br/>4.页面被永久删除，可以告诉搜索引擎更新它们的urls
<br/>header('HTTP/1.1301MovedPermanently');
<br/>5.服务器错误
<br/>header('HTTP/1.1500InternalServerError');
<br/>6.重定向到一个新的位置
<br/>header('Location:http://www.example.org/');
<br/>7.延迟一段时间后重定向
<br/>header('Refresh:10;url=http://www.example.org/');
<br/>echo'Youwillberedirectedin10seconds';
<br/>8.加载要下载的文件:
<br/>readfile('example.zip');
<br/>9.也可以使用HTML语法来实现延迟
<br/>header('Content-Transfer-Encoding:binary');
<br/>10.禁止缓存当前文档:
<br/>header('Cache-Control:no-cache,no-store,max-age=0,must-revalidate');
<br/>header('Expires:Mon,26Jul201005:00:00GMT');
<br/>header('Pragma:no-cache');
<br/>11.显示登录对话框，可以用来进行HTTP认证
<br/>header('HTTP/1.1401Unauthorized');
<br/>header('WWW-Authenticate:Basicrealm=&quot;TopSecret&quot;');
<br/>echo'Textthatwillbedisplayediftheuserhitscancelor';
<br/>echo'enterswronglogindata';
<br/>12.设置内容类型:
<br/>header('Content-Type:text/html;charset=iso-8859-1');
<br/>header('Content-Type:text/html;charset=utf-8');
<br/>header('Content-Type:text/plain');//plaintextfile
<br/>header('Content-Type:image/jpeg');//JPGpicture
<br/>header('Content-Type:application/zip');//ZIPfile
<br/>header('Content-Type:application/pdf');//PDFfile
<br/>header('Content-Type:audio/mpeg');//AudioMPEG(MP3,...)file
<br/>header('Content-Type:application/x-shockwave-flash');//Flashanimation]]></description>
		<pubDate>Thu, 07 Jan 2010 10:48:13 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[页面出现网页已过期的解决办法]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail954.shtml]]></link>
		<description><![CDATA[页面出现网页已过期的解决办法:
<br/>相信大家都遇到过当点击回头按钮的时候,之前填写的表单信息都清空了或出现网页已过期的警告,这是由于在表单提交页面中使用了session_start函数.由于我们后退浏览的是缓存页,而该函数会强制当前页面不被缓存。所以出现了'警告:网页已经过期!'.的提示.下面介绍一下解决的办法:
<br/>在你的Session_start函数后加入header(&quot;Cache-control:private&quot;);注意在本行之前你的PHP程序不能有任何输出和空白。
<br/>还有基于session的解决方法:
<br/>在session_start前加上如下代码:
<br/>session_cache_limiter('nocache');//清空表单
<br/>session_cache_limiter('private');//不清空表单，只在session生效期间
<br/>session_cache_limiter('public');//不清空表单，如同有没使用session一样]]></description>
		<pubDate>Tue, 05 Jan 2010 12:16:05 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[php中修改php.ini配置文件的几个函数介绍]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail953.shtml]]></link>
		<description><![CDATA[php中修改php.ini配置文件的几个函数介绍:
<br/>php中修改php配置文件(php.ini)的函数主要有四个函数：ini_get、ini_set、ini_get_all、ini_restore。其中ini_set和ini_get比较常用,下面分别做介绍。
<br/>(1)ini_get()
<br/>用来获取配置文件的选项值.
<br/>这个函数相信很多人都使过，就是获取配置文件中某一个选项的值，如果是true值就返回1，如果是false值就返回0，字符串就返回字符串。
<br/>php手册中的例子：
<br/>&lt;?php
<br/>/*
<br/>Ourphp.inicontainsthefollowingsettings:
<br/>display_errors=On
<br/>register_globals=Off
<br/>post_max_size=8M
<br/>*/
<br/>echo'post_max_size='.ini_get('post_max_size').&quot;\n&quot;;//最多能提交的文件大小
<br/>echo'post_max_size+1='.(ini_get('post_max_size')+1).&quot;\n&quot;;
<br/>echo'display_errors='.ini_get('display_errors').&quot;\n&quot;;//显示错误是否打开
<br/>echo'register_globals='.ini_get('register_globals').&quot;\n&quot;;//全局变量是否打开
<br/>?&gt;
<br/>输出：
<br/>display_errors=1
<br/>register_globals=0
<br/>post_max_size=8M
<br/>post_max_size+1=9
<br/>这个函数主要是为了获取配置文件，可以方便你很多操作。比如你想操作字符串过滤，但是又不清楚magic_quotes_gpc有没有打开，所以你就可以这样写一个函数：
<br/>/*字符串过滤函数*/
<br/>functionstringFilter($str)
<br/>{
<br/>if(ini_get('magic_quotes_gpc)'){
<br/>return$str;
<br/>}else{
<br/>returnaddslashes($str);
<br/>}
<br/>}
<br/>当然，如果你无法知道你的全局变量是否打开，也可以定制这样的函数：
<br/>/*变量检测函数*/
<br/>functiongetGetVar($var)
<br/>{
<br/>if(ini_set('register_gobals')){
<br/>return$var;
<br/>}else{
<br/>return$_GET['var'];
<br/>}
<br/>}
<br/>当然，你可以做很多用途，自己慢慢体会。
<br/>(2)ini_set函数
<br/>设置php.ini中的某些变量值.
<br/>这个函数是设置选项中的值，在执行函数后生效，脚本结束的时候，这个设置也失效。不是所有的选项都能被改函数设置的。具体那些值能够设置，可以查看手册中的列表。
<br/>就是能够设置php.ini中的选项值比如，display_error选项关闭了，但是你要显示程序中的错误信息，方便你调试程序，那么就可以使用这个函数：
<br/>ini_set(&quot;display_errors&quot;,&quot;On&quot;);
<br/>那么在你这个页面的程序都会显示错误信息了，而且你还可以使用error_reporting来设置显示的错误信息级别。
<br/>如果你需要增加脚本执行时间，那么可以设置：
<br/>ini_set(&quot;max_execution_time&quot;,&quot;180&quot;);
<br/>那么脚本执行时间就由默认的30秒变为180秒，当然，你也可以使用set_time_limit()来设置。
<br/>其实你把ini_set和ini_get结合使的话，非常好。比如你想在配置文件里添加自己的包含文件路径，但是你有没有权限更改php.ini，那么你可以结合两个函数：
<br/>ini_set('include_path',ini_get('include_path').':/your_include_dir:');
<br/>(3)ini_get_all
<br/>获取所有的设置选项变量
<br/>把所有选项值以数组的形式返回，方便你当phpinfo()无法使用的时候来使用。
<br/>手册例子：
<br/>&lt;?php
<br/>$inis=ini_get_all();
<br/>print_r($inis);
<br/>?&gt;
<br/>部分输出值：
<br/>Array
<br/>(
<br/>[allow_call_time_pass_reference]=&gt;Array
<br/>(
<br/>[global_value]=&gt;1
<br/>[local_value]=&gt;1
<br/>[access]=&gt;6
<br/>)
<br/>[allow_url_fopen]=&gt;Array
<br/>(
<br/>[global_value]=&gt;1
<br/>[local_value]=&gt;1
<br/>[access]=&gt;7
<br/>)
<br/>...
<br/>)
<br/>(4)ini_restore
<br/>恢复配置文件默认的值
<br/>就是恢复配置文件默认的值，当你使用ini_set设置后可以使用它来恢复。]]></description>
		<pubDate>Tue, 05 Jan 2010 11:19:54 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[php中static静态变量的用法介绍]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail952.shtml]]></link>
		<description><![CDATA[php中static静态变量的用法介绍:
<br/>php中的变量作用范围的另一个重要特性就是静态变量（static变量）。静态变量仅在局部函数域中存在且只被初始化一次,当程序执行离开此作用域时，其值不会消失,会使用上次执行的结果。
<br/>看看下面的实例：
<br/>&lt;?php
<br/>functionTest()
<br/>{
<br/>$w3sky=0;
<br/>echo$w3sky;
<br/>$w3sky++;
<br/>}
<br/>?&gt;
<br/>本函数每次调用时都会将$w3sky的值设为0并输出&quot;0&quot;。将变量加一的$w3sky++没有其到效果，因为一旦退出本函数则变量$w3sky就不存在了。要写一个不会丢失本次计数值的计数函数，要将变量$w3sky定义为静态(static)的：
<br/>如下:
<br/>&lt;?php
<br/>functionTest()
<br/>{
<br/>static$w3sky=0;
<br/>echo$w3sky;
<br/>$w3sky++;
<br/>}
<br/>?&gt;
<br/>本函数每调用Test()都会输出$w3sky的值并加一。
<br/>静态变量也提供了一种处理递归函数的方法。递归函数是一种自己调用自己的方法。写递归函数时要小心，因为可能会无穷递归下去,没有出口.务必确保有方法来中止递归。以下这个简单的函数递归计数到10，使用静态变量$count来判断何时停止：
<br/>静态变量与递归函数的例子:
<br/>&lt;?PHP
<br/>functionTest()
<br/>{
<br/>static$count=0;
<br/>$count++;
<br/>echo$count;
<br/>if($count&lt;10){
<br/>Test();
<br/>}
<br/>$count--;
<br/>}
<br/>?&gt;
<br/>注:静态变量可以按照上面的例子声明。如果在声明中用表达式的结果对其赋值会导致解析错误。
<br/>声明静态变量例子:
<br/>&lt;?PHP
<br/>functionfoo(){
<br/>static$int=0;//correct
<br/>static$int=1+2;//wrong(asitisanexpression)
<br/>static$int=sqrt(121);//wrong(asitisanexpressiontoo)
<br/>$int++;
<br/>echo$int;
<br/>}
<br/>?&gt;]]></description>
		<pubDate>Tue, 05 Jan 2010 10:22:08 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[php函数前的&符号的作用]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail951.shtml]]></link>
		<description><![CDATA[php函数前的&符号的作用:
<br/>看下面的代码,函数test前面有一个&amp;符号.
<br/>function&amp;test(){
<br/>//申明一个静态变量
<br/>static$b=0;
<br/>$b=$b+1;
<br/>echo$b;
<br/>return$b;
<br/>}
<br/>调用方式及输出结果如下:
<br/>$a=test();//这条语句会输出　$b的值　为１
<br/>$a=5;
<br/>$a=test();//这条语句会输出　$b的值　为2
<br/>$a=&amp;test();//这条语句会输出　$b的值　为3
<br/>$a=5;
<br/>$a=test();//这条语句会输出　$b的值　为6
<br/>说明:
<br/>通过这种方式$a=test();得到的其实不是函数的引用返回，这跟普通的函数调用没有区别.
<br/>至于原因：　这是PHP的规定
<br/>ＰＨＰ规定通过$a=&amp;test();方式得到的才是函数的引用返回.
<br/>至于什么是引用返回呢（php手册上说：引用返回用在当想用函数找到引用应该被绑定在哪一个变量上面时。)
<br/>手册上的这句话可能不太好理解,看下面的解释:
<br/>$a=test()方式调用函数，只是将函数的值赋给$a而已，　而$a做任何改变　都不会影响到函数中的$b.
<br/>而通过$a=&amp;test()方式调用函数呢,他的作用是将return$b中的　$b变量的内存地址与$a变量的内存地址,
<br/>指向了同一个地方.
<br/>即产生了相当于这样的效果($a=&amp;b;)所以改变$a的值,也同时改变了$b的值,所以在执行了:
<br/>$a=&amp;test();
<br/>$a=5;
<br/>以后，$b的值变为了5]]></description>
		<pubDate>Mon, 04 Jan 2010 11:08:00 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[用php实现将xml数据转化为数组(array)]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail950.shtml]]></link>
		<description><![CDATA[用php实现将xml数据转化为数组(array):
<br/>将xml转化为数组,使用正则表达式对xml数据进行匹配.代码如下:
<br/>functionxml_to_array($xml){
<br/>$reg=&quot;/&lt;(\w+)[^&gt;]*&gt;([\x00-\xFF]*)&lt;\/\1&gt;/&quot;;
<br/>if(preg_match_all($reg,$xml,$matches))
<br/>{
<br/>$count=count($matches[0]);
<br/>for($i=0;$i&lt;$count;$i++)
<br/>{
<br/>$subxml=$matches[2][$i];
<br/>$key=$matches[1][$i];
<br/>if(preg_match($reg,$subxml))
<br/>{
<br/>$arr[$key]=xml_to_array($subxml);
<br/>}else{
<br/>$arr[$key]=$subxml;
<br/>}
<br/>}
<br/>}
<br/>return$arr;
<br/>}
<br/>functionxmltoarray($xml){
<br/>$arr=xml_to_array($xml);
<br/>$key=array_keys($arr);
<br/>return$arr[$key[0]];
<br/>}]]></description>
		<pubDate>Mon, 04 Jan 2010 10:07:33 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[php中memcache的协议分析、适用场合和使用实例详解]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail946.shtml]]></link>
		<description><![CDATA[php中memcache的协议分析、适用场合和使用实例详解:
<br/>1.什么是Memcache?
<br/>Memcache是danga.com的一个项目，最早是为LiveJournal服务的，目前全世界不少人使用这个缓存项目来构建自己大负载的网站，来分担数据库的压力。
<br/>它可以应对任意多个连接，使用非阻塞的网络IO。由于它的工作机制是在内存中开辟一块空间，然后建立一个HashTable，Memcached自管理这些HashTable。
<br/>Memcache官方网站：http://www.danga.com/memcached，更多详细的信息可以来这里了解
<br/>Memcache和memcached的区别？
<br/>其实Memcache是这个项目的名称，而memcached是它服务器端的主程序文件名。一个是项目名称，一个是主程序文件名。
<br/>2.Memcache的使用
<br/>使用Memcache的网站一般流量都是比较大的，为了缓解数据库的压力，让Memcache作为一个缓存区域，把部分信息保存在内存中，在前端能够迅速的进行存取。那么一般的焦点就是集中在如何分担数据库压力和进行分布式，毕竟单台Memcache的内存容量的有限的。我这里简单提出我的个人看法，未经实践，权当参考。
<br/>分布式应用
<br/>Memcache本来支持分布式，我们客户端稍加改造，更好的支持。我们的key可以适当进行有规律的封装，比如以user为主的网站来说，每个用户都有UserID，那么可以按照固定的ID来进行提取和存取，比如1开头的用户保存在第一台Memcache服务器上，以2开头的用户的数据保存在第二胎Mecache服务器上，存取数据都先按照UserID来进行相应的转换和存取。
<br/>但是这个有缺点，就是需要对UserID进行判断，如果业务不一致，或者其他类型的应用，可能不是那么合适，那么可以根据自己的实际业务来进行考虑，或者去想更合适的方法。
<br/>减少数据库压力
<br/>这个算是比较重要的，所有的数据基本上都是保存在数据库当中的，每次频繁的存取数据库，导致数据库性能极具下降，无法同时服务更多的用户，比如MySQL，特别频繁的锁表，那么让Memcache来分担数据库的压力吧。我们需要一种改动比较小，并且能够不会大规模改变前端的方式来进行改变目前的架构。
<br/>我考虑的一种简单方法：
<br/>后端的数据库操作模块，把所有的Select操作提取出来（update/delete/insert不管），然后把对应的SQL进行相应的hash算法计算得出一个hash数据key（比如MD5或者SHA），然后把这个key去Memcache中查找数据，如果这个数据不存在，说明还没写入到缓存中，那么从数据库把数据提取出来，一个是数组类格式，然后把数据在set到Memcache中，key就是这个SQL的hash值，然后相应的设置一个失效时间，比如一个小时，那么一个小时中的数据都是从缓存中提取的，有效减少数据库的压力。缺点是数据不实时，当数据做了修改以后，无法实时到前端显示，并且还有可能对内存占用比较大，毕竟每次select出来的数据数量可能比较巨大，这个是需要考虑的因素。
<br/>3.Memcache的安全
<br/>我们上面的Memcache服务器端都是直接通过客户端连接后直接操作，没有任何的验证过程，这样如果服务器是直接暴露在互联网上的话是比较危险，轻则数据泄露被其他无关人员查看，重则服务器被入侵，因为Mecache是以root权限运行的，况且里面可能存在一些我们未知的bug或者是缓冲区溢出的情况，这些都是我们未知的，所以危险性是可以预见的。为了安全起见，我做两点建议，能够稍微的防止黑客的入侵或者数据的泄露。
<br/>内网访问
<br/>最好把两台服务器之间的访问是内网形态的，一般是Web服务器跟Memcache服务器之间。普遍的服务器都是有两块网卡，一块指向互联网，一块指向内网，那么就让Web服务器通过内网的网卡来访问Memcache服务器，我们Memcache的服务器上启动的时候就监听内网的IP地址和端口，内网间的访问能够有效阻止其他非法的访问。
<br/>#memcached-d-m1024-uroot-l192.168.0.200-p11211-c1024-P/tmp/memcached.pid
<br/>Memcache服务器端设置监听通过内网的192.168.0.200的ip的11211端口，占用1024MB内存，并且允许最大1024个并发连接
<br/>设置防火墙
<br/>防火墙是简单有效的方式，如果却是两台服务器都是挂在网的，并且需要通过外网IP来访问Memcache的话，那么可以考虑使用防火墙或者代理程序来过滤非法访问。
<br/>一般我们在Linux下可以使用iptables或者FreeBSD下的ipfw来指定一些规则防止一些非法的访问，比如我们可以设置只允许我们的Web服务器来访问我们Memcache服务器，同时阻止其他的访问。
<br/>#iptables-F
<br/>#iptables-PINPUTDROP
<br/>#iptables-AINPUT-ptcp-s192.168.0.2–dport11211-jACCEPT
<br/>#iptables-AINPUT-pudp-s192.168.0.2–dport11211-jACCEPT
<br/>上面的iptables规则就是只允许192.168.0.2这台Web服务器对Memcache服务器的访问，能够有效的阻止一些非法访问，相应的也可以增加一些其他的规则来加强安全性，这个可以根据自己的需要来做。
<br/>4.Memcache的安装
<br/>分为两个过程：memcache服务器端的安装和memcached客户端的安装。
<br/>所谓服务器端的安装就是在服务器（一般都是linux系统）上安装Memcache实现数据的存储
<br/>所谓客户端的安装就是指php（或者其他程序，Memcache还有其他不错的api接口提供）去使用服务器端的Memcache提供的函数，需要php添加扩展。
<br/>具体的配置大家可以参考：
<br/>Linux下的Memcache安装：http://www.ccvita.com/index.php/257.html
<br/>Windows下的Memcache安装：http://www.ccvita.com/index.php/258.html
<br/>Memcache基础教程：http://www.ccvita.com/index.php/259.html
<br/>PHP的Memcache
<br/>&lt;?php
<br/>//连接
<br/>$mem=newMemcache;
<br/>$mem-&gt;connect(&quot;192.168.0.200&quot;,11211);
<br/>//保存数据
<br/>$mem-&gt;set('key1','Thisisfirstvalue',0,60);
<br/>$val=$mem-&gt;get('key1');
<br/>echo&quot;Getkey1value:&quot;.$val.&quot;&lt;br/&gt;&quot;;
<br/>//替换数据
<br/>$mem-&gt;replace('key1','Thisisreplacevalue',0,60);
<br/>$val=$mem-&gt;get('key1');
<br/>echo&quot;Getkey1value:&quot;.$val.&quot;&lt;br/&gt;&quot;;
<br/>//保存数组
<br/>$arr=array('aaa','bbb','ccc','ddd');
<br/>$mem-&gt;set('key2',$arr,0,60);
<br/>$val2=$mem-&gt;get('key2');
<br/>echo&quot;Getkey2value:&quot;;
<br/>print_r($val2);
<br/>echo&quot;&lt;br/&gt;&quot;;
<br/>//删除数据
<br/>$mem-&gt;delete('key1');
<br/>$val=$mem-&gt;get('key1');
<br/>echo&quot;Getkey1value:&quot;.$val.&quot;&lt;br/&gt;&quot;;
<br/>//清除所有数据
<br/>$mem-&gt;flush();
<br/>$val2=$mem-&gt;get('key2');
<br/>echo&quot;Getkey2value:&quot;;
<br/>print_r($val2);
<br/>echo&quot;&lt;br/&gt;&quot;;
<br/>//关闭连接
<br/>$mem-&gt;close();
<br/>?&gt;
<br/>如果正常的话，浏览器将输出：
<br/>Getkey1value:Thisisfirstvalue
<br/>Getkey1value:Thisisreplacevalue
<br/>Getkey2value:Array([0]=&gt;aaa[1]=&gt;bbb[2]=&gt;ccc[3]=&gt;ddd)
<br/>Getkey1value:
<br/>Getkey2value:
<br/>初始化一个Memcache的对象：
<br/>$mem=newMemcache;
<br/>连接到我们的Memcache服务器端，第一个参数是服务器的IP地址，也可以是主机名，第二个参数是Memcache的开放的端口：
<br/>$mem-&gt;connect(&quot;192.168.0.200&quot;,12000);
<br/>保存一个数据到Memcache服务器上，第一个参数是数据的key，用来定位一个数据，第二个参数是需要保存的数据内容，这里是一个字符串，第三个参数是一个标记，一般设置为0或者MEMCACHE_COMPRESSED就行了，第四个参数是数据的有效期，就是说数据在这个时间内是有效的，如果过去这个时间，那么会被Memcache服务器端清除掉这个数据，单位是秒，如果设置为0，则是永远有效，我们这里设置了60，就是一分钟有效时间：
<br/>$mem-&gt;set(‘key1‘,‘Thisisfirstvalue’,0,60);
<br/>从Memcache服务器端获取一条数据，它只有一个参数，就是需要获取数据的key，我们这里是上一步设置的key1，现在获取这个数据后输出输出：
<br/>$val=$mem-&gt;get(’key1′);
<br/>echo&quot;Getkey1value:&quot;.$val;
<br/>现在是使用replace方法来替换掉上面key1的值，replace方法的参数跟set是一样的，不过第一个参数key1是必须是要替换数据内容的key，最后输出了：
<br/>$mem-&gt;replace(‘key1′,‘Thisisreplacevalue’,0,60);
<br/>$val=$mem-&gt;get(‘key1′);
<br/>echo&quot;Getkey1value:&quot;.$val;
<br/>同样的，Memcache也是可以保存数组的，下面是在Memcache上面保存了一个数组，然后获取回来并输出
<br/>$arr=array(‘aaa’,‘bbb’,‘ccc’,‘ddd’);
<br/>$mem-&gt;set(‘key2′,$arr,0,60);
<br/>$val2=$mem-&gt;get(‘key2′);
<br/>print_r($val2);
<br/>现在删除一个数据，使用delte接口，参数就是一个key，然后就能够把Memcache服务器这个key的数据删除，最后输出的时候没有结果
<br/>$mem-&gt;delete(‘key1′);
<br/>$val=$mem-&gt;get(‘key1′);
<br/>echo&quot;Getkey1value:&quot;.$val.&quot;&lt;br&gt;&quot;;
<br/>最后我们把所有的保存在Memcache服务器上的数据都清除，会发现数据都没有了，最后输出key2的数据为空，最后关闭连接
<br/>$mem-&gt;flush();
<br/>$val2=$mem-&gt;get(‘key2′);
<br/>echo&quot;Getkey2value:&quot;;
<br/>print_r($val2);
<br/>echo&quot;&lt;br&gt;&quot;;]]></description>
		<pubDate>Wed, 30 Dec 2009 16:27:19 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[php程序员需要掌握的五个概念]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail936.shtml]]></link>
		<description><![CDATA[php程序员需要掌握的五个概念:
<br/>我们从书本上学到的一些php理论知识和实际的程序设计还是有一些区别的，真正的知识和经验要从实际的开发中获得。每个php程序员在开始开发web应用程序之前，都应该了解下面的五件事：
<br/>1.模板引擎
<br/>如果您使用的不是一个框架来执行一个具体的设计模式，那么您想要使用的是模板引擎。不论你是自己创建或是使用现有的模板(如Smarty)，模板引擎都会使你的逻辑代码从HTML页面中独立出来(以及相关的CSS/js/等)。这大大的简化了你的代码，使整个程序的修改变得快速简单，也使非开发者更容易修改你的程序。
<br/>
<br/>2.php框架
<br/>框架可以说是php开发中的一个最重要的问题。用php开发web应用程序时有很多方法，有很多开源的框架可以使用，可以帮助快速的开发，保持更高的一致性和有效性。其中比较好的框架包括cakephp，Symfony和CodeIgniter。很多框架还按照MVC设计模式，如果你在这个模式下工作过，那你一定会很熟悉。过一段时间，你甚至可以根据自己的需要来创建框架。
<br/>
<br/>3.代码重用
<br/>正如我先前提过的，php是所用语言中代码重用性最好的。从多中小的文档到整个数据库类，php开发者需要的时候可以随意的选择重用现有的代码。其实，你几乎可以不用编写一行代码就能建立起整个应用程序。
<br/>
<br/>4.IRC是令人愉快的事
<br/>当你有个复杂的问题不能解决的时候，可以到IRC上。php非官方的支持频道，很多经验丰富的开发者陶醉其中。你需要一个IRC客户端，如果你用的Firefox，ChatZilla是一个很好的插件，当你需要帮助时，以irc://irc.freenode.net/php做为头部粘贴你的代码。张贴您的问题，并耐心等待;某种热心人(或多个)会给你答案。当你得到答案后，考虑一下其他需要帮助人的问题。对于php庞大的函数库来说，没有人是泰斗;在IRC上，汇集所有人的知识就可以解决任何问题
<br/>
<br/>5.不重新开发现有的东西
<br/>很明显的一件事，只有少数的php开发者知道php本身有很多可用之处。忘记新的图书馆，或复杂的代码例程-先看看PHP手册。例如，你们有没有听过number_format(),parse_url(),wordwrap()或bbcode_parse()?看一下整个函数参考，选择一个类别，浏览一下，您一定会有所发现。]]></description>
		<pubDate>Wed, 16 Dec 2009 11:15:58 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[用php实现ping命令的方法]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail933.shtml]]></link>
		<description><![CDATA[用php实现ping命令的方法:
<br/>实现方法其实很简单,主要使用php的内置函数exec来调用ping命令,从而实现ping的功能.也可以使用system等php内置函数,有兴趣的同学可以查看手册.实现代码如下:
<br/>&lt;?php
<br/>$to_ping=&quot;phpzixue.cn&quot;;
<br/>$count=2;
<br/>$psize=66;
<br/>echo&quot;Pleasebepatient,thiscantakeafewmoments...\n&lt;br&gt;&lt;br&gt;&quot;;
<br/>flush();while(1){
<br/>echo&quot;&lt;pre&gt;&quot;;
<br/>exec(&quot;ping-c$count-s$psize$to_ping&quot;,$list);
<br/>for($i=0;$i&lt;count($list);$i++){
<br/>print$list[$i].&quot;\n&quot;;
<br/>}
<br/>echo&quot;&lt;/pre&gt;&quot;;
<br/>flush();
<br/>sleep(3);
<br/>}
<br/>?&gt;]]></description>
		<pubDate>Tue, 15 Dec 2009 14:14:34 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[php中smarty模版引擎变量操作符汇总及使用方法]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail932.shtml]]></link>
		<description><![CDATA[php中smarty模版引擎中变量操作符汇总及使用方法:
<br/>smarty模板引擎中常用的20个变量操作符如下:
<br/>语法：｛变量名|操作符:｝
<br/>capitalize---首字母大写
<br/>count_characters---计算字符数
<br/>cat---连接字符串
<br/>count_paragraphs---计算段落数
<br/>count_sentences---计算句数
<br/>count_words---计算词数
<br/>date_format---时间格式
<br/>default---默认
<br/>escape---转码
<br/>indent---缩进
<br/>lower---小写
<br/>nl2br---换行符替换为
<br/>regex_replace---正则替换
<br/>replace---替换
<br/>spacify---插空
<br/>string_format---字符串格式化
<br/>strip---去除多余空格
<br/>strip_tags---去除html标签
<br/>truncate---截取
<br/>upper---大写
<br/>wordwrap--约束行宽
<br/>在php中的使用方法：
<br/>index.php
<br/>&lt;?php
<br/>include(&quot;smarty_inc.php&quot;);
<br/>$name=&quot;MynameisMaJi,age22,sexboy.&lt;ahref=&gt;aaaaaa&lt;/a&gt;.&quot;;
<br/>$smarty-&gt;assign(&quot;title&quot;,$name);
<br/>$smarty-&gt;assign(&quot;row&quot;,$row);
<br/>$smarty-&gt;assign(&quot;d&quot;,strtotime(&quot;-0&quot;));
<br/>$smarty-&gt;assign(&quot;nubmer&quot;,342345.736524);
<br/>$smarty-&gt;display(&quot;index.html&quot;);
<br/>?&gt;
<br/>在模板中的使用方法:
<br/>index.html
<br/>原始数据：{$title}
<br/>使用capitalize变量操作符后：{$title|capitalize}
<br/>使用count_characters变量操作符后：{$title|count_characters}
<br/>使用cat变量操作符后：{$title|cat:&quot;wwww.baidu.com&quot;}
<br/>使用count_paragraphs变量操作符后：{$title|count_paragraphs}
<br/>使用count_sentences变量函数操作符后：{$title|count_sentences}
<br/>使用count_words变量函数操作后：{$title|count_words}
<br/>原始时间数据：{$d}
<br/>使用date_format变量函数操作：{$d|date_format:&quot;%Y-%m-%d&quot;}
<br/>使用smarty.now调用时间：{$smarty.now|date_format:&quot;%Y-%m-%d&quot;}
<br/>使用default变量函数操作：{$title1|default:&quot;没有这个变量&quot;}
<br/>使用escape变量函数操作：{$title|escape:&quot;html&quot;}
<br/>使用indent变量函数操作：{$title|indent:2:&quot;&quot;}
<br/>使用lower变量函数操作：{$title|lower}
<br/>使用upper变量函数操作：{$title|upper}
<br/>使用replace变量函数操作：{$title|replace:&quot;is&quot;:&quot;@@&quot;}
<br/>使用spacify变量函数操作：{$title|spacify:&quot;_&quot;}
<br/>使用string_format变量函数操作：{$nubmer|string_format:&quot;%.2f&quot;}
<br/>使用strip变量函数操作：{$title|strip:&quot;_&quot;}
<br/>使用strip_tags变量函数操作：{$title|strip_tags}
<br/>使用truncate变量函数操作：{$title|truncate:30:&quot;...&quot;}
<br/>使用wordwrap变量函数操作：{$title|wordwrap:10:&quot;&lt;br&gt;&quot;}
<br/>相关文章:在smarty中使用php函数<ahref="http://www.phpzixue.cn/detail690.shtml">http://www.phpzixue.cn/detail690.shtml</a>]]></description>
		<pubDate>Tue, 15 Dec 2009 10:15:48 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[phpmyadmin中文乱码问题的解决办法]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail929.shtml]]></link>
		<description><![CDATA[phpmyadmin中文乱码问题的解决办法:
<br/>PHPMyAdmin中的中文乱码问题在实际中很常见。主要是UTF-8和GB2312编码的问题,下面说一下解决的方法。
<br/>(1).MySQL的默认编码是latin1，所以首先我们需要修改一下PHPMyAdmin的编码转换。修改libraries目录下面的select_lang.lib.php文件，将
<br/>'utf-8'=&gt;'utf8',
<br/>修改成
<br/>'utf-8'=&gt;'latin1',
<br/>(2).接下来还要修改一下页面的编码显示，将
<br/>'zh-gb2312'=&gt;array('zh|chinesesimplified','chinese_simplified-gb2312','zh'),
<br/>修改成
<br/>'zh-gb2312-utf-8'=&gt;array('zh|chinesesimplified','chinese_simplified-gb2312','zh'),
<br/>也就是在zh-gb2312后面增加-utf-8，这样页面编码就支持UTF-8了。
<br/>(3).首先选择zh-gb2312-utf-8进入PHPMyAdmin，这个时候浏览GB2312编码的数据正常，但是浏览UTF-8的数据是乱码。如果浏览UTF-8的数据的话，进入首页，然后在Language里面选择zh-utf-8就可以了。
<br/>说明：
<br/>1.默认的语言编码很长，你可以将其他编码用/**/注释掉，只保留zh-gb2312-utf-8和zh-utf-8两个编码。
<br/>2.目前PHPMyAdmin最新的版本是2.8.0-rc1，但是这个版本首页选择的语言不能具体到编码，所以不建议使用。]]></description>
		<pubDate>Fri, 11 Dec 2009 15:27:38 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[php中substr_count函数用法简介]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail924.shtml]]></link>
		<description><![CDATA[php中substr_count函数用法简介:
<br/>在PHP可以很容易的利用substr_count函数计算一个指定的子字符串在所给的字符串中出现的次数。
<br/>语法：
<br/>intsubstr_count(string$haystack,string$needle[,int$offset[,int$length]])
<br/>参数说明：
<br/>Haystack:指定要检查的字符串
<br/>Needle:指定要插入的字符串
<br/>Offset:指定在字符串中何处开始搜索默认为0
<br/>Length:指定搜索的长度
<br/>实例：
<br/>&lt;?php
<br/>$haystack=&quot;thisisatestcontents&quot;;
<br/>$handle=&quot;is&quot;;
<br/>$count=substr_count($haystack,$handle);
<br/>echo&quot;在&quot;.$haystack.&quot;字符串中共出现&quot;.$count.&quot;次&quot;.$handle;
<br/>?&gt;]]></description>
		<pubDate>Wed, 09 Dec 2009 16:45:16 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[用php计算给定两个日期相差多少天]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail923.shtml]]></link>
		<description><![CDATA[用php计算给定两个日期相差多少天:
<br/>计算方法不只下面介绍的这些,只是一些比较常规的方法:
<br/>如要计算2009-12-09和2009-12-05相差多少天:
<br/>&lt;?php
<br/>$startdate=strtotime(&quot;2009-12-09&quot;);
<br/>$enddate=strtotime(&quot;2009-12-05&quot;);
<br/>上面的php时间日期函数strtotime已经把字符串日期变成了时间戳,这样只要让两数值相减，然后把秒变成天就可以了，比较的简单，如下：
<br/>$days=round(($enddate-$startdate)/3600/24);
<br/>echo$days;//days为得到的天数;
<br/>?&gt;
<br/>下面介绍另外一种方法:
<br/>上面判断的是两个日期的大小，下面则是判断生日的程序代码，得到的$n就是相距生日的天数。
<br/>$birthday=&quot;生日&quot;;
<br/>$birthday=preg_replace('/\d+/',Date('Y'),$birthday,1);
<br/>$d=60*60*24;
<br/>$n=floor((strtotime($birthday)-time())/$d);
<br/>$n=$n+1;
<br/>还有如果相比的是现在的时间，就可以用time()函数，得到的就是现在的时间戳.
<br/>第二种情况呢，就是有数据库，这样就相对比较容易一些了!如果是MSSQL可以使用触发器!用专门计算日期差的函数datediff()计算便可!
<br/>如果是MYSQL那就用两个日期字段的时间戳值，进行计算后便可得到相差的天数了。方法和上面的代码很像。]]></description>
		<pubDate>Wed, 09 Dec 2009 16:26:25 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[php中smarty模板引擎中缓存的应用]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail910.shtml]]></link>
		<description><![CDATA[php中smarty模板引擎中缓存的应用:
<br/>1,Smarty缓存配置方法：
<br/>$smarty-&gt;cache_dir=&quot;目录名&quot;;//创建缓存目录名
<br/>$smarty-&gt;caching=true;//开启缓存，为false的时候缓存无效
<br/>$smarty-&gt;cache_lifetime=60;//缓存时间，单位是秒
<br/>2,Smarty缓存的使用与清除
<br/>$marty-&gt;display(&quot;cache.tpl&quot;,cache_id);//创建带ID的缓存
<br/>$marty-&gt;clear_all_cache();//清楚所有缓存
<br/>$marty-&gt;clear_cache(&quot;index.php&quot;);//清楚index.php中的缓存
<br/>$marty-&gt;clear_cache(&quot;index.php&quot;,cache_id);//清楚index.php中指定ID的缓存
<br/>3,Smarty的局部缓存
<br/>第一个：insert_函数默认不缓存，这个属性不能修改
<br/>index.php中，
<br/>functioninsert_get_time(){
<br/>returndate(&quot;Y-m-dH:m:s&quot;);
<br/>}
<br/>index.html中,
<br/>{insertname=&quot;get_time&quot;}
<br/>第二个：smarty_block
<br/>定义一个block:smarty_block_name($params,$content,&amp;$smarty){return$content;}//name表示区域名
<br/>注册block:$smarty-&gt;register_block('name','smarty_block_name',false);//第三参数false表示该区域不被缓存
<br/>模板写法:{name}内容{/name}
<br/>写成block插件:
<br/>1)定义一件插件函数:block.cacheless.php,放在smarty的plugins目录
<br/>block.cacheless.php的内容如下:
<br/>&lt;?php
<br/>functionsmarty_block_cacheless($param,$content,&amp;$smarty){
<br/>return$content;
<br/>}
<br/>?&gt;
<br/>2)编写程序及模板
<br/>示例程序:testCacheLess.php
<br/>&lt;?php
<br/>include('Smarty.class.php');
<br/>$smarty=newSmarty;
<br/>$smarty-&gt;caching=true;
<br/>$smarty-&gt;cache_lifetime=6;
<br/>$smarty-&gt;display('cache.tpl');
<br/>?&gt;
<br/>所用的模板:cache.tpl
<br/>已经缓存的:{$smarty.now}&lt;br&gt;
<br/>{cacheless}
<br/>没有缓存的:{$smarty.now}
<br/>{/cacheless}
<br/>4自定义缓存
<br/>设置cache_handler_func使用自定义的函数处理缓存
<br/>如:
<br/>$smarty-&gt;cache_handler_func=&quot;myCache&quot;;
<br/>functionmyCache($action,&amp;$smarty_obj,&amp;$cache_content,$tpl_file=null,$cache_id=null,$compile_id=null){
<br/>}
<br/>该函数的一般是根椐$action来判断缓存当前操作:
<br/>switch($action){
<br/>case&quot;read&quot;://读取缓存内容
<br/>case&quot;write&quot;://写入缓存
<br/>case&quot;clear&quot;://清空
<br/>}
<br/>一般使用md5($tpl_file.$cache_id.$compile_id)作为唯一的cache_id
<br/>如果需要,可使用gzcompress和gzuncompress来压缩和解压]]></description>
		<pubDate>Thu, 03 Dec 2009 14:48:17 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[用php控制页面的过期时间]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail901.shtml]]></link>
		<description><![CDATA[用php控制页面的过期时间:
<br/>控制页面的过期主要是对If-Modified-Since控制.
<br/>下面的程序实现页面5分钟后过期
<br/>&lt;?php
<br/>$headers=apache_request_headers();
<br/>$client_time=(isset($headers['If-Modified-Since'])?strtotime($headers['If-Modified-Since']):0);
<br/>$now=gmmktime();
<br/>$now_list=gmmktime()-60*5;
<br/>if($client_time&lt;$nowand$client_time&gt;$now_list){
<br/>header('Last-Modified:‘.gmdate('D,dMYH:i:s',$client_time).'GMT',true,304);
<br/>exit(0);
<br/>}else{
<br/>header('Last-Modified:‘.gmdate('D,dMYH:i:s',$now).'GMT',true,200);
<br/>}
<br/>?&gt;]]></description>
		<pubDate>Tue, 01 Dec 2009 16:55:54 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[php中通过设置p3p头解决cookie跨域访问问题]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail887.shtml]]></link>
		<description><![CDATA[php中通过设置p3p头解决cookie跨域访问问题:
<br/>大家都知道cookie是不能跨域的,但可以通过设置p3p头来解决这个问题.
<br/>为了测试先编辑hosts文件，加入测试域名（在C:\WINDOWS\system32\drivers\etc\hosts）
<br/>127.0.0.1www.a.com
<br/>127.0.0.1www.b.com
<br/>首先：创建a_setcookie.php文件，内容如下：
<br/>//header(’P3P:CP=&quot;CURaADMaDEVaPSAoPSDoOURBUSUNIPURINTDEMSTAPRECOMNAVOTCNOIDSPCOR&quot;’);
<br/>setcookie(&quot;test&quot;,$_GET[’id’],time()+3600,&quot;/&quot;,&quot;.a.com&quot;);
<br/>然后：创建a_getcookie.php文件，内容如下：
<br/>var_dump($_COOKIE);
<br/>最后：创建b_setcookie.php文件，内容如下：
<br/>三个文件创建完毕后，我们通过浏览器依次访问：
<br/>http://www.b.com/b_setcookie.php
<br/>http://www.a.com/a_getcookie.php
<br/>我们会发现，在访问b.com域的时候，我们并没有在a.com域设置上cookie值。
<br/>然后我们修改一下a_setcookie.php文件，去掉注释符号，a_setcookie.php即为：
<br/>header(’P3P:CP=&quot;CURaADMaDEVaPSAoPSDoOURBUSUNIPURINTDEMSTAPRECOMNAVOTCNOIDSPCOR&quot;’);
<br/>setcookie(&quot;test&quot;,$_GET[’id’],time()+3600,&quot;/&quot;,&quot;.a.com&quot;);
<br/>再次通过浏览器依次访问：
<br/>http://www.b.com/b_setcookie.php
<br/>http://www.a.com/a_getcookie.php
<br/>这次，你会发现在访问b.com域的时候，我们设置了a.com域的cookie值。
<br/>似乎只有IE对跨域访问COOKIE限制比较严格，上述代码在FIREFOX下测试，即使不发送P3P头信息，也能成功。]]></description>
		<pubDate>Tue, 24 Nov 2009 14:25:07 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[php中全等(===)和相等(==)的用法区别]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail886.shtml]]></link>
		<description><![CDATA[php中全等(===)和相等(==)的用法区别:
<br/>说明:
<br/>全等(===):如果$a和$b具有相同的键／值对并且顺序和类型都相同则为TRUE。
<br/>相等(==):如果$a和$b具有相同的键／值对则为TRUE。
<br/>看下面的例子:
<br/>$a==$b
<br/>相等
<br/>返回:true,如果$a等于$b。
<br/>$a===$b
<br/>全等
<br/>返回:true，如果$a等于$b，并且它们的类型也相同。（PHP4）
<br/>$a!=$b
<br/>不等
<br/>返回:true，如果$a不等于$b。
<br/>$a&lt;&gt;$b
<br/>不等
<br/>返回:true，如果$a不等于$b。
<br/>$a!==$b
<br/>非全等
<br/>返回:true，如果$a不等于$b，或者它们的类型不同。（PHP4）]]></description>
		<pubDate>Mon, 23 Nov 2009 13:36:14 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	<item>
		<title><![CDATA[用php中的popen函数实现php的并发处理]]></title>
		<link><![CDATA[http://www.phpzixue.cn/detail885.shtml]]></link>
		<description><![CDATA[用php中的popen函数实现php的并发处理:
<br/>当我们需要调用一个比较耗时外部资源时使用popen这个函数，最常见的就是从外部API获取相关内容.
<br/>使用方法：
<br/>1.建立外部资源脚本。如示例中使用t.sh。当然，也可以直接使用curl等命令行
<br/>2.准备好参数，提供给pipe脚本
<br/>2.使用popen调用脚本。调用之后，就不用关心了。
<br/>3.开始其他的和pipe不相关的逻辑处理
<br/>4.其他处理完成之后，使用fgets等方式，获取popen的数据
<br/>php程序：
<br/>#getargumentforpipehereifithas.
<br/>#startpipe
<br/>echo’callpopenstart:’.date(&quot;H:i:s&quot;),&quot;\n&quot;;
<br/>$pipe=popen(dirname(__FILE__).’/t.sh’,’r’);
<br/>echo’callpopenend:’.date(&quot;H:i:s&quot;),&quot;\n&quot;;
<br/>#Othercodehere
<br/>sleep(5);
<br/>echo&quot;Hereismycode.time:&quot;.date(&quot;H:i:s&quot;),&quot;\n&quot;;
<br/>#readpiperesult
<br/>while($s=fgets($pipe,1024)){
<br/>echo$s;
<br/>}
<br/>pipe脚本：
<br/>echo1,`date+%T`;
<br/>sleep1;
<br/>echo2,`date+%T`;
<br/>sleep10;
<br/>echo3,`date+%T`;
<br/>输出结果：
<br/>callpopenstart:10:16:40
<br/>callpopenend:10:16:40
<br/>Hereismycode.time:10:16:45
<br/>1,10:16:40
<br/>2,10:16:41
<br/>3,10:16:51
<br/>结论，我们有三个sleep。
<br/>php中一个sleep5,
<br/>sh中两个sleep，10+1
<br/>如果使用串行的方式，那么用时应该是10+1+5＝16秒。
<br/>而使用pipe方式，用时仅为：max(php,pipe)=max(5,11)=11秒。]]></description>
		<pubDate>Mon, 23 Nov 2009 11:10:36 +0800</pubDate>
		<author><![CDATA[互联网]]></author>
	</item>
	</channel>
</rss>

