<?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>潘少宁的博客 &#187; PHP开发</title>
	<atom:link href="http://www.gosoa.com.cn/category/php%e5%bc%80%e5%8f%91/feed" rel="self" type="application/rss+xml" />
	<link>http://www.gosoa.com.cn</link>
	<description>专注于高性能LAMP架构分析与实践</description>
	<lastBuildDate>Tue, 07 Feb 2012 10:12:10 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>http_build_query 的一个问题</title>
		<link>http://www.gosoa.com.cn/http_build_query-%e7%9a%84%e4%b8%80%e4%b8%aa%e9%97%ae%e9%a2%98</link>
		<comments>http://www.gosoa.com.cn/http_build_query-%e7%9a%84%e4%b8%80%e4%b8%aa%e9%97%ae%e9%a2%98#comments</comments>
		<pubDate>Mon, 06 Feb 2012 10:25:01 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[PHP开发]]></category>
		<category><![CDATA[http_build_query]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.gosoa.com.cn/?p=628</guid>
		<description><![CDATA[当我们使用CURL来post数据的时候，需要设置post的数据 curl_setopt($c, CURLOPT_POSTFIELDS, $post_data); 假如这里的$data是 $data = array( 'name'=>'scofield', 'time'=>'2012-2-3' ) 接下来，需要先将$data变成字符串 $post_data = http_build_query($data); 而采用 http_build_query 转换后再 curl_setopt($c, CURLOPT_POSTFIELDS, $post_data); 看起来没有什么问题。但在实际操作中，$post_data 并没有被post过去。于是，自己写了个转换的方法后就OK了。 function getStr($array,$Separator='&#038;') { if (empty($array)) return; if (!is_array($array)) { return $array; } $returnStr = ''; foreach ($array as $key => $val) { $temp = ''; if (is_array($val)) { for ($i = 0; [...]]]></description>
			<content:encoded><![CDATA[<p>当我们使用CURL来post数据的时候，需要设置post的数据<br />
curl_setopt($c, CURLOPT_POSTFIELDS, $post_data);</p>
<p>假如这里的$data是</p>
<pre name="php">
$data = array(
   'name'=>'scofield',
   'time'=>'2012-2-3'
)
</pre>
<p>接下来，需要先将$data变成字符串<br />
$post_data =  http_build_query($data);<br />
而采用 http_build_query 转换后再<br />
curl_setopt($c, CURLOPT_POSTFIELDS, $post_data); </p>
<p>看起来没有什么问题。但在实际操作中，$post_data 并没有被post过去。于是，自己写了个转换的方法后就OK了。</p>
<pre name="php">
 function getStr($array,$Separator='&#038;') {
        if (empty($array))
            return;
        if (!is_array($array)) {
            return $array;
        }
        $returnStr = '';
        foreach ($array as $key => $val) {
            $temp = '';
            if (is_array($val)) {
                for ($i = 0; $i < count($val); $i++) {
                    $returnStr .= $key . '[' . $i . ']' . '=' . $val[$i] . $Separator;
                }
            } else {
                $returnStr.= $key . '=' . $val . $Separator;
            }
        }
        $returnStr = substr(trim($returnStr), 0, -1);
        return $returnStr;
    }
</pre>
<p></p>
<p><b>感谢 黄斌-huangbin  童鞋的测试   http_build_query($data,"","&#038;");  即可，无需自己写方法解析了。</b></p>
<p></p>
]]></content:encoded>
			<wfw:commentRss>http://www.gosoa.com.cn/http_build_query-%e7%9a%84%e4%b8%80%e4%b8%aa%e9%97%ae%e9%a2%98/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>一个有意思的日期逻辑处理</title>
		<link>http://www.gosoa.com.cn/%e4%b8%80%e4%b8%aa%e6%9c%89%e6%84%8f%e6%80%9d%e7%9a%84%e6%97%a5%e6%9c%9f%e9%80%bb%e8%be%91%e5%a4%84%e7%90%86</link>
		<comments>http://www.gosoa.com.cn/%e4%b8%80%e4%b8%aa%e6%9c%89%e6%84%8f%e6%80%9d%e7%9a%84%e6%97%a5%e6%9c%9f%e9%80%bb%e8%be%91%e5%a4%84%e7%90%86#comments</comments>
		<pubDate>Tue, 19 Jul 2011 09:39:57 +0000</pubDate>
		<dc:creator>scofield</dc:creator>
				<category><![CDATA[PHP开发]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.gosoa.com.cn/?p=617</guid>
		<description><![CDATA[今天处理了一个很小的问题。
需求是这样的，从周一到周日只能看到上周一到上周日的数据。
这里直接从数据库里根据 date 字段查询 范围即可。
但需要PHP生成 开始日期和结束日期。

最开始，我直接这么处理。
<pre name="code" class="php">
$start_date = date('Y-m-d' , strtotime("-2 week monday"));
$end_date = date('Y-m-d' , strtotime("$start_date +6 day"));
</pre>
假如日期是 2011-07-19，$start_date= 2011-07-11  这样处理没有问题。
如果日期是  2011-07-18 ，$start_date 则会等于 2011-07-04，还活在上周。]]></description>
			<content:encoded><![CDATA[<p>今天处理了一个很小的问题。<br />
需求是这样的，从周一到周日只能看到上周一到上周日的数据。<br />
这里直接从数据库里根据 date 字段查询 范围即可。<br />
但需要PHP生成 开始日期和结束日期。</p>
<p>最开始，我直接这么处理。</p>
<pre name="code" class="php">
$start_date = date('Y-m-d' , strtotime("-2 week monday"));
$end_date = date('Y-m-d' , strtotime("$start_date +6 day"));
</pre>
<p>假如日期是 2011-07-19，$start_date= 2011-07-11  这样处理没有问题。<br />
如果日期是  2011-07-18 ，$start_date 则会等于 2011-07-04，还活在上周。</p>
<p>于是换了种方法</p>
<pre name="code" class="php">
$getWeekDay = date("w");
$startDay = date("Y-m-d", mktime(0, 0, 0, date("m"), date("d") - $getWeekDay + 1 - 7, date("Y")));
$endDay = date("Y-m-d", strtotime("+6 day $startDay"));
</pre>
<p>假如日期是 2011-07-19，$start_date= 2011-07-11  这样处理没有问题，和我们期望的一样。<br />
如果日期是 2011-07-24，我们期望的  $start_date 是 2011-07-11，但实际返回的是 2011-07-18。</p>
<p>不得已，我再改了下方法</p>
<pre name="code" class="php">
$getWeekDay = date("N") ;
$startDay = date("Y-m-d", mktime(0, 0, 0, date("m"), date("d") - $getWeekDay + 1 - 7, date("Y")));
$endDay = date("Y-m-d", strtotime("+6 day $startDay"));
</pre>
<p>这下就OK 了。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gosoa.com.cn/%e4%b8%80%e4%b8%aa%e6%9c%89%e6%84%8f%e6%80%9d%e7%9a%84%e6%97%a5%e6%9c%9f%e9%80%bb%e8%be%91%e5%a4%84%e7%90%86/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>PHP用CURL伪造IP和来源</title>
		<link>http://www.gosoa.com.cn/php%e7%94%a8curl%e4%bc%aa%e9%80%a0ip%e5%92%8c%e6%9d%a5%e6%ba%90</link>
		<comments>http://www.gosoa.com.cn/php%e7%94%a8curl%e4%bc%aa%e9%80%a0ip%e5%92%8c%e6%9d%a5%e6%ba%90#comments</comments>
		<pubDate>Tue, 19 Jul 2011 09:09:02 +0000</pubDate>
		<dc:creator>scofield</dc:creator>
				<category><![CDATA[PHP开发]]></category>
		<category><![CDATA[CURL]]></category>

		<guid isPermaLink="false">http://www.gosoa.com.cn/?p=614</guid>
		<description><![CDATA[以前没有这么搞过。

今天群里一个朋友在问这个问题。

查了下，CURL确实很强悍的可以伪造IP和来源。

1.php 请求 2.php 。

1.php代码：]]></description>
			<content:encoded><![CDATA[<p>以前没有这么搞过。</p>
<p>今天群里一个朋友在问这个问题。</p>
<p>查了下，CURL确实很强悍的可以伪造IP和来源。</p>
<p>1.php 请求 2.php 。</p>
<p>1.php代码：</p>
<pre name="code" class="php">

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://localhost/2.php");
curl_setopt($ch, CURLOPT_HTTPHEADER, array('X-FORWARDED-FOR:8.8.8.8', 'CLIENT-IP:8.8.8.8'));  //构造IP
curl_setopt($ch, CURLOPT_REFERER, "http://www.gosoa.com.cn/ ");   //构造来路
curl_setopt($ch, CURLOPT_HEADER, 1);
$out = curl_exec($ch);
curl_close($ch);
</pre>
<p>2.php代码如下：</p>
<pre name="code" class="php">

function getClientIp() {
    if (!empty($_SERVER["HTTP_CLIENT_IP"]))
        $ip = $_SERVER["HTTP_CLIENT_IP"];
    else if (!empty($_SERVER["HTTP_X_FORWARDED_FOR"]))
        $ip = $_SERVER["HTTP_X_FORWARDED_FOR"];
    else if (!empty($_SERVER["REMOTE_ADDR"]))
        $ip = $_SERVER["REMOTE_ADDR"];
    else
        $ip = "err";
    return $ip;
}

echo "IP: " . getClientIp() . "";
echo "referer: " . $_SERVER["HTTP_REFERER"];
</pre>
<p>伪造成功，这是不是给“刷票”的朋友提供了很好的换IP的方案！！<br />
哈哈。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gosoa.com.cn/php%e7%94%a8curl%e4%bc%aa%e9%80%a0ip%e5%92%8c%e6%9d%a5%e6%ba%90/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>优化PHP代码的40条建议[转]</title>
		<link>http://www.gosoa.com.cn/%e4%bc%98%e5%8c%96php%e4%bb%a3%e7%a0%81%e7%9a%8440%e6%9d%a1%e5%bb%ba%e8%ae%ae%e8%bd%ac</link>
		<comments>http://www.gosoa.com.cn/%e4%bc%98%e5%8c%96php%e4%bb%a3%e7%a0%81%e7%9a%8440%e6%9d%a1%e5%bb%ba%e8%ae%ae%e8%bd%ac#comments</comments>
		<pubDate>Fri, 01 Jul 2011 09:41:53 +0000</pubDate>
		<dc:creator>scofield</dc:creator>
				<category><![CDATA[PHP开发]]></category>
		<category><![CDATA[PHP优化]]></category>

		<guid isPermaLink="false">http://www.gosoa.com.cn/?p=603</guid>
		<description><![CDATA[1.如果一个方法可静态化，就对它做静态声明。速率可提升至4倍。

2.echo 比 print 快。

3.使用echo的多重参数（译注：指用逗号而不是句点）代替字符串连接。

4.在执行for循环之前确定最大循环数，不要每循环一次都计算最大值。

5.注销那些不用的变量尤其是大数组，以便释放内存。

6.尽量避免使用__get，__set，__autoload。]]></description>
			<content:encoded><![CDATA[<p>1.如果一个方法可静态化，就对它做静态声明。速率可提升至4倍。</p>
<p>2.echo 比 print 快。</p>
<p>3.使用echo的多重参数（译注：指用逗号而不是句点）代替字符串连接。</p>
<p>4.在执行for循环之前确定最大循环数，不要每循环一次都计算最大值。</p>
<p>5.注销那些不用的变量尤其是大数组，以便释放内存。</p>
<p>6.尽量避免使用__get，__set，__autoload。</p>
<p>7.require_once()代价昂贵。</p>
<p>8.在包含文件时使用完整路径，解析操作系统路径所需的时间会更少。</p>
<p>9.如果你想知道脚本开始执行（译注：即服务器端收到客户端请求）的时刻，使用$_SERVER[‘REQUEST_TIME’]要好于time()。</p>
<p>10.函数代替正则表达式完成相同功能。</p>
<p>11.str_replace函数比preg_replace函数快，但strtr函数的效率是str_replace函数的四倍。</p>
<p>12.如果一个字符串替换函数，可接受数组或字符作为参数，并且参数长度不太长，那么可以考虑额外写一段替换代码，使得每次传递参数是一个字符，而不是只写一行代码接受数组作为查询和替换的参数。</p>
<p>13.使用选择分支语句（译注：即switch case）好于使用多个if，else if语句。</p>
<p>14.用@屏蔽错误消息的做法非常低效。</p>
<p>15.打开apache的mod_deflate模块。</p>
<p>16.数据库连接当使用完毕时应关掉。</p>
<p>17.$row[‘id’]的效率是$row[id]的7倍。</p>
<p>18.错误消息代价昂贵。</p>
<p>19.尽量不要在for循环中使用函数，比如for ($x=0; $x &lt; count($array); $x)每循环一次都会调用count()函数。</p>
<p>20.在方法中递增局部变量，速度是最快的。几乎与在函数中调用局部变量的速度相当。</p>
<p>21.递增一个全局变量要比递增一个局部变量慢2倍。</p>
<p>22.递增一个对象属性（如：$this-&gt;prop++）要比递增一个局部变量慢3倍。</p>
<p>23.递增一个未预定义的局部变量要比递增一个预定义的局部变量慢9至10倍。</p>
<p>24.仅定义一个局部变量而没在函数中调用它，同样会减慢速度（其程度相当于递增一个局部变量）。PHP大概会检查看是否存在全局变量。</p>
<p>25.方法调用看来与类中定义的方法的数量无关，因为我（在测试方法之前和之后都）添加了10个方法，但性能上没有变化。</p>
<p>26.派生类中的方法运行起来要快于在基类中定义的同样的方法。</p>
<p>27.调用带有一个参数的空函数，其花费的时间相当于执行7至8次的局部变量递增操作。类似的方法调用所花费的时间接近于15次的局部变量递增操作。</p>
<p>28.用单引号代替双引号来包含字符串，这样做会更快一些。因为PHP会在双引号包围的字符串中搜寻变量，单引号则不会。当然，只有当你不需要在字符串中包含变量时才可以这么做。</p>
<p>29.输出多个字符串时，用逗号代替句点来分隔字符串，速度更快。注意：只有echo能这么做，它是一种可以把多个字符串当作参数的“函数”（译注：PHP手册中说echo是语言结构，不是真正的函数，故把函数加上了双引号）。</p>
<p>30.Apache解析一个PHP脚本的时间要比解析一个静态HTML页面慢2至10倍。尽量多用静态HTML页面，少用脚本。</p>
<p>31.除非脚本可以缓存，否则每次调用时都会重新编译一次。引入一套PHP缓存机制通常可以提升25%至100%的性能，以免除编译开销。</p>
<p>32.尽量做缓存，可使用memcached。memcached是一款高性能的内存对象缓存系统，可用来加速动态Web应用程序，减轻数据库负载。对运算码 (OP code)的缓存很有用，使得脚本不必为每个请求做重新编译。</p>
<p>33.当操作字符串并需要检验其长度是否满足某种要求时，你想当然地会使用strlen()函数。此函数执行起来相当快，因为它不做任何计算，只返回在zval 结构（C的内置数据结构，用于存储PHP变量）中存储的已知字符串长度。但是，由于strlen()是函数，多多少少会有些慢，因为函数调用会经过诸多步骤，如字母小写化（译注：指函数名小写化，PHP不区分函数名大小写）、哈希查找，会跟随被调用的函数一起执行。在某些情况下，你可以使用isset() 技巧加速执行你的代码。</p>
<p>（举例如下）<br />
if (strlen($foo) &lt; 5) { echo “Foo is too short”; }<br />
（与下面的技巧做比较）<br />
if (!isset($foo)) { echo “Foo is too short”; }</p>
<p>调用isset()恰巧比strlen()快，因为与后者不同的是，isset()作为一种语言结构，意味着它的执行不需要函数查找和字母小写化。也就是说，实际上在检验字符串长度的顶层代码中你没有花太多开销。</p>
<p>34.当执行变量$i的递增或递减时，$i++会比++$i慢一些。这种差异是PHP特有的，并不适用于其他语言，所以请不要修改你的C或Java代码并指望它们能立即变快，没用的。++$i更快是因为它只需要3条指令(opcodes)，$i++则需要4条指令。后置递增实际上会产生一个临时变量，这个临时变量随后被递增。而前置递增直接在原值上递增。这是最优化处理的一种，正如Zend的PHP优化器所作的那样。牢记这个优化处理不失为一个好主意，因为并不是所有的指令优化器都会做同样的优化处理，并且存在大量没有装配指令优化器的互联网服务提供商（ISPs）和服务器。</p>
<p>35.并不是事必面向对象(OOP)，面向对象往往开销很大，每个方法和对象调用都会消耗很多内存。</p>
<p>36.并非要用类实现所有的数据结构，数组也很有用。</p>
<p>37.不要把方法细分得过多，仔细想想你真正打算重用的是哪些代码？</p>
<p>38.当你需要时，你总能把代码分解成方法。</p>
<p>39.尽量采用大量的PHP内置函数。</p>
<p>40.如果在代码中存在大量耗时的函数，你可以考虑用C扩展的方式实现它们。</p>
<p>41.评估检验(profile)你的代码。检验器会告诉你，代码的哪些部分消耗了多少时间。Xdebug调试器包含了检验程序，评估检验总体上可以显示出代码的瓶颈。</p>
<p>42.mod_zip可作为Apache模块，用来即时压缩你的数据，并可让数据传输量降低80%。</p>
<p>原文地址： <a href="http://www.builder.com.cn/2008/0203/728680.shtml">http://www.builder.com.cn/2008/0203/728680.shtml</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.gosoa.com.cn/%e4%bc%98%e5%8c%96php%e4%bb%a3%e7%a0%81%e7%9a%8440%e6%9d%a1%e5%bb%ba%e8%ae%ae%e8%bd%ac/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP几个不常用但很有用的函数</title>
		<link>http://www.gosoa.com.cn/php%e5%87%a0%e4%b8%aa%e4%b8%8d%e5%b8%b8%e7%94%a8%e4%bd%86%e5%be%88%e6%9c%89%e7%94%a8%e7%9a%84%e5%87%bd%e6%95%b0</link>
		<comments>http://www.gosoa.com.cn/php%e5%87%a0%e4%b8%aa%e4%b8%8d%e5%b8%b8%e7%94%a8%e4%bd%86%e5%be%88%e6%9c%89%e7%94%a8%e7%9a%84%e5%87%bd%e6%95%b0#comments</comments>
		<pubDate>Wed, 29 Jun 2011 13:26:43 +0000</pubDate>
		<dc:creator>scofield</dc:creator>
				<category><![CDATA[PHP开发]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.gosoa.com.cn/?p=593</guid>
		<description><![CDATA[glob() 直接print_r(glob(&#8216;*&#8217;)) 看看效果吧。 再  print_r(glob(&#8216;*.PHP&#8217;)) 再看看效果吧。 &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;- PHP Filter函数 PHP自带的filter函数。直接可以用来验证email，IP等。也可以用来验证 INPUT等。 具体见这里 http://php.net/manual/en/book.filter.php &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;- get_browser() 获得浏览器信息的。 &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;- sys_getloadavg() 这个函数只针对linux系统有用。 可以用来监测系统的负载。 其值就是linux的 load average值。]]></description>
			<content:encoded><![CDATA[<ul>
<li><strong>glob()</strong></li>
</ul>
<p>直接print_r(glob(&#8216;*&#8217;)) 看看效果吧。</p>
<p>再  print_r(glob(&#8216;*.PHP&#8217;)) 再看看效果吧。</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-</p>
<ul>
<li><strong>PHP Filter函数</strong></li>
</ul>
<p><a href="http://php.net/manual/en/book.filter.php" target="_blank">PHP自带的filter函数</a>。直接可以用来验证email，IP等。也可以用来验证 INPUT等。</p>
<p>具体见这里 <a href="http://php.net/manual/en/book.filter.php">http://php.net/manual/en/book.filter.php</a></p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-</p>
<ul>
<li><strong>get_browser()</strong></li>
</ul>
<p>获得浏览器信息的。</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-</p>
<ul>
<li><strong>sys_getloadavg()</strong></li>
</ul>
<p>这个函数只针对linux系统有用。</p>
<p>可以用来监测系统的负载。 其值就是linux的 load average值。</p>
<p><strong><br />
</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://www.gosoa.com.cn/php%e5%87%a0%e4%b8%aa%e4%b8%8d%e5%b8%b8%e7%94%a8%e4%bd%86%e5%be%88%e6%9c%89%e7%94%a8%e7%9a%84%e5%87%bd%e6%95%b0/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>推荐一款开源的flashchart生成柱状图</title>
		<link>http://www.gosoa.com.cn/%e6%8e%a8%e8%8d%90%e4%b8%80%e6%ac%be%e5%bc%80%e6%ba%90%e7%9a%84flashchart%e7%94%9f%e6%88%90%e6%9f%b1%e7%8a%b6%e5%9b%be</link>
		<comments>http://www.gosoa.com.cn/%e6%8e%a8%e8%8d%90%e4%b8%80%e6%ac%be%e5%bc%80%e6%ba%90%e7%9a%84flashchart%e7%94%9f%e6%88%90%e6%9f%b1%e7%8a%b6%e5%9b%be#comments</comments>
		<pubDate>Mon, 27 Jun 2011 10:54:44 +0000</pubDate>
		<dc:creator>scofield</dc:creator>
				<category><![CDATA[PHP开发]]></category>
		<category><![CDATA[flashchart]]></category>
		<category><![CDATA[php生成饼图]]></category>

		<guid isPermaLink="false">http://www.gosoa.com.cn/?p=580</guid>
		<description><![CDATA[最近项目中需要生成类似excel的柱状图、饼图、趋势图等等。。。

网上google了一番，发现了 Open Flash Chart   地址：  http://teethgrinder.co.uk/open-flash-chart-2/ 。

非常好用的一款开源工具。目前最新版是2.0

--------------------------------------------------------------------------------

http://ofcgwt.googlecode.com/svn/demo/Demo.html 这里有很多示例可供参考。

不过不太推荐使用 googlecode上的这个示例代码，建议采用官方的示例代码和flash chart 。

flash chart的使用很简单。

如下示例：]]></description>
			<content:encoded><![CDATA[<p>最近项目中需要生成类似excel的柱状图、饼图、趋势图等等。。。</p>
<p>网上google了一番，发现了 Open Flash Chart   地址：  <a href="http://teethgrinder.co.uk/open-flash-chart-2/">http://teethgrinder.co.uk/open-flash-chart-2/</a> 。</p>
<p>非常好用的一款开源工具。目前最新版是2.0</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;</p>
<p><a href="http://ofcgwt.googlecode.com/svn/demo/Demo.html">http://ofcgwt.googlecode.com/svn/demo/Demo.html</a> 这里有很多示例可供参考。</p>
<p>不过不太推荐使用 googlecode上的这个示例代码，建议采用官方的示例代码和flash chart 。</p>
<p>flash chart的使用很简单。</p>
<p>如下示例：</p>
<pre name="code" class="js">//url形式
function embSwfWithUrl(dataurl,divcon){
     var params = {
        "wmode": "transparent",
        "menu": "false",
        "scale": "noScale",
        "allowFullscreen": "false",
        "allowScriptAccess": "always",
        "bgcolor": "#c0c0c0"  //背景
    };
    var flashvars = {
        'data-file' : dataurl
    };
    swfobject.embedSWF("/swf/open-flash-chart.swf?timestamp=" + Math.random(),divcon, "450", "300", "10.0.0", "./swf/expressInstall.swf" ,flashvars,params);
}

embSwfWithUrl('http://xxx.com/xxx.html','swfCon');</pre>
<p>这里的http://xxx.com/xxx.html返回的是相应的json格式的数据。</p>
<p>swfCon是放flash的div容器。</p>
<p>swfobject是开源的js处理flash的类。<a href="http://code.google.com/p/swfobject/">http://code.google.com/p/swfobject/</a></p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;</p>
<p>注意下，flash chart 获得数据的方式有两种，</p>
<p>一种是   data-file  一种是 get-data</p>
<p>data-file 正是如上示例，值必须是个 url地址，里面返回的是 json数据。</p>
<p>而get-data的值则是一个函数名称。 函数返回 json 数据。</p>
<p>如下示例：</p>
<pre name="code" class="js">//get-data
function embSwfWithData(divcon,getdataFn){
    var params = {
        "wmode": "transparent",  //窗口模式
        "menu": "false",  //菜单显示
        "scale": "noScale",  //缩放
        "allowFullscreen": "false", //允许全屏
        "allowScriptAccess": "always",  //允许脚本
        "bgcolor": "#c0c0c0"  //背景
    };
var flashVar = {
 "get-data":getdataFn
};
    swfobject.embedSWF("/swf/open-flash-chart.swf?timestamp=" + Math.random(), divcon, "450", "300", "10", "/swf/expressInstall.swf",flashVar  ,params);
}

function getJsonData(){
return 'json data';
}</pre>
<p>这里 “get-data”:getdataFn 需要传递的就是一个函数名称。函数中返回json数据。</p>
<p>还有一点需要注意下，/swf/open-flash-chart.swf?timestamp=+Math.random() .</p>
<p>这里之所以加随机数，是因为有的浏览器在缓存flash后，使其flash参数失效了。加上随机数后，每次浏览器会重新加载flash。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gosoa.com.cn/%e6%8e%a8%e8%8d%90%e4%b8%80%e6%ac%be%e5%bc%80%e6%ba%90%e7%9a%84flashchart%e7%94%9f%e6%88%90%e6%9f%b1%e7%8a%b6%e5%9b%be/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP导出excel</title>
		<link>http://www.gosoa.com.cn/php%e5%af%bc%e5%87%baexcel</link>
		<comments>http://www.gosoa.com.cn/php%e5%af%bc%e5%87%baexcel#comments</comments>
		<pubDate>Mon, 27 Jun 2011 10:23:07 +0000</pubDate>
		<dc:creator>scofield</dc:creator>
				<category><![CDATA[PHP开发]]></category>
		<category><![CDATA[PHPExcel]]></category>
		<category><![CDATA[PHP生成EXcel]]></category>

		<guid isPermaLink="false">http://www.gosoa.com.cn/?p=573</guid>
		<description><![CDATA[最近做一个项目，其中涉及到了数据导成excel的功能。

后来使用了 开源的 PHPExcel  <a href="http://phpexcel.codeplex.com/">http://phpexcel.codeplex.com/</a> 目前最新版是1.7.6

PHPExcel 可以生成 .xls 和 .xlsx （office2007）。其封装的方法很全了。

比如设置 excel的title，keywords,description

获得某个sheet，某个列的数据 等等。

具体的文档，查看这里，<a href="http://phpexcel.codeplex.com/releases/view/45412">http://phpexcel.codeplex.com/releases/view/45412</a> 非常详细。

下面是一段简单的示例。]]></description>
			<content:encoded><![CDATA[<p>最近做一个项目，其中涉及到了数据导成excel的功能。</p>
<p>后来使用了 开源的 PHPExcel  <a href="http://phpexcel.codeplex.com/">http://phpexcel.codeplex.com/</a> 目前最新版是1.7.6</p>
<p>PHPExcel 可以生成 .xls 和 .xlsx （office2007）。其封装的方法很全了。</p>
<p>比如设置 excel的title，keywords,description</p>
<p>获得某个sheet，某个列的数据 等等。</p>
<p>具体的文档，查看这里，<a href="http://phpexcel.codeplex.com/releases/view/45412">http://phpexcel.codeplex.com/releases/view/45412</a> 非常详细。</p>
<p>下面是一段简单的示例。</p>
<pre name="code" class="php">//这里要 include进来 phpexcel类
include ROOT_PATH . 'library/PHPExcel-1.7.6/PHPExcel.PHP';
include ROOT_PATH . 'library/PHPExcel-1.7.6/PHPExcel/Writer/Excel2007.PHP';

class MyExcel {

    public static function makeExcel($title, $data, $excle_name) {
        $exclefile = 'excel/' . date('Y-m-d') . '/' . md5($excle_name) . '.xlsx';

        $Excel = new PHPExcel();
        $Excel-&gt;setActiveSheetIndex(0);
        $Excel-&gt;getSheet()-&gt;setTitle($title);

        $cell_one = $data[0];
        $j = 0;
        foreach ($cell_one as $k =&gt; $v) {
            $Excel-&gt;getSheet()-&gt;setCellValue(self::getCharByNunber($j) . '1', $k);
            $j++;
        }

        $x = 2;
        foreach ($data as $value) {
            $y = 0;
            foreach ($value as $k =&gt; $v) {
                $Excel-&gt;getSheet()-&gt;setCellValue(self::getCharByNunber($y) . $x, $v);
                $y++;
            }
            $x++;
        }

        $objwriter = new PHPExcel_Writer_Excel2007($Excel);
        $objwriter-&gt;save($exclefile);
        TMDebugUtils::debugLog('make ' . $exclefile);
        return $exclefile;
    }

    protected static function getCharByNunber($num) {
        $num = intval($num);
        $arr = array('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',);
        return $arr[$num];
    }

}

//导出用户基本信息
function exportUserBaseInfo() {
    $excelTitle = '用户基本信息';
    $excelFileName = 'userbase';
    $data = array();
    // $rs = ....  这里rs是从db读取的数据
    for ($i = 0; $i &lt; count($rs); $i++) {         $data[$i]['姓名'] = $rs[$i]-&gt;name;
        $data[$i]['年龄'] = intval($rs[$i]-&gt;age);
        $data[$i]['日期'] = $rs[$i]-&gt;date;
    }
    MyExcel::makeExcel($excelTitle, $data, $excelFileName);
}

//导出新闻资讯信息
function exportUserBaseInfo() {
    $excelTitle = '新闻资讯信息';
    $excelFileName = 'news';
    $data = array();
    // $rs = ....  这里rs是从db读取的数据
    for ($i = 0; $i &lt; count($rs); $i++) {         $data[$i]['标题'] = $rs[$i]-&gt;title;
        $data[$i]['作者'] = $rs[$i]-&gt;author;
        $data[$i]['日期'] = $rs[$i]-&gt;date;
        $data[$i]['浏览数'] = floatval($rs[$i]-&gt;view_count);
        $data[$i]['被评论数'] = floatval($rs[$i]-&gt;comment_count);
    }
    MyExcel::makeExcel($excelTitle, $data, $excelFileName);
}

//end</pre>
<p>这里只是简单的生成的xlsx，其他需要读取更复杂的，可以阅读官方的手册，有很详细的说明。</p>
<p>如果不需要保存，直接输出到浏览，如下：</p>
<pre name="code" class="php">//不用保存，直接输出到浏览器
$objwriter = new PHPExcel_Writer_Excel2007($Excel);
        header("Content-Type: application/force-download");
        header("Content-Type: application/octet-stream");
        header("Content-Type: application/download");
        header('Content-Disposition:inline;filename=temp.xlsx');
        header("Content-Transfer-Encoding: binary");
        header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
        header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
        header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
        header("Pragma: no-cache");
        $objwriter-&gt;save('php://output');</pre>
<p>The End</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gosoa.com.cn/php%e5%af%bc%e5%87%baexcel/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>NoSQL &#8211; Redis几个认识误区</title>
		<link>http://www.gosoa.com.cn/nosql-redis%e5%87%a0%e4%b8%aa%e8%ae%a4%e8%af%86%e8%af%af%e5%8c%ba</link>
		<comments>http://www.gosoa.com.cn/nosql-redis%e5%87%a0%e4%b8%aa%e8%ae%a4%e8%af%86%e8%af%af%e5%8c%ba#comments</comments>
		<pubDate>Sat, 15 Jan 2011 10:02:13 +0000</pubDate>
		<dc:creator>scofield</dc:creator>
				<category><![CDATA[PHP开发]]></category>
		<category><![CDATA[Nosql]]></category>
		<category><![CDATA[Redis]]></category>

		<guid isPermaLink="false">http://www.gosoa.com.cn/?p=557</guid>
		<description><![CDATA[转自 http://timyang.net/data/redis-misunderstanding/ 前几天微博发生了一起大的系统故障，很多技术的朋友都比较关心，其中的原因不会超出James Hamilton在On Designing and Deploying Internet-Scale Service(1)概括的那几个范围，James第一条经验“Design for failure”是所有互联网架构成功的一个关键。互联网系统的工程理论其实非常简单，James paper中内容几乎称不上理论，而是多条实践经验分享，每个公司对这些经验的理解及执行力决定了架构成败。 题外话说完，最近又研究了Redis。去年曾做过一个MemcacheDB, Tokyo Tyrant, Redis performance test，到目前为止，这个benchmark结果依然有效。这1年我们经历了很多眼花缭乱的key value存储产品的诱惑，从Cassandra的淡出(Twitter暂停在主业务使用)到HBase的兴起(Facebook新的邮箱业务选用HBase(2))，当再回头再去看Redis，发现这个只有1万多行源代码的程序充满了神奇及大量未经挖掘的特性。Redis性能惊人，国内前十大网站的子产品估计用1台Redis就可以满足存储及Cache的需求。除了性能印象之外，业界其实普遍对Redis的认识存在一定误区。本文提出一些观点供大家探讨。 1. Redis是什么 这个问题的结果影响了我们怎么用Redis。如果你认为Redis是一个key value store, 那可能会用它来代替MySQL；如果认为它是一个可以持久化的cache, 可能只是它保存一些频繁访问的临时数据。Redis是REmote DIctionary Server的缩写，在Redis在官方网站的的副标题是A persistent key-value database with built-in net interface written in ANSI-C for Posix systems，这个定义偏向key value store。还有一些看法则认为Redis是一个memory database，因为它的高性能都是基于内存操作的基础。另外一些人则认为Redis是一个data structure server，因为Redis支持复杂的数据特性，比如List, Set等。对Redis的作用的不同解读决定了你对Redis的使用方式。 互联网数据目前基本使用两种方式来存储，关系数据库或者key value。但是这些互联网业务本身并不属于这两种数据类型，比如用户在社会化平台中的关系，它是一个list，如果要用关系数据库存储就需要转换成一种多行记录的形式，这种形式存在很多冗余数据，每一行需要存储一些重复信息。如果用key value存储则修改和删除比较麻烦，需要将全部数据读出再写入。Redis在内存中设计了各种数据类型，让业务能够高速原子的访问这些数据结构，并且不需要关心持久存储的问题，从架构上解决了前面两种存储需要走一些弯路的问题。 2. Redis不可能比Memcache快 很多开发者都认为Redis不可能比Memcached快，Memcached完全基于内存，而Redis具有持久化保存特性，即使是异步的，Redis也不可能比Memcached快。但是测试结果基本是Redis占绝对优势。一直在思考这个原因，目前想到的原因有这几方面。 Libevent。和Memcached不同，Redis并没有选择libevent。Libevent为了迎合通用性造成代码庞大(目前Redis代码还不到libevent的1/3)及牺牲了在特定平台的不少性能。Redis用libevent中两个文件修改实现了自己的epoll event [...]]]></description>
			<content:encoded><![CDATA[<p>转自 <a href="http://timyang.net/data/redis-misunderstanding/">http://timyang.net/data/redis-misunderstanding/</a></p>
<p>前几天微博发生了一起大的<a href="http://tech.sina.com.cn/i/2010-12-01/15324930344.shtml">系统故障</a>，很多技术的朋友都比较关心，其中的原因不会超出James Hamilton在On Designing and Deploying Internet-Scale Service(1)概括的那几个范围，James第一条经验“Design for failure”是所有互联网架构成功的一个关键。互联网系统的工程理论其实非常简单，James paper中内容几乎称不上理论，而是多条实践经验分享，每个公司对这些经验的理解及执行力决定了架构成败。</p>
<p>题外话说完，最近又研究了<a href="http://code.google.com/p/redis/">Redis</a>。去年曾做过一个<a href="http://timyang.net/data/mcdb-tt-redis/">MemcacheDB, Tokyo Tyrant, Redis performance test</a>，到目前为止，这个benchmark结果依然有效。这1年我们经历了很多眼花缭乱的key value存储产品的诱惑，从Cassandra的淡出(Twitter暂停在主业务使用)到HBase的兴起(Facebook新的邮箱业务选用HBase(2))，当再回头再去看Redis，发现这个只有1万多行源代码的程序充满了神奇及大量未经挖掘的特性。Redis性能惊人，国内前十大网站的子产品估计用1台Redis就可以满足存储及Cache的需求。除了性能印象之外，业界其实普遍对Redis的认识存在一定误区。本文提出一些观点供大家探讨。</p>
<h3>1. Redis是什么</h3>
<p>这个问题的结果影响了我们怎么用Redis。如果你认为Redis是一个key value store, 那可能会用它来代替MySQL；如果认为它是一个可以持久化的cache, 可能只是它保存一些频繁访问的临时数据。Redis是REmote DIctionary Server的缩写，在Redis在官方网站的的副标题是A persistent key-value database with built-in net interface written in ANSI-C for Posix systems，这个定义偏向key value store。还有一些看法则认为Redis是一个memory database，因为它的高性能都是基于内存操作的基础。另外一些人则认为Redis是一个data structure server，因为Redis支持复杂的数据特性，比如List, Set等。对Redis的作用的不同解读决定了你对Redis的使用方式。</p>
<p>互联网数据目前基本使用两种方式来存储，关系数据库或者key value。但是这些互联网业务本身并不属于这两种数据类型，比如用户在社会化平台中的关系，它是一个list，如果要用关系数据库存储就需要转换成一种多行记录的形式，这种形式存在很多冗余数据，每一行需要存储一些重复信息。如果用key value存储则修改和删除比较麻烦，需要将全部数据读出再写入。Redis在内存中设计了各种数据类型，让业务能够高速原子的访问这些数据结构，并且不需要关心持久存储的问题，从架构上解决了前面两种存储需要走一些弯路的问题。</p>
<h3>2. Redis不可能比Memcache快</h3>
<p>很多开发者都认为Redis不可能比Memcached快，Memcached完全基于内存，而Redis具有持久化保存特性，即使是异步的，Redis也不可能比Memcached快。但是测试结果基本是Redis占绝对优势。一直在思考这个原因，目前想到的原因有这几方面。</p>
<ul>
<li><a href="http://monkey.org/~provos/libevent/">Libevent</a>。和Memcached不同，Redis并没有选择libevent。Libevent为了迎合通用性造成代码庞大(目前Redis代码还不到libevent的1/3)及牺牲了在特定平台的不少性能。Redis用libevent中两个文件修改实现了自己的epoll event loop(4)。业界不少开发者也建议Redis使用另外一个libevent高性能替代libev，但是作者还是坚持Redis应该小巧并去依赖的思路。一个印象深刻的细节是编译Redis之前并不需要执行./configure。</li>
<li>CAS问题。CAS是Memcached中比较方便的一种防止竞争修改资源的方法。CAS实现需要为每个cache key设置一个隐藏的cas token，cas相当value版本号，每次set会token需要递增，因此带来CPU和内存的双重开销，虽然这些开销很小，但是到单机10G+ cache以及QPS上万之后这些开销就会给双方相对带来一些细微性能差别(5)。</li>
</ul>
<h3>3. 单台Redis的存放数据必须比物理内存小</h3>
<p>Redis的数据全部放在内存带来了高速的性能，但是也带来一些不合理之处。比如一个中型网站有100万注册用户，如果这些资料要用Redis来存储，内存的容量必须能够容纳这100万用户。但是业务实际情况是100万用户只有5万活跃用户，1周来访问过1次的也只有15万用户，因此全部100万用户的数据都放在内存有不合理之处，RAM需要为冷数据买单。</p>
<p>这跟操作系统非常相似，操作系统所有应用访问的数据都在内存，但是如果物理内存容纳不下新的数据，操作系统会智能将部分长期没有访问的数据交换到磁盘，为新的应用留出空间。现代操作系统给应用提供的并不是物理内存，而是虚拟内存(Virtual Memory)的概念。</p>
<p>基于相同的考虑，Redis 2.0也增加了VM特性。让Redis数据容量突破了物理内存的限制。并实现了数据冷热分离。</p>
<h3>4. Redis的VM实现是重复造轮子</h3>
<p>Redis的VM依照之前的epoll实现思路依旧是自己实现。但是在前面操作系统的介绍提到OS也可以自动帮程序实现冷热数据分离，Redis只需要OS申请一块大内存，OS会自动将热数据放入物理内存，冷数据交换到硬盘，另外一个知名的“理解了现代操作系统(3)”的Varnish就是这样实现，也取得了非常成功的效果。</p>
<p>作者antirez在解释为什么要自己实现VM中提到几个原因(6)。主要OS的VM换入换出是基于Page概念，比如OS VM1个Page是4K, 4K中只要还有一个元素即使只有1个字节被访问，这个页也不会被SWAP, 换入也同样道理，读到一个字节可能会换入4K无用的内存。而Redis自己实现则可以达到控制换入的粒度。另外访问操作系统SWAP内存区域时block进程，也是导致Redis要自己实现VM原因之一。</p>
<h3>5. 用get/set方式使用Redis</h3>
<p>作为一个key value存在，很多开发者自然的使用set/get方式来使用Redis，实际上这并不是最优化的使用方法。尤其在未启用VM情况下，Redis全部数据需要放入内存，节约内存尤其重要。</p>
<p>假如一个key-value单元需要最小占用512字节，即使只存一个字节也占了512字节。这时候就有一个设计模式，可以把key复用，几个key-value放入一个key中，value再作为一个set存入，这样同样512字节就会存放10-100倍的容量。</p>
<p>这就是为了节约内存，建议使用hashset而不是set/get的方式来使用Redis，详细方法见参考文献(7)。</p>
<h3>6. 使用aof代替snapshot</h3>
<p>Redis有两种存储方式，默认是snapshot方式，实现方法是定时将内存的快照(snapshot)持久化到硬盘，这种方法缺点是持久化之后如果出现crash则会丢失一段数据。因此在完美主义者的推动下作者增加了aof方式。aof即append only mode，在写入内存数据的同时将操作命令保存到日志文件，在一个并发更改上万的系统中，命令日志是一个非常庞大的数据，管理维护成本非常高，恢复重建时间会非常长，这样导致失去aof高可用性本意。另外更重要的是Redis是一个内存数据结构模型，所有的优势都是建立在对内存复杂数据结构高效的原子操作上，这样就看出aof是一个非常不协调的部分。</p>
<p>其实aof目的主要是数据可靠性及高可用性，在Redis中有另外一种方法来达到目的：Replication。由于Redis的高性能，复制基本没有延迟。这样达到了防止单点故障及实现了高可用。</p>
<h3>小结</h3>
<p>要想成功使用一种产品，我们需要深入了解它的特性。Redis性能突出，如果能够熟练的驾驭，对国内很多大型应用具有很大帮助。希望更多同行加入到Redis使用及代码研究行列。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gosoa.com.cn/nosql-redis%e5%87%a0%e4%b8%aa%e8%ae%a4%e8%af%86%e8%af%af%e5%8c%ba/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>推荐一款PHP调试工具 &#8212; FirePHP</title>
		<link>http://www.gosoa.com.cn/%e6%8e%a8%e8%8d%90%e4%b8%80%e6%ac%bephp%e8%b0%83%e8%af%95%e5%b7%a5%e5%85%b7-firephp</link>
		<comments>http://www.gosoa.com.cn/%e6%8e%a8%e8%8d%90%e4%b8%80%e6%ac%bephp%e8%b0%83%e8%af%95%e5%b7%a5%e5%85%b7-firephp#comments</comments>
		<pubDate>Sat, 01 Jan 2011 03:34:14 +0000</pubDate>
		<dc:creator>scofield</dc:creator>
				<category><![CDATA[PHP开发]]></category>
		<category><![CDATA[firephp]]></category>
		<category><![CDATA[PHP调试]]></category>

		<guid isPermaLink="false">http://www.gosoa.com.cn/?p=533</guid>
		<description><![CDATA[PHP调试工具之 &#8212; FirePHP PHP调试有很多中方法。今天给大家推荐的是 FirePHP（http://www.firephp.org/）。 这个工具，是基于firefox的一个组件。Firephp组件安装地址。使用之前需要先安装下这个组件。完了还需要down一个FirePHP的包。下载地址。 下载完成后可以看到包里的文件如下： 我们现在来写个例子测试下。（需要include 进来fb.php文件哦）代码如下： 我们在firefox下运行。结果如下： 在这里就可以看到$str的值了。 接下来来介绍下FirePHP的几个常用方法： 1、  fb($para) 该方法就是如上示例。可以监测某个变量的值。该方法等同于FB::log($para)。 2、  FB:: info ($str);   该方法和fb()方法类似。不同的地方在于其运行结果在firefox中会有个不同的标志。（见图三） 3、  FB::warn($str);   同上类似。 4、  FB::error($str);   同上类似。 图三 5、  FB::trace($str); 该方法用于监控变量的调用栈。如下图示例。 我们也可以在类中使用FB。如下示例： 运行结果如下： 在fb.php中，我们可以看到有如下多的方法，在这里就不一一介绍了。主要常用的就是上面五个。有兴趣的同学可以仔细去研究测试下其他方法。]]></description>
			<content:encoded><![CDATA[<p>PHP调试工具之 &#8212; FirePHP</p>
<p>PHP调试有很多中方法。今天给大家推荐的是 FirePHP（<a href="http://www.firephp.org/">http://www.firephp.org/</a>）。</p>
<p>这个工具，是基于firefox的一个组件。<a href="https://addons.mozilla.org/zh-CN/firefox/search/?q=firephp&amp;cat=all&amp;x=0&amp;y=0">Firephp组件安装地址</a>。使用之前需要先安装下这个组件。完了还需要down一个FirePHP的包。<a href="http://www.firephp.org/DownloadRelease/FirePHPLibrary-FirePHPCore-0.3.2">下载地址</a>。</p>
<p>下载完成后可以看到包里的文件如下：</p>
<p><img class="alignnone size-full wp-image-546" title="firephp" src="http://www.gosoa.com.cn/wp-content/uploads/2011/01/image001.gif" alt="" width="223" height="130" /></p>
<p>我们现在来写个例子测试下。（需要include 进来fb.php文件哦）代码如下：</p>
<p><img class="alignnone size-full wp-image-547" title="firephp - 2" src="http://www.gosoa.com.cn/wp-content/uploads/2011/01/image002.gif" alt="" width="408" height="81" /></p>
<p>我们在firefox下运行。结果如下：<br />
<img class="alignnone size-full wp-image-547" title="firephp - 3" src="http://www.gosoa.com.cn/wp-content/uploads/2011/01/image003.gif" alt="firephp - 3" /></p>
<p>在这里就可以看到$str的值了。</p>
<p>接下来来介绍下FirePHP的几个常用方法：</p>
<p>1、  <strong>fb($para) </strong>该方法就是如上示例。可以监测某个变量的值。该方法等同于FB::log($para)。</p>
<p>2、  FB:: info ($str);   该方法和fb()方法类似。不同的地方在于其运行结果在firefox中会有个不同的标志。（见图三）</p>
<p>3、  FB::warn($str);   同上类似。</p>
<p>4、  FB::error($str);   同上类似。</p>
<p><img class="alignnone size-full wp-image-549" title="firephp " src="http://www.gosoa.com.cn/wp-content/uploads/2011/01/image004.jpg" alt="" width="277" height="166" /><br />
图三</p>
<p>5、  FB::trace($str); 该方法用于监控变量的调用栈。如下图示例。<br />
<img class="alignnone size-full wp-image-550" title="firephp" src="http://www.gosoa.com.cn/wp-content/uploads/2011/01/image005.jpg" alt="" width="431" height="160" /></p>
<p>我们也可以在类中使用FB。如下示例：<br />
<img class="alignnone size-full wp-image-551" title="firephp" src="http://www.gosoa.com.cn/wp-content/uploads/2011/01/image006.jpg" alt="" width="229" height="269" /></p>
<p>运行结果如下：<br />
<img class="alignnone size-full wp-image-552" title="firephp" src="http://www.gosoa.com.cn/wp-content/uploads/2011/01/image007.jpg" alt="firephp" width="362" height="192" /></p>
<p>在fb.php中，我们可以看到有如下多的方法，在这里就不一一介绍了。主要常用的就是上面五个。有兴趣的同学可以仔细去研究测试下其他方法。</p>
<p><img class="alignnone size-full wp-image-554" title="firephp" src="http://www.gosoa.com.cn/wp-content/uploads/2011/01/image008.jpg" alt="firephp" width="360" height="310" /></p>
]]></content:encoded>
			<wfw:commentRss>http://www.gosoa.com.cn/%e6%8e%a8%e8%8d%90%e4%b8%80%e6%ac%bephp%e8%b0%83%e8%af%95%e5%b7%a5%e5%85%b7-firephp/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>PHP CURL CURLOPT_HTTPHEADER设置HOST</title>
		<link>http://www.gosoa.com.cn/php-curl-curlopt_httpheader%e8%ae%be%e7%bd%aehost</link>
		<comments>http://www.gosoa.com.cn/php-curl-curlopt_httpheader%e8%ae%be%e7%bd%aehost#comments</comments>
		<pubDate>Sat, 25 Sep 2010 04:05:11 +0000</pubDate>
		<dc:creator>scofield</dc:creator>
				<category><![CDATA[PHP开发]]></category>
		<category><![CDATA[CURL]]></category>
		<category><![CDATA[CURLOPT_HTTPHEADER]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.gosoa.com.cn/?p=512</guid>
		<description><![CDATA[为了安全，我们的web服务主机往往不能上网。维护的时候，也是通过跳板机，ssh登录后去操作。 有时候我们的程序需要访问外网。比如需要调用外网其他程序的某个接口。这下该怎么办呢？ 我们可以通过PHP的CURL函数的CURLOPT_HTTPHEADER来配置设置host访问。 在开发中，我遇到这样一个例子。 有一个活动程序，需要调用qzone那边的一个接口。 如下代码示例： $host = array("Host: act.qzone.qq.com"); $data = 'user=xxx&#38;qq=xxx&#38;id=xxx&#38;post=xxx'; $url = 'http://192.168.1.12/xxx/xxx/api/'; var_dump( $this-&#62;curl_post($host, $data,$url) ); / * 提交请求 * @param $host array 需要配置的域名 array("Host: act.qzone.qq.com"); * @param $data string 需要提交的数据 'user=xxx&#38;qq=xxx&#38;id=xxx&#38;post=xxx'.... * @param $url string 要提交的url 'http://192.168.1.12/xxx/xxx/api/'; */ function curl_post($host,$data,$url) { $ch = curl_init(); $res= curl_setopt ($ch, CURLOPT_URL,$url); var_dump($res); curl_setopt($ch, [...]]]></description>
			<content:encoded><![CDATA[<p>为了安全，我们的web服务主机往往不能上网。维护的时候，也是通过跳板机，ssh登录后去操作。</p>
<p>有时候我们的程序需要访问外网。比如需要调用外网其他程序的某个接口。这下该怎么办呢？</p>
<p>我们可以通过PHP的CURL函数的CURLOPT_HTTPHEADER来配置设置host访问。</p>
<p>在开发中，我遇到这样一个例子。</p>
<p>有一个活动程序，需要调用qzone那边的一个接口。</p>
<p>如下代码示例：</p>
<pre name="code" class="php">$host = array("Host: act.qzone.qq.com");
$data = 'user=xxx&amp;qq=xxx&amp;id=xxx&amp;post=xxx';
$url = 'http://192.168.1.12/xxx/xxx/api/';
var_dump( $this-&gt;curl_post($host, $data,$url) );

/
* 提交请求
* @param $host array 需要配置的域名 array("Host: act.qzone.qq.com");
* @param $data string 需要提交的数据 'user=xxx&amp;qq=xxx&amp;id=xxx&amp;post=xxx'....
* @param $url string 要提交的url 'http://192.168.1.12/xxx/xxx/api/';
*/
 function curl_post($host,$data,$url)
    {
       $ch = curl_init();
       $res= curl_setopt ($ch, CURLOPT_URL,$url);
       var_dump($res);
       curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
       curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
       curl_setopt ($ch, CURLOPT_HEADER, 0);
       curl_setopt($ch, CURLOPT_POST, 1);
       curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
       curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
       curl_setopt($ch,CURLOPT_HTTPHEADER,$host);
       $result = curl_exec ($ch);
       curl_close($ch);
       if ($result == NULL) {
           return 0;
       }
       TMDebugUtils::debugLog($result);
       return $result;
    }</pre>
<p>通过PHP CURL CURLOPT_HTTPHEADER设置HOST很方便的解决了访问外网接口的问题。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gosoa.com.cn/php-curl-curlopt_httpheader%e8%ae%be%e7%bd%aehost/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

