<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
  <channel>
    <title>phper</title>
    <description>php交流</description>
    <link>http://phpers.group.javaeye.com</link>
    <language>UTF-8</language>
    <copyright>Copyright 2003-2008, JavaEye.com</copyright>
    <docs>http://blogs.law.harvard.edu/tech/rss</docs>
    <generator>JavaEye - 做最棒的软件开发交流社区</generator>
      <item>
        <title>vAgent开发--HTML和Javascript彻底分离</title>
        <author>koda</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://koda.javaeye.com">koda</a>&nbsp;
          链接：<a href="http://phpers.group.javaeye.com/group/blog/215465" style="color:red;">http://phpers.group.javaeye.com/group/blog/215465</a>&nbsp;
          发表时间: 2008年07月16日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          传统瘦客户端开发，HTML/CSS/Javascript，彻底分离？理想主义吧？<br />对，就是有理想主义。没有理想，就不会尝试实践；不尝试实践，怎么能前进?日本人水都能发动汽车了，html/js分类算鸟？ 试试看吧：）<br /><br />在vAgent项目中，需求的来源是客户认为我们的网页上javascript代码很多，影响SEO(国外客户对SEO都是有整理策略的，马上有一篇小文介绍ON-Site Seo)<br /><br />而我们遇到的困难是：<br />1. 很多onclick事件充斥在html元素中<br />2. ROR程序员可能都遇到Helper问题，CakePHP采用类似的机制，比如GoogleApi就是借助了一个我们自己编写的Javascript Helper直接在页面中调用简化输出，结果导致传回浏览器时即时解析的javascript就混杂在页面当中<br />3. 有些javascript的变量是依赖于后台数据库输出结果的<br /><br />下面看一个典型页面应用（该页面是澳洲的州介绍）<br /><img src="http://koda.javaeye.com/upload/picture/pic/17970/77c75970-08ae-3cf7-9e73-f624dd4866dc.png" /><br /><br /><br />针对上面我们提到的困难，我们逐步重构.基本思路是，定义一个页面同名.js文件用&lt;script>标签包含进来，该例子中js文件名为destination.js<br /><br /><span style="color: red"><span style="font-size: medium"><strong>1. 很多onclick事件充斥在html元素中</strong></span></span><br /> 比如，页面右侧的+和-点击后分别展开和合并，那么起初我们的写法类似：<br /><pre name="code" class="html">&lt;a href="" onclick="expand(..)" >+&lt;/a></pre><br /><br />实际上前端开发经验丰富的人都知道如何剥离这段代码，特别是使用了prototype或者jquery框架之后。下面是使用prototype为例：<br />首先重新定义+，加入id属性<br /><pre name="code" class="html">&lt;a href="" id="state1" >+&lt;/a></pre><br /><br />在destination.js中(伪代码)<br /><pre name="code" class="javascript"> 
Event.observe("state1", 'click' , function() {
      expand(this);
      show_left_of_page(this);
    });</pre><br /><br /><br /><span style="color: red"><span style="font-size: medium"><strong>2. ROR程序员可能都遇到Helper问题，CakePHP采用类似的机制，比如GoogleApi就是借助了一个我们自己编写的Javascript Helper直接在页面中调用简化输出，结果导致传回浏览器时即时解析的javascript就混杂在页面当中</strong><br /></span></span><br /><br />这个问题经过我们反复分析得出结论：不使用javascript helper.<br /><br /><span style="color: red"><span style="font-size: medium"><strong>3. 有些javascript的变量是依赖于后台数据库输出结果的</strong></span></span><br />其实这个问题才是困扰我们的最大问题，很多程序员不假思索地否定了该种情况的javascript代码剥离.<br /><br />对于上面的页面例子，澳大利亚各州的数据（名称，介绍和图片）都是后台数据库取出的，每次load后，这些数据作为一个数组被存储到javascript变量中，以供+/-点击后切换叶面左边介绍。<br /><br />原(伪)代码片断如下：<br /><pre name="code" class="javascript">&lt;script>
  // destination要用来存放后台州的数据，是javascript变量
  var destination = new Array();

  &lt;?php
    $dests = array();
    // $destinations存放的是数据库中取出来的数据，是php变量
    foreach($destinations as $destination) {
      $dests[$destination['Destination']['id']] = 
        '&lt;h2>'.$destination['Destination']['name'].'&lt;/h2>'.
        '&lt;p>'. $destination['Destination']['description'].'&lt;/p>'.
        '&lt;p>'.$html->image('/files/destinations/area'.$destination['Destination']['id'].'.gif','&lt;/p>';
    }
    foreach($dests as $key=>$value) {
      echo 'destination['.$key."]='". $value ."';" . "\r\n";
    }
  ?>
&lt;/script>
</pre><br /><br />剥离思路:php 输出 json串存在html页面隐藏div中，然后javascript通过dom找到这个字符串用json库反解析<br /><br />经过改进后，在html页面中<br /><pre name="code" class="html">
&lt;div id="json_dests" style="display:none">
&lt;?php 
 // $distionation是php数组存放的是澳大利亚州数据
  echo $javascript->Object($destinations));
?>
&lt;/div>
</pre><br /><br />在destination.js中：<br /><pre name="code" class="javascript">function extract_destinations(){
  var json_dests = document.getElementById('json_dests').innerHTML;
  var destJsObj  = JSON.parse(json_dests);
  // 接下来输出destJsObj对象到destination数组变量中
}
</pre><br />经过以上三步，vAgent网站的网页"一干二净"。<br /><br />---执拗于面向初学者写烂文的人于2008年7月 （进入我的博客看更多烂文）
          <br/>
          <span style="color:red;">
            <a href="http://phpers.group.javaeye.com/group/blog/215465#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 16 Jul 2008 16:18:50 +0800</pubDate>
        <link>http://phpers.group.javaeye.com/group/blog/215465</link>
        <guid>http://phpers.group.javaeye.com/group/blog/215465</guid>
      </item>
      <item>
        <title>vAgent开发---图片服务器的分离</title>
        <author>koda</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://koda.javaeye.com">koda</a>&nbsp;
          链接：<a href="http://phpers.group.javaeye.com/group/blog/212079" style="color:red;">http://phpers.group.javaeye.com/group/blog/212079</a>&nbsp;
          发表时间: 2008年07月06日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          vAgent的共有2000条左右的宾馆数据，每个宾馆有5到8张图片；1600条旅游路线数据，每个旅游路线有一张图片。<br />起初图片和web程序是在同一台机器上的，并且是存在文件系统中的。在CakePHP框架下目录存放结构如下：<br /><img src="http://koda.javaeye.com/upload/picture/pic/17451/32c88dcb-c75c-3317-a20c-ce56ba5f4504.png" /><br />CakePHP使用下面的方式输出图片:<br /><br /><pre name="code" class="html">&lt;?php echo $html->image("/files/hotels/$hotel_id/$hotel_image_large"); ?></pre><br /><br />输出结果如下：<br /><br /><pre name="code" class="html">&lt;img src="http://vagent/files.hotels/1600/y9943oerttr_large.png" /></pre><br /><br />由于预期图片访问会使运行vAgent的web服务器压力过大，希望能将hotels,tours的图片数据从web服务器分离。当前系统的 html和图片结构如下：<br /><img src="http://koda.javaeye.com/upload/picture/pic/17447/e27ec3c3-652b-3e48-8d75-19e971901f17.png" /><br /><br />希望分离后结果如下：<br /><img src="http://koda.javaeye.com/upload/picture/pic/17449/d73e1cc4-24f1-382a-ba59-2717ad52d104.png" /><br /><br />基本能想到的是使用分布式文件存储系统；另一种是简单的图片目的地重新指向的重构方式。为了应急，我们首先采用的是后面的方案.<br /><br />1. 架设两台图片服务器上,一台给宾馆数据用，一台给旅行路线用。服务器域名分别为image1.vagent, image2.vagent.<br /><br />2.把web服务器上的files/hotels目录移动到image1.vagent服务器的http目录下，采用同样的目录结构<br />  把web服务器上的files/tours目录移动到image2.vagent服务器的http目录下，采用同样的目录结构<br /><br />3. 然后重构所有的图片访问代码如下：<br /><pre name="code" class="html">
&lt;?php 
// 输出宾馆图片
echo $html->image($HOTELS_DIR + "/files/hotels/$hotel_id/$hotel_image_large"); ?>
// 输出旅行图片
echo $html->image($TOURS_DIR + "/files/hotels/$tour_id/$tours_image_large"); ?>
</pre><br /><br />$HOTELS_DIR是一个全局变量，在CakePHP可以写在config/core.php中。<br /><pre name="code" class="html">
define('HOTEL_DIR','http://image1.vagent/');
define('TOUR_DIR','http://image2.vagent/');
</pre><br /><br />从而实现图片和web程序的分离。<br /><br /><br />一般来说站点的图片可分为两类：一个是美工装饰用；一个是产品图片，是数据。对于vAgent,hotels和tours的图片就是产品图片，也是着力分离的。对于网站本身用的按钮，徽标等依然和web程序放在一起。这里要注意一下。<br /><br />而且关于性能在图片服务器分离方面的优化还涉及到图片本身存储设计的问题上。系统的优化是逐步提高的，在现在优化的基础上，接下来还要进行分布式存储的优化。希望最初设计得缺失不要影响接下来的系统优化。关于分布式文件系统存储稍后要单独篇幅介绍了，不知道这篇算不算通俗易懂，希望大家能够有所收获，也接受板砖。
          <br/>
          <span style="color:red;">
            <a href="http://phpers.group.javaeye.com/group/blog/212079#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sun, 06 Jul 2008 17:50:04 +0800</pubDate>
        <link>http://phpers.group.javaeye.com/group/blog/212079</link>
        <guid>http://phpers.group.javaeye.com/group/blog/212079</guid>
      </item>
      <item>
        <title>Web开发中LightBox的选择</title>
        <author>koda</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://koda.javaeye.com">koda</a>&nbsp;
          链接：<a href="http://phpers.group.javaeye.com/group/blog/211706" style="color:red;">http://phpers.group.javaeye.com/group/blog/211706</a>&nbsp;
          发表时间: 2008年07月04日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          当您点选网页中的图片或连结时，背景会立即变暗并且出现Loading…然后跳出一个美美的方框显示图片或网页，这种效果就叫做Lightbox，底下收集了一些许多人开发或修改的Lightbox，通常都会有Demo，看个人喜好选择。<br /><br /><br /><a href="http://www.huddletogether.com/projects/lightbox2/" target="_blank">Lightbox JS</a><br />  典型也是最常见的一个，目前也出了 2.0 版，不过似乎只能显示图片而已。<br /><br /><a href="http://jquery.com/demo/thickbox/" target="_blank">ThickBox</a><br />  这个也很常见，可以显示图片、网页，并且可以指定方框的大小，推荐。<br /><br /><a href="http://shiftingpixel.com/lightbox/" target="_blank">Greased Lightbox</a><br /><br />  	<br />提供装在浏览器的扩充套件，平常看图片时就会有Lightbox效果。<br /><br /><a href="http://www.orangoo.com/labs/GreyBox/" target="_blank">GreyBox</a><br /><br />  这个最强，除了可以用于图片和网页外，连flash,影片都可以显示在Lightbox弹出的方框里面。<br /><br /><a href="http://particletree.com/features/lightbox-gone-wild/" target="_blank"> Lightbox Gone Wild!</a><br />  也可以显示网页图片，效果还不错
          <br/>
          <span style="color:red;">
            <a href="http://phpers.group.javaeye.com/group/blog/211706#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 04 Jul 2008 17:07:50 +0800</pubDate>
        <link>http://phpers.group.javaeye.com/group/blog/211706</link>
        <guid>http://phpers.group.javaeye.com/group/blog/211706</guid>
      </item>
      <item>
        <title>vAgent(宾馆、旅游线路订购网)五---开发环境准备</title>
        <author>koda</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://koda.javaeye.com">koda</a>&nbsp;
          链接：<a href="http://phpers.group.javaeye.com/group/blog/211599" style="color:red;">http://phpers.group.javaeye.com/group/blog/211599</a>&nbsp;
          发表时间: 2008年07月04日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <span style="font-size: medium"><strong>1. 开发服务器（Dev Server）：</strong></span><br />同时也做Internal Test，上面安装的软件有：<br />  Linux<br />  Apache2.0 + Mysql5.0 + PHP5.2.5<br />  Dokuwiki<br />  Mantis<br />  Subversion<br /><span style="font-size: medium"><strong>2. 测试服务器（UAT Server）</strong></span><br />实际是用户接受性测试(UAT)用，安放在美国。主要软件环境<br />  Linux<br />  Apache2.0 + Mysql5.0 + PHP5.2.5<br /><br /><span style="font-size: medium"><strong>3. PHP扩展</strong></span><br /> 经检查该项目将使用如下PHP扩展:<br />  1). json:　高效传递ａｊａｘ数据<br />  2). ssl: 支付模块用<br />  3). gd2: 统计报表<br />  4). soap: 第三方Ｔｏｕｒ数据以soap服务方式提供的<br />  5). curl: 抓取Hotel缓存数据,相当于Java里的httpclient<br /><br />所有这些PHP扩展只要相应打开php.ini相应配置即可生效。<br /><br /><span style="font-size: medium"><strong>4. 资产管理</strong></span><br />  所有项目文档和代码都存放到Subversion服务器，可使用专门SVNClient下载，或通过Dokuwiki前端友好接口浏览文档。初始化项目目录结果，导入Subversion，主要结构如下<br /><img src="http://koda.javaeye.com/upload/picture/pic/17313/86b6c5e0-8fd7-3936-9287-4f12209ef9fc.gif" /><br /><br />以上未加说明的目录和文件都是CakePHP的固有的，像ＲＯＲ一样，app子目录下将存放所有项目相关的源代码。<br /><br />之前朋友数度推荐TDD，运用工具Phing,Phpunit,Selenium. 但是我仍然决定去掉一切负担，这个"度"就是商业逻辑没有复杂到一定程度，引入的工具恐增技术门槛。<br /><br /><span style="font-size: medium"><strong>5. 每日开发模式</strong></span><br /> 1). 每个程序员机器上安装运行环境，供个人调试用,每天早上工作之前从Subversion更新代码，下班前提交代码。<br /> 2). 以任务为单元，每个单元任务完成，Senior程序员检查Junior程序员的的代码，发现问题及时重构。<br /> 3). 手动或者我写了一脚本每天自动从Subversion最新代码更新到Interal Test服务器，如果测试员检查通过，更新它到UAT服务器<br /><br /><img src="http://koda.javaeye.com/upload/picture/pic/17307/1f969318-109b-3b43-90c1-e2cc18c0e4ec.png" /><br /><span style="font-size: medium"><br /><strong>6. 初始化数据库</strong></span><br /> 经设计好的数据库sql语句导入MySQL中，准备开发鸟
          <br/>
          <span style="color:red;">
            <a href="http://phpers.group.javaeye.com/group/blog/211599#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 04 Jul 2008 16:01:25 +0800</pubDate>
        <link>http://phpers.group.javaeye.com/group/blog/211599</link>
        <guid>http://phpers.group.javaeye.com/group/blog/211599</guid>
      </item>
      <item>
        <title>vAgent(宾馆、旅游线路订购网)四---数据库设计</title>
        <author>koda</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://koda.javaeye.com">koda</a>&nbsp;
          链接：<a href="http://phpers.group.javaeye.com/group/blog/211391" style="color:red;">http://phpers.group.javaeye.com/group/blog/211391</a>&nbsp;
          发表时间: 2008年07月04日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <img src="http://koda.javaeye.com/upload/picture/pic/17227/6086ebc6-57a1-345e-a297-09a59af425bf.png" /><br />首先图示的是PowerDesigner软件的基本工作原理，不知道算不算秀，知道的就过。<br /><br />因为使用图形化数据化建模工具，被几个ROR的朋友鄙视。我从来不是一个极端分子，我的观点和准则是：<br />1. 使用一切能够提高生产率的工具，不论出身；<br />2. 不是说文本的、Console的就是高明的正确的。<br />3. 敢于面对重构，但不是总是重构。过多地重构说明设计严重缺失<br />4. 数据库设计不求尽善尽美，但是力所能及。开发阶段仍然会反复迭代<br /><br />工作了7日，整理出如下数据结构：<br /><br /><img src="http://koda.javaeye.com/upload/picture/pic/17235/d4b1b619-15ed-34bd-b8da-01598407c124.png" /><br /><br /><br />PowerDesigner可以设置一键导出基于特定数据库、特定版本的sql语句<br /><br />由于商业版权，我不能展示给大家数据库具体结构，橙色背景的表表示系统中的主干表，就是User,Hotel,Tour。有人可能疑问Tour（旅行路线）也能订购吗？答案是当然可以。在美国，宾馆，旅行路线这些资源都是有专门提供商的中央数据库，提供WebSerice接口，到了旅行社就真真正正是一个瘦瘦的前端系统，vAgent订购的所有产品都来源于这些供应商，反倒可以把所有精力用在前端营销和服务上面。<br /><br />既然数据Hotel,Tour都来自于第三方，为什么还要在数据库设计中提及呢？关键是基于性能考虑: Hotel,Tour事先缓存他们的基本信息，仅在订购时实时查询第三方数据库。
          <br/>
          <span style="color:red;">
            <a href="http://phpers.group.javaeye.com/group/blog/211391#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 04 Jul 2008 10:29:38 +0800</pubDate>
        <link>http://phpers.group.javaeye.com/group/blog/211391</link>
        <guid>http://phpers.group.javaeye.com/group/blog/211391</guid>
      </item>
      <item>
        <title>vAgent(宾馆、旅游线路订购网)序言一---技术平台选型</title>
        <author>koda</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://koda.javaeye.com">koda</a>&nbsp;
          链接：<a href="http://phpers.group.javaeye.com/group/blog/211242" style="color:red;">http://phpers.group.javaeye.com/group/blog/211242</a>&nbsp;
          发表时间: 2008年07月03日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          注定，这就是一个不可能完美的开始。因为摆在面前的，是眼花缭乱的，甚至语言的选择都是迷茫的。从哪里开始呢？<br /><span style="font-size: medium">语言：</span><br />Java, C#, PHP, Python or Ruby? <br />Java: 静态语言；语言特性完善；库足够丰富。<br />C#:   类JAVA语言；语言特性同样完善；不乏优秀的库。<br />PHP/Python/Ruby: 同属脚本语言。与静态语言相对，最直接了当的感受是，写完一行代码，我就可以在浏览器看到效果。<br />    PHP久经考验，Python和Ruby的多线程支持好一些。Ruby的语法怪异一些....<br /><span style="font-size: medium">框架：</span><br />PHP:    Zend,Symfony,CakePHP,FleaPHP,CodeIgnier.....<br />Python: Karrigell,Django...<br />Ruby :  Ruby On Rails<br />Java:   Struts,Wicket,Spring,Tapestry，JSF...<br />C#:     框架选择单一(.NET),真好，怎么能迷失方向:)<br /><br />罗列，根本就是内心混乱的表现。之所以百家争鸣这恰恰证明了存在就是道理，当今得Web开发：没有什么语言，没有什么框架绝对胜出。整理思绪后还是回到了问题的本源，合适就是最好的，遂列出如下参考原则：<br />1. 技术只要符合项目需求<br />2. 技术尽可能简单，但稳定。<br />3. 不求尽善尽美，但是遇到得所有问题所选技术至少能迂回解决<br />4. 技术平台有足够的扩展空间<br />5. 程序员要熟悉这个技术<br /><br />问题驱动是个好东西，其实在这之前，我甚至没仔细看看vAgent到底要什么呢。vAgent一期是美国某旅行社准备经营的网上宾馆旅行路线订购产品。之前甚至想过基于CMS平台，但是感觉网站定制性、功能性非常强，所以放弃了这个想法。总得来说，这个网站功能紧凑模块不多，至于性能在我脑子里根本灵光一现，就忘却了，但是总不能和语言选择有关吧？<br /><br />对，还是先选语言：哎，除了通读过Ruby，上述得罗列其实我只会Java和PHP. Java就像我得老婆，天天磨在一起，的确有点腻歪，年轻的时候花枝招展多少人趋之若鹜。不是喜新厌旧，而是现在得Java懈怠让人出离愤怒。漫天得XML，好不容易脱离出来，又要进入Annotation得苦海。连个打印都要System.out.println, Tapestry曾是让我抱有无尽的幻想，但是我苦苦等待了两年，妈了个X，v5现在还是Beta. 反过来我还是得感谢她，如果不是长时间和Tapestry厮混，我真得不知道ROR这个婚外恋别有洞天。<br /><br />ROR是我学习Ruby的源动力，于是和Ruby好了一段时间，无奈我这人百般挑剔，Ruby得语法实在足够另类，弃它而去。这时我是多少有点迷茫，最后所有希望都寄托在PHP身上.<br /><br />PHP好比我得老情人，多年不见分外多情。再次拾起PHP,我用Java得眼光竟然审视出那么多以前忽略得东西：Java有Ant，PHP有Phing; Java有junit/javadoc,php有phpunit/phpdoc。不像Java这种静态语言，php和ruby一样，你写好的代码立即调试，对于逻辑不是特别得复杂得应用，php这种脚本语言显得如此可爱。PHP得语法足够简单，你可以说他某些地方不够面向对象，但是System.out.println到底意义何在呢？Java的Tapestry推崇ROR，却绝没有PHP这种脚本语言实现得更自然，不完美但够用。这就是CakePHP. 偷偷地说一句：其实我是首先看中了Cake这个词然后才是PHP.<br /><br />其实大家想不到的是我的结论竟是这么的仓促和盲目：除了因为脚本语言直截了当，概念简单，然后就是自己熟悉PHP, Cake是我喜欢的ROR style等个人偏好问题。至于其他的原则基本都是一种感性认识，完全基于直觉。<br /><br /><span style="font-size: large">阶段I: CakePHP</span><br /><br />说干就干，刚刚说到稳定这个问题呢，我就大胆地采用CakePHP1.2 beta, 实在是因为经不住新特性的诱惑。想想项目完了stable版也该出来了吧.<br /><br />接下来开始前端技术平台的选择和集成，那就是前端JavaScript框架了，该系统将具有的web2.0技术特征，少不了AJAX,Thickbox等特效。又是一阵大脑抽筋，罗列如下javascript框架：<br />Prototype + Scriptaculous <br />JQuery<br />ExtJs<br />YUI<br />Mootools<br />DOJO<br />....<br />长话短说，像选择后台框架一样，首先我的个人偏好是：简单，轻量级；另外项目本身特效不算特别多。Jquery和Prototype足够担当。经过感性使用JQuery又另胜一筹<br /><br /><span style="font-size: large">阶段II: CakePHP + JQuery</span><br /><br />紧接着我就发现CakePHP本身就集成了Prototype的Helper，实际上当前平台已经具备：<br /><br /><span style="font-size: large">阶段III: CakePHP + JQuery + Prototype.</span><br /><br />为了保证两个javascript库的和平共处，我脚踏两只船，下面的代码大家应该知道含义哦：<br /><br /><pre name="code" class="javascript"> 
 &lt;script>
    var $j = jQuery.noConflict();
  &lt;/script>
</pre><br />不想一发不可收拾，那么CSS框架是不是也可以集成呢？以下这个链接<br /><a href="http://koda.javaeye.com/blog/211243" target="_blank">12个顶级的CSS框架</a>着实让我又耗了不少脑细胞结果，当然，我什么都没选择。因为该项目的网页结构已经有专业人士基本完成了<br /><br />再接下来基本没有悬念了，最后框架定型为<br /><br /><span style="font-size: large">最终: CakePHP + JQuery/Prototype + MySQL + Apache + Linux</span><br /><br />还缺什么东西么？ 对，以后再补
          <br/>
          <span style="color:red;">
            <a href="http://phpers.group.javaeye.com/group/blog/211242#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 03 Jul 2008 20:18:05 +0800</pubDate>
        <link>http://phpers.group.javaeye.com/group/blog/211242</link>
        <guid>http://phpers.group.javaeye.com/group/blog/211242</guid>
      </item>
      <item>
        <title>JavaEye插件开发--DokuWiki转换接口</title>
        <author>koda</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://koda.javaeye.com">koda</a>&nbsp;
          链接：<a href="http://phpers.group.javaeye.com/group/blog/210767" style="color:red;">http://phpers.group.javaeye.com/group/blog/210767</a>&nbsp;
          发表时间: 2008年07月02日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          我喜欢用DokuWiki来管理自己的个人知识库，理由如下：<br />1. web界面<br />2. 足够简洁<br />3. 足够简单，不需要数据库(LAMP without M)<br />4. 插件足够丰富，无限扩展<br />5. OpenSource<br /><br />太多的东西想与大家分享，可是dokuwiki写得很漂亮的文章想要发到javaeye就不得不一字一句重新编辑。我有个想法：Run一个转换页面在JavaEye，直接将我wiki里的文章源代码复制粘贴过来执行转换，就可以基本发布好一个javaeye格式的文章。父老乡亲们怎么看？
          <br/>
          <span style="color:red;">
            <a href="http://phpers.group.javaeye.com/group/blog/210767#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 02 Jul 2008 20:26:21 +0800</pubDate>
        <link>http://phpers.group.javaeye.com/group/blog/210767</link>
        <guid>http://phpers.group.javaeye.com/group/blog/210767</guid>
      </item>
      <item>
        <title>反向代理方式(转)</title>
        <author>xombat</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://xombat.javaeye.com">xombat</a>&nbsp;
          链接：<a href="http://phpers.group.javaeye.com/group/blog/205588" style="color:red;">http://phpers.group.javaeye.com/group/blog/205588</a>&nbsp;
          发表时间: 2008年06月19日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p><a href="http://www.blueidea.com/computer/server/2003/428.asp">转自：http://www.blueidea.com/computer/server/2003/428.asp</a></p>
<p>为了增加网络的安全和保护内部网络上的重要数据，需要将内部网与Internet相隔离，当前主要通过防火墙技术来完成这个目的。然而为了保护内部主机，防火墙软件就必须限制外部网络中的主机对内部网络的访问。因此普通防火墙软件的设置中，外部网络无法访问内部主机。然而，为了向外发布自己的信息，就需要允许外部网络访问自己的Web服务器。最简单的处理方法是将Web服务器放在防火墙之外，这样就将Web服务器和内部网络区分开，Web服务器暴露在网络外部，就有可能招受攻击而导致服务器瘫痪或网页被更改等潜在的问题。而当前，Web服务器上面的信息越来越丰富和重要，Web服务器的重要性也非常明显。因此就需要使用防火墙来保护它，如果要将Web服务器放在防火墙之内，则需要防火墙的支持。<br />
<br />
当前防火墙主要有两种类型，一种为包过滤型防火墙，这种防火墙针对每个IP包识别它是否符合管理员设定的过滤规则，符合一定要求的才被正确转发。可以使用的过滤规则包括源和目的主机的名字和IP地址，端口地址，使用的网络界面，以及IP包的类型。通常包过滤型的防火墙软件根据IP包的类型屏蔽所有的由外部发起的连接请求，从而保护内部网络。如果要将Web服务器放在放火墙之内，就需要允许对这个Web服务器和它使用的TCP端口的访问。<br />
<br />
另一种类型的防火墙为应用代理型的防火墙，这种防火墙针对每种应用协议提供相应的代理服务，由代理服务器访问网络，并将结果返回给客户机。标准的http协议的代理服务，客户端的浏览器必须配置代理服务器的IP地址，不可能要求其他外部主机为访问这个内部网络上的主机而重新设置代理服务器的地址。代理服务器并不区分外部网络和内部网络，但是代理服务器使用Internet上的名字解析来确定Web服务器的位置，而通常防火墙内使用内部地址，这也决定了普通代理型防火墙不支持外部网络对内部Web服务器的http访问请求。因此普通代理服务器简单的屏蔽外部地址的访问，因此最简单的保护对外发布信息的Web服务器的方式是使用包过滤型的防火墙。<br />
<br />
一旦允许外部网络中的主机可以向内部网络发起连接请求，攻击者就可以在网络外部尝试进行连接，这增加了攻击者攻击内部网络的方式，降低了整个网络的安全系数。如果不允许外部主机向内部网络发起连接请求，攻击者就只好在外部发起攻击，使用特洛伊木马或者IP spoof等技术，这些方式与发起主动连接的攻击方式相比，没有现成的工具供利用，因此使得攻击的复杂性大大增加，因此网络被攻击的可能性大为减少，几乎成为不可能。一旦攻击者进入内部网络中的Web服务器，整个内部网络就暴露在攻击者的面前，防火墙就不能起到应有的作用了。因此通过重新定义包过滤型防火墙的过滤规则，并将Web服务器放在内部网络内，只是一种简单的保护Web服务器的方法，然而不利于保护整个内部网络的安全。<br />
<br />
因此，为了在保护Web服务器和内部网络的安全，当前使用的更安全的做法是实现双层防火墙。外层防火墙实现包过滤功能，然而却允许外部网络访问其中的Web服务器，内部防火墙允许最中间的内部网络可以访问外部网络。在外部防火墙和内部防火墙之间称为停火区，提供外部网络访问的服务器就位于这个区域，表明即使攻击者通过外部防火墙进入这个区域，也无法攻入内部网络。双层防火墙通过设置了两层防火墙，使得内部网络更为安全。然而，它在保护 Web服务器方面的作用，与单层防火墙相似。因为此时Web服务器仍然只受到一层防火墙的保护，同样也无法对外部隐藏防火墙内主机的各种信息，例如服务器的ip等。而且这层防火墙是对应用协议一无所知的包过滤防火墙，由于包过滤的方式不识别应用协议，通常为http协议，那么就无法正确识别外部的连接请求是否属于正常连接，通常也无法进行详尽的连接记录。为了更好的保护Web服务器不被外部攻击者破坏，就应该屏蔽内部服务器的IP地址等信息，并且防火墙能够识别连接协议，显然这是代理型防火墙的任务。<br />
<br />
<br />
<br />
<br />
通常的代理服务器，只用于代理内部网络对Internet的连接请求，客户机必须指定代理服务器,并将本来要直接发送到Web服务器上的http请求发送到代理服务器中。由于外部网络上的主机并不会配置并使用这个代理服务器，普通代理服务器也被设计为在Internet上搜寻多个不确定的服务器,而不是针对Internet上多个客户机的请求访问某一个固定的服务器，因此普通的Web代理服务器不支持外部对内部网络的访问请求。当一个代理服务器能够代理外部网络上的主机，访问内部网络时，这种代理服务的方式称为反向代理服务。此时代理服务器对外就表现为一个Web服务器，外部网络就可以简单把它当作一个标准的Web服务器而不需要特定的配置。不同之处在于，这个服务器没有保存任何网页的真实数据，所有的静态网页或者CGI程序，都保存在内部的Web 服务器上。因此对反向代理服务器的攻击并不会使得网页信息遭到破坏，这样就增强了Web服务器的安全性。<br />
<br />
反向代理方式和包过滤方式或普通代理方式并无冲突，因此可以在防火墙设备中同时使用这两种方式，其中反向代理用于外部网络访问内部网络时使用，正向代理或包过滤方式用于拒绝其他外部访问方式并提供内部网络对外部网络的访问能力。因此可以结合这些方式提供最佳的安全访问方式。<br />
<br />
综合反向代理功能和普通拒绝外部访问的普通防火墙软件相结合，就能构成一个既具有保护内部网络、又能对外提供Web信息发布的能力的防火墙系统。由于反向代理能力需要软件实现，因此不能使用现有的防火墙系统，需要使用相关软件进行开发改进。Unix显然是首选平台，我们基于 FreeBSD系统，提出一种基于ipfw、natd与squid的防火墙设置方式。其中ipfw可以基于ip地址、端口、协议等对ip包进行过滤，natd提供网络地址转换功能，这样就隐藏了内部网络的拓扑等信息，ipfw和natd结合就构成了强大的包过滤网关。而squid是 Internet上最流行的Web代理服务器之一，虽然它提供的是普通的正向代理能力，但其为开放源代码软件，并且具有强大的可配置性，因此很容易可以将其更改为反向代理服务器。<br />
<br />
这种方式对内部网络的保护能力，要小于双层防火墙软件，等于普通的单层防火墙软件，然而其对Web服务器的保护却大于双层防火墙系统中对位于对停火区内的Web服务器的保护。然而其本身为单层系统，因此比双层系统配置起来更方便，是一种简单有效的方案。其中反向代理功能能够提供丰富的连接记录，可以用来提供预防和捕获攻击的能力，而包过滤和网络地址翻译可以让内部网络的主机可以使用多种协议访问外部网络，不需要考虑防火墙对应用协议的支持问题。这种方式适用于大多数Intranet系统。<br />
<br />
<br />
<br />
当需要对内部网络提供更进一步的保护时，仍然可以使用双层防火墙模式，这样兼具反向代理对Web服务器的保护能力，和双层防火墙对内部数据的更大的保护能力。<br />
<br />
当组织向外提供信息发布的时候，并不仅仅要提供一些静态的网页，更大的可能是要根据实际的数据动态发布信息。因此发布的网页便需要通过访问数据库动态生成，通常使用的动态生成技术有CGI或服务器端文档解析等方式生成的。然而无论那种方式，都需要使得Web服务器能够和数据库服务器进行连接、通信。然而系统数据库应该是内部网络中应该首要保护的系统，因此要求安全性要求不高的对外发布信息的Web服务器和内部数据库服务器放置在同一个网段，就会造成相应的安全问题。<br />
<br />
为了提高访问数据库服务器的安全性，就需要对能够访问数据库的CGI程序进行限制，这就要求对启动CGI的URL请求比对普通url进行更严格的限制。与普通包过滤型防火墙不同，反向代理能够理解http协议，能区分出不同的url请求，从而能够实现对cgi请求比普通http请求更严格的控制，甚至可以将cgi请求发送到一台专用的CGI服务器进行处理，从而分别处理普通url请求和cgi请求。这台cgi服务器可以具有访问数据库的能力，保证数据库的安全。<br />
<br />
总结本文中的论述，可以看出，反向代理方式是一种对外提供Web发布时使用的有效的防火墙技术，使用它和传统防火墙技术相结合，就能实现简单有效的防火墙系统。</p>
          <br/>
          <span style="color:red;">
            <a href="http://phpers.group.javaeye.com/group/blog/205588#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 19 Jun 2008 00:54:51 +0800</pubDate>
        <link>http://phpers.group.javaeye.com/group/blog/205588</link>
        <guid>http://phpers.group.javaeye.com/group/blog/205588</guid>
      </item>
      <item>
        <title>目前正在研究</title>
        <author>xombat</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://xombat.javaeye.com">xombat</a>&nbsp;
          链接：<a href="http://phpers.group.javaeye.com/group/blog/186570" style="color:red;">http://phpers.group.javaeye.com/group/blog/186570</a>&nbsp;
          发表时间: 2008年04月24日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>目前正在研究：</p>
<p>xplanner</p>
<p>wiki</p>
<p>软件工程</p>
<p>issue</p>
<p>REST</p>
<p>RSS</p>
<p>Hibernate</p>
<p>用户体验</p>
<p>等等</p>
          <br/>
          <span style="color:red;">
            <a href="http://phpers.group.javaeye.com/group/blog/186570#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 24 Apr 2008 23:56:15 +0800</pubDate>
        <link>http://phpers.group.javaeye.com/group/blog/186570</link>
        <guid>http://phpers.group.javaeye.com/group/blog/186570</guid>
      </item>
      <item>
        <title>php执行外部程序函数解析</title>
        <author>xombat</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://xombat.javaeye.com">xombat</a>&nbsp;
          链接：<a href="http://phpers.group.javaeye.com/group/blog/183088" style="color:red;">http://phpers.group.javaeye.com/group/blog/183088</a>&nbsp;
          发表时间: 2008年04月16日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          php中可以用来执行外部命令的函数或运算符有：<br /><pre name="code" class="java">``//backtick operator
string shall_exec(string cmd);
string exec(string cmd, array &output, int &ret_val);
string system(string cmd, int &ret_val);
void passthru(string cmd, int &ret_val);</pre><br /><br />其中：<br /><ul><li>backtick操作符和shall_exec函数完全相同，都是执行后，返回输出结果（注意没有返回程序的返回值）。</li><li>system和passthru都会自动打印输出，但是passthru更适合返回大量数据，因为它不需要返回任何信息，所以能直接将数据发送到客户端，用php手册中的原话是：<div class="quote_title">引用</div><div class="quote_div">If you need to execute a command and have all the data from the command passed directly back without any interference, use the passthru() function. </div>这就是system和passthru仅有的不同点。</li><li></li><li>exec函数不会打印输出，但是它能将输出按照行放到一个数组里面，而返回值是这个数组的最后一个元素（也就是输出的最后一行）。</li></ul><br /><br />对于任何函数的ret_val（int 类型），如果正常执行，那么返回0,否则返回非零。<br /><br /><strong><span style="color: green">问：对于返回的非零值，是不是根据错误信息的不同而有所不同？有的资料说一般错误会返回13，而我的大多数程序遇到错误返回1.<br /><br />问：如果程序执行错误，php应该如何捕获错误语句？<br /><br />问：php调用标注程序和调用shell脚本有什么区别吗？</span></strong><br /><br />更复杂的proc_open 函数和重定向问题，下次再写
          <br/>
          <span style="color:red;">
            <a href="http://phpers.group.javaeye.com/group/blog/183088#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 16 Apr 2008 00:52:31 +0800</pubDate>
        <link>http://phpers.group.javaeye.com/group/blog/183088</link>
        <guid>http://phpers.group.javaeye.com/group/blog/183088</guid>
      </item>
      <item>
        <title>实战WebService III: REST篇(基于php)</title>
        <author>koda</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://koda.javaeye.com">koda</a>&nbsp;
          链接：<a href="http://phpers.group.javaeye.com/group/blog/152045" style="color:red;">http://phpers.group.javaeye.com/group/blog/152045</a>&nbsp;
          发表时间: 2007年12月31日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <span style="color: darkred"><span style="font-size: 18pt">REST是什么</span></span><br /><br />REST是英文Representational State Transfer的缩写，中文翻译：表述性状态转移。<br /><br />他是由Roy Thomas Fielding博士在他的论文 《Architectural Styles and the Design of Network-based Software Architectures》中提出的一个术语。<br /><strong><br />REST本身只是为分布式超媒体系统设计的一种架构风格，而不是标准.<br />Restful Web Service面向资源，不是面向动作(Action)</strong><br /><span style="color: darkred"><span style="font-size: 18pt">REST风格Web Service报文格式</span></span><br />什么，你一点都不懂我说什么？那么先看看<a href="http://koda.javaeye.com/blog/152047" target="_blank">Rest基本概念</a><br /><br />有效的XML格式都可以说是Rest风格的报文。如YAHOO提供的Restful Web Service的一个例子 : http://api.search.yahoo.com/WebSearchService/V1/webSearch?query=%5C%22XML%20Query%5C%22&appid=YahooDemo <br />下面是访问后返回结果片断<br /><pre name="code" class="java">
&lt;?xml version="1.0" encoding="UTF-8" ?> 
&lt;ResultSet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:yahoo:srch" 
xsi:schemaLocation="urn:yahoo:srch http://api.search.yahoo.com/WebSearchService/V1/WebSearchResponse.xsd" type="web" totalResultsAvailable="575000" 
totalResultsReturned="10" firstResultPosition="1" moreSearch="/WebSearchService/V1/webSearch?query=%5C%22XML+Query%5C%22&appid=YahooDemo&region=us">
  &lt;Result>
    &lt;Title>W3C XML Query (XQuery)&lt;/Title> 
    &lt;Summary>Language that allows for flexible query facilities to extract data from real and virtual documents on the Web.&lt;/Summary> 
    &lt;Url>http://www.w3.org/XML/Query&lt;/Url> 
    &lt;ClickUrl>http://uk.wrs.yahoo.com/_ylt=A0Je5Vx_EWpHwV0AkC7dmMwF;_ylu=X3oDMTB2cXVjNTM5BGNvbG8DdwRsA1dTMQRwb3MDMQRzZWMDc3IEdnRpZAM-/SIG=11fuf4pkj/EXP=1198220031/**http%3A//www.w3.org/XML/Query&lt;/ClickUrl> 
    &lt;DisplayUrl>www.w3.org/XML/Query&lt;/DisplayUrl> 
    &lt;ModificationDate>1198051200&lt;/ModificationDate> 
    &lt;MimeType>text/html&lt;/MimeType> 
    &lt;Cache>
      &lt;Url>http://uk.wrs.yahoo.com/_ylt=A0Je5Vx_EWpHwV0AkS7dmMwF;_ylu=X3oDMTBwOHA5a2tvBGNvbG8DdwRwb3MDMQRzZWMDc3IEdnRpZAM-/SIG=16gufb4vc/EXP=1198220031/**http%
         3A//66.218.69.11/search/cache%3Fei=UTF-8%26query=%255C%2522XML%2BQuery%255C%2522%26appid=YahooDemo%26u=www.w3.org/XML/Query%26w=%2522xml%2Bquery%2522%26d=DYOEo7XiP-1e%26icp=1%26.intl=us&lt;/Url> 
      &lt;Size>58502&lt;/Size> 
    &lt;/Cache>
  &lt;/Result>
  &lt;Result>
    &lt;Title>XQuery 1.0: An XML Query Language&lt;/Title> 
    &lt;Summary>Don Chamberlin (XML Query WG), IBM Almaden Research Center, via http://www. ... has been developed by the W3C XML Query Working Group, which is part of the ...&lt;/Summary> 
    &lt;Url>http://www.w3.org/TR/xquery/&lt;/Url> 
    &lt;ClickUrl>http://uk.wrs.yahoo.com/_ylt=A0Je5Vx_EWpHwV0Aky7dmMwF;_ylu=X3oDMTB2ZjQ4dDExBGNvbG8DdwRsA1dTMQRwb3MDMgRzZWMDc3IEdnRpZAM-/SIG=11g15fbj0/EXP=1198220031/**http%3A//www.w3.org/TR/xquery/&lt;/ClickUrl> 
    &lt;DisplayUrl>www.w3.org/TR/xquery/&lt;/DisplayUrl> 
    &lt;ModificationDate>1169193600&lt;/ModificationDate> 
    &lt;MimeType>text/html&lt;/MimeType> 
    &lt;Cache>
      &lt;Url>http://uk.wrs.yahoo.com/_ylt=A0Je5Vx_EWpHwV0AlC7dmMwF;_ylu=X3oDMTBwZG5hOWwzBGNvbG8DdwRwb3MDMgRzZWMDc3IEdnRpZAM-/SIG=16hn3aelo/EXP=1198220031
        /**http%3A//66.218.69.11/search/cache%3Fei=UTF-8%26query=%255C%2522XML%2BQuery%255C%2522%26appid=YahooDemo%26u=www.w3.org/TR/xquery/%26w=%2522xml%2Bquery%2522%26d=YBKWrbXiP9TA%26icp=1%26.intl=us&lt;/Url> 
      &lt;Size>525624&lt;/Size> 
    &lt;/Cache>
  &lt;/Result>
....
&lt;/ResultSet>
&lt;!-- ws02.search.scd.yahoo.com compressed/chunked Wed Dec 19 22:53:51 PST 2007 --></pre><br /><br />下面是我使用CakePhp（一个PHP框架）在本机构建了一个rest服务，<br />当访问http://localhost/hostel/rest/countries/listing 时，得到下面的XML<br /><pre name="code" class="java">
&lt;?xml version="1.0" encoding="utf-8" ?>
&lt;rsp stat="ok">
  &lt;countries type='array'>
    &lt;country type='struct'>
      &lt;id>830&lt;/id>
      &lt;title>United States&lt;/title>
    &lt;/country>
    &lt;country type='struct'>
      &lt;id>831&lt;/id>
      &lt;title>Canada&lt;/title>
    &lt;/country>
    ....
  &lt;/countries>
&lt;/rsp></pre><br /><br />再次强调：Restful Web Service是一种风格，XML是任意的。不过最近好像出了WADL规范应用于Rest，好像WSDL规范SOAP一样，有空可以研究一下。<br /><span style="color: darkred"><span style="font-size: 18pt">访问Restful Web Service(客户端代码)</span></span><br /><br />再次确认，你理解了Restful?---风格，是一种风格，所以：<br />Restful webservice客户端像解析一般的xml一样，获得Restful Web Service返回的XML流，用DOM/SAX/SimpleXML解析它均可。<br /><br />这里使用php的SimpleXML API操纵前面提到Yahoo服务。<br /><br />SimpleXML 扩展适合于操纵不很复杂或者嵌套不太深并且没有混合内容的 XML 文档。SimpleXML 比 DOM 更容易编码，就像名称所暗示的那样。如果处理的文档结构已知，就更加直观。libXML2 架构的互操作性大大增强了 DOM 和 SimpleXML 的灵活性，能够随意在 DOM 和 SimpleXML 之间交换导入格式。<br /><br />下面的代码使用 SimpleXML 扩展解析查询结果。<br /><pre name="code" class="java">
&lt;?php
  //This query does a search for any Web pages relevant to "XML Query"
  $query = "http://api.search.yahoo.com/WebSearchService/V1/webSearch?"."query=%5C%22XML%20Query%5C%22&appid=YahooDemo";
  $xml = simplexml_load_file($query);
  // Load up the root element attributes
  foreach($xml->attributes() as $name=>$attr) {
   $res[$name]=$attr;
  }
  //Use one of those "informational" elements to display the total
  //number of results for the query.
  echo "&lt;p>The query returns ".$res["totalResultsAvailable"]." total results The first 10 are as follows:&lt;/p>";
  //Unlike with DOM, where we loaded the entire document into the result object, 
  // with SimpleXML, we get back an object in thefirst place, 
  // so we can just use the number of results returned to loop through the Result members.
  for($i=0; $i&lt;$res['totalResultsReturned']; $i++) {
   //The object represents each piece of data as a member variable
   //rather than an array element, so the syntax is a little bit
   //different from the DOM version.
   $thisResult = $xml->Result[$i];
   echo "&lt;a href='".$thisResult->ClickUrl."'>&lt;b>".
   $thisResult->Title."&lt;/b>&lt;/a>: ";
   echo $thisResult->Summary;
   echo "&lt;br />&lt;br />";
  }
?></pre><br /><br />输出结果类似如下HTML效果：<br /><img src="http://koda.javaeye.com/upload/picture/pic/6556/b2f3dfa7-4553-4d98-8209-c7e4adcb6cab.jpg" /><br /><br />写一个自己的Restful Web Service<br /><br />别嫌我啰嗦，再一次地，前面说过：Restful Web Service是任意的有效的XML。所以使用php/jsp等服务器端技术，不需要任何框架都可以生成你想要得XML流。如此说来：这个Restful Web Service例子也没什么好写的喽<br /><br />CakePHP是一个基于PHP的web框架,提供了更好的输出Restful风格的Web Service的能力。Y有兴趣请看官方Cakephp文档
          <br/>
          <span style="color:red;">
            <a href="http://phpers.group.javaeye.com/group/blog/152045#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 31 Dec 2007 13:10:02 +0800</pubDate>
        <link>http://phpers.group.javaeye.com/group/blog/152045</link>
        <guid>http://phpers.group.javaeye.com/group/blog/152045</guid>
      </item>
      <item>
        <title>实战WebService II: SOAP篇(基于php)   </title>
        <author>koda</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://koda.javaeye.com">koda</a>&nbsp;
          链接：<a href="http://phpers.group.javaeye.com/group/blog/152042" style="color:red;">http://phpers.group.javaeye.com/group/blog/152042</a>&nbsp;
          发表时间: 2007年12月31日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <span style="font-size: 18pt"><span style="color: darkred">概述（SOAP和XML-PRC比较）</span></span><br /><br />在Web服务发展的初期，XML格式化消息的第一个主要用途是，应用于XML-RPC协议，其中RPC代表远程过程调用。在XML远程过程调用 (XML-RPC)中，客户端发送一条特定消息，该消息中必须包括名称、运行服务的程序以及输入参数。<br /><br />　　XML-RPC只能使用有限的数据类型种类和一些简单的数据结构。人们认为这个协议还不够强大，于是就出现了SOAP——其最初的定义是简单对象访问协议。之后，大家逐渐意识到SOAP其实并不简单，而且也不需要必须使用面向对象语言，所以，现在人们只是沿用SOAP这个名称而已。<br /><br />　　XML-RPC只有简单的数据类型集，取而代之，SOAP是通过利用XML Schema的不断发展来定义数据类型的。同时，SOAP也能够利用XML 命名空间，这是XML-RPC所不需要的。如此一来，SOAP消息的开头部分就可以是任何类型的XML命名空间声明，其代价是在系统之间增加了更多的复杂性和不兼容性。<br /><br />　　随着计算机行业的觉醒，人们发现了基于XML的Web服务的商业潜力，于是，各家公司开始不断地发掘想法、观点、论据以及标准化尝试。W3C曾经设法以“Web服务活动”的名义来组织成果展，其中也包括实际做出SOAP的XML协议工作组(XML Protocol Working Group)。与Web服务有关的标准化成果(从某种程度上说与SOAP相关或者依赖于SOAP)的数量已经倍增了到了令人惊讶的程度。<br /><br />　　最初，SOAP是作为XML-RPC的扩展而发展起来的，它主要强调的是，通过从WSDL文件中所获得的方法和变量名来进行远程过程调用。现在，通过不断进步，人们发现了更多的使用SOAP的方式，而不仅仅是采用“文件”方式——基本上是使用一个SOAP信封来传送XML格式化文件。无论如何，要掌握SOAP，了解WSDL所扮演的角色是最根本的。 <br /><br /><span style="font-size: 18pt"><span style="color: darkred">SOAP数据包结构解析</span></span><br /><br />SOAP的消息被称为一个SOAP Envelope，包括SOAP Header和SOAP Body。其中，SOAP Header可以方便的插入各种其它消息来扩充Web Service的功能，比如Security（采用证书访问Web Service），SOAP Body则是具体的消息正文，也就是Marshall后的信息。<br /><br />SOAP调用的时候，也就是向一个URL（比如 http://api.google.com/search/beta2 ）发送HTTP Post报文（根据SOAP规范，HTTP Get报文也可被支持），调用方法的名字在HTTP Request Header SOAP-Action中给出，接下来就是SOAP Envelope了。服务端接到请求，执行计算，将返回结果Marshall成XML，用HTTP返回给客户端。<br /><br />以下[是移动MISC接入]Wap1.6业务订购数据包样例<br /><span style="font-size: 18pt"><span style="color: darkred">MISC1.6的业务订购关系同步的请求包</span></span><br /><br /><pre name="code" class="java">&lt;?xml version="1.0" encoding="utf-8" ?> 
&lt;SOAP-ENV:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
                   xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
                   xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" 
                   xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">
  &lt;SOAP-ENV:Header>
    &lt;TransactionID xmlns="http://10.1.2.122/misc/dsmp.xsd">
00110100037392&lt;/TransactionID> 
  &lt;/SOAP-ENV:Header>
  &lt;SOAP-ENV:Body>
    &lt;SyncOrderRelationReq xmlns="http://10.1.2.122/misc/dsmp.xsd">
      &lt;Version>1.5.0&lt;/Version> 
      &lt;MsgType>SyncOrderRelationReq&lt;/MsgType> 
      &lt;Send_Address>
        &lt;DeviceType>0&lt;/DeviceType> 
        &lt;DeviceID>0011&lt;/DeviceID> 
      &lt;/Send_Address>
      &lt;Dest_Address>
        &lt;DeviceType>400&lt;/DeviceType> 
        &lt;DeviceID>0&lt;/DeviceID> 
      &lt;/Dest_Address>
      &lt;FeeUser_ID>
        &lt;UserIDType>2&lt;/UserIDType> 
        &lt;MSISDN /> 
        &lt;PseudoCode>00116000000286&lt;/PseudoCode> 
      &lt;/FeeUser_ID>
      &lt;DestUser_ID>
        &lt;UserIDType>2&lt;/UserIDType> 
        &lt;MSISDN /> 
        &lt;PseudoCode>00116000000286&lt;/PseudoCode> 
      &lt;/DestUser_ID>
      &lt;LinkID>SP&lt;/LinkID> 
      &lt;ActionID>1&lt;/ActionID> 
      &lt;ActionReasonID>1&lt;/ActionReasonID> 
      &lt;SPID>919102&lt;/SPID> 
      &lt;SPServiceID>0000000064&lt;/SPServiceID> 
      &lt;AccessMode>2&lt;/AccessMode> 
      &lt;FeatureStr /> 
    &lt;/SyncOrderRelationReq>
  &lt;/SOAP-ENV:Body>
&lt;/SOAP-ENV:Envelope></pre><br /><br /><span style="font-size: 18pt"><span style="color: darkred">MISC1.6的业务订购关系同步的响应包：</span></span><br /><pre name="code" class="java">
&lt;?xml version="1.0" encoding="utf-8"?>
&lt;SOAP-ENV:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
         xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
         xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" 
         xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">
  &lt;SOAP-ENV:Header>
    &lt;TransactionID xmlns="http://www.monternet.com/dsmp/schemas/">
00110100037392&lt;/TransactionID>
  &lt;/SOAP-ENV:Header>
  &lt;SOAP-ENV:Body>
    &lt;SyncOrderRelationResp xmlns="http://www.monternet.com/dsmp/schemas/">
      &lt;Version>1.5.0&lt;/Version>
      &lt;MsgType>SyncOrderRelationResp&lt;/MsgType>
      &lt;hRet>0&lt;/hRet>
    &lt;/SyncOrderRelationResp>
  &lt;/SOAP-ENV:Body>
&lt;/SOAP-ENV:Envelope>
</pre><br /><span style="font-size: 18pt"><span style="color: darkred">实战SOAPI</span></span><br /><br />现在做SOAP开发一般有三种方式选择<br />    * PEAR自带的soap扩展，<br />    * PHP自带的SOAP扩展，<br />    * NuSOAP(纯PHP，似乎已经过时)<br /> 注：还有WSO2.org(关于WSO2.org可以考虑尝试一下)<br /><br />PHP 5 中新增了内置的 SOAP 扩展，我们称之为 ext/soap。它是作为 PHP 的一部分提供的，因此不需要下载、安装和管理单独的包。这是第一个用 C 而不是 PHP 为 PHP 编写的 SOAP 实现，因此作者声称它的速度要快得多。<br /><br />因为新的扩展是 PHP 的完整组成部分之一，相关文档包含在 PHP 手册的 Function Reference 部分(php_soap.dll)。<br /><br />SOAP 参考是以一个重要的免责声明开始的：<br /><br />警告：该扩展是试验性的（EXPERIMENTAL）。本扩展的行为，包括关于本扩展的函数名和其他内容，在以后的 PHP 版本中随时可能改变，不另行通知。使用该扩展的风险自负。<br /><br />警告看起来有点让人担心，但实际上这个扩展似乎得到了很好的支持。和任何新代码一样，该扩展也存在缺陷，但是报告的问题通常很快就能得到修正。在 PHP 站点上可以看到缺陷列表。我们估计，在将来的 PHP 版本中，该扩展将从试验性功能转为主流功能<br /><br /><span style="font-size: 18pt"><span style="color: darkred">一个访问.NET WEB服务的客户端例子</span></span><br /><pre name="code" class="java">&lt;?php
 
$objSoapClient = new SoapClient("http://www.webservicemart.com/uszip.asmx?WSDL");
 
$param=array("ZipCode"=>'12209');
$out=$objSoapClient->ValidateZip($param);
$data=$out->ValidateZipResult;
echo $data;
?></pre><br /><br />运行后输出<br /><pre name="code" class="java">
&lt;result code="200">&lt;item zip="12209" state="NY" 
latitude ="42.64081" longitude ="-73.7856"/>&lt;/result></pre><br /><br />在实验的过程当中，使用了一个抓包工具Wireshark来分析报文。Wireshark很不错，在Filter处设置ip.addr == 208.109.78.12(208.109.78.12 是 www.webservicemart.com 的IP),然后启动监控，可以分析上述调用过程中HTTP包是什么样的。<br /><img src="http://koda.javaeye.com/upload/picture/pic/6555/752d3a87-43bd-4cc5-b7f6-948851b01fb1.jpg" /><br /><br /><span style="font-size: 18pt"><span style="color: darkred">实战SOAPII</span></span><br /><span style="font-size: 18pt"><span style="color: darkred">用PHP建立SOAP服务</span></span><br /><br />建立soap_server.php（虚拟路径为:http://172.16.0.24/php/soap/soap_server.php） <br /><br /><pre name="code" class="java">&lt;?php
/**
* A simple math utility class
* @author John Coggeshall john@zend.com
 */
class math {
  /**
   * Add two integers together
  *
  * @param integer $a The first integer of the addition
  * @param integer $b The second integer of the addition
  * @return integer The sum of the provided integers
   */
  public function add($a, $b) {
    return $a + $b;
  }
 
 /**
  * Subtract two integers from each other
  *
  * @param integer $a The first integer of the subtraction
  * @param integer $b The second integer of the subtraction
  * @return integer The difference of the provided integers
  */
  public function sub($a, $b) {
    return $a - $b;
  }
 
 /**
  * Div two integers from each other
  *
  * @param integer $a The first integer of the subtraction
  * @param integer $b The second integer of the subtraction
  * @return double The difference of the provided integers
  */
  public function div($a, $b) {
    if($b == 0) {
      throw new SoapFault(-1, "Cannot divide by zero!");
    }
    return $a / $b;
  }  
}
  $server = new SoapServer('math.wsdl', array('soap_version' => SOAP_1_2));
  $server->setClass("math");
  $server->handle();
 
?></pre><br /><br /> 注意几点：<br /><ol><br />    <li> math类是即将公开的webservice.</li>    <li> 注$server→setClass,不是$server→addClass</li></ol><br /><br /><span style="font-size: 18pt"><span style="color: darkred">用PHP客户端访问刚建立SOAP服务</span></span><br /><pre name="code" class="java">
&lt;?php
  //$client = new SoapClient('http://localhost/php/soap/math.wsdl'); 
  $client = new SoapClient("http://localhost/php/soap/soap_server.php?WSDL");
  try {
    $result = $client->div(8, 2); // will cause a Soap Fault if divide by zero
    print "The answer is: $result";
  } catch(SoapFault $e) {
    print "Sorry an error was caught executing your request: {$e->getMessage()}";
  }
?></pre><br /><br />注意代码中注释行：也可以调用静态WSDL文件创建$client,但是这样必须要手工生成wsdl文件。<br /><br />可以用ZendStudio生成静态的WSDL文件，此时用到math类的phpdoc作为生成WSDL的元数据。 用ZendStudio生成wsdl文件时，必须正确说明web服务目标地址，片断如下：<br /><pre name="code" class="java">
...
	&lt;service name="mathService">
		&lt;port name="mathPort" binding="typens:mathBinding">
			&lt;soap:address location="http://localhost/php/soap/soap_server.php"/>
		&lt;/port>
	&lt;/service>
....
</pre><br /><br />特别注意：我发现调用php webserver的方法和调用.net web服务的方法不一样。 调用.net service方法必须传入命名参数；而调用php web服务方法，一定不能传入命名参数，只能按顺序传入，为什么？这一点尤其要注意
          <br/>
          <span style="color:red;">
            <a href="http://phpers.group.javaeye.com/group/blog/152042#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 31 Dec 2007 12:58:27 +0800</pubDate>
        <link>http://phpers.group.javaeye.com/group/blog/152042</link>
        <guid>http://phpers.group.javaeye.com/group/blog/152042</guid>
      </item>
      <item>
        <title>实战WebService I: XML-PRC篇(基于php)</title>
        <author>koda</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://koda.javaeye.com">koda</a>&nbsp;
          链接：<a href="http://phpers.group.javaeye.com/group/blog/152040" style="color:red;">http://phpers.group.javaeye.com/group/blog/152040</a>&nbsp;
          发表时间: 2007年12月31日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          XML-RPC是一种简单的，轻量级的通过HTTP协议进行RPC通信的规范。一个XML-RPC消息就是一个请求体为XML的HTTP-POST请求，被调用的方法在服务器端执行并将执行结果以XML格式编码后返回。 XML-RPC 和SOAP是创建web services的两种标准协议。XML-RPC是出现较早的(也比较简单)，而SOAP较新，也比较复杂。Microsoft的.NET就是基于 SOAP，而很多流行的WEB程序，如Frontier和blogger，则提供XML-RPC接口。<br /><br />PHP通过xmlrpc扩展提供SOAP和XML-RPC的访问途径。xmlrpc基于xmlrpc-epi项目（更多信息请查看http://xmlrpc-epi.sourceforge.net）。xmlrpc扩展默认是不可用的，你需要在编译PHP时加上–with-xmlrpc选项来启用该扩展。<br /><br />以下是通过ethereal抓到的一个典型的XML-RPC调用包（为便于阅读，进行了格式化）：<br /><br /><span style="font-size: 18pt"><span style="color: darkred">1. 请求报文格式</span></span><br /><pre name="code" class="java">POST /xmlrpc HTTP/1.1
Content-Type: text/xml
User-Agent: Apache XML RPC 3.0 (Jakarta Commons httpclient Transport)
Host: 135.252.156.147:8080
Content-Length: 260
&lt;?xml version="1.0" encoding="UTF-8"?>
&lt;methodCall xmlns:ex="http://ws.apache.org/xmlrpc/namespaces/extensions">
      &lt;methodName>Calculator.add&lt;/methodName>
      &lt;params>
            &lt;param>
                  &lt;value>
                        &lt;i4>2&lt;/i4>
                  &lt;/value>
            &lt;/param>
            &lt;param>
                  &lt;value>
                        &lt;i4>3&lt;/i4>
                  &lt;/value>
            &lt;/param>
      &lt;/params>
&lt;/methodCall>
</pre><br /><br /><span style="color: darkred"><span style="font-size: 18pt">2. 报文返回格式</span></span><br /><br /> 而对应的返回数据包为：<br /><br /><pre name="code" class="java">HTTP/1.1 200 OK
Server: Apache XML-RPC 1.0
Connection: close
Content-Type: text/xml
Content-Length: 189
&lt;?xml version="1.0" encoding="UTF-8"?>
&lt;methodResponse xmlns:ex="http://ws.apache.org/xmlrpc/namespaces/extensions">
      &lt;params>
            &lt;param>
                  &lt;value>
                        &lt;i4>5&lt;/i4>
                  &lt;/value>
            &lt;/param>
      &lt;/params>
&lt;/methodResponse></pre><br /><br />其格式很简单，几乎是不言自明的，分别用methodCall和methodResponse标签标识发送给Server的调用请求和Server的返回结果，请求方法的名称用methodName标识，参数用params和param标识，而参数的类型标签则如下表所示：<br /><br /><span style="color: darkred"><span style="font-size: 18pt">示例</span></span><br /><br />XML-RPC需要PECL扩展支持，在Windows下，对应的dll文件是：php_xmlrpc.dll<br /><span style="color: darkred"><span style="font-size: 15pt">写一个XML-RPC服务器</span></span><br /><br /><pre name="code" class="java">&lt;?php
 //该函数暴露给客名端的名称为“multiply( )”
 function times ($method, $args) {
   return $args[0] * $args[1];
 }
 $request = $HTTP_RAW_POST_DATA;
 if (!$request) $request_xml = $HTTP_POST_VARS['xml'];
 
 $server = xmlrpc_server_create(  );
 
 if (!$server) die("Couldn't create server");
 xmlrpc_server_register_method($server, 'multiply', 'times');
 $options = array('output_type' => 'xml', 'version' => 'auto');
 echo xmlrpc_server_call_method($server, $request, null, $options);
 
 xmlrpc_server_destroy($server);
?></pre><br /><br /><span style="color: darkred"><span style="font-size: 18pt">客户端</span></span><br /><br />XML-RPC客户端的主要工作是发出HTTP请求和解析服务器发回的响应。PHP所带的xmlrpc扩展可以将XML-RPC请求用XML编码，但它不知道如何发送HTTP请求。如果要具有这样的功能，可以从http://xmlrpc-epi.sourceforge.net下载xmlrpc-epi程序包，然后安装其中的sample/utils/utils.php文件。该文件包含一个可以执行HTTP请求的函数。 <br /><br /><pre name="code" class="java">&lt;?php
  require_once('utils.php');
  $options = array('output_type' => 'xml', 'version' => 'xmlrpc');
  $result = xu_rpc_http_concise(
    array(method  => 'multiply',
          args     => array(9, 6),
          host     => 'localhost',
          uri      => '/php/rpc_webservice/xmlrpc_server.php',
          options => $options)
  );
  //echo $result;
  echo "9 * 6 is $result";
?></pre><br /><br />还有一些XML-RPC特性这里未提及，如XML-RPC的数据类型并不总是与PHP的数据类型精确对应，但可以将这些值编码成特殊的数据类型而不采用 xmlrpc扩展通过最佳猜测选择的数据类型。当然，PHP的xmlrpc扩展的一些特性我们也没有介绍，如SOAP错误。想知道全部细节，请查看http://www.php.net , 上面有xmlrpc扩展的详细文档。
          <br/>
          <span style="color:red;">
            <a href="http://phpers.group.javaeye.com/group/blog/152040#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 31 Dec 2007 12:43:42 +0800</pubDate>
        <link>http://phpers.group.javaeye.com/group/blog/152040</link>
        <guid>http://phpers.group.javaeye.com/group/blog/152040</guid>
      </item>
  </channel>
</rss>