﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>IT博客-CoffeeCat's IT Blog</title><link>http://www.cnitblog.com/CoffeeCat/</link><description /><language>zh-cn</language><lastBuildDate>Mon, 22 Mar 2010 09:31:35 GMT</lastBuildDate><pubDate>Mon, 22 Mar 2010 09:31:35 GMT</pubDate><ttl>60</ttl><item><title>Outlook Express的一个问题</title><link>http://www.cnitblog.com/CoffeeCat/archive/2010/03/08/64541.html</link><dc:creator>CoffeeCat</dc:creator><author>CoffeeCat</author><pubDate>Mon, 08 Mar 2010 07:44:00 GMT</pubDate><guid>http://www.cnitblog.com/CoffeeCat/archive/2010/03/08/64541.html</guid><wfw:comment>http://www.cnitblog.com/CoffeeCat/comments/64541.html</wfw:comment><comments>http://www.cnitblog.com/CoffeeCat/archive/2010/03/08/64541.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/CoffeeCat/comments/commentRss/64541.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/CoffeeCat/services/trackbacks/64541.html</trackback:ping><description><![CDATA[今天用Outlook Express发邮件的时候，总是在发送快结束的时候出现如下错误信息<br><br><span style="color: #000000; font-style: italic;">The&nbsp;message&nbsp;could&nbsp;not&nbsp;be&nbsp;opened&nbsp;from&nbsp;out&nbsp;Outbox&nbsp;folder.&nbsp;Account:&nbsp;'pop.gmail.com',&nbsp;Server:&nbsp;'smtp.gmail.com',&nbsp;Protocol:&nbsp;SMTP,&nbsp;Port:&nbsp;25,&nbsp;Secure(SSL):&nbsp;Yes,&nbsp;Error&nbsp;Number:&nbsp;0x800420C8</span><br style="font-style: italic;"><br>经过测试，发现邮件实际上已经发送出去了。最后我朋友发现问题是Outlook的Sent Items满了，所以从outbox移动到sent items出错了。<br><br><span style="font-weight: bold;">解决方法：删除一些Outlook发件箱里的邮件即可。</span><br style="font-weight: bold;"><br style="font-weight: bold;"><span style="font-weight: bold;">To solve this problem: delete some mails in your sent items.</span><br><br>Ferris Xu<br>2010-03-08<br><br> <img src ="http://www.cnitblog.com/CoffeeCat/aggbug/64541.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/CoffeeCat/" target="_blank">CoffeeCat</a> 2010-03-08 15:44 <a href="http://www.cnitblog.com/CoffeeCat/archive/2010/03/08/64541.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>如何用Javascript捕获ActiveX对象的事件</title><link>http://www.cnitblog.com/CoffeeCat/archive/2009/10/30/62254.html</link><dc:creator>CoffeeCat</dc:creator><author>CoffeeCat</author><pubDate>Fri, 30 Oct 2009 05:57:00 GMT</pubDate><guid>http://www.cnitblog.com/CoffeeCat/archive/2009/10/30/62254.html</guid><wfw:comment>http://www.cnitblog.com/CoffeeCat/comments/62254.html</wfw:comment><comments>http://www.cnitblog.com/CoffeeCat/archive/2009/10/30/62254.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/CoffeeCat/comments/commentRss/62254.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/CoffeeCat/services/trackbacks/62254.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp; 最近参与了一个项目，我的同事在开发一个ActiveX对象，我帮他编写JS脚本来调用这个对象，其中碰到蛮多问题，最难的就是如何响应由ActiveX对象返回的对象事件。正好，现在一起总结一下。<br><br>&nbsp;&nbsp;&nbsp; 首先，我来介绍一下COM组件，以便说明js如何响应<br><br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;COM组件<br>&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;&nbsp;&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;init()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">初始化对象</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Project&nbsp;createProject()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">创建一个Project类型的对象并返回</span><span style="color: #008000;"><br></span><span style="color: #000000;">&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;&nbsp;&nbsp;onInit(&nbsp;int_code&nbsp;)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">当init成功后触发</span></div>
<br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Project类的结构：<br>&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;&nbsp;&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;init()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">初始化Project对象</span><span style="color: #008000;"><br></span><span style="color: #000000;">&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;&nbsp;&nbsp;onInit(&nbsp;int_code&nbsp;)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">当init成功后触发</span></div>
<br>&nbsp;&nbsp;&nbsp; 然后，我们在网页里创建一个ActiveX对象<br><br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">object&nbsp;</span><span style="color: #ff0000;">id</span><span style="color: #0000ff;">="myobj"</span><span style="color: #ff0000;">&nbsp;classid</span><span style="color: #0000ff;">="CLSID:XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"</span><span style="color: #0000ff;">&gt;&lt;/</span><span style="color: #800000;">object</span><span style="color: #0000ff;">&gt;</span></div>
<br>&nbsp;&nbsp;&nbsp; 然后，我们定义全局的变量obj和project，来保存对象的实例，并调用他们的相关方法<br><br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #0000ff;">var</span><span style="color: #000000;">&nbsp;obj&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">全局对象</span><span style="color: #008000;"><br></span><span style="color: #0000ff;">var</span><span style="color: #000000;">&nbsp;project&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">Project对象</span><span style="color: #008000;"><br></span><span style="color: #000000;">window.onload&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">function</span><span style="color: #000000;">(){<br>&nbsp;&nbsp;&nbsp;&nbsp;obj&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;document.getElementById('myobj');&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">获取对象</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;obj.init();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">初始化对象</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;project&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;obj.createProject();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #008000;">//</span><span style="color: #008000;">创建project对象</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;project.init();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">调用project对象的方法</span><span style="color: #008000;"><br></span><span style="color: #000000;">};</span></div>
<br><span style="font-weight: bold; font-size: 14pt;">最常见的对象事件响应方法</span><br><br>最常见的莫过于使用script event for的标签语法来响应对象事件了，Windows Media Player就是这样做的<br><br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #000000;">&lt;</span><span style="color: #000000;">script&nbsp;language</span><span style="color: #000000;">=</span><span style="color: #000000;">"</span><span style="color: #000000;">Javascript</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;event</span><span style="color: #000000;">=</span><span style="color: #000000;">"</span><span style="color: #000000;">onInit(&nbsp;code&nbsp;)</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">for</span><span style="color: #000000;">=</span><span style="color: #000000;">"</span><span style="color: #000000;">myobj</span><span style="color: #000000;">"</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;&nbsp;<br></span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(&nbsp;code&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">&nbsp;)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">Todo:</span><span style="color: #008000;"><br></span><span style="color: #000000;">}<br></span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">script</span><span style="color: #000000;">&gt;</span></div>
<br>for属性指定了这个事件响应的对象是myobj，注意，这里要写object标签的id，不能是js变量<br>event属性指定了要响应哪个事件，这里是onInit事件。<br><br><br><span style="font-weight: bold; font-size: 14pt;">如何响应ActiveX对象返回的对象事件</span><br><br>现在问题来了，我们调用了createProject方法，得到了一个project对象。这个对象也有事件，那么这时应该如何来响应呢？<br>显然，用之前的script event for的方法是不行的，因为for属性不能指定js变量的值。网上搜索了一下，找到了一种很特别的方法，就是用双冒号来定义函数名，于是，修改程序如下：<br><br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #0000ff;">var</span><span style="color: #000000;">&nbsp;project&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;obj.createProject();<br></span><span style="color: #0000ff;">function</span><span style="color: #000000;">&nbsp;project::onInit(&nbsp;code&nbsp;)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(&nbsp;code&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">&nbsp;)<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">Todo:</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;}<br>}</span></div>
<br>不过，运行后有报错，说project未定义，想起来，js会优先执行function这个函数定义，也就是说先定义函数，然后才执行语句。所以，function必须在project创建成功以后才能定义，因此，修改程序如下：<br><br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #0000ff;">var</span><span style="color: #000000;">&nbsp;project&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;createProject();<br></span><span style="color: #0000ff;">var</span><span style="color: #000000;">&nbsp;fn&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">function</span><span style="color: #000000;">(){&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">定义一个函数，这个函数内部会定义我们的回调函数</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">回调函数</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">function</span><span style="color: #000000;">&nbsp;project::onInit(&nbsp;code&nbsp;)<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(&nbsp;code&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">&nbsp;)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">Todo:</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>};<br>fn();&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">执行这个函数，也就是定义回调函数</span></div>
<br>运行了一下，确实能响应了。<br><br><br><br><span style="font-weight: bold; font-size: 14pt;">后记</span><br><br>不知大家看到 <span style="color: #0000ff;">function</span><span style="color: #000000;">&nbsp;project::onInit</span>( code ) 这样的写法，是不是觉得很奇怪？我看到这种写法以后，很吃惊，因为我从没看到过javascript有这样的语法，这看上去像是定义一个静态函数，又像是在project命名空间中定义一个函数。于是我测试了一下，发现firefox并不能识别这样的函数定义，会报语法错误，说明这个不是标准javascript的写法，是IE-Only的写法。难道是JScript的语法？我又把JScript的手册从头到尾看了一遍，也没看到类似的语法。上微软的MSDN，也没有找到双冒号的语法参考。不过，我在一个论坛里，看到了这样一段话<br><br>
<table style="width: 694px; height: 186px;" bgcolor="#ececec" border="1" cellpadding="0" cellspacing="0">
    <tbody>
        <tr>
            <td>A second script block that defines your event handler based on the
            global variable.&nbsp; This has to be a separate script block, and the
            object has to be defined before this script block evaluates.&nbsp; Syntax is
            "function object::Event(params)", where "object" is the name of the
            variable containing the object, "Event" is the name of the even to
            which you're subscribing, and "params" is the set of parameters the
            event handler expects.<br>
            </td>
        </tr>
    </tbody>
</table>
<br>或许这种写法就是为了实现ActiveX的event handler而准备的吧<br><br><br><br>Ferris Xu<br>2009-10-30<br><br>  <img src ="http://www.cnitblog.com/CoffeeCat/aggbug/62254.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/CoffeeCat/" target="_blank">CoffeeCat</a> 2009-10-30 13:57 <a href="http://www.cnitblog.com/CoffeeCat/archive/2009/10/30/62254.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>PHP的Session阻塞问题探讨</title><link>http://www.cnitblog.com/CoffeeCat/archive/2009/10/22/62053.html</link><dc:creator>CoffeeCat</dc:creator><author>CoffeeCat</author><pubDate>Thu, 22 Oct 2009 03:33:00 GMT</pubDate><guid>http://www.cnitblog.com/CoffeeCat/archive/2009/10/22/62053.html</guid><wfw:comment>http://www.cnitblog.com/CoffeeCat/comments/62053.html</wfw:comment><comments>http://www.cnitblog.com/CoffeeCat/archive/2009/10/22/62053.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/CoffeeCat/comments/commentRss/62053.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/CoffeeCat/services/trackbacks/62053.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp; 最近在开发一个项目，其中有1个PHP页面需要执行较长时间，而且我发现，在执行这个页面的时候，其他的页面都不能访问了，需要等这个页面执行完成以后，其他页面才能打开。<br><br>&nbsp;&nbsp;&nbsp; 猜想了一下，有以下几种可能<br>
<ol>
    <li>Web Server(Apache 2.2)是不是只能同时处理1个客户端连接?</li>
    <li>是不是打开MySQL数据库的时候被阻塞了？</li>
    <li>是不是session_start导致了阻塞？</li>
</ol>
<br>&nbsp;&nbsp;&nbsp; 于是，我写了几个页面测试了一下，发现是session导致了阻塞，而其他两种情况不会造成阻塞。<br><br>&nbsp;&nbsp;&nbsp; 查了下PHP的Bug列表，发现有人提出了这个问题：<br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #000000;">Description:<br></span><span style="color: #000000;">------------</span><span style="color: #000000;"><br>Calling&nbsp;session_start()&nbsp;appears&nbsp;to&nbsp;wait&nbsp;until&nbsp;other&nbsp;scripts&nbsp;have&nbsp;exited<br><br>that&nbsp;are&nbsp;using&nbsp;the&nbsp;same&nbsp;session.&nbsp;My&nbsp;guess&nbsp;is&nbsp;the&nbsp;1st&nbsp;request&nbsp;locks&nbsp;the&nbsp;<br>session&nbsp;file&nbsp;</span><span style="color: #0000ff;">for</span><span style="color: #000000;">&nbsp;exclusive&nbsp;use,&nbsp;and&nbsp;the&nbsp;second&nbsp;request&nbsp;blocks&nbsp;until&nbsp;it&nbsp;<br>can&nbsp;open&nbsp;it.<br></span></div>
<br><br>&nbsp;&nbsp;&nbsp; PHP官方的回复是：<br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #000000;">Thank&nbsp;you&nbsp;</span><span style="color: #0000ff;">for</span><span style="color: #000000;">&nbsp;taking&nbsp;the&nbsp;time&nbsp;to&nbsp;write&nbsp;to&nbsp;us,&nbsp;but&nbsp;</span><span style="color: #0000ff;">this</span><span style="color: #000000;">&nbsp;is&nbsp;not&nbsp;a&nbsp;bug.This&nbsp;is&nbsp;expected,&nbsp;the&nbsp;session&nbsp;file&nbsp;is&nbsp;locked&nbsp;to&nbsp;avoid&nbsp;corruption.</span></div>
<br>&nbsp;&nbsp;&nbsp; 结合了PHP的Session机制，找到了阻塞的原因。由于PHP的Session信息是写入文件的，1个客户端占有1个session文件。因此，当session_start被调用的时候，该文件是被锁住的，而且是以读写模式锁住的（因为程序中可能要修改session的值），这样，第2次调用session_start的时候就被阻塞了。<br><br>&nbsp;&nbsp;&nbsp; 最简解决方法：<br><br>&nbsp;&nbsp;&nbsp; 查了PHP的手册，发现一个session_write_close函数，作用是Write session data and end session，也就是写session的数据，同时关闭这个session。因此，我们可以在用完session之后，调用这个函数关闭session文件即可接触锁定。一般，session是用来记录用户身份信息的，以便PHP进行身份认证，因此完全可以将session的读写放在页面刚开始执行的时候，在执行完以后，马上调用session_write_close函数即可。<br><br><br>Ferris Xu<br>2009年10月20日<br><img src ="http://www.cnitblog.com/CoffeeCat/aggbug/62053.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/CoffeeCat/" target="_blank">CoffeeCat</a> 2009-10-22 11:33 <a href="http://www.cnitblog.com/CoffeeCat/archive/2009/10/22/62053.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Zend Studio中的代码折叠设置</title><link>http://www.cnitblog.com/CoffeeCat/archive/2009/10/15/61884.html</link><dc:creator>CoffeeCat</dc:creator><author>CoffeeCat</author><pubDate>Thu, 15 Oct 2009 04:51:00 GMT</pubDate><guid>http://www.cnitblog.com/CoffeeCat/archive/2009/10/15/61884.html</guid><wfw:comment>http://www.cnitblog.com/CoffeeCat/comments/61884.html</wfw:comment><comments>http://www.cnitblog.com/CoffeeCat/archive/2009/10/15/61884.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/CoffeeCat/comments/commentRss/61884.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/CoffeeCat/services/trackbacks/61884.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp; 用Zend Studio打开PHP代码，默认是代码折叠的，如果需要展开，可以按ctrl+/来打开，注意，这个/是数字小键盘左上角的/。不过，我用的是笔记本电脑，如果要切换到小键盘就比较麻烦。所以如果能在打开文件的时候就自动展开，不自动折叠代码，就好了，具体的方法如下：<br><br>&nbsp;&nbsp;&nbsp; 进入window菜单-&gt;preferences，在左边找到PHP项，然后找到Editor-&gt;Code Folding，里面有Enable folding的选项，去掉就可以了。<br><br>&nbsp;&nbsp;&nbsp; 注意，如果左边选的是General，则在Editor的Stuctured Text Editors中也有Enable folding的选项。不过实验证明这个选项不能控制打开时代码的折叠，只对当前编辑的有效。<br><br><br>Ferris Xu<br>2009-10-15<br><br><img src ="http://www.cnitblog.com/CoffeeCat/aggbug/61884.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/CoffeeCat/" target="_blank">CoffeeCat</a> 2009-10-15 12:51 <a href="http://www.cnitblog.com/CoffeeCat/archive/2009/10/15/61884.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>解决iconv函数无法转换某些中文的问题</title><link>http://www.cnitblog.com/CoffeeCat/archive/2009/08/21/60917.html</link><dc:creator>CoffeeCat</dc:creator><author>CoffeeCat</author><pubDate>Fri, 21 Aug 2009 10:24:00 GMT</pubDate><guid>http://www.cnitblog.com/CoffeeCat/archive/2009/08/21/60917.html</guid><wfw:comment>http://www.cnitblog.com/CoffeeCat/comments/60917.html</wfw:comment><comments>http://www.cnitblog.com/CoffeeCat/archive/2009/08/21/60917.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/CoffeeCat/comments/commentRss/60917.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/CoffeeCat/services/trackbacks/60917.html</trackback:ping><description><![CDATA[请先看以下代码，这个页面是GB2312编码的：<br><br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #000000;">&lt;?</span><span style="color: #000000;">php<br></span><span style="color: #800080;">$str</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">'</span><span style="color: #000000;">陶喆</span><span style="color: #000000;">'</span><span style="color: #000000;">;<br></span><span style="color: #0000ff;">echo</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">'</span><span style="color: #000000;">gb2312-</span><span style="color: #000000;">'</span><span style="color: #000000;">.</span><span style="color: #800080;">$str</span><span style="color: #000000;">;<br></span><span style="color: #0000ff;">echo</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">'</span><span style="color: #000000;">&lt;br&nbsp;/&gt;</span><span style="color: #000000;">'</span><span style="color: #000000;">;<br></span><span style="color: #800080;">$str</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #008080;">iconv</span><span style="color: #000000;">(&nbsp;</span><span style="color: #000000;">'</span><span style="color: #000000;">gb2312</span><span style="color: #000000;">'</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">,</span><span style="color: #000000;">'</span><span style="color: #000000;">utf-8</span><span style="color: #000000;">'</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">,</span><span style="color: #000000;">&nbsp;</span><span style="color: #800080;">$str</span><span style="color: #000000;">&nbsp;);<br></span><span style="color: #0000ff;">echo</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">'</span><span style="color: #000000;">utf8-</span><span style="color: #000000;">'</span><span style="color: #000000;">.</span><span style="color: #800080;">$str</span><span style="color: #000000;">;<br></span><span style="color: #0000ff;">echo</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">'</span><span style="color: #000000;">&lt;br&nbsp;/&gt;</span><span style="color: #000000;">'</span><span style="color: #000000;">;<br></span><span style="color: #800080;">$str</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #008080;">iconv</span><span style="color: #000000;">(</span><span style="color: #000000;">'</span><span style="color: #000000;">utf-8</span><span style="color: #000000;">'</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">,</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">'</span><span style="color: #000000;">gb2312</span><span style="color: #000000;">'</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">,</span><span style="color: #000000;">&nbsp;</span><span style="color: #800080;">$str</span><span style="color: #000000;">&nbsp;);<br></span><span style="color: #0000ff;">echo</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">'</span><span style="color: #000000;">gb2312-</span><span style="color: #000000;">'</span><span style="color: #000000;">.</span><span style="color: #800080;">$str</span><span style="color: #000000;">;<br></span><span style="color: #000000;">?&gt;</span></div>
<br>程序做的事情很简单，首先打印出原始的陶喆，这是GB2312编码的，然后转换成UTF-8，最后再转换成GB2312。按照程序逻辑，第3行应该也打出陶喆，不过，实际的输出却是：<br><br><img alt=""  src="http://www.cnitblog.com/images/cnitblog_com/coffeecat/iconv/iconvsnap1.JPG" width="100" height="70"><br><br>我们用UTF-8编码来显示这个网页，可以看到输出是<br><img alt=""  src="http://www.cnitblog.com/images/cnitblog_com/coffeecat/iconv/iconvsnap2.JPG" width="96" height="73"><br><br><br>可见，在从gb2312转换到utf-8的过程中，&#8220;喆&#8221;不见了。<br><br>出现这个问题的原因是&#8220;喆&#8221;不属于gb2312字符集里的字符，而是属于gbk里的字符，所以，要从gb2312转换到utf-8就不行了<br><br>修改程序，将gb2312改成gbk，就可以解决这个问题了。<br><br><br><br>Ferris Xu<br>2009-08-21<br><br><br><br><img src ="http://www.cnitblog.com/CoffeeCat/aggbug/60917.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/CoffeeCat/" target="_blank">CoffeeCat</a> 2009-08-21 18:24 <a href="http://www.cnitblog.com/CoffeeCat/archive/2009/08/21/60917.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>让Apache支持中文Directory的最简方法</title><link>http://www.cnitblog.com/CoffeeCat/archive/2009/08/11/60708.html</link><dc:creator>CoffeeCat</dc:creator><author>CoffeeCat</author><pubDate>Tue, 11 Aug 2009 02:43:00 GMT</pubDate><guid>http://www.cnitblog.com/CoffeeCat/archive/2009/08/11/60708.html</guid><wfw:comment>http://www.cnitblog.com/CoffeeCat/comments/60708.html</wfw:comment><comments>http://www.cnitblog.com/CoffeeCat/archive/2009/08/11/60708.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/CoffeeCat/comments/commentRss/60708.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/CoffeeCat/services/trackbacks/60708.html</trackback:ping><description><![CDATA[<span style="font-weight: bold;">问题描述：</span><br>&nbsp;&nbsp;&nbsp;&nbsp; 我打开httpd.conf，将网站根目录设置为一个带中文的路径，如图：<br>&nbsp;&nbsp;&nbsp;&nbsp; <img alt="" src="http://www.cnitblog.com/images/cnitblog_com/coffeecat/apache_chinese/apache_chinese_snap2.JPG" height="217" width="524"><br>&nbsp;&nbsp;&nbsp;&nbsp; 设置完成以后保存配置文件，重启Apache服务器，出现错误提示，如图：<br>&nbsp;&nbsp;&nbsp;&nbsp; <img alt="" src="http://www.cnitblog.com/images/cnitblog_com/coffeecat/apache_chinese/apache_chinese_snap1.JPG" height="119" width="248"><br>&nbsp;&nbsp;&nbsp;&nbsp; 打开logs/error.log查看，找到错误原因是<br>&nbsp;&nbsp;&nbsp;&nbsp; <img style="width: 723px; height: 247px;" alt="" src="http://www.cnitblog.com/images/cnitblog_com/coffeecat/apache_chinese/apache_chinese_snap3.JPG"><br><br><br>&nbsp;&nbsp;&nbsp;&nbsp; Apache是不是不支持中文目录呢？<br><br><br><span style="font-weight: bold;">最简解决方法：</span><br><br>&nbsp;&nbsp;&nbsp;&nbsp; 解决方法很简单，一句话，将配置文件的字符编码转换成UTF-8即可。<br><br>&nbsp;&nbsp;&nbsp;&nbsp; 转换方法也很简单，在记事本中选择 文件-&gt;另存为，弹出的窗口中选择编码为UTF-8即可，如图：<br>&nbsp;&nbsp;&nbsp;&nbsp; <img alt="" src="http://www.cnitblog.com/images/cnitblog_com/coffeecat/apache_chinese/apache_chinese_snap4.JPG" height="446" width="563"><br><br><br><br>&nbsp;&nbsp;&nbsp;&nbsp; 启动Apache服务器，这次OK了<br><br><br><br>Ferris<br>2009-08-11<br><br>&nbsp;&nbsp;&nbsp;&nbsp; <br><br> <img src ="http://www.cnitblog.com/CoffeeCat/aggbug/60708.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/CoffeeCat/" target="_blank">CoffeeCat</a> 2009-08-11 10:43 <a href="http://www.cnitblog.com/CoffeeCat/archive/2009/08/11/60708.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>如何自定义file input控件的样式</title><link>http://www.cnitblog.com/CoffeeCat/archive/2009/06/29/59708.html</link><dc:creator>CoffeeCat</dc:creator><author>CoffeeCat</author><pubDate>Mon, 29 Jun 2009 03:50:00 GMT</pubDate><guid>http://www.cnitblog.com/CoffeeCat/archive/2009/06/29/59708.html</guid><wfw:comment>http://www.cnitblog.com/CoffeeCat/comments/59708.html</wfw:comment><comments>http://www.cnitblog.com/CoffeeCat/archive/2009/06/29/59708.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cnitblog.com/CoffeeCat/comments/commentRss/59708.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/CoffeeCat/services/trackbacks/59708.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp; 在上传文件的时候，一般会在表单中加入file input表单元素。这个控件的标准视图是一个文本框加上一个浏览按钮，如图：<br>&nbsp;&nbsp;&nbsp; <img alt="" src="http://www.cnitblog.com/images/cnitblog_com/coffeecat/custom_fileinput/snap1.gif" width="235" height="41"><br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; 不过，有时为了美化页面，我们常常需要用图片来制作美观的浏览按钮，用户点击这张图片，可以弹出文件选择对话框。例如，开心网的网盘在上传文件时的页面<br><br>&nbsp;&nbsp;&nbsp; <img alt="" src="http://www.cnitblog.com/images/cnitblog_com/coffeecat/custom_fileinput/snap3.gif" width="635" height="165"><br><br>&nbsp;&nbsp;&nbsp; 开心网是用Flash实现的，因为它使用了类似swfupload的控件，可以带进度的上传文件。不过，如果我们不用Flash的话，是否可以实现呢？答案是肯定的。<br><br><br><br><span style="font-weight: bold;">实现思路</span><br><br>&nbsp;&nbsp;&nbsp; 我们可以将file input控件设置成完全透明，然后，加入一个自定义的浏览按钮，可以是图片。然后，我们定义这个按钮的onmousemove属性，捕获到鼠标移动到上面的时候，我们就将透明的file input控件盖在上面，这样，如果我们点击了，那将点击file input控件，就能弹出文件选择框了。由于file input是透明的，给用户的感觉就是点击了自定义图片而弹出的文件选择框。<br><br><br><span style="font-weight: bold;">关键代码</span><br><br>注：2010-01-01修复了不支持IE8的Bug<br><br><br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">input&nbsp;</span><span style="color: #ff0000;">type</span><span style="color: #0000ff;">="file"</span><span style="color: #ff0000;">&nbsp;id</span><span style="color: #0000ff;">="browse"</span><span style="color: #ff0000;">&nbsp;size</span><span style="color: #0000ff;">="1"</span><span style="color: #ff0000;">&nbsp;style</span><span style="color: #0000ff;">="position:absolute;&nbsp;width:10px;&nbsp;filter:alpha(opacity=0);-moz-opacity:0;&nbsp;top:0px;"</span><span style="color: #ff0000;">&nbsp;</span><span style="color: #0000ff;">/&gt;</span><span style="color: #000000;">&nbsp;&nbsp;<br></span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">img&nbsp;</span><span style="color: #ff0000;">src</span><span style="color: #0000ff;">="upload.gif"</span><span style="color: #ff0000;">&nbsp;align</span><span style="color: #0000ff;">="absmiddle"</span><span style="color: #ff0000;">&nbsp;onmousemove</span><span style="color: #0000ff;">="document.getElementById('browse').style.top=(event.clientY-10)+'px';document.getElementById('browse').style.left=&nbsp;(event.clientX)+'px';"</span><span style="color: #ff0000;">&nbsp;</span><span style="color: #0000ff;">/&gt;</span><span style="color: #000000;"><br></span></div>
<br><br><br><br>以上代码在IE8和Firefox3测试通过，页面上有1个美化的添加文件按钮，点击这个按钮会弹出文件选择框。<br><br><br><span style="font-weight: bold;">代码下载</span><br><br><a style="text-decoration: line-through;" href="http://www.cnitblog.com/CoffeeCat/admin/EditPosts.aspx?postid=59708">http://www.cnitblog.com/Files/CoffeeCat/custom_upload.rar</a><br><br><a  href="http://www.cnitblog.com/Files/CoffeeCat/custom_upload_ie8_fixed.rar">http://www.cnitblog.com/Files/CoffeeCat/custom_upload_ie8_fixed.rar</a><br><br>此版本支持IE8<br><br><br><br>Ferris Xu<br>2009-06-29<br><br><br><br>  <img src ="http://www.cnitblog.com/CoffeeCat/aggbug/59708.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/CoffeeCat/" target="_blank">CoffeeCat</a> 2009-06-29 11:50 <a href="http://www.cnitblog.com/CoffeeCat/archive/2009/06/29/59708.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>一个iframe不显示内容的原因</title><link>http://www.cnitblog.com/CoffeeCat/archive/2009/05/08/57012.html</link><dc:creator>CoffeeCat</dc:creator><author>CoffeeCat</author><pubDate>Fri, 08 May 2009 01:39:00 GMT</pubDate><guid>http://www.cnitblog.com/CoffeeCat/archive/2009/05/08/57012.html</guid><wfw:comment>http://www.cnitblog.com/CoffeeCat/comments/57012.html</wfw:comment><comments>http://www.cnitblog.com/CoffeeCat/archive/2009/05/08/57012.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cnitblog.com/CoffeeCat/comments/commentRss/57012.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/CoffeeCat/services/trackbacks/57012.html</trackback:ping><description><![CDATA[今天碰到个很离奇的问题：我有2个文件，内容是一样。我用Firefox打开，效果完全一样，用IE打开，发现其中1个网页的iframe的内容全部没有显示。<br><br>我用UltraEdit打开，对比了两个文件的文本，完全一样，然后我切换到16进制模式，再对比了一下，还是完全一样。这就奇怪了，两个完全一样的网页，怎么一个能正常显示，另一个却不能呢？<br><br>这两个文件肯定是有差别的，如果内容没有差别，那么就是文件名有差别了。不过从理论上来说，文件名有差别不会影响内容的显示啊。我试验了一下，问题依然存在。<br><br>难道是缓存的问题？试了一下，还是不行。<br><br>然后我把这两个文件分别复制了一份，命名为另外一个名字，问题还是存在。这个太离奇啦，完全一样的两个文件怎么显示的效果会不同呢？<br><br>总算，同事想到了还有一个可能存在差异的地方：那就是文件的属性。<br><br>于是，我看了两个文件的属性，果然，不能正常显示的那个文件的属性页里有这样一句话：&#8220;此文件来自其他计算机,可能被阻止以帮助保护该计算机&#8221;。点击解除锁定以后，再刷新一下浏览器，这下正常了。<br><br>至此，问题解决。这个问题虽然不常见，不过很典型，与大家分享。<br><br><br>Ferris<br>2009-05-08<br><br><br><img src ="http://www.cnitblog.com/CoffeeCat/aggbug/57012.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/CoffeeCat/" target="_blank">CoffeeCat</a> 2009-05-08 09:39 <a href="http://www.cnitblog.com/CoffeeCat/archive/2009/05/08/57012.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>浅谈SQL Update返回影响行数的意义</title><link>http://www.cnitblog.com/CoffeeCat/archive/2009/05/04/56908.html</link><dc:creator>CoffeeCat</dc:creator><author>CoffeeCat</author><pubDate>Mon, 04 May 2009 10:30:00 GMT</pubDate><guid>http://www.cnitblog.com/CoffeeCat/archive/2009/05/04/56908.html</guid><wfw:comment>http://www.cnitblog.com/CoffeeCat/comments/56908.html</wfw:comment><comments>http://www.cnitblog.com/CoffeeCat/archive/2009/05/04/56908.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/CoffeeCat/comments/commentRss/56908.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/CoffeeCat/services/trackbacks/56908.html</trackback:ping><description><![CDATA[<p>在大学的时候学习了JSP，其中使用JDBC进行数据库操作，有一个语句是Statement.ExecuteUpdate，这个语句执行一个SQL的更新操作（如delete，update，insert），返回所影响的行数。当返回0时，则表示没有更新任何行。我以为可以判断返回值是否大于0来判断更新是否成功，但是，下面的两种情况均返回0：</p>
<p>&nbsp;&nbsp;&nbsp; 1：没有找到需要更新的数据<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 比如，我们进行update的时候，条件是id=5，但是id=5的数据不存在。这种情况下，更新是失败的，返回0，很正确。</p>
<p>&nbsp;&nbsp;&nbsp; 2：要更新的数据和更新的值是完全一样的<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 比如，我们要对id=5的记录进行更新，把title变成hello。虽然这条记录存在，但是这条记录的title本来就是hello，那么，返回值也是0</p>
<p>&nbsp;</p>
<p>这样就有个问题，当第2种情况发生时，从逻辑上讲，更新操作是成功的，你可以理解成title被重新覆盖了，不管它原来是不是hello，但是现在就被更新成hello了。</p>
<p>因此，如果要对Update进行是否更新成功的判断，就需要在Update之前，调用Statement.ExecuteQuery进行查询，如果能查询到记录，则表示更新会成功。ExecuteUpdate的返回值仅仅代表更新了多少行。</p>
<p>这样，一个Update操作就会执行2次SQL语句的，效率会降低。我当时就纳闷，为什么ExecuteUpdate对于第2种情况会不返回0，虽然从数据库的角度上，它是可以忽略更新这条记录，但是从逻辑的角度上看，这条记录被更新似乎更加合乎情理，返回大于0的值似乎更有意义。<br></p>
<p><br>不过，为什么基本上所有的编程语言，只要有类似的函数，都会在第2种情况返回0呢？<br><br><br>最近，这个问题总算想通了，之所以返回0，其实是为了解决同步的问题。<br></p>
<p>举个例子，现在，著名的开心网要对菜园的功能进行扩展，不光是能让玩家种菜，还要能让玩家偷别人家的菜。我们的程序逻辑如下：</p>
<p>&nbsp;</p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">某菜园：有成熟的菜N颗<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>A：&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;有偷来的菜0颗<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">===========================</span><span style="COLOR: #000000"><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>A：&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;某菜园有多少颗成熟的菜？<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>某菜园：N<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>A：&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;偷1颗<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>某菜园：成熟的菜=N-1</span><span style="COLOR: #000000"><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>A：&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;口袋里的菜</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000"><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">===========================</span><span style="COLOR: #000000"><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>某菜园：有成熟的菜N-1颗<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>A：&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;有偷来的菜1颗&nbsp;&nbsp;</span></div>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>这段程序的逻辑没有任何问题。</p>
<p>好了，现在程序开始给玩家用了，有一颗超级无敌白金大青菜快成熟了，众玩家垂涎欲滴等着偷。成熟的那一刻，众玩家以瞬间的爆发力点击了鼠标左键，进行了偷菜。</p>
<p>假设有2个人A和B，几乎同时点击了鼠标，我们看服务器上程序的逻辑：</p>
<p><br>&nbsp;</p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">某菜园：有成熟的菜N颗<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>A：&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;有偷来的菜0颗<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>B：&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;有偷来的菜0颗<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">===========================</span><span style="COLOR: #000000"><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>A：&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;某菜园有多少颗成熟的菜？<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>B：&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;某菜园有多少颗成熟的菜？<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>某菜园：N<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>某菜园：N<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>A：&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;偷过来<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>B：&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;偷过来<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>某菜园：成熟的菜=N-1</span><span style="COLOR: #000000"><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><strong>某菜园：成熟的菜=N-1</strong></span><span style="COLOR: #000000"><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>A：&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;口袋里的菜</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000"><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>A：&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;口袋里的菜</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000"><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">===========================</span><span style="COLOR: #000000"><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>某菜园：有成熟的菜</span><span style="COLOR: #000000">N-1</span><span style="COLOR: #000000">颗<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>A：&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;有偷来的菜1颗&nbsp;&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>B：&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;有偷来的菜1颗&nbsp;&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span></div>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>大家可以看到，现在的超级无敌白金大青菜总数变成了N+1了，无故多出了1颗，显然，这个结果是不对的，也不是我们想要的。<br></p>
<p>开心网的代码是用PHP开发的，PHP中可没有Java中的Synchronous关键字。如果用一个本地文件来实现锁的功能，服务器的运行效率就会大大打折。那么，我们如何高效的解决这个同步问题呢？这时候，执行Update返回所影响的行数就具有了超人般的意义了。</p>
<p><br>&nbsp;请看上面第2段中的粗体代码，在执行这个逻辑的时候，我们会得到的Update的返回值是0，因为在做这个操作之前，菜园里的蔬菜数量已经被更新成N-1了，所以这个更新操作会被忽略，这样，我们就可以在程序中加一个判断：如果更新的返回值是0，则表示偷菜失败，虽然Update是成功的。虽然B问菜园的时候是有菜的，但是偷的时候却没有了，那也表示B没有偷到。<br><br>可见，返回所影响的行数是非常有意义的，对于并发量大的网站，可以好好利用这个返回值，能在保证效率的状态下，解决同步的问题。<br><br><br><br>Ferris<br>2009-05-04</p>
<img src ="http://www.cnitblog.com/CoffeeCat/aggbug/56908.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/CoffeeCat/" target="_blank">CoffeeCat</a> 2009-05-04 18:30 <a href="http://www.cnitblog.com/CoffeeCat/archive/2009/05/04/56908.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ASP出现Disallowed Parent Path的一个解决方法</title><link>http://www.cnitblog.com/CoffeeCat/archive/2009/04/30/56835.html</link><dc:creator>CoffeeCat</dc:creator><author>CoffeeCat</author><pubDate>Thu, 30 Apr 2009 07:14:00 GMT</pubDate><guid>http://www.cnitblog.com/CoffeeCat/archive/2009/04/30/56835.html</guid><wfw:comment>http://www.cnitblog.com/CoffeeCat/comments/56835.html</wfw:comment><comments>http://www.cnitblog.com/CoffeeCat/archive/2009/04/30/56835.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/CoffeeCat/comments/commentRss/56835.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/CoffeeCat/services/trackbacks/56835.html</trackback:ping><description><![CDATA[<p>问题描述：<br>&nbsp;&nbsp;&nbsp; &lt;!--#include File "../int/conn.asp"--&gt;代码出现ASP运行错误，提示Disallowed Parent Path，原因是脚本所在的服务器不支持父目录寻址，这个问题在Apache支持ASP的Web服务器中比较常见。<br><br><br>解决方法：<br>&nbsp;&nbsp;&nbsp;&nbsp; 我们可以使用include Virtual来代替include File。include Virtual后面跟的是相对于网站跟目录的路径，不是相对与当前文件的路径。例如：我们的站点目录如下：<br><br><img height=51 alt="" src="http://www.cnitblog.com/images/cnitblog_com/coffeecat/aspdisallowedparentpath.JPG" width=108 border=0></p>
<br>其中，WebApp是站点根目录，inc目录下有conn.asp，lib下有test.asp，原先，在test.asp中是使用以下代码来包含conn.asp的<br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">--</span><span style="COLOR: #000000">#include&nbsp;File&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">../inc/test.asp</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">--&gt;</span></div>
<br>现在，修改成<br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">--</span><span style="COLOR: #000000">#include&nbsp;Virtual&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">inc/test.asp</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">--&gt;</span></div>
<br>这样就可以解决那个运行错误了<br><br><br>Ferris<br>2009年04月30日
<img src ="http://www.cnitblog.com/CoffeeCat/aggbug/56835.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/CoffeeCat/" target="_blank">CoffeeCat</a> 2009-04-30 15:14 <a href="http://www.cnitblog.com/CoffeeCat/archive/2009/04/30/56835.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>