PHP开发Linux桌面应用和Android应用思路

Stella981
• 阅读 751

PHP7中用opcache.file_cache导出脚本opcode实现源代码保护
http://my.oschina.net/eechen/blog/539995
下载PHPDroid: 基于WebView和PHP内置HTTP服务器开发Android应用
http://my.oschina.net/eechen/blog/655689
PHP开发Linux桌面应用和Android应用思路
截图是我在Ubuntu上用arm-none-linux-gnueabi-gcc交叉编译的Android版PHP(静态链接glibc等库).
adb push ./php /data/local/tmp 上传到Android系统(小米4),直接 ./php -S 127.0.0.1:8181 跑Web服务.
套个WebView就能用PHP(内置Web服务器和SQLite引擎)写Android应用了.
生成的php用arm-none-linux-gnueabi-strip去掉符号表,zip压缩后约5MB.
少用些图片,整个应用做到8MB以内应该没什么问题.

http://my.oschina.net/eechen/blog/298027
HHVM和PHP7都已经发出来了,还有具体的编译打包方法,可以自行按照教程构建出Nginx/Apache/MySQL,至于Android版PHP的交叉编译构建,参考的是DroidPHP的方法.

我的Android App也基本写好了,已经跑在我的小米4上了.
过程就是把/data/app/net.php.phpdroid.apk/assets/php/复制到/data/data/net.php.phpdroid/php/,
然后Java exec调用/system/bin/sh执行命令,先给php/bin/start.sh赋予执行权限,然后执行start.sh,
start.sh里给php/bin/php赋予执行权限,然后调用php生成用于标记WebView的UserAgent的随机串php/bin/ua,
并调用php的fsockopen从8181开始在127.0.0.2上找到可用的端口php/bin/port,
然后启动PHP的HTTP服务器,然后用echo $! > php/bin/pid记录PHP的PID,
start.sh执行完后回到Java主程序,主程序读取UserAgent(php/bin/ua)并setUserAgentString和
读取端口(php/bin/port)并loadUrl,从而打开WebView并访问本地PHP.
退出关闭的时候则执行stop.sh调用kill杀死php/bin/pid.
start.sh的开头也执行一次stop.sh,关掉可能没有被杀死的旧进程.

补充一下User Agent验证的说明:
/data/data/net.php.phpdroid/php/bin/php \
-c /data/data/net.php.phpdroid/php/bin/php.ini \
-S 127.0.0.2:8181 \
-t /data/data/net.php.phpdroid/www \
/data/data/net.php.phpdroid/php/auth.php
其中auth.php是PHP内置的HTTP服务器的特性,就是每个请求都会经过auth.php处理.
名字不要求是auth.php,可以随意取,加到php启动参数里就能生效.
https://wiki.php.net/rfc/builtinwebserver
<?php
//return false;
$ua = file_get_contents(dirname(__FILE__).'/ua');
if(isset($_SERVER['HTTP_USER_AGENT']) && $_SERVER['HTTP_USER_AGENT']===$ua) return false;
else exit('Auth Failed');
代码意思就是如果客户端User Agent不是/data/data/net.php.phpdroid/bin/ua,则拒绝访问.

等我整理好,我会把这些资源全都放出来,授人以鱼也应该授人以渔,
这些知识都是从网络上获得的,如果每个人都藏着掖着,那我也不会捕鱼,
正是因为有的人乐于分享,知识才得以广泛传播.
像patchelf便携式打包参考的就是百度技术博客的分享:
http://lamp.baidu.com/2014/10/17/gou-jian-ke-sui-di-bu-shu-de-lampji-chu-huan-jing-bao/
构建Android版PHP参考的则是DroidPHP的分享:
https://github.com/DroidPHP/DroidPHP/blob/master/docs/Compiling.md

Linux上,用tar.xz打包GCC -O3编译的php7cli(3MB)和依赖库php7libs(7MB),大小约10MB.
因为打包了依赖库,所以能做到解压即用,适配所有Linux发行版.
整个应用打包下来,可以做到不超过15MB.
如果源代码不想被别人看到,PHP7支持用opcache.file_cache导出脚本opcode实现源代码保护,详情看:
http://my.oschina.net/eechen/blog/539995
我打包了适用于64位Linux的PHP7:
http://my.oschina.net/eechen/blog/411534
去掉里面的PHP-FPM和PHP-CGI,保留PHP CLI,整个PHP7环境就是10MB左右了.

假设应用安装在/png/php/7.0.0,其下的www作为根目录,启动HTTP服务:
/png/php/7.0.0/bin/php -S localhost:9393 -t /png/php/7.0.0/www
浏览器做界面,访问localhost:9393打开应用.
这两个步骤可以做成一个启动脚本start.sh:
#!/bin/bash
nohup /png/php/7.0.0/bin/php -S localhost:9393 -t /png/php/7.0.0/www >/dev/null 2>&1 &
nohup xdg-open http://localhost:9393/ >/dev/null 2>&1 &
关闭脚本stop.php就更简单了,调用kill关闭PHP CLI进程即可:
<?php
shell_exec('kill '.getmypid());

比如PHP调用系统自带命令lshw或者读取/proc/cpuinfo就能拿到各种硬件信息,包括CPU的即时运行频率等.
PHP可以把命令返回的信息直接写在

,或者转为数组进行精确的哈希操作后输出.
这样,像 雅黑探针 那样,通过Web界面就能获取像Windows上CPU-Z工具的硬件信息.
Linux"一切皆文件"的思想方便PHP获取系统信息开发Linux桌面应用.
/proc和/sys这两个文件系统里包含了Linux的各种运行时信息和硬件信息.

通过man proc查查每项的说明,任何语言都能以文本形式访问里面的数据,比如PHP获取内存使用信息:
<?php
$arr = explode("\n", file_get_contents('/proc/meminfo'));
foreach($arr as $k => $v) {
    if(!empty($v)) {
        $tmp = explode(':', $v);
        $new[trim($tmp[0])] = trim($tmp[1]);
    }
}
echo 'MemTotal:   '.$new['MemTotal']."\n";
echo 'MemFree:    '.$new['MemFree']."\n";
echo 'Buffers:    '.$new['Buffers']."\n";
echo 'Cached:     '.$new['Cached']."\n";
echo 'SwapCached: '.$new['SwapCached']."\n";

本地存储用SQLite,浏览器跟本地和服务器交互可以用AJAX或者WebSocket(Swoole),
程序更新时pclose(popen('upgrade.php', 'r'))打开一个CLI进程用file_get_contents()或者curl获取更新包.
进程间可以通过文件系统标记或者SQLite数据库进行通信.

CodeSourcery基于GNU GCC改造的交叉编译器 arm-none-linux-gnueabi 编译的程序能兼容多种ARM架构.
在Linux上把PHP移植到Android上运行的DroidPHP项目就用到了 arm-none-linux-gnueabi-gcc 这个交叉编译器:
https://github.com/DroidPHP/DroidPHP/blob/master/docs/Compiling.md
把PHP部署到客户端Android,WebView做界面,这样用网站开发技术HTML/CSS/JS/PHP/SQL就能够开发Android应用.
DroidPHP编译教程里面有一些小错误,比如:
LDFLAGS="-static -I$ROOTFS/lib -L$ROOTFS/usr/lib" \
应该改为:
LDFLAGS="-static -L$ROOTFS/lib -L$ROOTFS/usr/lib" \
还有应该使用arm-none-linux-gnueabi的头文件,比如:
mv /png/dev/android/glibc/usr/include /png/dev/android/glibc/usr/include_backup
ln -s /png/dev/android/arm-2014.05/arm-none-linux-gnueabi/libc/usr/include /png/dev/android/glibc/usr
因为PHP默认调用/bin/sh来执行命令,而Android上没有/bin/sh,只有/system/bin/sh.
所以交叉编译前需要把/bin/sh该为/system/bin/sh:
sed -i "s{/bin/sh{/system/bin/sh{" ext/standard/proc_open.c

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
3个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
PHP创建多级树型结构
<!lang:php<?php$areaarray(array('id'1,'pid'0,'name''中国'),array('id'5,'pid'0,'name''美国'),array('id'2,'pid'1,'name''吉林'),array('id'4,'pid'2,'n
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
9个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这