Archive

Author Archive

最近想明白一点事儿

September 7th, 2010 CoCoWool No comments

今天中午的时候,有点感慨这一年来发生的林林总总的事件。比如换工作、拒掉别人的邀请还有工作以外的一些烦心事儿,又想想现在自己的境况,不免有些焦虑。可是也始终明白,焦虑是没有什么作用的。

人生应该以什么为目标,要追求什么东西,一味的以物质为最终目标吗?

刚和小宝通了电话,说了30岁之前最好安安稳稳的。我想也许这样才是一个适合我的状态。壁立千仞,无欲则刚。不要被外界过多的东西所迷惑了,抓紧时间充实自己,眼界再放的广一点重点深入两个领域,而不是被一些技术性的细节羁绊,工作上的事情,需要更有前瞻性、全局性,这样才能有更好的发展。

加油!

Categories: Life Tags: , ,

PHP开源Apache日志分析工具收集与比较

September 7th, 2010 CoCoWool No comments

我们知道已经有很多像Awtstat这样的使用perl、c或者c++开发的强大的日志分析工具,但是同样也有很多使用PHP开发并且开源的日志分析软件,今天我就收集了一些与大家分享。

1、LogAnalyzer

LogAnalyzer是 Adiscon的监控软件产品线中的一部分。可以再Windows以及Unix环境下运行。LogAnalyzer本是是免费的,GPL许可的产品。

LogAnalyzer的原名为phpLogCon,他在2010年的3月29日发布了3.0的稳定版,并且正式改名为LogAnalyzer

程序运行必须有他们制定的数据支持,在Windows环境下, 可以使用MonitorWare AgentWinSysLogEventReport。在Linux环境下可以使用rsyslog。现在Yum的源中包含了rsyslog这款软件,源中的版本是3.22.1,官方的最高版本是4.6.4的稳定版以及6.1.0的开发版。

由于不能使用原生的数据进行分析,我觉得算是他的一个缺点。

2、Jawstats

image

这是一款基于Awstat的PHP开源程序,提供了非常漂亮的分析统计结果的展示界面,支持中文。他的作者是 Jon Come

JAWStats可以减轻AWStats的计算压力,同时安装非常简单,只要稍微修改一下配置文件就可以运行。配置项也可以非常简单。

JAWStats的使用界面也非常人性化,因为作者原来是一个UI工程师。在系统中,我们可以非常容易的在不同月份之间切换,还可以在不同站点的日志之间进行切换。也可以通过Web界面来进行分析数据的更新,正好切合我们的需求,只在需要看的时候出报表就好了。

JAWStats支持主题,可以进行主题的设计和切换。

总的来说,看完了JAWStats的介绍,觉得是比较推荐的一款产品。

3、Web Analytics. Open Source

一款GPL协议下的开源软件,界面和数据获取方式都是模仿GA的,对于小型站点的分析应该不错。有对于Wordpress和Mediawiki的统计支持。

4、Log Miner

LogMiner是一个分析Apache或者IIS日志,或者其他支持 combined 或者 W3C扩展日志格式的服务器。能够提取并展示包括访问量、点击、流量、请求数、访问路径、浏览器和操作系统在内的诸多指标。数据存储采用的是PostgreSQL,存储比较精简。

Log Miner开发的灵感源自于流行的 Webalizer ,但是有一些主要的不同:

使用关系型数据库作为后端数据存储,实时生成报表。而 Webalizer 则是生成 html 文件。基于DBMS数据库的方式能够随时提供不同形式的数据,但是日志文件的解析速度上不如 Webalizer。

Webalizer只保存最近12个月的数据,之前的数据则无法再查看。

Webalizer的报告结果是硬编码的,而Logminer则是每个报告对应一个PHP类,我们可以灵活的进行定义。

LogMiner提供了比Webalizer更多的报表,比如操作系统和访问路径。

5、Webalizer

Webalizer虽然不是PHP的,但是上面LogMiner总是拿这个作比较,就顺便说一下。用C写成,日志分析能力非常出众,采用HTML的报表展示形式,是一个非常流行的日志分析工具。

6、TraceWatch

一个PHP+Mysql的日志分析工具,界面不太喜欢,好像就是路径分析比较有特点,其他的感觉还有点慢,就没什么了。

 

其他还有一些不太知名的工具,就没有一一细看:

AudiStatSlimStatPiwik

结合看到的这些工具,针对我们单位的实际需求,感觉 Awstat + JAWStats 组合更为好一点。因为日志会收集到单独的日志服务器上,所以性能上的消耗也就不会在意了。接下来看看实际的效果吧。

PS:刚才看AWS的文档,看到一个对比,可能对于特性的了解能够更加的一目了然。

image

Technorati 标签: ,,,,

参考资料:

1、CrunchTools
2、LogAnalyzer
3、Jawstats
4、Awstat
5、Web Analytics . Open Source
6、Log Miner
7、Webalizer
8、TraceWatch

Categories: WebTech Tags: , , , ,

Ajax应用中CKEDITOR多实例问题的解决

September 3rd, 2010 CoCoWool No comments

著名的Fckeditor升级之后就改名叫了CKEDITOR,界面和功能有了很大的提升,所以我在最近的项目中应用CKEDITOR。随着项目的深入,在Ajax应用较多的一个部分使用CKEDITOR时发现了问题,描述如下:

通过单击一个链接,调入需要显示的内容,其中包括一个富文本编辑器,这里使用了CKEDITOR。第一次调入时,一切正常。噩梦从第二次开始,在Firefox3.5+中,第二次的时候提示 i.contentWindow is null ,而在IE系列中则是一些模糊的错误提示。

出现这个问题后,分析的方向一直集中在CKEDITOR多实例的问题。因为第一次点击链接,调用内容时,已经进行了一次CKEDITOR的实例化,第二次调入时必然会与第一次的冲突。查阅了CKEDITOR的样例资料,试了下面的方法:

if( editor ){

  editor.destroy();

  editor = null;

}

editor = CKEDITOR.replace(‘content’);

但是没有用,问题依然发生。后来google之,得到了目前可以正常解决这个问题的方法

if( CKEDITOR.instances['content'] ){
    CKEDITOR.remove(CKEDITOR.instances['content']);
}

 

CKDEITOR.replace(‘content’);

应用了这个方法之后,不管是多少次调用,都不会再发生错误,应该就是正确的解决方法了,但是可惜的是在CKEDITOR的官方文档和论坛中均为看到相关的说明,遗憾…

Technorati 标签: ,,

参考资料:

1、CKEDITOR

2、CKEDITOR instance already exists

Categories: WebTech Tags: , ,

利用MapabcAPI实现基于浏览器的地理定位

August 30th, 2010 CoCoWool No comments

现在互联网中有了越来越多的地理位置服务,正在制定中的HTML5规范也试图在浏览器中内置嵌入地理位置共享服务,而且幸运的是,我们已经能够在Firefox 3.5+、Chrome 5.0+、Opera 10.60+、Safari 5.0+ 以及一些移动终端,注入IPhone、Android上使用这项服务,那么这个服务能否有Mapabc的API结合,来实现用户的地理定位呢?

传统上,地图应用上为用户定位的方式一般是:

用户访问时获得用户的IP。
用这个IP到IP库中匹配用户的城市信息。
根据获取的城市信息去已有的城市中心点字典中进行匹配。
匹配完成后将用户地图的中心点进行相应的切换。

这个过程繁琐,而且准确性极大程度上依赖于我们IP库的准确程度。现在有了浏览器的位置共享服务,我们可以更容易的实现用户的地理定位。

Geolocation对象介绍

正如开头所讲的,到目前为止,W3C中deGeolocation API规范已经在非IE的浏览中得到了实现。规范中提到,浏览器提供位置信息的来源是不固定的,可能是GPS、也可能来自于IP地址、RFID、WiFi、蓝牙或者GSM\CDMA的定位信息,也不保证返回的结果一定准确。Geolocation的API同时对“只获得一次”定位和“持续监督”定位都做出了规定。

Geolocation的一些方法

Geolocation对象位于浏览器Navigator对象下,可以通过 navigator.geolcation 来访问,不支持 geolocation 的浏览器不会包含这一对象,不会造成错误,可以用来做浏览器的区分。

if ( navigator.geolcation ){

    alert(‘ Your Browser dosent support geolcocation ‘);

} else{

    alert(‘ Your Browser support geolocation’);

}

在访问 geolocation 对象时,浏览器会进行提示,询问用户使用许可对网站提供位置服务,得到用户的许可后,访问才会继续,否则会被停止。而且,我们可以捕捉到用户同意或者拒绝的事件。

在获得用户的学科之后,就可以利用Geolocation获取当前位置,核心方法如下:

navigator.geolocation.getCurrentPosition( getPositionSuccess , getPositionError );

上面的代码中,调用了 getCurrentPosition 方法,并且传递了两个回调函数的参数,分别用来处理位置获取成功和失败时的情况。实事上,这个函数还可以接受第三个参数,用来传入一些配置信息,包括对于超时的设置等。下面来看两个获取成功和获取失败时,回调函数的处理。

获取地理信息成功的错误处理信息

function getPositionSuccess ( position ) {

  var lat = position.coords.latitude;

  var lng = position.coords.longitude;

  alert( ‘Now you are lat – lng ‘);

}

 

获取地理位置失败的回调函数

function getPositionError( error ){

    switch(error.code)

         case error.TIMEOUT;

          //Do something

          break;

          case error.PERMISSION_DENIED;

          //Do something

          break;

          case error.POSITION_UNAVAILIABLE;

          //Do something

          break;

}

获取地理位置信息的配置变量。在填入获取地理位置信息变量时,能够对获取地理位置的一些细节进行影响。下面是目前包括的几个具体参数

In ECMAScript, the enableHighAccuracy, timeout and maximumAge properties are all optional: when creating a PositionOptions object, the developer may specify any of these properties.

刚才也提到,我们还可以对地理位置进行持续的追踪,这是需要用到 watchPosition 方法。

因为对于移动设备的用户来说,位置并不是固定的,我们需要来处理这种移动客户端的情况,而不是每次要提醒用户去刷新浏览器来更新位置。

navigator.geolocation.watchPosition( refreshPosition );

与Mapabc API的整合

看完上面的关于 geolocation 的介绍之后,我们就可以将这个服务与Mapabc API一起,整合到我们的应用中了。下面是一个具体的实现样例,供参考:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<div>
    <div id="mapobj" style="width:500px; height:500px; border:1px solid black;"></div>
    <div id="info"></div>
    <input type="button" id="getPos" value="Get My Position" />
</div>
<script src="http://app.mapabc.com/apis?&t=flashmap&v=2.3.4&key=0c3235346b1e00772eafe1c099f4b23fe5ec1202d393f952395e628567934baceedcaf1508ea044f" type="text/javascript"></script>
<script type="text/javascript">
    function getPositionSuccess( position ){
        var lat = position.coords.latitude;
        var lng = position.coords.longitude;
        //alert( "您所在的位置: 经度" + lat + ",纬度" + lng );

        var mapOptions = new MMapOptions();//构建地图辅助类
        mapOptions.zoom=13;//设置地图zoom级别
        mapOptions.center=new MLngLat(lng,lat);   //设置地图中心点
        mapOptions.toolbar = MINI;//工具条
        mapOptions.toolbarPos = new MPoint(15,15);  //工具条偏移
        mapOptions.overviewMap = SHOW;//是否显示鹰眼
        mapOptions.scale = SHOW;//是否显示比例尺
        mapOptions.returnCoordType = COORD_TYPE_OFFSET;//返回偏移明码坐标
        mapOptions.zoomBox = true;//鼠标滚轮缩放和双击放大时是否有红框动画效果。
        mapabc.map=new MMap("mapobj",mapOptions); //地图初始

        if(typeof position.address !== "undefined"){
                var country = position.address.country;
                var province = position.address.region;
                var city = position.address.city;
                alert(’ 您位于 ‘ + country + province + ‘省’ + city +’市’);
        }
    }

    function getPositionError( error ){
        switch(error.code){
            case error.TIMEOUT :
                alert( " 连接超时,请重试 " );
                break;
            case error.PERMISSION_DENIED :
                alert( " 您拒绝了使用位置共享服务,查询已取消 " );
                break;
            case error.POSITION_UNAVAILABLE :
                alert( " 亲爱的火星网友,非常抱歉,我们暂时无法为您所在的星球提供位置服务 " );
                break;
        }
    }

    var dom = {
        btn    : document.getElementById("getPos"),
        info: document.getElementById("info"),
        map    : document.getElementById("mapObj")
    };

    var mapabc = {
        map        : null,
        marker    : null
    };

    dom.btn.onclick = function(){
        if( navigator.geolocation ){
            dom.info.innerHTML = "Waiting for the geolocation result…";
            navigator.geolocation.getCurrentPosition( getPositionSuccess, getPositionError );       
        } else {
            dom.info.innerHTML = "Your browser doesn’t support geolocation.";
        }
    }
</script>
</body>
</html>

上面的代码,会在地图显示后询问用户是否共享位置信息,如果共享则会切换地图中心点到相应的位置。当然,我们可以在自己的应用中更加灵活的使用位置共享服务,既然有了这么 Cool 的服务支持,我们还等什么呢。

 

 

 

参考资料:

1、Blueidea BBS
2、Geolocation API Specification
3、Mapabc API

Categories: WebTech Tags: ,

VIM在多窗口编辑时的几个快捷键

June 25th, 2010 CoCoWool No comments

image

使用VI提供的多窗口编辑在项目文件比较多的情况下非常方便。今天总结了几个比较好用的快捷键。

最基本的是打开分割窗口 :sp a.pl

切换窗口 Ctrl + w 按一次加上下键可以自己选择切换方向,按两次则从上到下自动遍历窗口

扩大窗口 Ctrl-w + 扩大窗口

缩小窗口 Ctrl-w – 缩小当前编辑窗口

在vim中执行shell命令 :! ls 这样可以执行shell命令,或者也可以 :shell top

放大当前窗口,缩小其他窗口 :res ,后面可以设置行数,比如 :res 10 则将当前窗口设置为10行

有了这几个功能,在vim中编辑复杂的项目也变得非常简单了

Categories: WebTech Tags:

设计网事读书笔记

June 13th, 2010 CoCoWool No comments

从三月份的时候开始读,利用零零星星的时间,终于读完了千年的《设计网事》这本书。虽名为书,实则是他最近几年的博文汇集而来。纵观此书,却与阅读单篇感觉很不一样。下面是读书的时候,摘抄的一些句子。

SEO的迎合对象是搜索引擎,而我们主张的迎合对象是用户需求

搜索引擎的需求其实就是用户需求的不完全表述

提供服务的关键是有没有效,而不是叫SEO或UCD

1998年,W3C发布HTML 4.0 Specification

每天都有无数的网站消失、无数页面在改版

改版的目标是平稳过渡,让大家不觉得这么陌生

用户挑剔,说明还在乎

Web Design是跨学科的技艺结合体,将来一定是互联网的世界

通过事物的本质去总结出概念,而不是通过概念放大理解事物的本质

超过90%的原创者无法做到有效积累,同样超过90%的阅读者对内容好坏没有准确判断力

互联网设计不是行业,只是个技术领域,参考立足于传统行业设计

规则有规则的秩序感,不规则有不规则的位置感

做真实的自己,不要想复制别人的生活方式和轨迹

此书并没有长篇累牍的的设计理论,也没有太多枯燥无味的技术教程,加上合理的编排,让我感觉受益良多

1、互联网产品,甚至做任何事情都得有自己的想法。所有事情都需要经过自己的思考提炼,而不是人云亦云。就像有一篇讨论电梯按钮排布的文章,平凡的日常现象,其实背后也有通用的艺术设计原则。我们一则是需要认真的观察,同时还需要融入自己的思考。做事情,不能为完成而完成,加入自己的想法,才能使产品不断地进步。

2、流程化的管理和团队合作非常重要。现在互联网的项目,不再是单枪匹马就能够做出花样的年代。Ajax、CSS、DOM结构、后台,构建一个成熟的Web 2.0应用时,这些东西必不可少,在不可能一个人全完成的情况下,团队协作和流程管理就非常重要。我目前所在的单位,基本上就是按照瀑布式的开发方式来进行的,我想国内多数做互联网的团队应该也都是这个模式。敏捷目前还没试验过,感觉其实现门槛比较高,只有小组成员都具备了敏捷的能力之后,才能谈得上。所以,我相信,规范化的管理流程,是推进提高生产率的关键因素。

3、用户体验,需要用心、细致的去做。在一个趋同的审美背景下,要把自己的产品做到出彩,做到令人过目不忘常回头。在用户体验的界面设计上,必须要用心、细致的去做。互联网产品的产生过程,是一个技术和艺术结合的过程。我们不能只看艺术性而忽略了开发商的难度,也不能只考虑开发上的便捷性,而把一堆丑陋的页面丢给用户。从重要性上来看,应该吧界面设计与交互设计放在技术开发之前。首先,很多需求的产生是来自战略层而不是技术人员,所以需要有足以说服人的细化的原型作为基础。

以上是一些合上书之后的胡思乱想,看来自己的思维系统性和整理性还是有待强化。

Technorati 标签: ,,,,,

PHP性能监测的工具介绍 – XHProf

June 2nd, 2010 CoCoWool No comments

XHProf

这个软件本是Facebook内部的一个应用工具,2009年3月份开源,为PHP的性能监测提供了很好的工具。官方的介绍中提到:

XHProf is a hierarchical profiler for PHP. It reports function-level call counts and inclusive and exclusive metrics such as wall (elapsed) time, CPU time and memory usage.

XHProf’s light-weight nature and aggregation capabilities make it well suited for collecting "function-level" performance statistics from production environments.

 

可以先来看看 XHProf 提供的图形界面的截图

 

XHProf的一些特性:

1、Flat Profile. 提供函数级的汇总信息,比如调用次数、执行时间、内存使用、CPU占用等。

2、Hierarchical Profile。 对每个程序,进行了父级调用和子级调用的分解。

3、Diff Reports(差异报告)。有很多种情况,我们希望能够对比,比如新版本比旧版本提升了多少速度,两个版本的差距究竟在哪里。Diff Report 就是这样的工具,接收两个输入,并且分别给出各自的 Flat Profile 和 Hierarchical Profile 报告。

4、Callgraph View(调用视图)。性能监测的数据可以绘制成调用视图,方便我们查看。

5、Memory Profile(内存监控)。这个特性帮助我们了解PHP如何分配和释放内存。值得注意的是,XHProf并不是严格的监测内存的分配和释放动作,而是计算每个函数进入和退出时的内存状况,这是一个相对简单的实现方式,但是基本上也能够满足我们日常的监控需求。

6、如何处理外部文件。XHProf将 include,require,include_once,require_once进来的文件视作是一个 function。

XHProf目前只支持一个级别的函数追踪,但是貌似也没有特别大的影响。

XHProf的安装配置

xhprof的安装配置很简单,我们首先在 PECL 的网站上下载 源码包 然后执行安装过程

% cd <xhprof_source_directory>/extension/
% phpize
% ./configure --with-php-config=<path to php-config>
% make
% make install
% make test

php.ini file: You can update your php.ini file to automatically load your extension. Add the following to your php.ini file.

[xhprof]
extension=xhprof.so
;
; directory used by default implementation of the iXHProfRuns
; interface (namely, the XHProfRuns_Default class) for storing
; XHProf runs.
;
xhprof.output_dir=<directory_for_storing_xhprof_runs>

 

xhprof的使用也很简单,只要将需要监控的脚本放在 xhprof_enable() 和 xhprof_disable() 中间,就可以得到相应的结果,同时也提供了一些参数可以让我们设置是否监控 Memory, CPU 的使用,是否监控PHP内置的函数,从 0.9.2 之后,还可以设置跳过一些特定的函数。

XHProf 生成的数据,可以用 XHProf UI 来进行简单的显示。

XHProf使用也很简单,下面是一个官方的例子:

<?php

function bar($x) {

  if ($x > 0) {

    bar($x – 1);

  }

}

function foo() {

  for ($idx = 0; $idx < 2; $idx++) {

    bar($idx);

    $x = strlen("abc");

  }

}

xhprof_enable(XHPROF_FLAGS_CPU + XHPROF_FLAGS_MEMORY);

foo();

$xhprof_data = xhprof_disable();

//

// Saving the XHProf run

// using the default implementation of iXHProfRuns.

//

include_once "xhprof_lib/utils/xhprof_lib.php";

include_once "xhprof_lib/utils/xhprof_runs.php";

$xhprof_runs = new XHProfRuns_Default();

// Save the run under a namespace "xhprof_foo".

//

// **NOTE**:

// By default save_run() will automatically generate a unique

// run id for you. [You can override that behavior by passing

// a run id (optional arg) to the save_run() method instead.]

//

$run_id = $xhprof_runs->save_run($xhprof_data, "xhprof_foo");

echo "—————\n".

     "Assuming you have set up the http based UI for \n".

     "XHProf at some address, you can view run at \n".

     "http://<xhprof-ui-address>/index.php?run=$run_id&source=xhprof_foo\n".

     "—————\n";

?>

 

我们可以持久化记录的数据,数据以文件的形式保存在指定的目录,如下图:

image 有了这个工具,我们可以根据其提供的数据,与相应的通知接口整合,在程序运行出现问题时,及时的发送通知信息。

 

PHP性能监控,还有两个可用的工具,一个是 XDebug,另外一个是 ZendServer,我会在接下来继续进行介绍。

Technorati 标签: ,,

参考文档:

1、Speed UP your php with xhprof

2、xhprof document

Categories: WebTech Tags: , , , ,

利用PUT方式上传文件的方法研究

May 30th, 2010 CoCoWool No comments

虽然没有POST方法使用广泛,但是PUT方法却是向服务器上传文件最有效率的方法。POST上传文件时,我们通常需要将所有的信息组合成 multipart 传送过去,然后服务器再解码这些信息,解码过程则必不可少的会消耗内存和CPU资源,这种现象在上传大文件时尤其明显。而PUT方法则允许你通过与服务器建立的socket链接传递文件的内容,而不附带其他的信息。

最近一个项目上需要利用这种方式来进行文件的上传,下面介绍一下在 Apache + PHP 的环境下如何进行PUT方式的文件上传。

Apache 有一个模块 mod_actions,先看看官方的说明:

This module has two directives. The Action directive lets you run CGI scripts whenever a file of a certain MIME content type is requested. The Script directive lets you run CGI scripts whenever a particular method is used in a request. This makes it much easier to execute scripts that process files.

也就是说,这个模块可以指定对于特定 MIME 类型的文件处理,或者对于特定脚本的请求进行指定的处理。我用到的就是 Script 这个选项。

在Apache 配置文件的 Directory 中指定

Script PUT /receive.php

这个含义就是,对于所有对服务器的PUT请求,都交给根目录下的 receive.php 去处理,当然我们也可以选择 perl 或者其他的CGI脚本来进行处理。

接下来就是这个 receive.php 脚本的编写了,他的主要任务就是将请求的文件写到指定的位置

<?php
/**
* Process The PUT File, receive and move a file to corresponsed location
* Created by shiqiang<cocowool@gmail.com> at 2010-05-24
*
**/

class Receive {
    var $default_log_file = "logs/error.log";
    var $default_server_info = "logs/server.log";
    var $default_header_info = "logs/header.log";
    var $default_prefix = "/data1/vhosts";    //Default project location prefix;
    var $default_module = "test.cn";
    var $max_filesize = 2048000;
    var $request_uri;

    function Receive(){
        $this->request_uri = $_SERVER['REQUEST_URI'];
    }
    function saveFile(){
        //receive data and save
        $putdata = fopen("php://input", "r");

        $path = $this->getPath($this->request_uri);
        $fp = fopen($path, ‘w’);
        while($data = fread($putdata, 1024) ){
            fwrite($fp, $data);
        }

        fclose($fp);
        fclose($putdata);

        //Log The filesize check and limit check
        if( filesize($path) != $_SERVER['CONTENT_LENGTH'] ){
            $this->errorLog( "[warn] " . date("Y-m-d H:i:s")  . " The file’s ($path) size dosen’t match Server Filesize = " . filesize($path) . "; Put Filesize = " . $_SERVER['CONTENT_LENGTH']. "\r\n" );
            header(’HTTP/1.1 526 Receive Data Error’);
        }

        if( filesize($path) > $this->max_filesize ){
            $this->errorLog( "[warn] " . date("Y-m-d H:i:s")  . " The file’s ($path) size exceed the system limit");
        }
    }

    //Log Error Info
    function errorLog( $info ){
        $f = fopen($this->default_log_file, ‘a+’);
        fwrite($f, $info);
        flcose($f);
    }

    function serverLog(){
        $f = fopen($this->default_server_info, ‘w’);
        $info = $_SERVER;
        $str = "The Last Request Server Info:\r\n";
        foreach ($info as $key => $value){
            $str .= "$key = $value\r\n";
        }
        $str .= $this->getPath($this->request_uri) . "\r\n";
        $str .= "PHP_UPLOADED_FILE_NAME=" . $PHP_UPLOADED_FILE_NAME . "\r\n";
        fwrite($f , $str);
        fclose($f);
    }

    //Log the Request Header info
    function headerLog(){
        $f = fopen($this->default_header_info, ‘w’);
        $info = get_headers();
        $str = "The Last Request header Info:\r\n";
        foreach ($info as $key => $value){
            $str .= "$key = $value\r\n";
        }
        fwrite($f , $str);
        fclose($f);
    }

    //get the path where the file should be
    function getPath($uri){
        $module = $this->defalt_module;    //Default storage module

        $referer = $this->request_uri;
        preg_match(’/(?<=\/)(.*?)(?=\/)/s’, $referer, $match);

        if( !empty($match) && !empty($match[0]) ){
            $module = $match[0];
        }

        $path = $this->default_prefix;
        $path .= ‘/’ . $module . ‘/htdocs’;
        $fullpath = substr($uri, strlen($match[0]) + 1, strlen($uri) );

        $arr = explode(’/', ltrim($fullpath, ‘/’));
        foreach($arr as $v){
            if( !strstr($v, ‘.’) ){
                $path .= ‘/’ . $v;
                //exec("echo $path >> dir.txt");
                if( !is_dir($path) ){
                    //For php > 5.0
                    //mkdir($path, "0766", true);
                    mkdir($path, 0766);
                }
            }else{
                $path .= ‘/’ . $v;
            }
        }

        return $path;
    }

}

$instance = new Receive();
$instance->serverLog();
//$instance->headerLog();
$instance->saveFile();

?>

这个脚本,使用PHP手册中的接收PUT方式的方法,详细的使用,GOOGLE的时候,并没有找到很多,所以可能对于错误情况,考虑的也不是很全面,如果有使用过这个方法的欢迎和我讨论。

Technorati 标签: ,,

参考资料:
1、PUT Upload
2、RFC 2616

Categories: WebTech Tags: , , ,

通过设置双网卡实现VirtualBox虚机上网及主宿互访

May 26th, 2010 CoCoWool No comments

最近,经过一些研究,终于调通了VirtualBox虚拟机互连、主宿机互连、以及主宿机连接互联网。下面分享一下。

1、VirtualBox中的虚拟网卡。VirtualBox安装完成后,会在系统中装一块虚拟网卡,我们在管理->全局设定中可以看到。这块网卡是在 Host-Only 连接方式中,主宿机互访的桥梁。

0GNO4}~D]5R]S32KPW37B}7

2、主机访问虚拟机通过Host Only的方式实现。

主机访问虚拟机这个是最简单的。通过在网络连接1中选择 Host-only Adapter ,我们的虚拟机就可以获得一个内网的地址,主机可以直接访问这个地址。我们可以使用DHCP,也可以自己指定IP,多数情况下,都会指定一个固定的IP。

PUB}7VB28B%2SQS4)E%EXDY

3、现在要想实现虚拟机上网,我们可以为虚拟机再添加一块网卡,通过Bridge方式,达到虚拟机上网的目的。

9)N`XA15%{3UJIGA}D~IW3N

4、但是笔者在这样设置以后,测试 ping www.baidu.com 时,发现网络并没有通,仔细检查后发现,需要在我们的第二块网卡的配置上,指定他的网关。我在 /etc/sysconfig/network-scripts/ifcfg-eth1 中添加

GATEWAY=10.207.0.11

重启网络之后,就可以PING通了。

这样,我们既能访问虚拟机,又可以访问互联网,利用各种在线更新的工具,大大的方便了 Linux 的使用。

基于Mapabc API的周边查询应用

May 23rd, 2010 CoCoWool No comments

现在,越来越多的 Location Based 应用,或者Geolocation的应用出现在网络、手机等各种各样的终端上,为人们的日常生活、出行和工作都提供了不少的便利。最常见的就是出门前,利用地图工具,看看合适的公共交通路线,寻找一个自己最满意的方案,既方便有低碳环保。有时候,对周边环境不熟悉,想要找到周边的医院、银行、学校等一些单位的时候,地图同样可以帮上我们的大忙。

今天,我就做了一个基于Mapabc地图API的周边查询工具,利用Mapabc详尽的基础地物信息,为我查找周边的便民信息提供了有利的帮助。

开始之前,我大概需要知道最后的结果是什么样子的,可以借助传统的纸和笔,也可以用现代的原型工具,当然PS这样的重量级工具就不太需要了。下面是效果图:

1131

有了效果图,接下来需要稍微规划一下代码。Mapabc的API在页面加载完成后,需要初始化地图,所以初始化的操作放在一个函数 pageInit() 中。周边查询的操作,希望通过用户输入一个关键词,然后通过点选地图设置中心点的方式实现。那么就需要一个函数来监听鼠标在地图上的单击事件,然后一个负责查询的函数和一个负责显示结果的函数。程序的结构大致如此,接下来就进入实质的编码过程。

编码的重点函数有以下几个:

mapObj.addEventListener(mapObj, MOUSE_CLICK, searchAround);

对地图添加监听事件。

mls.poiSearchByCenterXY(new MLngLat(cordx, cordy),keyword,citycode,mlsp);

利用中心点坐标查询查找周边信息

利用这两个函数,加上参考Mapabc官方的示例,我们就可以完成这个应用。

1132

通过修改区号和关键字,可以在不同城市之间切换,怎么样,简单吧。

Technorati 标签: ,,,
Categories: WebTech Tags: