1. 云栖社区>
  2. PHP教程>
  3. 正文

用PHP开发Android应用的可行性探究(PHPDroid)

作者:用户 来源:互联网 时间:2017-12-01 17:57:30

androidphp开发应用探究可行性PHPDroid

用PHP开发Android应用的可行性探究(PHPDroid) - 摘要: 本文讲的是用PHP开发Android应用的可行性探究(PHPDroid), 大家以前可能都听说过PFA(PHP for Android)这么一个东西,可以下结论的是,这个项目其实已经不再活跃失败了,因为其依赖的SL4A(Scripting Layer for Android)已经停止更新和维护了,而且它依赖SL4

大家以前可能都听说过PFA(PHP for Android)这么一个东西,可以下结论的是,这个项目其实已经不再活跃失败了,因为其依赖的SL4A(Scripting Layer for Android)已经停止更新和维护了,而且它依赖SL4A的运行模式也跟我下面提到的PHPDroid的本地Browser/Server模式截然不同.

个人在Ubuntu上用交叉编译工具链 musl-cross-compilers参考 DroidPHP的教程构建了适用于Linux ARM架构的二进制PHP解释器.其中DroidPHP的教程用的是arm-none-linux-gnueabi那一套工具链,我发现不好使,后来我又看到了 PocketMine,一个用PHP7构建的MineCraft Android版服务器端,它用的是 musl-cross-compilers,所以我也改用这套工具链.我主要做了一些修改,比如修改libc库的shell路径,以及DNS相关的resolv.conf和hosts位置,主要是为了让PHP能在Android上跑.

现在有了能够运行在Android上的PHP解释器,接下来就是看看能用什么方法构建App.因为PHP解释器从5.4开始内置了一个 CLI HTTP Server,这是一个C实现的支持PHP编程的单进程Web服务器,很轻量,官方定位是开发测试.而且它还支持一个特性,就是可以启动时给它指定一个PHP路由脚本:

php -S 127.0.0.2:8080 -t /www auth.php

比如我打包的PHPDroid里的auth.php是这样的:

<?php//以下代码的意思就是,如果UserAgent不匹配,就输出Forbidden并退出$ua = dirname(__FILE__).'/ua';if( isset($_SERVER['HTTP_USER_AGENT']) && file_exists($ua) && $_SERVER['HTTP_USER_AGENT'] === trim(file_get_contents($ua)) ) { return false;} else { exit('Forbidden');}

我们还知道,PHP还内置了SQLite引擎,一个文件就是一个数据库,管理起来非常方便,可视化管理工具可以用免费开源跨平台的 SQLiteStudio.现在有了HTTP服务器和SQLite数据库,我编译时还启用了一些常用的扩展,如下:

bcmath calendar Core ctype curl date dom exif filter ftp gd hash json libxml mbstring mcrypt openssl pcre PDO pdo_sqlite Reflection session SimpleXML sockets SPL sqlite3 standard swoole xml xmlreader xmlwriter zip zlib

有了上面这些东西,我们该怎么进行图形化交互呢?我想大家都想到了,那就是Android内置的WebView.个人认为,浏览器是有史以来最成功的跨平台GUI应用.Android从4.4开始,WebView底层由Chromium驱动,性能也是相当不错的.如果你要调用一些Java编写的本地功能,WebView一直都提供有一个addJavascriptInterface的特性,可以把Java对象注入到WebView中供JS调用,比如:

Java代码:webview.addJavascriptInterface(new Object() { @JavascriptInterface public String getprop(String prop) { return java.lang.System.getProperties().getProperty(prop);; }}, "android");WebView里的HTML代码:<a href="javascript:void(0)" onclick="alert(android.getprop('os.name'))">os.name</a>

也就是说,你用WebView也是可以进行一些本地API调用的,当然你得先用Java写好那些功能.

好了,现在PHPDroid的整个运行模式就比较清晰了,应用启动时,执行start.sh随机生成UserAgent并记录下来(ua.php),找到可用端口并记录下来(port.php),然后启动PHP内置HTTP服务器并记录PID(用于关闭),Java里启动WebView前读取随机生成UserAgent并setUserAgentString设置,PHP内置服务器的路由auth.php会对UserAgent进行比对,拒绝本机上其他应用(比如浏览器)发出的请求.各个脚本如下:

start.sh#!/system/bin/shcd $1/php/binchmod 700 busyboxif [ ! -f php ]; then ./busybox xz -d file.tar.xz ./busybox tar xf file.tar && rm file.tar chmod 700 lib/ld php watcher qrencode ./busybox sed -i "[email protected]/data/data/[email protected][email protected]" php.ini ./busybox sed -i "[email protected]/storage/self/[email protected][email protected]" php.ini cp resolv.conf $1/php/www cp hosts $1/php/wwwfi#随机生成UserAgent./php -c php.ini ua.php#获取可用端口./php -c php.ini port.php#开发调试时把网站根目录复制到SD卡,方便修改# -t $1/php/www 实际应用的网站根目录# -t $2/phpdroid 开发调试的网站根目录if [ ! -d $2/phpdroid ]; then cp -R $1/php/www $2/phpdroid; fi#启动PHP服务$1/php/bin/php /-c php.ini /-S 127.0.0.2:`cat $1/php/bin/port` /-t $2/phpdroid /$1/php/bin/auth.php />/dev/null 2>&1 记录PHP的PIDecho $! > pid#监听,发现文件auth.php被删除,则关闭PHP进程$1/php/bin/watcher $1/php/bin/auth.php >/dev/null 2>&1 记录watcher的PIDecho $! > pid_watcherreturn 0stop.sh#!/system/bin/shua=$1/php/bin/uaif [ -e $ua ]; then rm $uafiport=$1/php/bin/portif [ -e $port ]; then rm $portfipid=$1/php/bin/pidif [ -e $pid ]; then kill -9 `cat $pid` rm $pidfipid=$1/php/bin/pid_watcherif [ -e $pid ]; then kill -9 `cat $pid` rm $pidfireturn 0ua.php<?php$ua = 'Mozilla/5.0 (Linux; Android; PHPDroid) AppleWebKit (KHTML, like Gecko) Chrome Mobile Safari';file_put_contents(dirname(__FILE__).'/ua', $ua.' '.sha1(uniqid(mt_rand(), true)));port.php<?php//PHP用 fsockopen 检测端口是否被占用,返回可用端口.$port = 8181;while ( $fp = @fsockopen('127.0.0.2', $port, $errno, $errstr, 1) ) { fclose($fp); $port++;}file_put_contents(dirname(__FILE__).'/port', $port);MainActivity.java 在 onCreate 时启动 WebView 如下:webview = new WebView(this);webview.getSettings().setUserAgentString(ua);webview.getSettings().setJavaScriptEnabled(true);webview.setWebChromeClient(new WebChromeClient());webview.setWebViewClient(new WebViewClient() { public boolean shouldOverrideUrlLoading(WebView view, String url) { view.loadUrl(url); return true; }});webview.loadUrl("http://127.0.0.2:" + port);setContentView(webview);

好了,看到这里,大家基本已经明白我所说的用PHP开发Android应用的思路.

大家感兴趣可以下载我打包好的APK来体验一下:

phpdroid_20160703.apk(5.8M)

phpdroid_20160703.7z(4.7M)

apk里包含PHP最新的7.0.8和高性能网络编程扩展Swoole,

另外还有BusyBox和生成二维码的qrencode.

7z包是项目源代码,主要就是MainActivity.java和assets数据.

提示下,我打包的APK在start.sh里把网站根目录调整到了SD卡的phpdroid目录下,主要上方便大家体验时USB连接手机把自己写的PHP文件放到里面运行测试.

以上是云栖社区小编为您精心准备的的内容,在云栖社区的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索android , php , 开发 , 应用 , 探究 , 可行性 PHPDroid ,以便于您获取更多的相关知识。

弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率

40+云计算产品,6个月免费体验

现在注册,免费体验40+云产品,及域名优惠!

云服务器9.9元/月,大学必备