<?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>Leakon &#187; PHP</title>
	<atom:link href="http://www.leakon.com/archives/category/php/feed" rel="self" type="application/rss+xml" />
	<link>http://www.leakon.com</link>
	<description>勤奋 - 创新 - 矢志不渝 - 锲而不舍</description>
	<lastBuildDate>Mon, 06 Feb 2012 02:43:07 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>PHP 未知类型变量 empty isset 陷阱</title>
		<link>http://www.leakon.com/archives/673?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=673</link>
		<comments>http://www.leakon.com/archives/673#comments</comments>
		<pubDate>Tue, 22 Mar 2011 02:36:39 +0000</pubDate>
		<dc:creator>leakon</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[empty]]></category>
		<category><![CDATA[isset]]></category>

		<guid isPermaLink="false">http://www.leakon.com/?p=673</guid>
		<description><![CDATA[用 empty 检查位置类型的变量时，容易掉进难以察觉的陷阱，请看下面简单的代码，预测一下 3 个 var_dump 的输出：
$mixed_1    = array();
$mixed_2    = 'Nihao';

$bool_1        = empty($mixed_1['1_type']);
$bool_2        =  [...]]]></description>
			<content:encoded><![CDATA[<p>用 empty 检查位置类型的变量时，容易掉进难以察觉的陷阱，请看下面简单的代码，预测一下 3 个 var_dump 的输出：</p>
<pre>$mixed_1    = array();
$mixed_2    = 'Nihao';

$bool_1        = empty($mixed_1['1_type']);
$bool_2        = empty($mixed_2['2_type']);

var_dump($bool_1);
var_dump($bool_2);

var_dump($mixed_2['2_type']);</pre>
<p>为了不影响你的判断，我多空几行，然后对比结果，是否跟你判断的一致。</p>
<p>。</p>
<p>。</p>
<p>。</p>
<p>。</p>
<p>。</p>
<p>。</p>
<p>。</p>
<p>。</p>
<p>。</p>
<p>。</p>
<p>。</p>
<p>。</p>
<p>。</p>
<p>。</p>
<p>公布结果：</p>
<pre>bool(true)
bool(false)
string(1) "h"</pre>
<p>后面 2 个结果，是不是有点意外？</p>
<p>导致问题的原因，就是 PHP 会自动把字符串按照数组来处理，并且，当 $mixed 不是严格意义的数组时，对元素的引用 key 会把 key 转换为数字，2_type 转换为数字之后，就是数字 &#8220;2&#8243;，对应的元素值就是 &#8220;h&#8221;。</p>
<p>对应的，isset 也会认为 $mixed_2['2_type'] 是存在的。</p>
<p>结论：</p>
<p>在对未知类型的变量做 isset 或 empty 查询时，应同时附加 is_array 等类型检查，才会更安全。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.leakon.com/archives/673/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Duplicate entry &#8216;localhost-&#8217; for key 1</title>
		<link>http://www.leakon.com/archives/620?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=duplicate-entry-localhost-for-key-1</link>
		<comments>http://www.leakon.com/archives/620#comments</comments>
		<pubDate>Wed, 17 Mar 2010 13:18:40 +0000</pubDate>
		<dc:creator>leakon</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[RPM]]></category>

		<guid isPermaLink="false">http://www.leakon.com/?p=620</guid>
		<description><![CDATA[导致这个错误的原因：
因为安装系统时设置了hostname为localhost导致mysql在创建表的时候没有创建成功。因此mysql库中user表里没有root这个用户或者说root没有显示出来，无法查看root的状态。这时需要手动创建。然而在安全模式无法直接创建用户，错误见下。
变个方向就能创建了，先给root给予权限，然后刷新表。之后就可以创建了。
一、killall -TERM mysqld
以安全模式启动mysql
/usr/bin/mysqld_safe &#8211;skip-grant-tables &#38;
进入mysql
/usr/bin/mysql
mysql&#62;  [...]]]></description>
			<content:encoded><![CDATA[<p>导致这个错误的原因：<br />
因为安装系统时设置了hostname为localhost导致mysql在创建表的时候没有创建成功。因此mysql库中user表里没有root这个用户或者说root没有显示出来，无法查看root的状态。这时需要手动创建。然而在安全模式无法直接创建用户，错误见下。<br />
变个方向就能创建了，先给root给予权限，然后刷新表。之后就可以创建了。<br />
一、killall -TERM mysqld<br />
以安全模式启动mysql<br />
/usr/bin/mysqld_safe &#8211;skip-grant-tables &amp;<br />
进入mysql<br />
/usr/bin/mysql<br />
mysql&gt; use mysql<br />
Database changed<br />
mysql&gt; select * from user where user=&#8217;root&#8217;;<br />
Empty set (0.00 sec)</p>
<p>mysql&gt; grant all privileges on *.* to root@localhost identified by &#8216;linuxtone&#8217; with GRANT OPTION;<br />
ERROR 1290 (HY000): The MySQL server is running with the &#8211;skip-grant-tables option so it cannot execute</p>
<p>this statement<br />
mysql&gt; update user set password=password(&#8216;linuxtone&#8217;) where user=&#8217;root&#8217;;<br />
Query OK, 0 rows affected (0.00 sec)<br />
Rows matched: 0 Changed: 0 Warnings: 0</p>
<p>注意单双引号。</p>
<p>mysql&gt; flush privileges;   //注意先刷新下表<br />
Query OK, 0 rows affected (0.00 sec)</p>
<p>mysql&gt; grant all privileges on *.* to root@localhost identified by &#8216;linuxtone&#8217; with GRANT OPTION;<br />
Query OK, 0 rows affected (0.00 sec)</p>
<p>mysql&gt; flush privileges;<br />
Query OK, 0 rows affected (0.00 sec)</p>
<p>mysql&gt; select * from user where user=&#8217;root&#8217;;</p>
<p>后期处理：<br />
/usr/local/mysql/bin/mysqladmin shutdown -uroot -p<br />
刚才的密码<br />
然后正常启动：/usr/bin/mysqld_safe &amp;<br />
/usr/local/mysql/bin/mysql -uroot -p<br />
能正常登录！</p>
<p>二Duplicate entry &#8216;localhost-&#8217; for key 1 问题，很可能是你的主机名有问题，比如是localhost？<br />
导致mysql 的root 帐号的三个主机值（分别是%、localhost、主机名）的后二者的名字弄成一样了，导使唯一键值出现重复而禁用该记录了？<br />
朋友的主机名设置成了：localhost 遭成了Duplicate entry &#8216;localhost-&#8217; for key 1</p>
<p>设置好正确的主机名仍后重新编译就可以了，朋友安装系统的时候没有注意主机名</p>
]]></content:encoded>
			<wfw:commentRss>http://www.leakon.com/archives/620/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>用工具提高效率 解决 PhpMyAdmin 乱码</title>
		<link>http://www.leakon.com/archives/618?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=%25e7%2594%25a8%25e5%25b7%25a5%25e5%2585%25b7%25e6%258f%2590%25e9%25ab%2598%25e6%2595%2588%25e7%258e%2587-%25e8%25a7%25a3%25e5%2586%25b3-phpmyadmin-%25e4%25b9%25b1%25e7%25a0%2581</link>
		<comments>http://www.leakon.com/archives/618#comments</comments>
		<pubDate>Mon, 15 Mar 2010 05:08:31 +0000</pubDate>
		<dc:creator>leakon</dc:creator>
				<category><![CDATA[Efficiency]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.leakon.com/?p=618</guid>
		<description><![CDATA[最近做的项目有点特殊，多人共用开发服务器，无法搭建个人独享的开发环境。
连数据库，不能使用客户端的 GUI 工具，本来我已经离不开 SQLyog 了，现在逼我用命令行，我怎么受得了？
欣慰的是，尽管 MySQL server 虽然不在开发服务器上，也没有 root 权限给我的 IP 做授权，但开发服务器的 IP 是在授权列表内的。
我又想起了 PhpMyAdmin 这个好久不用的工具。
在 Dev server 上装好，配好用户名和密码，然后即可访问 MySQL，不过又遇到新问题！
MySQL server、Database、Table 和 Column 的字符集都是  [...]]]></description>
			<content:encoded><![CDATA[<p>最近做的项目有点特殊，多人共用开发服务器，无法搭建个人独享的开发环境。</p>
<p>连数据库，不能使用客户端的 GUI 工具，本来我已经离不开 SQLyog 了，现在逼我用命令行，我怎么受得了？</p>
<p>欣慰的是，尽管 MySQL server 虽然不在开发服务器上，也没有 root 权限给我的 IP 做授权，但开发服务器的 IP 是在授权列表内的。</p>
<p>我又想起了 PhpMyAdmin 这个好久不用的工具。</p>
<p>在 Dev server 上装好，配好用户名和密码，然后即可访问 MySQL，不过又遇到新问题！</p>
<p>MySQL server、Database、Table 和 Column 的字符集都是 latin1，而写入数据库的字符是 GBK。虽然设计不够合理，但也算勉强能用，用 SecureCRT 的命令行连接 MySQL，是可以看到正确的中文字符的，因为 SecureCRT 设置的是默认的字符集。</p>
<p>但 PhpMyAdmin 却总是乱码！</p>
<p>查了下 Variables 标签，有 2 个关于字符集的高亮提示，意思是全局设置是 latin1，但 character set client 是 utf8。</p>
<p>任凭我怎么改 MySQL connection collation 的设置，都无效。</p>
<p>tail 了一下 MySQL query log，看到 PhpMyAdmin 总是发送</p>
<p>SET CHARACTER SET &#8216;utf8&#8242;<br />
SET collation_connection = &#8216;utf8_general_ci&#8217;</p>
<p>这 2 条语句！</p>
<p>我又 grep 一下，看到有个文件中的代码，让这 2 条语句被强制执行！</p>
<p>用 <a title="解决 PhpMyAdmin 字符乱码问题" href="http://wiki.leakon.com/wiki/PhpMyAdmin" target="_blank">解决 PhpMyAdmin 字符乱码问题</a> 所述的方法修改，即刻解决问题！</p>
<p>这下又能高效的访问 MySQL 啦，我相信打字再快的人，输入一条 Select 语句也没有我点击一下鼠标快！</p>
]]></content:encoded>
			<wfw:commentRss>http://www.leakon.com/archives/618/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>phpDocumentor PHP 文档生成 CHM</title>
		<link>http://www.leakon.com/archives/615?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=phpdocumentor-php-%25e6%2596%2587%25e6%25a1%25a3%25e7%2594%259f%25e6%2588%2590-chm</link>
		<comments>http://www.leakon.com/archives/615#comments</comments>
		<pubDate>Sat, 13 Mar 2010 14:59:29 +0000</pubDate>
		<dc:creator>leakon</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[phpDocumentor]]></category>

		<guid isPermaLink="false">http://www.leakon.com/?p=615</guid>
		<description><![CDATA[好久没写新东西了。
最近遇到很头疼的事，好多代码要维护，时间长了，自己写过的代码都想不起来。
要调用某个对象的方法，每次都要打开那个类定义的 PHP 文件，找到方法的定义部分，然后仔细看看参数列表才能想起来怎么用。
最麻烦的是，有时候想不起来那个方法是在哪个类里面定义的，必须得去代码根目录 grep ，然后等半天……
相对比的，我开发程序时，手边必备的几个文档：PHP手册、MySQL手册、HTML手册、CSS手册、Javascript手册，以及最近开始用的 ActionScript手册。这些都是 chm 版本的！
Chm 帮助文件有 2  [...]]]></description>
			<content:encoded><![CDATA[<p>好久没写新东西了。</p>
<p>最近遇到很头疼的事，好多代码要维护，时间长了，自己写过的代码都想不起来。</p>
<p>要调用某个对象的方法，每次都要打开那个类定义的 PHP 文件，找到方法的定义部分，然后仔细看看参数列表才能想起来怎么用。</p>
<p>最麻烦的是，有时候想不起来那个方法是在哪个类里面定义的，必须得去代码根目录 grep ，然后等半天……</p>
<p>相对比的，我开发程序时，手边必备的几个文档：PHP手册、MySQL手册、HTML手册、CSS手册、Javascript手册，以及最近开始用的 ActionScript手册。这些都是 chm 版本的！</p>
<p>Chm 帮助文件有 2 个最大的好处，一个是索引，另一个是全文检索。</p>
<p>用索引可以一边输入，一边过滤掉不匹配的关键词，迅速定位到想要的那个函数名。</p>
<p>当不知道关键词是什么的时候，可以用 like 语句在 chm 文件里面的每一句话中匹配关键词。</p>
<p>原本，用 Zend Studio 也有代码提示和自动完成，不过这个用 Java 虚拟机运行的 IDE 实在是慢，受不了，也不习惯。</p>
<p>今天花了好长时间，研究 php 文档生成工具，找到了几个，主要都是生成 html 页面的，而且格式很难看，重要的是没有好用的索引，更没有全文搜索，没意思。</p>
<p>PhpDocumentor 支持 chm 生成，这个让我眼前一亮！</p>
<p>简单看了下官方文档，然后就下载了 zip 格式的压缩包，就是这个压缩包，浪费了我好长时间去调试错误！！</p>
<p>设定好 php 源码路径，再设置文档格式，选择 chm，输出了一堆文件，包含 hhc，hhp 等，这些是 chm 的“源码”，需要用 Windows 自带的 HTML Help WorkShop 进行编译，然后才能生成 chm。</p>
<p>而那个 zip 压缩包，居然是有严重 bug 的版本，生成的 hhc 文件，里面有一行错误代码，提示 contents.hhc.tpl 找不到！！！</p>
<p>最开始我没有意识到问题在这里，只是用 WorkShop 反复编译那堆 hhc 文件，总是不成功！我都有放弃的念头了。</p>
<p>后来仔细看错误提示，好像是 hhc 文件的问题，打开一看，才知道是上述原因。</p>
<p>再去 phpDocument 源码里面找 contents.hhc.tpl，真的没有！不过，却有 contents.hhc.tp 这个文件！！！</p>
<p>然后列了下目录，几十个文件，大部分都是 tpl 扩展名，而有几个文件是 tp！！！</p>
<p>靠！什么玩意儿，是程序员马虎了还是打包工具的问题？</p>
<p>重新下了个 tgz 版本的 phpDocument，问题全无，chm 编译顺利！</p>
<p>另外，默认编译的 chm 是不带搜索（全文检索）功能的，更改方式如下：</p>
<p>打开一个项目文件，单击“Project（项目）”选项卡的“Change project options（改变项目选项）”，在“Options（选项）”对话框的“Compiler（编译）”选项卡中选中“Compile Full Text Search Information（编译全文搜索信息）”即可。</p>
<p>附赠命令行范例：</p>
<p>$&gt; php phpdoc -o CHM:default:default -d ../lib/ -t ../docs/ &gt; ../php_doc.log</p>
]]></content:encoded>
			<wfw:commentRss>http://www.leakon.com/archives/615/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>CUrl 蜘蛛 优化 CURLOPT_HEADERFUNCTION</title>
		<link>http://www.leakon.com/archives/546?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=curl-%25e8%259c%2598%25e8%259b%259b-%25e4%25bc%2598%25e5%258c%2596-curlopt_headerfunction</link>
		<comments>http://www.leakon.com/archives/546#comments</comments>
		<pubDate>Thu, 26 Nov 2009 17:23:37 +0000</pubDate>
		<dc:creator>leakon</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[创新]]></category>
		<category><![CDATA[原创]]></category>
		<category><![CDATA[CUrl]]></category>

		<guid isPermaLink="false">http://www.leakon.com/?p=546</guid>
		<description><![CDATA[正搞一个小蜘蛛，用 CUrl 写的，遇到一个问题，分析完 url 后，有可能遇到 rar 或 jpg 等资源文件，也是要下载回来分析内容。
这样的做法太笨了，有很多缺点：

 浪费带宽，文件也许很大
 文件无用，下载回来也无法分析文件内容

怎么解决？
看浏览器会发送 Accept 指令，告诉服务器可接受的内容类型，但这不能阻止服务器返回不接受的内容，即哪怕请求的资源不在 Accept 列表中，仍然会把文件返回给客户端。
这方法不行。
想着，有没有办法，在得到服务器 response 的时候先分析 header，如果不是可接受的类型，就断掉连接，不必下载后续内容？
如果用 fsockopen  [...]]]></description>
			<content:encoded><![CDATA[<p>正搞一个小蜘蛛，用 CUrl 写的，遇到一个问题，分析完 url 后，有可能遇到 rar 或 jpg 等资源文件，也是要下载回来分析内容。</p>
<p>这样的做法太笨了，有很多缺点：</p>
<ol>
<li> 浪费带宽，文件也许很大</li>
<li> 文件无用，下载回来也无法分析文件内容</li>
</ol>
<p>怎么解决？</p>
<p>看浏览器会发送 Accept 指令，告诉服务器可接受的内容类型，但这不能阻止服务器返回不接受的内容，即哪怕请求的资源不在 Accept 列表中，仍然会把文件返回给客户端。</p>
<p>这方法不行。</p>
<p>想着，有没有办法，在得到服务器 response 的时候先分析 header，如果不是可接受的类型，就断掉连接，不必下载后续内容？</p>
<p>如果用 fsockopen 写的网络通讯接口，这一点很好实现。但 CUrl 怎么控制？</p>
<p>仔细看文档，找到一个选项 CURLOPT_HEADERFUNCTION。</p>
<p>这个选项要给一个回调函数作为参数，回调函数相当于一个触发器，CUrl 会把每一条 response 的 header 指令传给这个函数，由函数来决定如何执行后面的步骤。</p>
<p>回调函数要定义 2 个参数，第 1 个是 CUrl 的资源标识符，第 2 个是单独的一条 header 字符串。</p>
<p>如果想让 CUrl 继续下载后续内容，那么回调函数应该返回 header 字符串的长度：</p>
<p>return strlen($strOneHeader);</p>
<p>如果不想继续下载，直接返回数字 0，那么 CUrl 就会发送 TCP 的终止连接的指令，不会继续下载后续内容了。</p>
<p>加上这个触发器，经过测试，我的小蜘蛛可以成功地忽略非 text/html 类型的文件，大大加快了抓取速度，避免了很多问题！</p>
<p>小提示，给 CURLOPT_HEADERFUNCTION 设置回调函数的时候，文档上说要一个字符串形式的函数名作为参数。</p>
<p>这不准确。</p>
<p>实际上 PHP 可以指定任意类型的回调函数，可以是纯函数、类的静态方法和对象的方法：</p>
<ul>
<li> 纯函数：$callback = &#8216;my_callback_func&#8217;;</li>
<li> 类常量：$callback = array(&#8216;NAME_OF_CLASS&#8217;, &#8216;nameOfMethod&#8217;);</li>
<li> 对象方法：$callback = array($object, &#8216;publicMethod&#8217;);</li>
</ul>
<p>完。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.leakon.com/archives/546/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>类常量 字符串 对比 性能测试</title>
		<link>http://www.leakon.com/archives/538?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=%25e7%25b1%25bb%25e5%25b8%25b8%25e9%2587%258f-%25e5%25ad%2597%25e7%25ac%25a6%25e4%25b8%25b2-%25e5%25af%25b9%25e6%25af%2594-%25e6%2580%25a7%25e8%2583%25bd%25e6%25b5%258b%25e8%25af%2595</link>
		<comments>http://www.leakon.com/archives/538#comments</comments>
		<pubDate>Thu, 26 Nov 2009 02:54:05 +0000</pubDate>
		<dc:creator>leakon</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[原创]]></category>

		<guid isPermaLink="false">http://www.leakon.com/?p=538</guid>
		<description><![CDATA[写一个处理 url 的 PHP 工具类，需要用到很多字符串相关的函数，比如 preg_match、preg_replace、strpos 之类的。
正则表达式和查找的 needle 字符，都是用字符加引号直接作为参数传递给上述函数，比如：
preg_match(&#8220;#^http[s]?://#i&#8221;, $strUrl);
用以匹配是否是 http 开头的 url。
记得以前看过过类常量与普通常量的性能对比，类常量快得多，在这个例子上，把字符串传给函数，是不是每次调用都是先把字符串转换成内部变量呢？如果预先定义类常量，然后以常量为参数传给函数，是不是能快一点？像下面这样：
const  [...]]]></description>
			<content:encoded><![CDATA[<p>写一个处理 url 的 PHP 工具类，需要用到很多字符串相关的函数，比如 preg_match、preg_replace、strpos 之类的。</p>
<p>正则表达式和查找的 needle 字符，都是用字符加引号直接作为参数传递给上述函数，比如：</p>
<p>preg_match(&#8220;#^http[s]?://#i&#8221;, $strUrl);</p>
<p>用以匹配是否是 http 开头的 url。</p>
<p>记得以前看过过类常量与普通常量的性能对比，类常量快得多，在这个例子上，把字符串传给函数，是不是每次调用都是先把字符串转换成内部变量呢？如果预先定义类常量，然后以常量为参数传给函数，是不是能快一点？像下面这样：</p>
<p>const PREG_HTTP_URL = &#8216;#^http[s]?://#i&#8217;;</p>
<p>preg_match(self::PREG_HTTP_URL, $strUrl);</p>
<p>两种方式，性能肯定不一样，那种更快呢？</p>
<p>&#8230;</p>
<p>&#8230;</p>
<p>&#8230;</p>
<p>揭晓结果：</p>
<p>运行外层方法 50 万次各 3 次，取平均值<br />
字符串：[31284.85]q/s    [15.98]seconds<br />
类常量：[29175.49]q/s    [17.14]seconds</p>
<p>可以看到，用类常量的方式，性能不升反降！！</p>
<p>现在还不太理解为什么会这样。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.leakon.com/archives/538/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>xdebug xampp profiler 真是背到家了</title>
		<link>http://www.leakon.com/archives/533?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=xdebug-xampp-profiler-%25e7%259c%259f%25e6%2598%25af%25e8%2583%258c%25e5%2588%25b0%25e5%25ae%25b6%25e4%25ba%2586</link>
		<comments>http://www.leakon.com/archives/533#comments</comments>
		<pubDate>Wed, 18 Nov 2009 15:31:04 +0000</pubDate>
		<dc:creator>leakon</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[xampp]]></category>
		<category><![CDATA[xdebug]]></category>

		<guid isPermaLink="false">http://www.leakon.com/?p=533</guid>
		<description><![CDATA[我在Windows环境开发PHP，用XAMPP套件，今天追查程序，看源码搞不定，求助xdebug。
想来很简单，不就在php.ini开启几个选项么，奶奶的，折腾半天没搞定！
问题是：不管怎么设置，开启，就是不输出 profiler 文件！
在网上看人家配置xdebug咋就那么顺利呢，我咋就这么费劲呢？
用中文关键字搜不到，试试英文的吧。
然后找到这个：
http://www.apachefriends.org/f/viewtopic.php?f=16&#38;t=37137
这个天杀的 Wiedmann 估计是 ApacheFriends 的开发人员，把跟我一样可怜的 th1alb  [...]]]></description>
			<content:encoded><![CDATA[<p>我在Windows环境开发PHP，用XAMPP套件，今天追查程序，看源码搞不定，求助xdebug。</p>
<p>想来很简单，不就在php.ini开启几个选项么，奶奶的，折腾半天没搞定！</p>
<p>问题是：不管怎么设置，开启，就是不输出 profiler 文件！</p>
<p>在网上看人家配置xdebug咋就那么顺利呢，我咋就这么费劲呢？</p>
<p>用中文关键字搜不到，试试英文的吧。</p>
<p>然后找到这个：</p>
<p><a href="http://www.apachefriends.org/f/viewtopic.php?f=16&amp;t=37137">http://www.apachefriends.org/f/viewtopic.php?f=16&amp;t=37137</a></p>
<p>这个天杀的 Wiedmann 估计是 ApacheFriends 的开发人员，把跟我一样可怜的 th1alb 兄弟害得够惨，2 个小时啊！！！</p>
<p>一切的根源居然是 Wiedmann 这怂儿把错误的配置参数包含到了 php.ini ，并打包到 xampp-1.7.2 的版本中！！！</p>
<p>我只能问候你母亲文明用语了！！！</p>
<p>给出问题解决方法，简单得要死：</p>
<p>把</p>
<p>xdebug.profiler_output_name = &#8220;xdebug_profile.%R::%u&#8221;</p>
<p>替换为</p>
<p>xdebug.profiler_output_name = &#8220;cachegrind.out.%p&#8221;</p>
<p>其实跟文件名前面的部分没关系，关键是那个&#8221;::&#8221;，Windows 不允许文件名中出现 &#8220;:&#8221;，在Linux下居然可以用这个字符当文件名，怎一个强字了得！</p>
<p>我测了下，Windows下&#8221;%R&#8221;这个占位符无效，所以，我是这么改的：</p>
<p>xdebug.profiler_output_name = &#8220;xdebug_profile.%u&#8221;</p>
<p>哦了，但愿后来的同学们能早点搜到，别再浪费宝贵的时间了！</p>
]]></content:encoded>
			<wfw:commentRss>http://www.leakon.com/archives/533/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>XAMPP PHP Pecl Extension MemCache</title>
		<link>http://www.leakon.com/archives/529?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=xampp-php-pecl-extension-memcache</link>
		<comments>http://www.leakon.com/archives/529#comments</comments>
		<pubDate>Tue, 17 Nov 2009 15:22:01 +0000</pubDate>
		<dc:creator>leakon</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[CentOS]]></category>
		<category><![CDATA[MemCache]]></category>
		<category><![CDATA[PECL]]></category>
		<category><![CDATA[phpize]]></category>

		<guid isPermaLink="false">http://www.leakon.com/?p=529</guid>
		<description><![CDATA[问题：用 xampp 套件的 php 测试程序，程序中用到了 memcache，xampp 中未编译这个 extension，因此无法运行。
如果为了 memcache，重新编译 Apache、PHP 和 MySQL，太费时间，没有收获，而且重要的是逃避了问题，没有解决。
这回找到了解决方法，可以用此方法编译其他 PECL 的 PHP Extension，使 xampp 的 PHP 有更多功能！
闲言少叙，直奔主题：给 xampp 套件的 PHP 安装 memcache 扩展。
流程：
下载 http://pecl.php.net/get/memcache-2.2.5.tgz，得到最新的  [...]]]></description>
			<content:encoded><![CDATA[<p>问题：用 xampp 套件的 php 测试程序，程序中用到了 memcache，xampp 中未编译这个 extension，因此无法运行。</p>
<p>如果为了 memcache，重新编译 Apache、PHP 和 MySQL，太费时间，没有收获，而且重要的是逃避了问题，没有解决。</p>
<p>这回找到了解决方法，可以用此方法编译其他 PECL 的 PHP Extension，使 xampp 的 PHP 有更多功能！</p>
<p>闲言少叙，直奔主题：给 xampp 套件的 PHP 安装 memcache 扩展。</p>
<p>流程：</p>
<p>下载 http://pecl.php.net/get/memcache-2.2.5.tgz，得到最新的 PHP memcache PECL extension。</p>
<p>解压后，是一些源码，不能直接 configure 和 make。</p>
<p>config9.m4  CREDITS      memcache_consistent_hash.c  memcache_queue.c    memcache_standard_hash.c<br />
config.m4   example.php  memcache.dsp                memcache_queue.h    php_memcache.h<br />
config.w32  memcache.c   memcache.php                memcache_session.c  README</p>
<p>需要先用 phpize 配置一下，不过，我这次并不是平常的 phpize，因为我在 VMware 的 CentOS 上用的是 xampp 的集成环境，用这个环境下的 phpize 会提示缺少文件。</p>
<p>[leakon memcache-2.2.5]$ /opt/lampp/bin/phpize<br />
grep: /opt/lampp/include/php/main/php.h: No such file or directory<br />
grep: /opt/lampp/include/php/Zend/zend_modules.h: No such file or directory<br />
grep: /opt/lampp/include/php/Zend/zend_extensions.h: No such file or directory<br />
Configuring for:<br />
PHP Api Version:<br />
Zend Module Api No:<br />
Zend Extension Api No:</p>
<p>提示缺少 3 个文件，这些文件在 xampp 中都没有，因为 xampp 提供的是运行环境，不是开发环境。</p>
<p>这样的目录结构（include/php/*）只有在安装好的 php 目录中才有，其实如果从源码直接复制更容易，不过那不是好方法。</p>
<p>下一个新版 PHP 源码，本地编译安装。</p>
<p>下载 http://cn2.php.net/get/php-5.2.11.tar.gz/from/cn.php.net/mirror。</p>
<p>configure 的时候不必跟上很多参数，我们只是要一个目录结构，而且是目录里面的源码，扩展和模块什么的都无所谓，只要能编译即可。</p>
<p>编译完成后，找到安装路径 /home/leakon/local/php5，可以看到 include 目录及其下面的目录结构。</p>
<p>回到 lampp 目录，下面并没有 include 目录，那我们创建一个：</p>
<p>[leakon ~]$ cd /opt/lampp/<br />
[leakon lampp]$ mkdir include &amp;&amp; cd include<br />
[leakon include]$ ln -s /home/leakon/local/php5/include/php php</p>
<p>这样，建立一个指向 php 安装目录的符号链接。</p>
<p>再回到 memcache-2.2.5 源码目录，重新配置：</p>
<p>[leakon memcache-2.2.5]$ /opt/lampp/bin/phpize<br />
Configuring for:<br />
PHP Api Version:         20041225<br />
Zend Module Api No:      20060613<br />
Zend Extension Api No:   220060519</p>
<p>然后可以 configure 了：</p>
<p>[leakon memcache-2.2.5]$ ./configure &#8211;prefix=/home/leakon/local/pecl-memcache &#8211;with-php-config=/opt/lampp/bin/php-config</p>
<p>完成后 make 就可以啦，再完成后，编译的 so 文件生成到了 memcache-2.2.5/modules 目录下，有 2 个：</p>
<p>memcache.la  memcache.so</p>
<p>memcache.so 是我们要用的。</p>
<p>然后，修改 php.ini，添加 extension=leakon-modules/memcache.so</p>
<p>这个过程，还有点小波折。</p>
<p>本来我把 memcache.so 放到了 /home/leakon/modules/ 下，然后设置 extension=&#8221;/home/leakon/modules/memcache.so&#8221;</p>
<p>结果用 php -m 找不到 memcache 模块。</p>
<p>我的 php 报错输出到单独的文件中，tail 那个文件，看到：</p>
<p>PHP Startup: Unable to load dynamic library &#8216;/opt/lampp/lib/php/extensions/no-debug-non-zts-20060613//home/leakon/modules/memcache.so&#8217;</p>
<p>原来是扩展的加载路径是相对的，不管你怎么设置，都在 /opt/lampp/lib/php/extensions/no-debug-non-zts-20060613/ 之下。</p>
<p>知道原因就好解决了，要么 cp memcache.so 到 no-debug-non-zts-20060613 目录下，要么做个 symbol link 链接到 /home/leakon/modules/，然后在 php.ini 修改正确的路径即可。</p>
<p>我记得很早写过一个编译 xdebug 的文章，刚才又看了一下，跟这回是一样的情况，也是在 xampp 的集成套件下编译 php extension。只是那次失败了，这次成功了。原文在这里：http://www.leakon.com/archives/44 。</p>
<p>搞了几个小时，总算时间没白费~~</p>
]]></content:encoded>
			<wfw:commentRss>http://www.leakon.com/archives/529/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>memcache PECL bug fix</title>
		<link>http://www.leakon.com/archives/525?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=google-docs-%25e8%25b0%25b7%25e6%25ad%258c%25e6%2596%2587%25e6%25a1%25a3-https-%25e8%25ae%25bf%25e9%2597%25ae-ssl-%25e5%258a%25a0%25e5%25af%2586</link>
		<comments>http://www.leakon.com/archives/525#comments</comments>
		<pubDate>Fri, 13 Nov 2009 02:37:31 +0000</pubDate>
		<dc:creator>leakon</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[MemCache]]></category>
		<category><![CDATA[PECL]]></category>

		<guid isPermaLink="false">http://www.leakon.com/?p=525</guid>
		<description><![CDATA[使用 memcache 的过程中，遇到一个奇怪的问题，在 CentOS 环境下，PHP 的 memcache 扩展创建的客户端对象，在 delete 一个 key 的时候报错：
[25-Nov-2009 13:57:04] PHP Notice:  Memcache::delete(): Server 192.168.10.131 (tcp 11211) failed with: CLIENT_ERROR bad command line format.  Usage: delete &#60;key&#62; [noreply]
可是在 Windows 环境下，用的人家编译好的  [...]]]></description>
			<content:encoded><![CDATA[<p>使用 memcache 的过程中，遇到一个奇怪的问题，在 CentOS 环境下，PHP 的 memcache 扩展创建的客户端对象，在 delete 一个 key 的时候报错：</p>
<p>[25-Nov-2009 13:57:04] PHP Notice:  Memcache::delete(): Server 192.168.10.131 (tcp 11211) failed with: CLIENT_ERROR bad command line format.  Usage: delete &lt;key&gt; [noreply]</p>
<p>可是在 Windows 环境下，用的人家编译好的 <a title="memcache PECL extension" href="http://down.leakon.com/200911/php_memcache-cvs-20090703-5.3-VC6-x86.zip">php_memcache-cvs-20090703-5.3-VC6-x86.dll</a> (20KB) 却没问题！</p>
<p>在 Google 上找了半天，终于在 PHP 官方手册的评论中发现了线索：</p>
<p><a href="http://php.net/manual/en/function.memcache-delete.php">http://php.net/manual/en/function.memcache-delete.php</a></p>
<p>请看 10-Nov-2009 11:17 这条，简短翻译一下：</p>
<p>memcache 这个 PECL 扩展的 2.2.5 稳定版本有一个错误，导致在向 memcached 1.4.3 调用 delete 方法时返回 false。</p>
<p>用 -vvv 模式运行 memcached 将显示出为什么 delete 调用失败：</p>
<p>CLIENT_ERROR bad command line format.  Usage: delete &lt;key&gt; [noreply]</p>
<p>简单修改一下，在这个 PECL 扩展的 memcache.c 这个文件的 1494 行的 mmc_delete() 函数中。把 command_len 修改为下面这样：</p>
<p>command_len = spprintf(&amp;command, 0, &#8220;delete %s&#8221;, key);</p>
<p>去掉了弃用的第 3 个参数，然后 delete 就可以工作了。希望这个可以帮到你！</p>
<p>再提示一下改动前的代码：</p>
<p>//  command_len = spprintf(&amp;command, 0, &#8220;delete %s %d&#8221;, key, time);</p>
<p>修改完成后，重新编译出 memcache.so 即可。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.leakon.com/archives/525/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Windows PHP dirname root</title>
		<link>http://www.leakon.com/archives/521?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=windows-php-dirname-root</link>
		<comments>http://www.leakon.com/archives/521#comments</comments>
		<pubDate>Thu, 05 Nov 2009 12:05:53 +0000</pubDate>
		<dc:creator>leakon</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[原创]]></category>
		<category><![CDATA[UnitTest]]></category>

		<guid isPermaLink="false">http://www.leakon.com/?p=521</guid>
		<description><![CDATA[遇到奇怪的问题，在 Windows 环境下，你猜 dirname(&#8216;/&#8217;) 返回虾米？
string(1) &#8220;\&#8221;
Linux 下呢？
string(1) &#8220;/&#8221;
换个参数，dirname(&#8216;/home/leakon/sofav.php&#8217;)，如果你认为上面的不同，是因为 Windows 的目录分隔符是反斜线 &#8220;\&#8221;，那下面的结果如何解释？
Windows: string(12) &#8220;/home/leakon&#8221;
Linux: string(12)  [...]]]></description>
			<content:encoded><![CDATA[<p>遇到奇怪的问题，在 Windows 环境下，你猜 dirname(&#8216;/&#8217;) 返回虾米？</p>
<p>string(1) &#8220;\&#8221;</p>
<p>Linux 下呢？</p>
<p>string(1) &#8220;/&#8221;</p>
<p>换个参数，dirname(&#8216;/home/leakon/sofav.php&#8217;)，如果你认为上面的不同，是因为 Windows 的目录分隔符是反斜线 &#8220;\&#8221;，那下面的结果如何解释？</p>
<p>Windows: string(12) &#8220;/home/leakon&#8221;</p>
<p>Linux: string(12) &#8220;/home/leakon&#8221;</p>
<p>再换参数，dirname(&#8216;D:\Leakon\Code\sofav.php&#8217;)</p>
<p>Windows: string(14) &#8220;D:\Leakon\Code&#8221;</p>
<p>Linux: string(1) &#8220;.&#8221;</p>
<p>奇怪吧，为什么有这么大区别呢？</p>
<p>现在还不太清楚，提供一下我的测试环境：</p>
<p>Windows 下存在 D:\Leakon\Code\sofav.php 这个文件，Linux 下存在 /home/leakon/sofav.php。</p>
<p>等搞明白回来顶，看到的，用到的，留心记一下吧。</p>
<p>顺便说下，这个问题，是用单元测试发现的。</p>
<p>我知道很多开发者都懂单元测试，我也知道很多开发者并没有切身去实践单元测试。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.leakon.com/archives/521/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

