<?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>Magki&#039;s Blog &#187; 源码修改</title>
	<atom:link href="http://www.magki.com/blog/tag/%e6%ba%90%e7%a0%81%e4%bf%ae%e6%94%b9/feed" rel="self" type="application/rss+xml" />
	<link>http://www.magki.com/blog</link>
	<description>努力赚钱ing &#124; 承接各种企业站, 门户站, 商城等开发(PHP)</description>
	<lastBuildDate>Fri, 16 Dec 2011 03:26:33 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>给 PHPCMS 添加删除栏目的代码做优化</title>
		<link>http://www.magki.com/blog/2009/08/code-optimization-for-phpcms.html</link>
		<comments>http://www.magki.com/blog/2009/08/code-optimization-for-phpcms.html#comments</comments>
		<pubDate>Tue, 11 Aug 2009 00:58:15 +0000</pubDate>
		<dc:creator>Magki</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[源码修改]]></category>

		<guid isPermaLink="false">http://www.magki.com/blog/?p=31</guid>
		<description><![CDATA[最近几个单都是用 PHPCMS 做二次开发，包括现在正在进行的这个大单，有多大？给客户添数据后，光是栏目数就已经设置到3000+并且上升势头不减……
以前没遇到过一个网站有那么多栏目的情况，估计 PHPCMS 的开发人员也没遇到过，因为我发现栏目越多，添加和修改栏目的速度越慢，栏目数过1000的时候，基本修改一次栏目就得花上1分钟时间，现在 3000+ 栏目已经要4，5分钟了……查阅了下 PHPCMS 的代码发现了问题所在。
PHPCMS 的栏目相关处理方法都是在 include\admin\category.class.php 里，这个类文件中有一个被频繁使用的方法 repair，问题就出在这里。无论是添加、删除还是其他的一些栏目操作，大多都会执行一次这个方法（有个地方连续执行两次，不解，应该是开发人员的失误）。而这个方法的主要工作就是将整个站的所有栏目遍历一次遍，对每个栏目都更新一下 arrparentid, parentdir, arrchildid 三个字段的内容。妈妈呀，那3000多个栏目岂不是要执行3000多次 update？怪不得……

我想开发人员之所以这么设计，应该是考虑到一个栏目的路径以及父栏目的变更对其父栏目和子栏目的影响，就计划要整体更新一遍防止出错。不过这种全盘更新的方式有失斟酌呀！一般只需要对影响到到的某几个栏目分支的所有栏目更新一遍就可以了。于是我将这个方法修改如下：

function repair($id=0,$pid=-1,$opid=-1)
{
&#160;&#160;&#160;&#160;@set_time_limit(600);
&#160;&#160;&#160;&#160;if($id==0){
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;if(is_array($this->category))
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;{
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;foreach($this->category as $catid => $cat)
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;{
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;if($catid == 0) continue;
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;$arrparentid = $this->get_arrparentid($catid);
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;$parentdir = $this->get_parentdir($catid);
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;$arrchildid = $this->get_arrchildid($catid);
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;$child = is_numeric($arrchildid) ? 0 : 1;
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;$this->db->query("UPDATE `$this->table` SET arrparentid='$arrparentid',parentdir='$parentdir',arrchildid='$arrchildid',child='$child' WHERE catid=$catid");
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;if($cat['module']=='phpcms') $this->url($catid);
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;}
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;}
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;$this->cache();
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;return TRUE;
&#160;&#160;&#160;&#160;}
&#160;&#160;&#160;&#160;if($pidget_arrparentid($opid).",".$opid);
&#160;&#160;&#160;&#160;$arrchildid = explode(",",$this->get_arrchildid($id));
&#160;&#160;&#160;&#160;$allid = array_merge($arrpid,$arropid);
&#160;&#160;&#160;&#160;$allid = array_merge($allid,$arrchildid);
&#160;&#160;&#160;&#160;$allid = array_flip($allid);
&#160;&#160;&#160;&#160;foreach($allid as $catid=>$v)
&#160;&#160;&#160;&#160;{
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;if($catid [...]]]></description>
			<content:encoded><![CDATA[<p>最近几个单都是用 PHPCMS 做二次开发，包括现在正在进行的这个大单，有多大？给客户添数据后，光是栏目数就已经设置到3000+并且上升势头不减……</p>
<p>以前没遇到过一个网站有那么多栏目的情况，估计 PHPCMS 的开发人员也没遇到过，因为我发现栏目越多，添加和修改栏目的速度越慢，栏目数过1000的时候，基本修改一次栏目就得花上1分钟时间，现在 3000+ 栏目已经要4，5分钟了……查阅了下 PHPCMS 的代码发现了问题所在。</p>
<p>PHPCMS 的栏目相关处理方法都是在 include\admin\category.class.php 里，这个类文件中有一个被频繁使用的方法 repair，问题就出在这里。无论是添加、删除还是其他的一些栏目操作，大多都会执行一次这个方法（有个地方连续执行两次，不解，应该是开发人员的失误）。而这个方法的主要工作就是将整个站的所有栏目遍历一次遍，对每个栏目都更新一下 <span style="color: #ff0000;">arrparentid</span>, <span style="color: #ff0000;">parentdir</span>, <span style="color: #ff0000;">arrchildid</span> 三个字段的内容。妈妈呀，那3000多个栏目岂不是要执行3000多次 update？怪不得……</p>
<p><span id="more-31"></span></p>
<p>我想开发人员之所以这么设计，应该是考虑到一个栏目的路径以及父栏目的变更对其父栏目和子栏目的影响，就计划要整体更新一遍防止出错。不过这种全盘更新的方式有失斟酌呀！一般只需要对影响到到的某几个栏目分支的所有栏目更新一遍就可以了。于是我将这个方法修改如下：</p>
<blockquote><p>
function repair($id=0,$pid=-1,$opid=-1)<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;@set_time_limit(600);<br />
&nbsp;&nbsp;&nbsp;&nbsp;if($id==0){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(is_array($this->category))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;foreach($this->category as $catid => $cat)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if($catid == 0) continue;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$arrparentid = $this->get_arrparentid($catid);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$parentdir = $this->get_parentdir($catid);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$arrchildid = $this->get_arrchildid($catid);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$child = is_numeric($arrchildid) ? 0 : 1;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this->db->query("UPDATE `$this->table` SET arrparentid='$arrparentid',parentdir='$parentdir',arrchildid='$arrchildid',child='$child' WHERE catid=$catid");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if($cat['module']=='phpcms') $this->url($catid);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this->cache();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return TRUE;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;if($pid<1) $pid=$id;<br />
&nbsp;&nbsp;&nbsp;&nbsp;if($opid<1) $opid=$id;<br />
&nbsp;&nbsp;&nbsp;&nbsp;$arrpid = explode(",",$this->get_arrparentid($pid).",".$pid);<br />
&nbsp;&nbsp;&nbsp;&nbsp;$arropid = explode(",",$this->get_arrparentid($opid).",".$opid);<br />
&nbsp;&nbsp;&nbsp;&nbsp;$arrchildid = explode(",",$this->get_arrchildid($id));<br />
&nbsp;&nbsp;&nbsp;&nbsp;$allid = array_merge($arrpid,$arropid);<br />
&nbsp;&nbsp;&nbsp;&nbsp;$allid = array_merge($allid,$arrchildid);<br />
&nbsp;&nbsp;&nbsp;&nbsp;$allid = array_flip($allid);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;foreach($allid as $catid=>$v)<br />
&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if($catid == 0) continue;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$arrparentid = $this->get_arrparentid($catid);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$parentdir = $this->get_parentdir($catid);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$arrchildid = $this->get_arrchildid($catid);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$child = is_numeric($arrchildid) ? 0 : 1;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this->db->query("UPDATE `$this->table` SET arrparentid='$arrparentid',parentdir='$parentdir',arrchildid='$arrchildid',child='$child' WHERE catid=$catid");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if($this->category[$catid]['module']=='phpcms') $this->url($catid);<br />
&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;$this->cache();<br />
&nbsp;&nbsp;&nbsp;&nbsp;return TRUE;<br />
}
</p></blockquote>
<p>这个方法修改完毕后，在去这个类文件的 add 和 edit 方法中修改 <span style="color: #ff0000;">$this-&gt;repair();</span> 这一行，主要是有三个参数依次为<span style="color: #ff0000;">栏目ID</span>，<span style="color: #ff0000;">最后的父级ID</span>，<span style="color: #ff0000;">之前的父级ID</span>。三个参数都不设置则和原来的效果完全一致，只填栏目ID则只更新该栏目以及其子栏目的前面所说的那三个字段内容，填写最后的父级ID，则会将所指定栏目最后所在栏目分支里的所有栏目更新一遍，填写之前的父级ID，则会将所指定栏目更改父级栏目之前所在的栏目分支里所有栏目更新一遍。注意，如果要更新相关栏目分支里的栏目，栏目ID这个参数必须同时设置。针对我这边的情况，我将 add 方法里的 repair 方法调用修改成 <span style="color: #ff0000;">$this-&gt;repair($catid,$parentid);</span>，edit 方法里则改成 <span style="color: #ff0000;">$this-&gt;repair($catid,$parentid,$oldparentid);</span>。</p>
<p>另外 add 方法里执行 repair 方法之前还得插入如下代码，以保证新添加的栏目可以更新到缓存里去。</p>
<blockquote><p>
$this->category[$catid]['parentid'] = $category['parentid'];<br />
$this->category[$catid]['arrparentid'] = $category['arrparentid'];<br />
$this->category[$catid]['parentdir'] = $category['parentdir'];<br />
$this->category[$catid]['arrchildid'] = $catid;
</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://www.magki.com/blog/2009/08/code-optimization-for-phpcms.html/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>

