<?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>Web Development Notes &#187; Drupal</title>
	<atom:link href="http://blog.eood.cn/tag/drupal/feed" rel="self" type="application/rss+xml" />
	<link>http://blog.eood.cn</link>
	<description>PHP, Drupal, Erlang, MySQL, Java, MongoDB, Linux, vim, ssh, screen etc</description>
	<lastBuildDate>Sat, 31 Dec 2011 12:49:49 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Why Drupal is not popular in China</title>
		<link>http://blog.eood.cn/why-drupal-is-not-popular-in-china</link>
		<comments>http://blog.eood.cn/why-drupal-is-not-popular-in-china#comments</comments>
		<pubDate>Fri, 30 Dec 2011 05:35:11 +0000</pubDate>
		<dc:creator>Bruce Dou</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[My Thinking]]></category>
		<category><![CDATA[China]]></category>
		<category><![CDATA[Drupal]]></category>

		<guid isPermaLink="false">http://blog.eood.cn/why-drupal-is-not-popular-in-china</guid>
		<description><![CDATA[I have developed based on Drupal stack for more than 4 years. In my opinion: The learning curve of Drupal is higher than other stacks, since It&#8217;s flexibility.&#160; Server environment in China is very poor. Drupal can works well at least installed in VPS. The requirement is very simple in China, you can just install [...]]]></description>
			<content:encoded><![CDATA[</p>
<p>I have developed based on Drupal stack for more than 4 years. In my opinion:</p>
<ul>
<li>The learning curve of Drupal is higher than other stacks, since It&#8217;s flexibility.&nbsp;</li>
<li>Server environment in China is very poor. Drupal can works well at least installed in VPS.</li>
<li>The requirement is very simple in China, you can just install something like DZ forum or DEDE cms to accomplish the goal. Since the feature requirement is not comes from business requirement, they just want a simple web page to display there company profile etc.</li>
<li>Lots of teams want to build there own framework. (I disagree with this idea, it is wasting resource and time.)</li>
<li>The traffic of the website in China almost 100x larger than EU or US, but the value of the traffic is very low. So you need do more performance optimization for the Drupal site in China.</li>
<li>Most developers in China works on a Windows PC. So no drush, varnish, memcache, cron, etc.</li>
<li>Lots of developers installed Drupal and thought that Drupal is a blog :)</li>
</ul>
<div></div>
]]></content:encoded>
			<wfw:commentRss>http://blog.eood.cn/why-drupal-is-not-popular-in-china/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[Drupal] 错误执行MYSQL命令之后如何挽救</title>
		<link>http://blog.eood.cn/drupal_mysql_tips</link>
		<comments>http://blog.eood.cn/drupal_mysql_tips#comments</comments>
		<pubDate>Mon, 28 Nov 2011 02:25:00 +0000</pubDate>
		<dc:creator>Bruce Dou</dc:creator>
				<category><![CDATA[Life & Work]]></category>
		<category><![CDATA[Drupal]]></category>
		<category><![CDATA[mysql]]></category>

		<guid isPermaLink="false">http://blog.eood.cn/drupal_mysql_tips</guid>
		<description><![CDATA[长期维护生产环境的数据库，恐怕很多人会犯这样的错误: update tableA set field1value = VVVV (where &#8230;); 忘记了加括号中的约束条件，等反应过来，Shell 中显示已经更新了几万条数据。 如何挽救这样的失误呢？ 每天进行数据备份，我们的方案是每天 dump 整库，保存在 S3 中，服务器上只保存昨天的数据 假如有前一天的备份数据，可以选择性恢复除了今天以外的数据。Shell 中命令行失误往往被损坏的数据都涉及一张表的一个字段或者几个字段。 Drupal 中可以利用其支持多库的特性，新建一个旧数据的库，从旧数据库中读取数据，覆盖到新库上。以下是恢复数据的脚本例子 假如不是 Drupal 系统，也可以直接用 PHP 连接2个数据库，进行类似操作。]]></description>
			<content:encoded><![CDATA[<p>长期维护生产环境的数据库，恐怕很多人会犯这样的错误:</p>
<p>update table<em></em><em>A set field</em>1value = VVVV (where &#8230;);</p>
<p>忘记了加括号中的约束条件，等反应过来，Shell 中显示已经更新了几万条数据。</p>
<p>如何挽救这样的失误呢？</p>
<ol>
<li>每天进行数据备份，我们的方案是每天 dump 整库，保存在 S3 中，服务器上只保存昨天的数据</li>
<li>假如有前一天的备份数据，可以选择性恢复除了今天以外的数据。Shell 中命令行失误往往被损坏的数据都涉及一张表的一个字段或者几个字段。</li>
<li>Drupal 中可以利用其支持多库的特性，新建一个旧数据的库，从旧数据库中读取数据，覆盖到新库上。以下是恢复数据的脚本例子</li>
</ol>
<p><script src=http://gist.github.com/cb5584ba78c08ff8073b.js ></script></p>
<p>假如不是 Drupal 系统，也可以直接用 PHP 连接2个数据库，进行类似操作。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.eood.cn/drupal_mysql_tips/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Drupal Views PHP Code Validator</title>
		<link>http://blog.eood.cn/drupal-views-php-code-validator</link>
		<comments>http://blog.eood.cn/drupal-views-php-code-validator#comments</comments>
		<pubDate>Mon, 30 May 2011 07:48:12 +0000</pubDate>
		<dc:creator>Bruce Dou</dc:creator>
				<category><![CDATA[Life & Work]]></category>
		<category><![CDATA[Drupal]]></category>
		<category><![CDATA[Views]]></category>

		<guid isPermaLink="false">http://blog.eood.cn/drupal-views-php-code-validator</guid>
		<description><![CDATA[Views is one of the best module of Drupal. It provide a way to map the data in the mysql database to the web interface. You can do that even without writing any SQL query, just some clicks. I do not want to cover all the aspet of Views, but only to show how to [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Views </strong>is one of the best module of Drupal. It provide a way to map the data in the mysql database to the web interface. You can do that even without writing any SQL query, just some clicks. I do not want to cover all the aspet of Views, but only to show how to restrict the Veiws result based on <strong>Arguments</strong>.</p>
<p>Arguments are parts of URL, may be a node id in /node/xxxx, or user id in /user/xxxx. Views provide some build-in arguments: See <a href="http://drupal.org/node/54455">Views arguments</a>. You can restrict the views by Node type, User ID, Term ID, etc. But these build-in features can not meet all of our requirement.</p>
<p>So we can use <strong>PHP Code Validator</strong>.</p>
<p>For example, I want to show the view only in the node where a CCK field eqs <strong>1</strong>. And only show in the content type <em>blog</em>.</p>
<blockquote><p>$nid = $argument;<br />
$node = node_load($nid);<br />
return ($node-&gt;type == &#8216;blog&#8217; &amp;&amp; $node-&gt;field_Myfield_type[0]['value'] == 1);</p>
</blockquote>
<p>Put the php code block in the views argument, then you will find the result.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.eood.cn/drupal-views-php-code-validator/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ajax 调用 Drupal 中 Block 数据</title>
		<link>http://blog.eood.cn/ajax_call_drupal_block</link>
		<comments>http://blog.eood.cn/ajax_call_drupal_block#comments</comments>
		<pubDate>Sat, 19 Feb 2011 06:17:45 +0000</pubDate>
		<dc:creator>Bruce Dou</dc:creator>
				<category><![CDATA[Life & Work]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[Drupal]]></category>

		<guid isPermaLink="false">http://blog.eood.cn/?p=1557</guid>
		<description><![CDATA[启用了 Boost 模块缓存整个网站，或者需要在站外调用 Drupal 网站的数据，如何调用 Drupal 中的动态数据？ Ajax 调用 Drupal 中的 block 需要以下步骤 启动 Drupal 页面 动态输出 block 的内容，json 格式或者 html 格式 在目标页面中 Jquery 输出 Ajax 调用的数据 启动 Drupal 输出HTML格式内容 1 2 3 4 5 6 7 &#60;?php // block.php include_once './includes/bootstrap.inc'; drupal_bootstrap&#40;DRUPAL_BOOTSTRAP_FULL&#41;; $block = module_invoke&#40;'statistics', 'block', 'view', 0&#41;; print $block&#91;'content'&#93;; ?&#62; 在目标页面中 Jquery 输出 [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://blog.eood.cn/wp-content/uploads/2010/02/drupal1.gif"><img class="alignright size-full wp-image-796" title="drupal" src="http://blog.eood.cn/wp-content/uploads/2010/02/drupal1.gif" alt="" width="250" height="250" /></a>启用了 Boost 模块缓存整个网站，或者需要在站外调用 Drupal 网站的数据，如何调用 Drupal 中的动态数据？</p>
<p>Ajax 调用 Drupal 中的 block 需要以下步骤</p>
<ul>
<li>启动 Drupal 页面</li>
<li>动态输出 block 的内容，json 格式或者 html 格式</li>
<li>在目标页面中 Jquery 输出 Ajax 调用的数据</li>
</ul>
<p>启动 Drupal 输出HTML格式内容</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #666666; font-style: italic;">// block.php</span>
<span style="color: #b1b100;">include_once</span> <span style="color: #0000ff;">'./includes/bootstrap.inc'</span><span style="color: #339933;">;</span>
drupal_bootstrap<span style="color: #009900;">&#40;</span>DRUPAL_BOOTSTRAP_FULL<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$block</span> <span style="color: #339933;">=</span> module_invoke<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'statistics'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'block'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'view'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">print</span> <span style="color: #000088;">$block</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'content'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></td></tr></table></div>

<p>在目标页面中 Jquery 输出 Ajax 调用的数据</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
</pre></td><td class="code"><pre class="html" style="font-family:monospace;">&lt;div id=&quot;info&quot;&gt;&lt;/div&gt;
&lt;script&gt;
$('#info').load('/block.php')
&lt;/script&gt;</pre></td></tr></table></div>

]]></content:encoded>
			<wfw:commentRss>http://blog.eood.cn/ajax_call_drupal_block/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Drupal upload progress integrate with Nginx</title>
		<link>http://blog.eood.cn/drupal-upload-progress-integrate-with-nginx</link>
		<comments>http://blog.eood.cn/drupal-upload-progress-integrate-with-nginx#comments</comments>
		<pubDate>Tue, 11 Jan 2011 15:43:17 +0000</pubDate>
		<dc:creator>Bruce Dou</dc:creator>
				<category><![CDATA[Life & Work]]></category>
		<category><![CDATA[Drupal]]></category>
		<category><![CDATA[Nginx]]></category>

		<guid isPermaLink="false">http://blog.eood.cn/?p=1519</guid>
		<description><![CDATA[Drupal upload progress Drupal filefield provide a upload progress bar when you uploding files. You should install APC upload progress module or PECL uploadprogress module. PHP 5.2+ should be updated if you use APC as the upload progress system. The detailed instruction you can find at IBM&#8217;s guide. PECL uplaod progress module can be find [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Drupal upload progress</strong></p>
<p>Drupal filefield provide a upload progress bar when you uploding files. You should install APC upload progress module or PECL uploadprogress module.</p>
<p><img class="size-full wp-image-1520" title="uploadprogress" src="http://blog.eood.cn/wp-content/uploads/2011/01/uploadprogress.png" alt="" width="418" height="123" /></p>
<p>PHP 5.2+ should be updated if you use APC as the upload progress system. The detailed instruction you can find at <a href="http://www.ibm.com/developerworks/library/os-php-v525/index.html" target="_blank">IBM&#8217;s guide</a>.</p>
<p>PECL uplaod progress module can be find at <a href="http://pecl.php.net/package/uploadprogress/">http://pecl.php.net/package/uploadprogress/</a></p>
<p>Or install just a command line<code>: </code><span style="color: #008000;">pecl install uploadprogress</span>.  Then Add<span style="color: #008000;"> extension=uploadprogress.so </span>to php.ini, restart your Apache Server. This module is suggested.</p>
<p>All these modules must install with Apache Server.</p>
<p><strong>Nginx upload progress Module</strong></p>
<p><a href="../wp-content/uploads/2011/01/nginxupload.png"><img title="nginxupload" src="../wp-content/uploads/2011/01/nginxupload.png" alt="" width="207" height="267" /></a></p>
<p>Nginx also provide the <a href="http://wiki.nginx.org/HttpUploadProgressModule" target="_blank">upload progress system</a>. If this module are enabled, all upload files will be cached in Nginx before the whole file is uploaded.</p>
<p>Nginx buffers the entire upload before passing it to the php backend. So if you chose Nginx as the HTTP server or Proxy at the front of Apache Server, the Drupal upload progress will not work!</p>
<p>But the Nginx upload system is so brilliant that it will reduce the stress to the PHP backend, so your Server will be more stable and fast.</p>
<p><strong>How to use Nginx upload progress module with Drupal uploading progress bar</strong>:</p>
<p>1. APC progress or PECL progress module are NOT required, because we use Nginx upload progress moudle.</p>
<p>2. You should install filefield_nginx_progress module in Drupal</p>
<p>3. You should compile Nginx with <a href="http://wiki.nginx.org/HttpUploadProgressModule">HttpUploadProgressModule</a></p>
<p>./configure &#8211;add-module=/www/nginx_uploadprogress_module</p>
<p>4. Configure in php.ini with upload file size limit and post size limit.</p>
<p>post_max_size = 2000M</p>
<p>upload_max_filesize = 2000M</p>
<p>5. Sample Nginx configuration file:</p>
<p>Apache as the back end server at port 81, Nginx as the proxy at port 80. Your domain name is www1.dev</p>
<pre>http {
   <span style="color: #ff0000;"> client_max_body_size 2000M;
    client_body_buffer_size 128k;</span>

    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    <span style="color: #ff0000;">upload_progress uploads 1m;</span>

    #gzip  on;

    server {
        listen       80;
        server_name  www1.dev;

	<span style="color: #ff0000;">location ~ (.*)/x-progress-id:(\w*) {
            rewrite ^(.*)/x-progress-id:(\w*)  $1?X-Progress-ID=$2;
        }

        location ^~ /progress {
            report_uploads uploads;
        }</span>

	location / {
	   proxy_set_header    X-Real-IP  $remote_addr;
	   proxy_set_header    X-Forwarded-For $proxy_add_x_forwarded_for;
	   proxy_set_header    Host $http_host;

	   proxy_pass          http://127.0.0.1:81;
	   proxy_redirect      default;
	   add_header        X-Test Proxied;  # for diagnosis only - can be removed

	   <span style="color: #ff0000;">track_uploads uploads 60s;</span>
	}

	# serve static files directly
	location ~* ^.+.(jpg|jpeg|gif|css|png|js|ico)$ {
	   root /www/docs/www1.dev/drupal-6.x-dev;
	   access_log        off;
           expires           30d;
           add_header        X-Test Direct;  # for diagnosis only - can be removed
	}
    }
}</pre>
<p>Drupal nginx progress module:<a href="http://drupal.org/project/filefield_nginx_progress"> http://drupal.org/project/filefield_nginx_progress</a></p>
<p>Nginx upload progress module:<a href="https://github.com/masterzen/nginx-upload-progress-module"> https://github.com/masterzen/nginx-upload-progress-module</a></p>
<p>Instruction about Drupal nginx uploading progress module:<a href="http://drupalcode.org/viewvc/drupal/contributions/modules/filefield_nginx_progress/README.txt?view=co&amp;pathrev=DRUPAL-6--1"> </a></p>
<p><a href="http://drupalcode.org/viewvc/drupal/contributions/modules/filefield_nginx_progress/README.txt?view=co&amp;pathrev=DRUPAL-6--1">http://drupalcode.org/viewvc/drupal/contributions/modules/filefield_nginx_progress/README.txt?view=co&amp;pathrev=DRUPAL-6&#8211;1</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.eood.cn/drupal-upload-progress-integrate-with-nginx/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Drupal 高效部署和维护</title>
		<link>http://blog.eood.cn/drupal-server-admin</link>
		<comments>http://blog.eood.cn/drupal-server-admin#comments</comments>
		<pubDate>Sun, 09 Jan 2011 03:00:17 +0000</pubDate>
		<dc:creator>Bruce Dou</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Drupal]]></category>

		<guid isPermaLink="false">http://blog.eood.cn/?p=1529</guid>
		<description><![CDATA[Drupal 是由很小的核心和几千个实现不同功能的模块组成，无论要实现什么功能，几乎都可以通过找到模块来实现。但是一个中等的系统会需要几十个或者上百个模块。所以Drupal 模块的部署和维护必须通过高效的方式来实现。 Drupal 提供了两种不同的部署方式，你可以通过命令行来部署，或者通过传统的WEB界面来维护。 本文只介绍命令行的方式。Drupal 有命令行维护工具 Drush 。通过Drush来维护系统是Drupal众多优秀的特性之一，它类似于Django中命令行自动生成数据库结构，或者PECL安装PHP的扩展模块，或者yum来维护Linux软件包。只需要一行命令就可以安装系统，或者下载一个模块。 1. Drush的安装： 对于Drupal6.x,下载Drush模块，并且解压即可： $ cd ~ $ wget http://ftp.drupal.org/files/projects/drush-6.x-3.3.tar.gz $ tar zxvf drush-6.x-3.3.tar.gz $ ln -s /path/to/drush/drush /usr/local/bin/drush 这样你可以在任何目录执行drush命令。 2. 用Drush来下载安装Drupal： 你不需要从Drupal网站下载安装包，上传到FTP，再配置数据库，从WEB界面安装： 下载并且解压Drupal包： $ drush dl 安装Drupal $ drush is 安装CCK $ drush dl cck $ drush en cck 清空cache可能是开发中最常用的功能： $ drush cc 查看watchdog信息： $ drush [...]]]></description>
			<content:encoded><![CDATA[<p>Drupal 是由很小的核心和几千个实现不同功能的模块组成，无论要实现什么功能，几乎都可以通过找到模块来实现。但是一个中等的系统会需要几十个或者上百个模块。所以Drupal 模块的部署和维护必须通过高效的方式来实现。</p>
<p>Drupal 提供了两种不同的部署方式，你可以通过命令行来部署，或者通过传统的WEB界面来维护。</p>
<p>本文只介绍命令行的方式。Drupal 有命令行维护工具 <a href="http://drupal.org/project/drush" target="_blank">Drush</a> 。通过Drush来维护系统是Drupal众多优秀的特性之一，它类似于Django中命令行自动生成数据库结构，或者PECL安装PHP的扩展模块，或者yum来维护Linux软件包。只需要一行命令就可以安装系统，或者下载一个模块。</p>
<p><strong>1. Drush的安装：</strong></p>
<p>对于Drupal6.x,下载Drush模块，并且解压即可：</p>
<p>$ cd ~</p>
<p>$ wget http://ftp.drupal.org/files/projects/drush-6.x-3.3.tar.gz</p>
<p>$ tar zxvf drush-6.x-3.3.tar.gz</p>
<p>$ ln -s /path/to/drush/drush /usr/local/bin/drush</p>
<p>这样你可以在任何目录执行drush命令。</p>
<p><strong>2. 用Drush来下载安装Drupal：</strong></p>
<p>你不需要从Drupal网站下载安装包，上传到FTP，再配置数据库，从WEB界面安装：</p>
<p>下载并且解压Drupal包：</p>
<p>$ drush dl</p>
<p>安装Drupal</p>
<p>$ drush is</p>
<p>安装CCK</p>
<p>$ drush dl cck</p>
<p>$ drush en cck</p>
<p>清空cache可能是开发中最常用的功能：</p>
<p>$ drush cc</p>
<p>查看watchdog信息：</p>
<p>$ drush ws</p>
<p>执行cron</p>
<p>$ drush cron</p>
<p>更多drush命令：http://drush.ws</p>
<p><strong>推荐用Drush来部署和维护Drupal</strong></p>
<p>所有模块的安装维护仅仅需要1-2行命令,不必在忍受WEB界面网速的问题。我们需要用最好最快的方式来节约时间，提高效率。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.eood.cn/drupal-server-admin/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>高效程序调试和测试方法</title>
		<link>http://blog.eood.cn/efficient_debugging_php_java_python</link>
		<comments>http://blog.eood.cn/efficient_debugging_php_java_python#comments</comments>
		<pubDate>Sun, 28 Nov 2010 03:26:30 +0000</pubDate>
		<dc:creator>Bruce Dou</dc:creator>
				<category><![CDATA[My Thinking]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[debug]]></category>
		<category><![CDATA[Drupal]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://blog.eood.cn/?p=1419</guid>
		<description><![CDATA[调试程序往往比编写程序更浪费时间，正如一些有经验的程序员所说，软件的开发应该包括20%的程序编写时间和80%的Debug时间。并且调试程序比编写程序要难2倍。编写巧妙的程序并不一定调试方便。 程序的调试有很多方法，比如最常见的VC之类的IDE都提供加断点，逐步执行，逐段执行的功能。但是这只能针对程序某个微小的片段，对于前期bug的范围的界定并不是很方便。况且对于不满IDE的臃肿，身陷Vim, notepad++, Editplus之类的编辑器之中，我们需要找到更加高效的程序调试和测试方法。 在程序执行的关键点打印Log是一个非常高效的方法，如何打印log进行程序调试呢? 以PHP程序开发为例，需要2个步骤: 1. PHP函数中两个关键的打印变量的方法 print_r var_dump 所以我们可以在关键的地方打印需要的变量。 2. 收集我们在程序中打印的变量 我们可以把程序执行过程中打印的变量逐条写到文本文件里。在程序执行完毕之后进行分析，查找Bug，修正程序。 PHP中打印时间，和变量的程序片段： function file_log($message) { global $file_log_location; ob_start(); echo date("Y-m-d H:i:s \t", time()); print_r($message); echo "\n"; $var = ob_get_contents(); ob_end_clean(); $open=@fopen($file_log_location,"a"); @fwrite($open,$var); fclose($open); } 应用此段程序还需要对log的存储位置$file_log_location赋值。 在需要的地方插入此片段，执行PHP程序，就会得到所需信息。 但是假如是长时间运行的程序如何在程序执行的过程中就查看到log的信息？相信你已经想到了可以在shell中用 tail -f /var/debug.log 这样总可以看到程序吐出的最新的debug信息。 附件是Drupal中进行debug的一个小的module,做drupal开发的同学可以尝试一下。 Drupal debug module 虽然本文针对PHP开发所言，但是这种方法也适合python,java之类的动态语言的开发。 &#8211;EOF&#8211;]]></description>
			<content:encoded><![CDATA[<blockquote><p>调试程序往往比编写程序更浪费时间，正如一些有经验的程序员所说，软件的开发应该包括20%的程序编写时间和80%的Debug时间。并且调试程序比编写程序要难2倍。编写巧妙的程序并不一定调试方便。</p></blockquote>
<p><img class="alignright size-full wp-image-1435" title="debug" src="http://blog.eood.cn/wp-content/uploads/2010/11/debug.gif" alt="" width="410" height="171" />程序的调试有很多方法，比如最常见的VC之类的IDE都提供加断点，逐步执行，逐段执行的功能。但是这只能针对程序某个微小的片段，对于前期bug的范围的界定并不是很方便。况且对于不满IDE的臃肿，身陷Vim, notepad++, Editplus之类的编辑器之中，我们需要找到更加高效的程序调试和测试方法。</p>
<p>在程序执行的关键点打印Log是一个非常高效的方法，如何打印log进行程序调试呢? 以PHP程序开发为例，需要2个步骤:</p>
<h4>1. PHP函数中两个关键的打印变量的方法</h4>
<p><em><span style="color: #000000;">print_r var_dump</span></em></p>
<p>所以我们可以在关键的地方打印需要的变量。</p>
<h4>2. 收集我们在程序中打印的变量</h4>
<p>我们可以把程序执行过程中打印的变量逐条写到文本文件里。在程序执行完毕之后进行分析，查找Bug，修正程序。</p>
<p>PHP中打印时间，和变量的程序片段：</p>
<pre>function file_log($message) {
    global $file_log_location;
    ob_start();
    echo date("Y-m-d H:i:s \t", time());
    print_r($message);
    echo "\n";
    $var = ob_get_contents();
    ob_end_clean();
    $open=@fopen($file_log_location,"a");
    @fwrite($open,$var);
    fclose($open);
}
</pre>
<p>应用此段程序还需要对log的存储位置<em><span style="color: #000000;">$file_log_location</span></em>赋值。</p>
<p>在需要的地方插入此片段，执行PHP程序，就会得到所需信息。</p>
<p>但是假如是长时间运行的程序如何在程序执行的过程中就查看到log的信息？相信你已经想到了可以在shell中用</p>
<p><em><span style="color: #000000;">tail -f /var/debug.log</span></em></p>
<p>这样总可以看到程序吐出的最新的debug信息。</p>
<p>附件是Drupal中进行debug的一个小的module,做drupal开发的同学可以尝试一下。</p>
<p><a href="http://blog.eood.cn/wp-content/uploads/2010/11/filelog_0.zip">Drupal debug module</a></p>
<p>虽然本文针对PHP开发所言，但是这种方法也适合python,java之类的动态语言的开发。</p>
<p>&#8211;EOF&#8211;</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.eood.cn/efficient_debugging_php_java_python/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Workflow in Drupal</title>
		<link>http://blog.eood.cn/workflow-in-drupal</link>
		<comments>http://blog.eood.cn/workflow-in-drupal#comments</comments>
		<pubDate>Tue, 19 Oct 2010 10:03:07 +0000</pubDate>
		<dc:creator>Bruce Dou</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Project Manament]]></category>
		<category><![CDATA[Actions]]></category>
		<category><![CDATA[Drupal]]></category>
		<category><![CDATA[Triggers]]></category>
		<category><![CDATA[Workflow]]></category>

		<guid isPermaLink="false">http://blog.eood.cn/?p=1256</guid>
		<description><![CDATA[Workflow is the essential feature of complex modern system. Lots of automate process can be implemented if the workflow states defines.And it contributed to the ACL system. Think of the following situations: 1. The Draft news should only be shown to moderator. After moderation, the state changed to open. And open news should be shown [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: center;"><img class="size-full wp-image-1258    aligncenter" title="workflow_drupal" src="http://blog.eood.cn/wp-content/uploads/2010/10/workflow_drupal.gif" alt="" width="460" height="208" /></p>
<p>Workflow is the essential feature of complex modern system. Lots of automate process can be implemented if the workflow states defines.And it contributed to the ACL system.<br />
<strong>Think of the following situations:</strong><br />
1. The Draft news should only be shown to moderator. After moderation, the state changed to open. And open news should be shown to All automatically.<br />
2. In the open state, some field shows to all, and some hidden, only can be seen by some roles.<br />
3. In the Draft state, some fields such as title can not be edited, but other fields can be edited.<br />
4. The job can be processed just after money access. Automatically change the state of the job. (By Trigger)<br />
5. The payment process<br />
6. Automatically hide the article after open 1 weeks.<br />
In Drupal, workflow module always work together with Actions*, Triggers*, VBO*. Triggers can be assigned to the workflow changes. Do something automatically when the workflow changes. Triggers fire the Actions* we defined.</p>
<p><strong>How to define Actions</strong>, please see our other articles.</p>
<p><strong>Important feature or bug of workflow module of Drupal:</strong><br />
When a new CCK field added to a content type. The workflow of this state should be saved again, or the field will not be constrained by Workflow.</p>
<p>Change the workflow programmingly in one line:</p>
<pre><span style="color: #4444ff;">&lt;</span>?<span style="color: #2040a0;">php</span>
    <span style="color: #2040a0;">workflow_execute_transition</span><span style="color: #4444ff;">(</span><span style="color: #2040a0;">node_load</span><span style="color: #4444ff;">(</span>$<span style="color: #2040a0;">nid</span><span style="color: #4444ff;">)</span>, <span style="color: #ff0000;">21</span>, '<span style="color: #2040a0;">Test</span> <span style="color: #2040a0;">comment</span> ',<span style="color: #2040a0;">TRUE</span><span style="color: #4444ff;">)</span><span style="color: #4444ff;">;</span>
?<span style="color: #4444ff;">&gt;</span></pre>
<p>You can change the workflow state by Trigger*, by cron and conditions, by xmlrpc, etc.<br />
<script type="text/javascript"><!--
google_ad_client = "pub-5744751471423663";
google_ad_slot = "7076368164";
google_ad_width = 336;
google_ad_height = 280;
//-->
</script><br />
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.eood.cn/workflow-in-drupal/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to show custom menu links to special roles in Drupal</title>
		<link>http://blog.eood.cn/how-to-show-custom-menu-links-to-special-roles-in-drupal</link>
		<comments>http://blog.eood.cn/how-to-show-custom-menu-links-to-special-roles-in-drupal#comments</comments>
		<pubDate>Wed, 07 Jul 2010 14:46:48 +0000</pubDate>
		<dc:creator>Bruce Dou</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Drupal]]></category>
		<category><![CDATA[menu]]></category>
		<category><![CDATA[theme]]></category>

		<guid isPermaLink="false">http://blog.eood.cn/?p=1168</guid>
		<description><![CDATA[1. Create new menu root for example *merchant* 2. Override function hook_preprocess_page(&#38;$vars) in templete.php and add the following code: global $user; if (in_array(&#8216;Merchant&#8217;, $user-&#62;roles)) { $vars['nav_links'] = menu_navigation_links(&#8220;menu-merchant&#8221;); } elseif (in_array(&#8216;&#8230;&#8217;, $user-&#62;roles)) { &#8230; } 3. Add the following code in your tpl file: &#60;?php print theme(&#8216;links&#8217;, $nav_links) ?&#62; That is all.]]></description>
			<content:encoded><![CDATA[<p>1. Create new menu root for example *merchant*</p>
<p>2. Override function hook_preprocess_page(&amp;$vars) in templete.php and add the following code:</p>
<p>global $user;<br />
if (in_array(&#8216;Merchant&#8217;, $user-&gt;roles)) {<br />
$vars['nav_links'] = menu_navigation_links(&#8220;menu-merchant&#8221;);<br />
} elseif (in_array(&#8216;&#8230;&#8217;, $user-&gt;roles)) {<br />
&#8230;<br />
}</p>
<p>3. Add the following code in your tpl file:</p>
<p>&lt;?php print theme(&#8216;links&#8217;, $nav_links) ?&gt;</p>
<p>That is all.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.eood.cn/how-to-show-custom-menu-links-to-special-roles-in-drupal/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>5 tips you should know when building a Drupal theme</title>
		<link>http://blog.eood.cn/5-tips-you-should-know-when-building-a-drupal-theme</link>
		<comments>http://blog.eood.cn/5-tips-you-should-know-when-building-a-drupal-theme#comments</comments>
		<pubDate>Tue, 27 Apr 2010 15:55:24 +0000</pubDate>
		<dc:creator>Bruce Dou</dc:creator>
				<category><![CDATA[Life & Work]]></category>
		<category><![CDATA[Drupal]]></category>
		<category><![CDATA[theme]]></category>

		<guid isPermaLink="false">http://blog.eood.cn/?p=1055</guid>
		<description><![CDATA[1. Adding and manipulating template variables and the Drupal call order: template_preprocess() template_preprocess_breadcrumb() MODULENAME_preprocess() // Defined in module MODULENAME_preprocess_breadcrumb() // Defined in module phptemplate_preprocess() phptemplate_preprocess_breadcrumb() THEMENAME_preprocess() THEMENAME_preprocess_breadcrumb() 2. Overriding with Theme Functions and the Drupal call order: THEMENAME_breadcrumb() phptemplate_breadcrumb() sites/all/themes/THEMENAME/breadcrumb.tpl.php theme_breadcrumb() 3. Devel module and Theme development module is helpful to show you message about [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://blog.eood.cn/wp-content/uploads/2010/02/drupal1.gif"><img class="alignright size-full wp-image-796" title="drupal" src="http://blog.eood.cn/wp-content/uploads/2010/02/drupal1.gif" alt="" width="150" height="150" /></a></p>
<p>1. Adding and manipulating template variables and the Drupal call order:</p>
<p><code>template_preprocess()<br />
template_preprocess_breadcrumb()<br />
MODULENAME_preprocess() // Defined in module<br />
MODULENAME_preprocess_breadcrumb() // Defined in module<br />
phptemplate_preprocess()<br />
phptemplate_preprocess_breadcrumb()<br />
THEMENAME_preprocess()<br />
THEMENAME_preprocess_breadcrumb()</code></p>
<p>2. Overriding with Theme Functions and the Drupal call order:</p>
<p><code>THEMENAME_breadcrumb()<br />
phptemplate_breadcrumb()<br />
sites/all/themes/THEMENAME/breadcrumb.tpl.php<br />
theme_breadcrumb()</code></p>
<p>3. Devel module and Theme development module is helpful to show you message about theme override.</p>
<p>4. When you theme a CCK filed by adding a file content-filed-field_xxx.tpl.php, do not forget to place an original content-field.tpl.php in the same folder.</p>
<p>5. Do not forget to clear cache if no changes show.﻿</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.eood.cn/5-tips-you-should-know-when-building-a-drupal-theme/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

<!-- Dynamic page generated in 0.428 seconds. -->
<!-- File not cached! Super Cache Couldn't write to: wp-content/cache/wp-cache-5542f5ae86db46faf6ecf51a4d5d8df9.html -->

