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

<channel>
	<title>浮山狼de博客 &#187; php</title>
	<atom:link href="https://www.fushanlang.com/category/programming-skill/php/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.fushanlang.com</link>
	<description>next station - 下一站，活在当下，且行且思</description>
	<lastBuildDate>Sat, 29 Nov 2014 15:14:11 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=4.2.5</generator>
	<item>
		<title>opencart CDN</title>
		<link>https://www.fushanlang.com/opencart-cdn-opencart-2355/</link>
		<comments>https://www.fushanlang.com/opencart-cdn-opencart-2355/#comments</comments>
		<pubDate>Fri, 24 Jan 2014 16:09:44 +0000</pubDate>
		<dc:creator><![CDATA[fushanlang]]></dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[软件]]></category>
		<category><![CDATA[opencart]]></category>

		<guid isPermaLink="false">http://www.fushanlang.com/blog/?p=2355</guid>
		<description><![CDATA[<p>Opencart CDN is a general CDN solution for opencart.</p> <p>the main features are: 1.separated data images and theme resources. 2.easy operate on backend module setting. 3.support multi-cdn domains 4.support adding &#8220;?version=numberic&#8221; at CDN resource urls to solve CDN expiration issue when updated static resources.</p> <p>===================== installation:</p> <p>1. VQmod is required. 2. unzip this extension <span style="color:#777"> . . . &#8594; Read More: <a href="https://www.fushanlang.com/opencart-cdn-opencart-2355/">opencart CDN</a></span>]]></description>
				<content:encoded><![CDATA[<p>Opencart CDN is a general CDN solution for opencart.</p>
<p>the main features are:<br />
1.separated data images and theme resources.<br />
2.easy operate on backend module setting.<br />
3.support multi-cdn domains<br />
4.support adding &#8220;?version=numberic&#8221; at CDN resource urls to solve CDN expiration issue when updated static resources.</p>
<p>=====================<br />
installation:</p>
<p>1. VQmod is required.<br />
2. unzip this extension and reset to your opencart site document root, login backend,<br />
click &#8220;extension-&gt;module&#8221; menu, then pick &#8220;Opencart CDN&#8221; module,</p>
<p><img alt="" src="http://opencart.site4test.com/image/data/opencart_cdn.png" /></p>
<p>demo site:</p>
<p>backend : http://opencart.site4test.com/admin/index.php<br />
login : demo/demo</p>
<p>if you have further question, you can contact opencart@site4test.com directly or leave comments.</p>
<p>if you want to buy click to view it  in  <a href="http://www.opencart.com/index.php?route=extension/extension/info&amp;extension_id=15463&amp;filter_search=CDN" target="_blank">http://www.opencart.com/index.php?route=extension/extension/info&amp;extension_id=15463&amp;filter_search=CDN</a></p>
]]></content:encoded>
			<wfw:commentRss>https://www.fushanlang.com/opencart-cdn-opencart-2355/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP store session with couchbase</title>
		<link>https://www.fushanlang.com/php-store-session-with-couchbase-2302/</link>
		<comments>https://www.fushanlang.com/php-store-session-with-couchbase-2302/#comments</comments>
		<pubDate>Wed, 11 Sep 2013 06:10:34 +0000</pubDate>
		<dc:creator><![CDATA[fushanlang]]></dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[session]]></category>

		<guid isPermaLink="false">http://www.fushanlang.com/blog/?p=2302</guid>
		<description><![CDATA[如何用couchbase存储session <p>有两种常见方式： 1.采用memcache模式连接couchbase 只需两句修改：</p> ini_set('session.save_handler', 'memcache'); ini_set('session.save_path', 'tcp://couchbase_host:9999'); <p>注意里面的9999是couchbase 里面创建的bucket的对外memcache端口，这种访问方式运行以memcache兼容的模式访问couchbase。 2.采用couchbase扩展添加一个sessionhandler如下：</p> /**** * php storage session with couchbase * by fushanlang@gmail.com */ /*** * SessionHandlerInterface is a internal interface only for PHP_VERSION>=5.4.0 * so if interface_exists() false we need to define by yourself. */ if (!interface_exists('SessionHandlerInterface')) { interface SessionHandlerInterface { public function close(); public <span style="color:#777"> . . . &#8594; Read More: <a href="https://www.fushanlang.com/php-store-session-with-couchbase-2302/">PHP store session with couchbase</a></span>]]></description>
				<content:encoded><![CDATA[<h2>如何用couchbase存储session</h2>
<p>有两种常见方式：<br />
1.采用memcache模式连接couchbase 只需两句修改：</p>
<pre name="code" class="php">
ini_set('session.save_handler', 'memcache');
ini_set('session.save_path', 'tcp://couchbase_host:9999');
</pre>
<p>注意里面的9999是couchbase 里面创建的bucket的对外memcache端口，这种访问方式运行以memcache兼容的模式访问couchbase。<br />
2.采用couchbase扩展添加一个sessionhandler如下：</p>
<pre name="code" class="php">
/****
 * php storage session with couchbase
 * by fushanlang@gmail.com
 */

/***
 * SessionHandlerInterface is a internal interface only for PHP_VERSION>=5.4.0
 * so if interface_exists() false we need to define by yourself.
 */
if (!interface_exists('SessionHandlerInterface')) {
    interface SessionHandlerInterface
    {
        public function close();

        public function destroy($session_id);

        public function gc($maxlifetime);

        public function open($save_path, $session_id);

        public function  read($session_id);

        public function write($session_id, $session_data);
    }
}
/**
 * A reference implementation of a custom Couchbase session handler.
 */
class CouchbaseSessionHandler implements SessionHandlerInterface
{

    /**
     * Holds the Couchbase connection.
     */
    protected $_connection = null;

    /**
     * The Couchbase host and port.
     */
    protected $_host = null;

    /**
     * The Couchbase bucket name.
     */
    protected $_bucket = null;

    /**
     * The prefix to be used in Couchbase keynames.
     */
    protected $_keyPrefix = 'session:';

    /**
     * Define a expiration time of 10 minutes.
     */
    protected $_expire = 600;

    /**
     * Set the default configuration params on init.
     */
    public function __construct($host = '127.0.0.1:8091', $bucket = 'default')
    {
        $this->_host = $host;
        $this->_bucket = $bucket;
    }

    /**
     * Open the connection to Couchbase (called by PHP on `session_start()`)
     */
    public function open($savePath, $sessionName)
    {
        $this->_connection = new Couchbase($this->_host, '', '', $this->_bucket);
        return $this->_connection ? true : false;
    }

    /**
     * Close the connection. Called by PHP when the script ends.
     */
    public function close()
    {
        unset($this->_connection);
        return true;
    }

    /**
     * Read data from the session.
     */
    public function read($sessionId)
    {
        $key = $this->_keyPrefix . $sessionId;
        $result = $this->_connection->get($key);

        return $result ? : null;
    }

    /**
     * Write data to the session.
     */
    public function write($sessionId, $sessionData)
    {
        $key = $this->_keyPrefix . $sessionId;
        if (empty($sessionData)) {
            return false;
        }

        $result = $this->_connection->set($key, $sessionData, $this->_expire);
        return $result ? true : false;
    }

    /**
     * Delete data from the session.
     */
    public function destroy($sessionId)
    {
        $key = $this->_keyPrefix . $sessionId;
        $result = $this->_connection->delete($key);

        return $result ? true : false;
    }

    /**
     * Run the garbage collection.
     */
    public function gc($maxLifetime)
    {
        return true;
    }

}

//usage example
define('COUCHBASE_HOST_PORT','xxxxx:8091');
define('COUCHBASE_BUCKET','session');

if(class_exists('Couchbase')&#038;&#038;defined('COUCHBASE_HOST_PORT')&#038;&#038;defined('COUCHBASE_BUCKET')){
    $handler = new CouchbaseSessionHandler(COUCHBASE_HOST_PORT,COUCHBASE_BUCKET);
    if(version_compare(PHP_VERSION,'5.4.0')>=0){
        session_set_save_handler($handler,true);
    }else{
        session_set_save_handler(
            array($handler, 'open'),
            array($handler, 'close'),
            array($handler, 'read'),
            array($handler, 'write'),
            array($handler, 'destroy'),
            array($handler, 'gc'));
    }
}
session_start();
</pre>
]]></content:encoded>
			<wfw:commentRss>https://www.fushanlang.com/php-store-session-with-couchbase-2302/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>理解PHP session机制(zhuan)</title>
		<link>https://www.fushanlang.com/understanding-of-php-session-mechanism-zhuan-2300/</link>
		<comments>https://www.fushanlang.com/understanding-of-php-session-mechanism-zhuan-2300/#comments</comments>
		<pubDate>Wed, 11 Sep 2013 05:55:12 +0000</pubDate>
		<dc:creator><![CDATA[fushanlang]]></dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[session]]></category>

		<guid isPermaLink="false">http://www.fushanlang.com/blog/?p=2300</guid>
		<description><![CDATA[<p>1.session.save_handler = files</p> <p>* 1. session_start() 1. session_start()是session机制的开始，它有一定概率开启垃圾回收,因为session是存放在文件中， PHP自身的垃圾回收是无效的，SESSION的回收是要删文件的，这个概率是根据php.ini的配置决定的， 但是有的系统是 session.gc_probability = 0，这也就是说概率是0，而是通过cron脚本来实现垃圾回收。</p> <p>session.gc_probability = 1 session.gc_divisor = 1000 session.gc_maxlifetime = 1440//过期时间 默认24分钟 //概率是 session.gc_probability/session.gc_divisor 结果 1/1000, //不建议设置过小，因为session的垃圾回收，是需要检查每个文件是否过期的。 session.save_path = //好像不同的系统默认不一样，有一种设置是 &#8220;N;/path&#8221; //这是随机分级存储，这个样的话，垃圾回收将不起作用，需要自己写脚本</p> <p>2. session会判断当前是否有$_COOKIE[session_name()];session_name()返回保存session_id的COOKIE键值， 这个值可以从php.ini找到</p> <p>session.name = PHPSESSID //默认值PHPSESSID</p> <p>3. 如果不存在会生成一个session_id,然后把生成的session_id作为COOKIE的值传递到客户端. 相当于执行了下面COOKIE 操作，注意的是，这一步执行了setcookie()操作，COOKIE是在header头中发送的， 这之前是不能有输出的，PHP有另外一个函数 session_regenerate_id() 如果使用这个函数，这之前也是不能有输出的。</p> <p>setcookie(session_name(), session_id(), session.cookie_lifetime,//默认0 session.cookie_path,//默认&#8217;/&#8217;当前程序跟目录下都有效 session.cookie_domain,//默认为空 )</p> <p>4. <span style="color:#777"> . . . &#8594; Read More: <a href="https://www.fushanlang.com/understanding-of-php-session-mechanism-zhuan-2300/">理解PHP session机制(zhuan)</a></span>]]></description>
				<content:encoded><![CDATA[<p>1.session.save_handler = files</p>
<p>* 1. session_start()<br />
1. session_start()是session机制的开始，它有一定概率开启垃圾回收,因为session是存放在文件中，<br />
PHP自身的垃圾回收是无效的，SESSION的回收是要删文件的，这个概率是根据php.ini的配置决定的，<br />
但是有的系统是 session.gc_probability = 0，这也就是说概率是0，而是通过cron脚本来实现垃圾回收。</p>
<p>session.gc_probability = 1<br />
session.gc_divisor = 1000<br />
session.gc_maxlifetime = 1440//过期时间 默认24分钟<br />
//概率是 session.gc_probability/session.gc_divisor 结果 1/1000,<br />
//不建议设置过小，因为session的垃圾回收，是需要检查每个文件是否过期的。<br />
session.save_path = //好像不同的系统默认不一样，有一种设置是 &#8220;N;/path&#8221;<br />
//这是随机分级存储，这个样的话，垃圾回收将不起作用，需要自己写脚本</p>
<p>2. session会判断当前是否有$_COOKIE[session_name()];session_name()返回保存session_id的COOKIE键值，<br />
这个值可以从php.ini找到</p>
<p>session.name = PHPSESSID //默认值PHPSESSID</p>
<p>3. 如果不存在会生成一个session_id,然后把生成的session_id作为COOKIE的值传递到客户端.<br />
相当于执行了下面COOKIE 操作，注意的是，这一步执行了setcookie()操作，COOKIE是在header头中发送的，<br />
这之前是不能有输出的，PHP有另外一个函数 session_regenerate_id() 如果使用这个函数，这之前也是不能有输出的。</p>
<p>setcookie(session_name(),<br />
session_id(),<br />
session.cookie_lifetime,//默认0<br />
session.cookie_path,//默认&#8217;/&#8217;当前程序跟目录下都有效<br />
session.cookie_domain,//默认为空<br />
)</p>
<p>4. 如果存在那么session_id = $_COOKIE[session_name];<br />
然后去session.save_path指定的文件夹里去找名字为&#8217;SESS_&#8217; . session_id()的文件.<br />
读取文件的内容反序列化，然后放到$_SESSION中<br />
* 2. 为$_SESSION赋值<br />
比如新添加一个值$_SESSION[&#8216;test&#8217;] = &#8216;blah'; 那么这个$_SESSION只会维护在内存中，当脚本执行结束的时候，<br />
用把$_SESSION的值写入到session_id指定的文件夹中，然后关闭相关资源. 这个阶段有可能执行更改session_id的操作，<br />
比如销毁一个旧的的session_id，生成一个全新的session_id.一半用在自定义 session操作，角色的转换上，<br />
比如Drupal.Drupal的匿名用户有一个SESSION的，当它登录后需要换用新的session_id</p>
<p>if (isset($_COOKIE[session_name()])) {<br />
setcookie(session_name(), &#8221;, time() &#8211; 42000, &#8216;/&#8217;);//旧session cookie过期<br />
}<br />
session_regenerate_id();//这一步会生成新的session_id<br />
//session_id()返回的是新的值</p>
<p>3.写入SESSION操作<br />
在脚本结束的时候会执行SESSION写入操作，把$_SESSION中值写入到session_id命名的文件中，可能已经存在，<br />
可能需要创建新的文件。<br />
* 4. 销毁SESSION<br />
SESSION发出去的COOKIE一般属于即时COOKIE，保存在内存中，当浏览器关闭后，才会过期，假如需要人为强制过期，<br />
比如 退出登录，而不是关闭浏览器，那么就需要在代码里销毁SESSION，方法有很多，<br />
o 1. setcookie(session_name(), session_id(), time() &#8211; 8000000, ..);//退出登录前执行<br />
o 2. usset($_SESSION);//这会删除所有的$_SESSION数据，刷新后，有COOKIE传过来，但是没有数据。<br />
o 3. session_destroy();//这个作用更彻底，删除$_SESSION 删除session文件，和session_id</p>
<p>当不关闭浏览器的情况下，再次刷新，2和3都会有COOKIE传过来，但是找不到数据</p>
<p>2.session.save_handler = user</p>
<p>用户自定义session处理机制，更加直观<br />
* session_set_save_handler(&#8216;open&#8217;, &#8216;close&#8217;, &#8216;read&#8217;, &#8216;write&#8217;, &#8216;destroy&#8217;, &#8216;gc&#8217;);<br />
1.session_start(),<br />
执行open($save_path, $session_name)打开session操作句柄<br />
$save_path 在session.save_handler = files的情况下它就是session.save_path，<br />
但是如果用户自定的话，这个两个参数都用不上，直接返回TRUE</p>
<p>执行read($id)从中读取数据.//这个参数是自动传递的就是session_id(),可以通过这个值进行操作。<br />
* 2.脚本执行结束<br />
执行write($id, $sess_data) //两个参数，很简单<br />
* 3.假如用户需要session_destroy()<br />
先执行destroy.在执行第2步</p>
<p>一个实际例子：</p>
<p>//SESSION初始化的时候调用<br />
function open($save_path, $session_name)<br />
{<br />
global $sess_save_path;<br />
$sess_save_path = $save_path;<br />
return(true);<br />
}</p>
<p>//关闭的时候调用<br />
function close()<br />
{<br />
return(true);<br />
}</p>
<p>function read($id)<br />
{<br />
global $sess_save_path;<br />
$sess_file = &#8220;$sess_save_path/sess_$id&#8221;;<br />
return (string) @file_get_contents($sess_file);<br />
}<br />
//脚本执行结束之前，执行写入操作<br />
function write($id, $sess_data)<br />
{<br />
echo &#8220;sdfsf&#8221;;<br />
global $sess_save_path;</p>
<p>$sess_file = &#8220;$sess_save_path/sess_$id&#8221;;<br />
if ($fp = @fopen($sess_file, &#8220;w&#8221;)) {<br />
$return = fwrite($fp, $sess_data);<br />
fclose($fp);<br />
return $return;<br />
} else {<br />
return(false);<br />
}</p>
<p>}</p>
<p>function destroy($id)<br />
{<br />
global $sess_save_path;</p>
<p>$sess_file = &#8220;$sess_save_path/sess_$id&#8221;;<br />
return(@unlink($sess_file));<br />
}</p>
<p>function gc($maxlifetime)<br />
{<br />
global $sess_save_path;</p>
<p>foreach (glob(&#8220;$sess_save_path/sess_*&#8221;) as $filename) {<br />
if (filemtime($filename) + $maxlifetime &lt; time()) {<br />
@unlink($filename);<br />
}<br />
}<br />
return true;<br />
}</p>
]]></content:encoded>
			<wfw:commentRss>https://www.fushanlang.com/understanding-of-php-session-mechanism-zhuan-2300/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ubuntu 12.04 (Precise Pangolin) with latest PHP</title>
		<link>https://www.fushanlang.com/ubuntu-12-04-precise-pangolin-with-latest-php-2290/</link>
		<comments>https://www.fushanlang.com/ubuntu-12-04-precise-pangolin-with-latest-php-2290/#comments</comments>
		<pubDate>Fri, 06 Sep 2013 09:04:55 +0000</pubDate>
		<dc:creator><![CDATA[fushanlang]]></dc:creator>
				<category><![CDATA[linux]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.fushanlang.com/blog/?p=2290</guid>
		<description><![CDATA[<p>如何让ubuntu 12.04 apt-get install 最新版本的PHP?</p> <p>1. Install the signing key for the PPA (which also adds the sources to apt):</p> add-apt-repository ppa:ondrej/php5 <p>If the above command is not available, install it using:</p> apt-get install python-software-properties <p>2. Now update the package database and then upgrade the system. As part of upgrading, PHP 5.4 will be <span style="color:#777"> . . . &#8594; Read More: <a href="https://www.fushanlang.com/ubuntu-12-04-precise-pangolin-with-latest-php-2290/">Ubuntu 12.04 (Precise Pangolin) with latest PHP</a></span>]]></description>
				<content:encoded><![CDATA[<p>如何让ubuntu 12.04 apt-get install 最新版本的PHP?</p>
<p>1. Install the signing key for the PPA (which also adds the sources to apt):</p>
<pre>add-apt-repository ppa:ondrej/php5</pre>
<p>If the above command is not available, install it using:</p>
<pre>apt-get install python-software-properties</pre>
<p>2. Now update the package database and then upgrade the system. As part of upgrading, PHP 5.4 will be installed automatically:</p>
<pre>apt-get update
apt-get upgrade
apt-get dist-upgrade

</pre>
<pre># php -v  // will show you the latest php version.</pre>
]]></content:encoded>
			<wfw:commentRss>https://www.fushanlang.com/ubuntu-12-04-precise-pangolin-with-latest-php-2290/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP缓存方式以及常用策略(zhuan)</title>
		<link>https://www.fushanlang.com/php-caching-methods-and-common-strategy-zhuan-2278/</link>
		<comments>https://www.fushanlang.com/php-caching-methods-and-common-strategy-zhuan-2278/#comments</comments>
		<pubDate>Fri, 30 Aug 2013 09:50:20 +0000</pubDate>
		<dc:creator><![CDATA[fushanlang]]></dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[编程]]></category>
		<category><![CDATA[设计]]></category>
		<category><![CDATA[软件]]></category>

		<guid isPermaLink="false">http://www.fushanlang.com/blog/?p=2278</guid>
		<description><![CDATA[<p>一、PHP常用的缓存技术</p> <p>１、代码级缓存</p> <p>1)数据缓存：是指数据库查询PHP缓存机制，每次访问页面的时候,都会先检测相应的缓存数据是否存在，如果不存在，就连接数据库，得到数据，并把查询结果序列化后保存到文件中，以后同样的查询结果就直接从缓存表或文件中获得。</p> <p>2)页面缓存：每次访问页面的时候，都会先检测相应的缓存页面文件是否存在，如果不存在，就重新动态生成，得新内容，显示页面并同时生成缓存页面文件，这样下次访问的时候页面文件就发挥作用了。(模板引擎和常见的一些PHP缓存机制类通常有此功能)</p> <p>3)时间触发缓存：检查文件是否存在并且时间戳小于设置的过期时间,如果文件修改的时间戳比当前时间戳减去过期时间戳大，那么就用缓存，否则更新缓存。</p> <p>4)内容触发缓存：当插入数据或更新数据时，强制更新PHP缓存机制。</p> <p>5)静态缓存：是指静态化，直接生成HTML或XML等文本文件，有更新的时候重生成一次，适合于不太变化的页面。</p> <p>２、服务器级缓存</p> <p>1)内存缓存:著名就是Memcached，主要用于多台web服务器，是高性能的，分布式的内存对象PHP缓存机制系统，用于在动态应用中减少数据库负载，提升访问速度。</p> <p>2)操作码缓存：就是在PHP代码解析编译的过程中进行缓存，主要有eaccelerator， apc， phpa，xcache等</p> <p>3)数据库缓存：就是对sql语句及结果进行缓存，mysql中用的比较多，采用LRU（即least recently used 最近最少使用）算法。</p> <p>4)基于反向代理的Web缓存:是指在外部请求过来时，设置缓存根据配置文件进行转向解析。这样，服务器请求就可以转发到我们指定的内部地址上，实际就相当于一个内容分发机。如：Nginx，SQUID(一个专用的代理服务器)，mod_proxy(apache2以上又分为mod_proxy和mod_cache)。</p> <p>二、500wan网站缓存机制</p> <p>目前，500wan用到的缓存技术有：APC(默认), Memcache(全站), Redis(系统平台部), Quickcache(500pai,ledou,show).</p> <p>网站中看到：类似</p> <p>Others_EaCache::proc(‘getLotInfoByID_’);</p> <p>这样的代码,就是用到了缓存机制，他是apc和memcache二级缓存的结合体。默认是用apc,当apc缓存不存在时，会调用memcache缓存。</p> <p>Apc是什么？</p> <p>apc它其实是一种php的缓冲器,也叫操作码缓存。它提供两种缓存功能，即缓存Opcode(目标文件)，我们称之为apc_compiler_cache。同时它还提供一些接口用于将用户数据驻留在内存中，我们称之为apc_user_cache。我们应该是用到第二种，因为它用到apc_store(),而手册上说：使用apc_store()存储的变量 在不同的请求之间一直持久存在（直到从缓存系统中移除），即缓存在内存中。使用apc缓存时，需要安装apc扩展。</p> <p>apc默认通过mmap(它将一个文件或者其它对象映射进内存)匿名映射创建共享内存，缓存对象都存放在这块”大型”的内存空间。由APC自行管理该共享内存。通过调整apc.shm_size、apc.num_files_hints、apc.user_entries_hint等参数的值可以使性能达到最佳。当apc.user_entries_hint设置的足够大时，它就相当于纯内存缓存了。当它设置很小时，会比memcahced还慢。</p> <p>Acp如何缓存？</p> <p>先看一下PHP代码的执行过程，PHP是解释型语言，对每个web请求都要执行 “解析-编译-执行” 的整个步骤，过程如下：</p> <p>php解释过程</p> <p>经过操作码缓存后：</p> <p>因此当 PHP 脚本的缓存操作码存在时，可以跳过 PHP 请求流程的解析和编译步骤，直接执行缓存操作码并输出结果。明显缩短时间。</p> <p>Memcache缓存</p> <p>Memcached缓存属于内存缓存，它是以守护程序方式运行于一个或多个服务器中，随时接受客户端的连接操作，客户端可以由各种语言编写，目前已知的客户端 API 包括 Perl/PHP/Python/Ruby/Java/C#/C 等等。PHP 等客户端在与 memcached 服务建立连接之后，接下来的事情就是存取对象了，每个被存取的对象都有一个唯一的标识符 key，存取操作均通过这个 key 进行，保存到 memcached 中的对象实际上是放置内存中的，并不是保存在 <span style="color:#777"> . . . &#8594; Read More: <a href="https://www.fushanlang.com/php-caching-methods-and-common-strategy-zhuan-2278/">PHP缓存方式以及常用策略(zhuan)</a></span>]]></description>
				<content:encoded><![CDATA[<p>一、PHP常用的缓存技术</p>
<p>１、代码级缓存</p>
<p>1)数据缓存：是指数据库查询PHP缓存机制，每次访问页面的时候,都会先检测相应的缓存数据是否存在，如果不存在，就连接数据库，得到数据，并把查询结果序列化后保存到文件中，以后同样的查询结果就直接从缓存表或文件中获得。</p>
<p>2)页面缓存：每次访问页面的时候，都会先检测相应的缓存页面文件是否存在，如果不存在，就重新动态生成，得新内容，显示页面并同时生成缓存页面文件，这样下次访问的时候页面文件就发挥作用了。(模板引擎和常见的一些PHP缓存机制类通常有此功能)</p>
<p>3)时间触发缓存：检查文件是否存在并且时间戳小于设置的过期时间,如果文件修改的时间戳比当前时间戳减去过期时间戳大，那么就用缓存，否则更新缓存。</p>
<p>4)内容触发缓存：当插入数据或更新数据时，强制更新PHP缓存机制。</p>
<p>5)静态缓存：是指静态化，直接生成HTML或XML等文本文件，有更新的时候重生成一次，适合于不太变化的页面。</p>
<p>２、服务器级缓存</p>
<p>1)内存缓存:著名就是Memcached，主要用于多台web服务器，是高性能的，分布式的内存对象PHP缓存机制系统，用于在动态应用中减少数据库负载，提升访问速度。</p>
<p>2)操作码缓存：就是在PHP代码解析编译的过程中进行缓存，主要有eaccelerator， apc， phpa，xcache等</p>
<p>3)数据库缓存：就是对sql语句及结果进行缓存，mysql中用的比较多，采用LRU（即least recently used 最近最少使用）算法。</p>
<p>4)基于反向代理的Web缓存:是指在外部请求过来时，设置缓存根据配置文件进行转向解析。这样，服务器请求就可以转发到我们指定的内部地址上，实际就相当于一个内容分发机。如：Nginx，SQUID(一个专用的代理服务器)，mod_proxy(apache2以上又分为mod_proxy和mod_cache)。</p>
<p>二、500wan网站缓存机制</p>
<p>目前，500wan用到的缓存技术有：APC(默认), Memcache(全站), Redis(系统平台部), Quickcache(500pai,ledou,show).</p>
<p>网站中看到：类似</p>
<p>Others_EaCache::proc(‘getLotInfoByID_’);</p>
<p>这样的代码,就是用到了缓存机制，他是apc和memcache二级缓存的结合体。默认是用apc,当apc缓存不存在时，会调用memcache缓存。</p>
<p>Apc是什么？</p>
<p>apc它其实是一种php的缓冲器,也叫操作码缓存。它提供两种缓存功能，即缓存Opcode(目标文件)，我们称之为apc_compiler_cache。同时它还提供一些接口用于将用户数据驻留在内存中，我们称之为apc_user_cache。我们应该是用到第二种，因为它用到apc_store(),而手册上说：使用apc_store()存储的变量 在不同的请求之间一直持久存在（直到从缓存系统中移除），即缓存在内存中。使用apc缓存时，需要安装apc扩展。</p>
<p>apc默认通过mmap(它将一个文件或者其它对象映射进内存)匿名映射创建共享内存，缓存对象都存放在这块”大型”的内存空间。由APC自行管理该共享内存。通过调整apc.shm_size、apc.num_files_hints、apc.user_entries_hint等参数的值可以使性能达到最佳。当apc.user_entries_hint设置的足够大时，它就相当于纯内存缓存了。当它设置很小时，会比memcahced还慢。</p>
<p>Acp如何缓存？</p>
<p>先看一下PHP代码的执行过程，PHP是解释型语言，对每个web请求都要执行 “解析-编译-执行” 的整个步骤，过程如下：</p>
<p>php解释过程</p>
<p>经过操作码缓存后：</p>
<p>因此当 PHP 脚本的缓存操作码存在时，可以跳过 PHP 请求流程的解析和编译步骤，直接执行缓存操作码并输出结果。明显缩短时间。</p>
<p>Memcache缓存</p>
<p>Memcached缓存属于内存缓存，它是以守护程序方式运行于一个或多个服务器中，随时接受客户端的连接操作，客户端可以由各种语言编写，目前已知的客户端 API 包括 Perl/PHP/Python/Ruby/Java/C#/C 等等。PHP 等客户端在与 memcached 服务建立连接之后，接下来的事情就是存取对象了，每个被存取的对象都有一个唯一的标识符 key，存取操作均通过这个 key 进行，保存到 memcached 中的对象实际上是放置内存中的，并不是保存在 cache 文件中的，这也是为什么 memcached 能够如此高效快速的原因。但是，这些对象并不是持久的，服务停止之后，里边的数据就会丢失。</p>
<p>Memcached对高并发请求效果很明显，用的最多是在缓存数据库数据，使用 memcached 之后，可以减少数据库连接、查询操作，数据库负载下来了，脚本的运行速度也提高了。</p>
<p>Redis与Memcached类似，数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件，并且在此基础上实现了master-slave(主从)同步。</p>
<p>Quickcache是轻量级的页面缓存，实用于实效性不是很强的页面。</p>
<p>三、缓存使用会出现的问题</p>
<p>对于代码级缓存，除了服务器，网络会影响缓存，基本不会有什么大的问题。但是在高并发的应用中，服务器级缓存就可能会引起严重的问题，主要有以下三种情况：</p>
<p>1. 缓存穿透：500wan网站在接到用户请求时，会先判断缓存是否存在，如果存在就直接返回缓存内容，如果不存在，就直接查询DB，得到结果，缓存后再返回给用户。但是，如果用户请求的数据缓存中一直都不存在，那么就会直接查询DB，缓存就没起到作用了，如果请求量很大，就会给DB造成压力，甚至挂掉。</p>
<p>解决办法：对所有可能查询的参数以hash形式存储，在控制层先进行校验，不符合则丢弃。比如：用户请求某个用户abc的个人信息，但实际上abc用户并不存在，这里就会出现缓存穿透。如果在用户第一次请求时，以用户名作为一个key进行缓存，以后请教时，判断key是否存在，如果存在就返回定义好的结果，如果不存在，也不让它连续多次查询DB，这样就可以防止缓存被穿透了。</p>
<p>2.缓存失效：引起这个问题的主要原因还是高并发的时候。比如500wan网站默认缓存时间是10分钟，并发很高时可能会出在某一个时间 同时生成了很多的缓存，并且过期时间都一样，这个时候就可能引发一当过期时间到后，这些缓存同时失效，请求全部转发到DB，DB可能会压力过重。</p>
<p>解决办法：将缓存失效时间分散开，比如我们可以在原有的失效时间基础上增加一个随机值，比如1-5分钟随机，这样每一个缓存的过期时间的重复率就会降低，就很难引发集体失效的事件。</p>
<p>3.缓存雪崩：这种情况可能出现在并发访问时候。如果缓存集中在一段时间内失效，DB的压力凸显。当发生大量的缓存穿透，例如对某个失效的缓存的大并发访问就造成了缓存雪崩。</p>
<p>解决办法：解决这个问题，其实是在缓存穿透的防止阶段，我们对缓存查询加锁，如果KEY不存在，就加锁，然后查DB入缓存，然后解锁；其他进程如果发现有锁就等待，然后等解锁后返回数据或者进入DB查询。</p>
<p><cite><a href="http://www.thisuc.com/php_cache.html">http://www.thisuc.com/php_cache.html</a></cite></p>
]]></content:encoded>
			<wfw:commentRss>https://www.fushanlang.com/php-caching-methods-and-common-strategy-zhuan-2278/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

<!-- Dynamic page generated in 0.251 seconds. -->
<!-- Cached page generated by WP-Super-Cache on 2025-09-16 16:36:36 -->
