标签:php

浏览模式: 标准 | 列表 | 图文
php simplexmlElement 操作xml的命名空间

php simplexmlElement 操作xml的命名空间

这是今天中午发生的事情,有人在群里求助,比如xml中如果标记是<xx:xxxx>content</xx:xxxx>这样的情况下,取不到 xx:xxxx 为下标的值。
看了这个问题,第一个反应就是namespace的关系,但我从来没有使用simplexml操作过namespace,于是就翻开手册查了一下资料,问题并没有解决,最终是通过google解决了该问题。

提问题的朋友贴出了数据源,来自于:http://code.google.com/intl/zh-CN/apis/contacts/docs/3.0/developers_guide_protocol.html#retrieving_without_query,数据结构大致如下:

<feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearch/1.1/' xmlns:gContact='http://schemas.google.com/contact/2008' xmlns:batch='http://schemas.google.com/gdata/batch' xmlns:gd='http://schemas.google.com/g/2005' gd:etag='W/"CUMBRHo_fip7ImA9WxRbGU0."'>
<id>liz@gmail.com</id>
<updated>2008-12-10T10:04:15.446Z</updated>
<category scheme='http://schemas.google.com/g/2005#kind' term='http://schemas.google.com/contact/2008#contact' />
<title>Elizabeth Bennet's Contacts</title>
<link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='https://www.google.com/m8/feeds/contacts/liz%40gmail.com/full' />
<link rel='http://schemas.google.com/g/2005#post' type='application/atom+xml' href='https://www.google.com/m8/feeds/contacts/liz%40gmail.com/full' />
<link rel='http://schemas.google.com/g/2005#batch' type='application/atom+xml' href='https://www.google.com/m8/feeds/contacts/liz%40gmail.com/full/batch' />
<link rel='self' type='application/atom+xml' href='https://www.google.com/m8/feeds/contacts/liz%40gmail.com/full?max-results=25' />
<author>
<name>Elizabeth Bennet</name>
<email>liz@gmail.com</email>
</author>
<generator version='1.0' uri='http://www.google.com/m8/feeds'> Contacts </generator>
<openSearch:totalResults>1</openSearch:totalResults>
<openSearch:startIndex>1</openSearch:startIndex>
<openSearch:itemsPerPage>25</openSearch:itemsPerPage>
<entry gd:etag='"Qn04eTVSLyp7ImA9WxRbGEUORAQ."'>
<id> http://www.google.com/m8/feeds/contacts/liz%40gmail.com/base/c9012de </id>
<updated>2008-12-10T04:45:03.331Z</updated>
<app:edited xmlns:app='http://www.w3.org/2007/app'>2008-12-10T04:45:03.331Z</app:edited>
<category scheme='http://schemas.google.com/g/2005#kind' term='http://schemas.google.com/contact/2008#contact' />
<title>Fitzwilliam Darcy</title>
<gd:name>
<gd:fullName>Fitzwilliam Darcy</gd:fullName>
</gd:name>
<link rel='http://schemas.google.com/contacts/2008/rel#photo' type='image/*' href='https://www.google.com/m8/feeds/photos/media/liz%40gmail.com/c9012de' gd:etag='"KTlcZWs1bCp7ImBBPV43VUV4LXEZCXERZAc."' />
<link rel='self' type='application/atom+xml' href='https://www.google.com/m8/feeds/contacts/liz%40gmail.com/full/c9012de' />
<link rel='edit' type='application/atom+xml' href='https://www.google.com/m8/feeds/contacts/liz%40gmail.com/full/c9012de' />
<gd:phoneNumber rel='http://schemas.google.com/g/2005#home' primary='true'> 456 </gd:phoneNumber>
<gd:extendedProperty name='pet' value='hamster' />
<gContact:groupMembershipInfo deleted='false' href='http://www.google.com/m8/feeds/groups/liz%40gmail.com/base/270f' />
</entry>
</feed>

这个结构在上面的地址里有,这个是我格式化过的XML数据,现在要取得类似于“<gd:phoneNumber rel='http://schemas.google.com/g/2005#home' primary='true'> 456 </gd:phoneNumber> ”中的值。

最终代码如下:

$x = new SimpleXmlElement($str);
foreach($x->entry as $t){
echo $t->id . "<br >";
echo $t->updated . "<br />";
$namespaces = $t->getNameSpaces(true);
$gd = $t->children($namespaces['gd']);
echo $gd->phoneNumber;
}

当然,如果不象上面这样写,也可以写成这样:

$x = new SimpleXmlElement($str);
foreach($x->entry as $t){
echo $t->id . "<br >";
echo $t->updated . "<br />";
//$namespaces = $t->getNameSpaces(true);
//注意这里与上面一段的区别
$gd = $t->children('http://schemas.google.com/g/2005');
echo $gd->phoneNumber;
}

只是象第二种写法就属于硬编码了,这样不太好,万一哪天有变化,还得再更改N多代码。
问题接踵而来,比如象下面这段:

<event:event>
<event:sessionKey></event:sessionKey>
<event:sessionName>Learn QB in Minutes</event:sessionName>
<event:sessionType>9</event:sessionType>
<event:hostWebExID></event:hostWebExID>
<event:startDate>02/12/2009</event:startDate>
<event:endDate>02/12/2009</event:endDate>
<event:timeZoneID>11</event:timeZoneID>
<event:duration>30</event:duration>
<event:description></event:description>
<event:status>NOT_INPROGRESS</event:status>
<event:panelists></event:panelists>
<event:listStatus>PUBLIC</event:listStatus>
</event:event>

这种非标准的XML,没有定义命名空间,怎么办?在这种情况下,其实SimpleXmlElement就已经直接可以解决了,但是会报warnging,因为他认为event这个命名空间不存在。
解决方法是:

$xml = @new SimpleXmlElement($str);//在前面加@抑止错误。
echo "<pre>";
print_r($xml);

目前看来,这种解决方法比较好。

linux filename xss攻击

linux filename xss攻击

看到这篇文章的时候是在晚上,然后就觉得好郁闷,不过也挺佩服淘宝QA那些人的奇思怪想,看看他们是怎么说的吧。

一、关于文件名
大家都知道在 windows 下面文件名是有规则,定义了一些保留的字符,他们分别是:

< (less than)
> (greater than)
: (colon)
" (double quote)
/ (forward slash)
\ (backslash)
| (vertical bar or pipe)
? (question mark)
* (asterisk)

而linux下面是没有对这些大部分字符进行限制的,可以随意定义的,那么,我们就可以将 XSS Pyload 存储在文件名中,如图所示:
4b8ced78664c77720f8612082fdf9068
我们可以看到可以成功将 xss pyload 存储在文件名当中了。
二、利用攻击
很多时候,由于代码的各种环境,让我们的攻击成为可能,查看以下PHP上传文件代码:

<?php
if ($_FILES["file"]["error"] > 0)
{
echo "Error: " . $_FILES["file"]["error"] . "<br />";
}
else
{
echo "Upload: " . $_FILES["file"]["name"] . "<br />";
echo "Type: " . $_FILES["file"]["type"] . "<br />";
echo "Size: " . ($_FILES["file"]["size"] / 1024) . " Kb<br />";
echo "Stored in: " . $_FILES["file"]["tmp_name"];
}
?>
<html>
<body>
<form action="" method="post" enctype="multipart/form-data">
<label for="file">Filename:</label>
<input type="file" name="file" id="file" />
<br />
<input type="submit" name="submit" value="Submit" />
</form>
</body>
</html>
当文件上传成功,程序将文件信息进行输出。而此时没有对文件名进行任何处理,那么,如果将我们定义好的特殊字符的文件名进行上传,然后经过程序输出,就可以攻击了,如图所示:

3ca3c42982ee32774da3937b31894834

可以看到,我们确实可以攻击成功了!那么,并不是所有的上传地方都存在,要满足以下条件才可以:
1、文件上传后保存前进行了一次原样输出。
2、直接按原文件名进行存储。
3、其他特定环境,看程序逻辑。
4、web server 为 linux。
5、上传攻击机器为 linux。
示例代码:http://code.google.com/p/madal-example-project/source/browse/trunk/controllers/image_uploader.php?r=2
更多的:http://code.google.com/query/#q=$_FILES[%22file%22][%22name%22]
线上攻击测试:http://www.woyigui.cn/fileupload.php

三、防范
1、存储时以随机文件名保存。
2、任意时候对文件名进行处理后输出,可以进行 html 编码后输出。

参考:

http://msdn.microsoft.com/en-us/library/aa365247%28VS.85%29.aspx

--EOF——

原文来自:http://qa.taobao.com/?p=10139,虽然这个条件很苛刻,但毕竟还是存在被注入的可能啊,而且这种注入真的很妖。

随笔,乱弹

随笔,乱弹

随笔,乱弹,随便说说一些事情喽。

这篇,用WEB来实现UNIX负载的监控,其实也就是用exec来执行一些unix下的命令,但事实上这种方式可能是不成功的(因为WEB执行权限应该是没有过多的权利去执行那些程序。。。),可以看看这篇:http://www.cnblogs.com/wgw8299/archive/2010/11/05/1870138.html,随便看看喽。

了解一些JS效率低下的原因,可以让你在写程序的时候注意到很多,比如这篇JavaScript游戏之优化篇,虽然是讲的游戏中的一些JS优化,但是可以发现,这些东西在普通的WEB开发中也会遇到,也可以用来进行JS的性能提升。

这篇文章讲的也是JS中的问题,记一次开发中一个奇特的错误,这个问题我虽然没有遇到过,但是我们在开发中遇到过另外的事情,发现一个问题,是发现有一个效果在Firefox下正常,但是IE下不正常。最后查来查去,居然是因为文字做了一个断行(Firefox会自动忽略,但是IE对这个\t却不能忽略,有点妖。。。)

这篇文章嘛。。黑黑,其实是一种常见的手段,不过,据我了解,目前很多做WEB居然还是不知道有这个工具,所以也算是对该软件的介绍吧,用Fiddler给别人的网站“优化”,WEB开发有很多这样的小工具,适时的用上,一来可以协助自己开发,二来也能针对性对于WEb进行优化。

Lnmp一键安装

Lnmp一键安装

如果你是VPS,又不太会配置系统,那么这个选择就挺不错的。。LNMP一键安装包,一下子就把所有的东西全部安装回来了,而且每增加一个域名之类的都不算特别难,当然前提是你最起码得懂一点点linux的操作,比如你会使用ssh,那样,你在vps下就能很方便的操作了(我今天操作了一次,只是安装的时候非常长,还好,国外的VPS速度很快,就是编译时间长了一点)
来吧,看步骤和内容吧。

系统需求:

  • 需要2 GB硬盘剩余空间
  • 128M以上内存
  • 安装步骤:

    1、下载LNMP一键安装包:
  • 可以选择使用下载版(推荐国外或者美国VPS使用)或者完整版(推荐国内VPS使用),如果使用下载版执行命令 wget -c http://soft.vpser.net/lnmp/lnmp0.5.tar.gz,如果使用完整版,执行命令 wget -c http://soft.vpser.net/lnmp/lnmp0.5-full.tar.gz,执行上述命令后LNMP一键安装包就会被下载到VPS上。

  • 2、解压LNMP一键安装包:
  • 执行tar zxvf lnmp0.5.tar.gz 或者tar zxvf lnmp0.5-full.tar.gz 就会将LNMP一键安装包解压缩。

  • 3、CentOS下安装步骤
  • 下载版执行命令 cd lnmp0.5/ ,完整版执行命令:cd lnmp0.5-full/
  • 然后再执行./centos.sh ,输入要绑定的域名,回车,再输入要设置的MySQL root的密码,再次回车确认。程序会自动安装编译Nginx、PHP、MySQL、phpMyAdmin、Zend这几个软件。

  • 4、Debian/Ubuntu下安装步骤
  • 下载版执行命令 cd lnmp0.5/ ,完整版执行命令:cd lnmp0.5-full/
  • 然后32位系统执行./debian.sh ,输入要绑定的域名,回车,再次输入VPS/服务器所在位置:asia、 america、europe、oceania或africa,回车,再输入要设置的MySQL root的密码,回车后,再次回车确认。程序会自动安装编译Nginx、PHP、MySQL、phpMyAdmin、Zend这几个软件。安装大约10分 钟左右需要设置MySQL root用户的密码。
  • 安装其他组件

  • 1、安装eAccelerator,执行如下命令:./eaccelerator.sh 就会自动安装并重启web服务。
  • 2、安装ionCube,执行如下命令:./ionCube.sh 就会自动安装并重启web服务。
  • 3、安装PureFTPd和管理面板,执行如下命令:./pureftpd.sh 就会自动安装PureFTPd,安装完PureFTPd,需要在浏览器执行http://你的域名或IP/ftp/install.php 安装PureFTPd用户管理。详细教程参考:http://www.vpser.net/manage/lnmp-pureftpd-cp.html
  • 4、安装VsFTPD,执行如下命令:./vsftpd.sh 就会自动安装上vsftpd,只需要执行命令:useradd -d /home/wwwroot -s /sbin/nologin adminftp 添加上帐号指定好ftp帐号的根目录,再执行:passwd adminftp 设置上密码,登录就可以了。
  • 虚拟主机管理

  • 1、添加虚拟主机,执行如下命令:/root/vhost.sh 根据提示输入要绑定的域名,回车,如果需要添加更多的域名,输入y,再输入要另外绑定的域名,多个域名可以用空格隔开。再输入域名绑定的目录(绝对目录, 如/home/wwwroot/lnmp,如果不填默认是/home/wwwroot/绑定的域名),再选择是否添加伪静态规则,默认已经有了 Discuz、Wordpress、Sablog、emlog、dabr,可直接输入以上名称即可,如果需要添加自定义伪静态规则,直接输入一个想要的名 字,程序会自动创建伪静态文件,直接在/usr/local/nginx/conf/你自定义的伪静态名字.conf 里面添加伪静态规则就行。接下来会提示是否需要启用日志功能,一般情况下不需要启动,直接输入n就行,如需启动,输入y,再输入要定义的日志文件名字,回 车就会自动添加虚拟主机。

  • 2、状态管理及相关管理页面
    LNMP状态管理: /root/lnmp {start|stop|reload|restart|kill|status}
    PureFTPd状态管理 /root/pureftpd {start|stop|restart|kill|status}
    phpinfo : http://前面输入的域名或IP/phpinfo.php
    phpMyAdmin : http://前面输入的域名或IP/phpmyadmin/
    探针 : http://前面输入的域名或IP/p.php
    MySQL root密码:如果不输入直接回车为root,否则为你输入的密码。

    LNMP相关目录:
    mysql : /usr/local/mysql
    php : /usr/local/php
    nginx : /usr/local/nginx
    网站目录: /home/wwwroot
  • 注:已经在DiaHosting、PhotonVPS(感谢提供测试VPS)、RasHost、VPSYOU、VPS.net、breezehost、Rapidxen 及几位lnmp网友提供的VPS上的CentOS 32/64bit、Debian 4/5 32/64bit上测试成功。同时感谢提供测试VPS的商家及网友。

    来源:http://lnmp.org/install.html

    笔记:开发PHP中的粗心导致的问题

    笔记:开发PHP中的粗心导致的问题

    开发中,总是会有粗心的情况出现,只是有时候这些问题还真的不容易被发现和注意。或者说,是不好的习惯导致了问题的隐藏。

    在项目中使用memcache的时候,出现了:php_network_getaddresses: getaddrinfo failed,理论上,这是因为DNS解析有问题造成的,因此可以证明的是

    1、dns有问题
    2、hosts里没有加正确
    3、配置的URL是否有问题

    检查了这三个都没有问题的时候,人傻了,问题在哪里?确定从代码上看问题,最后才发现。。原来是代码上的粗心导致问题的产生。使得应该传递的host参数传递了空值(为什么memcache在遇到空值是不能自动判断为localhost呢?)不过,如果真这么判断了,估计我也永远找不到这个BUG了。

    以后还是要细心啊。

    为ubuntu 10的php版本降级

    为ubuntu 10的php版本降级

    一键式安装PHP果然还是有问题的,不是说程序有问题,而是说版本。其实在9.10的时候,PHP已经被ubuntu默认为5.3了。这就让人很痛苦了,现在很多程序在5.3下跑不起来。怎么办?降级喽。还能怎么办?
    这里有很多方式,不过,我还是建议使用第一种,最方便不过了:http://2bits.com/drupal-planet/various-ways-running-php-52-ubuntu-1004-lucid-lynx.html
    第一种是这样的,先搞一个脚本运行一下:

    #!/bin/sh
    
    # Script to install PHP 5.2 from 9.10 on 10.04
    # And pin it so it does not get updated
    
    PKGS=`dpkg -l | grep php | awk '{print $2}'`
    
    apt-get remove $PKGS
    
    sed s/lucid/karmic/g /etc/apt/sources.list |
    tee /etc/apt/sources.list.d/karmic.list
    
    mkdir -p /etc/apt/preferences.d/
    
    for PACKAGE in $PKGS
    do
    echo "Package: $PACKAGE
    Pin: release a=karmic
    Pin-Priority: 991
    " | tee -a /etc/apt/preferences.d/php
    done
    
    apt-get update
    
    apt-get install $PKGS

    这时候,其实最后一步经常会失败。。(因为他的安装顺序可能不是php5-common在第一个)
    因此在运行完第一句PKGS后,可以Echo $PKGS > xxx.php.list ,将它输出到一个文件里。如果最后一步失败了,再把这个PKGS导出的变量查看一下,再尝试重新install。避免有遗漏。

    这里还介绍了drupal在安装的时候的一些问题:http://randyfay.com/node/63,上面的链接其实就是从这篇文章里找到的。(我不建议用randyfay.com里的源,速度还是比较慢的,如果你原来的源速度很快,那就不要换了,直接用上面的脚本吧。)以前就说过。网易的源还是不错的。。可以加上去喽。

    Editplus 自动检查语法

    Editplus 自动检查语法

    用惯了IDE写PHP,再次回到Editplus的时候总有点不太习惯,比如没有函数提示了(当然也可以自己打造)。不过。。语法检查总还是需要的,总不能自己程序传到服务器上后运行了才知道语法有问题吧?于是利用Editplus的小功能aftersave。改造了一下。

    进入editplus的选项设置,点击左侧的User tools菜单,在右侧的Group and Tools下拉框中选择 AutoSave:after save。

    1eb4da3ab0048828ba2a29d3c4545c6a

    在右侧的 add tool里选择 program。然后输入:标题,程序所在位置,以及参数。。

    php语法检测是php.exe -l filename,这个可以通过命令行下运行 php -? 了解。然后要catch output,以及针对current file。。

    OK,这样就over了。

    看看效果?

    95ce8150adb63552a893ffe8e83d2ddb

    js模拟php:print_r

    js模拟php:print_r

    在PHP中,我们打印一个数组或者对象的时候,都是用print_r,相对比较直观,可是javascript就不行。翻了翻资料,也看到一些代码的写法。这里是一个简单的处理(不能打印window,document等对象):

    function print_r( $value ){
    if($value.constructor == Array || $value.constructor == Object ){
    document.write("<ul>");
    for (var $i in $value){
    if($value[$i].constructor == Array || $value[$i].constructor == Object ){
    document.write("<li>["+$i+"] => " + typeof( $value ) + " </li><ul>");
    print_r($value[$i]);
    document.write("</ul>");
    }else{
    document.write("<li>["+$i+"] => " + $value[$i] + "</li>");
    }
    }
    document.write("</ul>");
    }
    }
    var s = {};
    s.i = '123';
    s.o = {};
    s.o.test = 'tt';
    print_r(s);

    然后看了一下phpjs.org,它上面的print_r就比较复杂了。。。

    function print_r (array, return_val) {
    // Prints out or returns information about the specified variable
    //
    // version: 1008.1718
    // discuss at: http://phpjs.org/functions/print_r // + original by: Michael White (http://getsprink.com)
    // + improved by: Ben Bryan
    // + input by: Brett Zamir (http://brett-zamir.me)
    // + improved by: Brett Zamir (http://brett-zamir.me)
    // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) // - depends on: echo
    // * example 1: print_r(1, true);
    // * returns 1: 1
    
    var output = "", pad_char = " ", pad_val = 4, d = this.window.document; var getFuncName = function (fn) {
    var name = (/\W*function\s+([\w\$]+)\s*\(/).exec(fn);
    if (!name) {
    return '(Anonymous)';
    } return name[1];
    };
    
    var repeat_char = function (len, pad_char) {
    var str = ""; for (var i=0; i < len; i++) {
    str += pad_char;
    }
    return str;
    };
    var formatArray = function (obj, cur_depth, pad_val, pad_char) {
    if (cur_depth > 0) {
    cur_depth++;
    }
    var base_pad = repeat_char(pad_val*cur_depth, pad_char);
    var thick_pad = repeat_char(pad_val*(cur_depth+1), pad_char);
    var str = "";
    if (typeof obj === 'object' && obj !== null && obj.constructor && getFuncName(obj.constructor) !== 'PHPJS_Resource') {
    str += "Array\n" + base_pad + "(\n";
    for (var key in obj) {
    if (obj[key] instanceof Array) {
    str += thick_pad + "["+key+"] => "+formatArray(obj[key], cur_depth+1, pad_val, pad_char); } else {
    str += thick_pad + "["+key+"] => " + obj[key] + "\n";
    }
    }
    str += base_pad + ")\n"; } else if (obj === null || obj === undefined) {
    str = '';
    } else { // for our "resource" class
    str = obj.toString();
    }
    return str;
    };
    
    output = formatArray(array, 0, pad_val, pad_char);
    if (return_val !== true) {
    if (d.body) {
    this.echo(output);
    } else {
    try {
    d = XULDocument; // We're in XUL, so appending as plain text won't work; trigger an error out of XUL
    this.echo('<pre xmlns="http://www.w3.org/1999/xhtml" style="white-space:pre;">'+output+'</pre>');
    } catch (e) {
    this.echo(output); // Outputting as plain text may work in some plain XML
    }
    }
    return true; } else {
    return output;
    }
    }

    果然是没有做不到的事,只有想不到的事呀。。。(上面的phpjs.org的print_r需要echo方法,请到phpjs.org下载)

    写在NetBeans IDE 6.9.1 发布时

    写在NetBeans IDE 6.9.1 发布时

    怎么说呢,netbeans这个IDE工具是目前我用的时间最长的一款IDE,以前也用过其他的一些IDE,不过,在算上版权问题后,这是目前唯一一款值得推荐的IDE吧?komodoEdit和netbeans相比,功能差了很多。当然各人习惯不一样,有的人喜欢拿GVIM来配置,把它配置成一款符合自己使用习惯的IDE,这,我也没话说。

    正好看到cnbeta上说了6.9.1发布了,仔细看了一下更新内容,对于PHP来说,只有一小部份的更新,那就是:支持 PHP Zend 框架。这让我很吃惊。事实上,虽然我挺力挺这款IDE,但对他还是有抱怨的,或许在以前的贴子里也发表过,这里我再发发牢骚。。
    用到现在nb让我郁闷的有几件事
    1、同一项目中不能存在两种编码的文件。。。否则读取可能会是乱码(不过,这个能忍,自己的项目能够保证,主要是别人的)

    2、耗内存,还有就是项目扫描,好几次就死在这上面了,卡死了

    3、自动換行。配置里的自动换行永远是灰色的。。明明有这玩意却不能用。太让人郁闷了。。。

    其他。。。好象还都能忍受 。在6.9更新的时候(http://wiki.netbeans.org/NewAndNoteworthy69#PHP),我们也看到,6.9对于PHP最大的更新其实就是formatter。格式化代码更优秀和准确了(在团队中,可以更方便的把代码格式化成同一风格,方便后来人),还有一个就是改进了语法检测。

    虽然问题有一堆 ,不过,我还是推荐它。除非出来一款更好的(还要能跨平台,比如当我用LINUX进行IB的时候,我也有功能强劲的IDE可用)

    新闻:开源公司 IronTec将推动PHP进驻Android平台

    新闻:开源公司 IronTec将推动PHP进驻Android平台

    看到这个新闻不转载一下恐怕对不起自己。
    本来都以为自己会学习scala然后进行android的开发了,现在看来,还有其他的途径啊。当然,效率可能不能保证吧?(小应用估计没大问题。)不过在看到新闻的同时也要想到,PHP做界面的话,可不一定就OK呀。

    上新闻:

    对Java心生厌恶的朋友们 不妨来看看Android上的新玩意--PHP。

    PHP可不仅仅只能在互联网站上发 展,一个PHP for Android (PFA)网站表示他们将可以发布编程模型、工具盒文档让PHP在Android上实现应用。

    该项目的主要赞助商是开源公司IronTec,PFA使用Scripting Layer for Android (SL4A),也就是Androd Scripting Environment (ASE)来实现这一点,您可以参看他们的网站来了解更多技术内幕。

    【事实上,我并未找到这个网站,而对于ASE,其实在09年infoQ上已经有介绍】

    Android Scripting Environment(ASE)项目为Android增加了脚本支持。通过安装ASE,我们可以在设备上编写脚本并执行。

    虽然现在已经涌现出了不少工具用于开发Android应用,但如果能在设备上编写脚本将是一件很爽的事情,这样我们就可以直接在设备上进行试验并快 速编写原型而无需启动IDE、编译、部署等。

    ASE通过两种手段来访问Android API。目前我们可以通过ASE使用Python及Lua运行时来运行脚本,这些运行时都是本地应用,他们通过JSON-RPC来访问Android API。

    由于Android本身基于Java,因此我们还可以运行基于JVM的语言。目前可以使用的是BeanShell——Java语言的动态版本。基于JVM的解释器就 在ASE内部加载,无需间接的RPC调用。

    ASE还计划让更多的JVM语言运行在Android上。虽 然JRuby早就能运行在Android上了,但却存在一些问题,首当其冲的就是Android使用了Dalvik VM(Android应用被编译成Dalvik VM字节码)。

    有兴趣的话就去看看ASE 的SVN仓库吧,那上面清 楚地表明了未来的Ruby支持也将基于JSON-RPC。

    我们还可以通过Rhodes在 Android设备上使用Ruby。

    大家都对ASE未来的发展拭目以待。iPhone不允许上面的应用自带解释器,而ASE却通过脚本扩展了Android,并且用户可以创建、编辑这 些脚本。

    InfoQ原文:http://www.infoq.com/cn/news/2009/07/android-scripting