Update 7 May 2012: New version released, containing PHP 5.4.2 version (CGI only). It now contains openssl / curl / SQLite modules statically linked within php-cgi executable and thus curlssl works! Beside the version number, all installation instructions below still apply.
If you are already using PHP 5.3.8, just grab the php-cgi
file from the 5.4.2 archive system/xbin
folder and replace the /system/xbin/php-cgi
on the device.
Introduction
Below you can find an bundle of PHP 5.3.8 (CGI only) and Lighttpd 1.4.29 (FastCGI module included) which are cross compiled for ARMv5 CPUs (Android platforms mainly).
As you mail well know, both PHP and Lighttpd offer modules that could be loaded at run-time based on settings within configuration files. The bundle doesn’t include all modules, due to difficulties encountered when compiling for ARM platforms. Those modules that are included are statically linked in the executables (so no additional files are needed) nor configuration files need to be updated to load them.
Screenshots
Below you can see screenshots with the phone browser opening localhost address. Once you unpack the archive, there’s an index.php file which just calls phpinfo() to show the details about the build.
Of course, you can remove the file and put your own scripts π
PHP Modules
The list of PHP modules that are statically linked:
[root@arc]/sdcard# php -m [PHP Modules] cgi-fcgi Core ctype date dom ereg fileinfo filter ftp gd hash iconv json libxml pcre PDO pdo_sqlite Phar posix Reflection session SimpleXML soap sockets SPL SQLite sqlite3 standard tokenizer xml xmlreader xmlwriter zlib [Zend Modules]
Lighttpd Modules
mod_indexfile mod_userdir mod_dirlisting mod_status mod_simple_vhost mod_evhost mod_secdownload mod_cgi mod_fastcgi mod_scgi mod_ssi mod_proxy mod_staticfile mod_evasive mod_compress mod_usertrack mod_expire mod_accesslog
Download
This comes with NO WARRANTY. Use it at your own risk!
php-5.4.2_lighttpd_1.4.29_armv5.tar.gz
php-5.3.8_lighttpd_1.4.29_armv5.tar.gz
License
Please check README.txt file found in /system/README.txt within the bundle.
PHP executable is offered under PHP license, Lighttpd executable under Lighttpd license, all other files in the bundle are offered under New BSD License (3 clause BSD license).
Installing
The bundle tries to mimic as much as possible the layout of a Debian installation of the two files. However, due to file system layout on Android phones (binaries under /system
folder), the folders are one step down, under /system
folder:
`-- system |-- bin | |-- lighttpd -> /system/xbin/lighttpd-static | `-- php -> /system/xbin/php-cgi |-- etc | |-- lighttpd | | `-- lighttpd.conf | `-- php | `-- php.ini |-- var | |-- log | `-- www | `-- index.php `-- xbin |-- fcgiserver |-- lighttpd-static |-- php-cgi |-- reload_fcgi.sh `-- reload_lighttpd.sh
Prerequisites:
- rooted phone with busybox installed.
- mount the /system partition as RW.
Using DroidSSHd on the phone and connecting with Putty (or equivalent) makes the whole process faster.
After you copy the archive above into the root of your SD Card, installation is easy:
cd / tar xf /sdcard/php-5.3.8_lighttpd_1.4.29_armv5.tar.gz reload-fcgi.sh reload-lighttpd.sh
You might notice that the owner / group of the files is 1000:1000. Ignore that, as long as you execute them as root, there’s no issue (those are the IDs of my username on the PC I created the tar.gz archive and tar tries to conserve the user / creation time / etc from when the archive was created).
The last two commands start the FCGI server (PHP with 4 children processes), and then launch lighttpd server as daemon.
The default port is 80.
Default htdocs folder is /system/var/www
.
The configuration files are under /system/etc/lighttpd/lighttpd.conf
and /system/etc/php/php.ini
. To restart either PHP or Lighttpd, please use one of the commands above.
It is mandatory that you are on the root folder when you extract the archive. tar will take care of creating all the missing folders, creating the links, etc, as long as you are on the root folder.
You can now open the phone’s browser and point it at localhost
π and the phpinfo()
page should appear.
Example usage
Installing Simple Machines Forum 2.0.1 on Android
Before executing the commands below, you need the “Full Install” smf_2-0-1_install.tar.gz archive downloaded from SMF and then copied onto your /sdcard root folder.
# cd /system/var/www # ls index.php # mkdir forum # cd forum # tar xf /sdcard/smf_2-0-1_install.tar.gz # reload_fcgi.sh # reload_lighttpd.sh
Last two commands are optional, if you already started the FastCGI server as well as lighttpd.
You should now connect to http://localhost/forum
and finish installation of the forum.
Enjoy π
Darkness Angel
you don’t need to DEFAULT_LIMIT_REQUEST_LINE
it will make 413 error when try to attatch large file π (default value is 2GB but your httpd has too small value)
if someone want to increase it
add this lines on your lighttpd.conf
server.max-request-size=10240
server.network-backend=”writev”
server.upload-dirs=( “/sddata/www/tmp” )
size=kb
dirs=must same as upload_tmp_dir on your php.ini
Eric
Could you let me know how to cross compile it?
Thanks!
viulian
To make a long story short, please start here http://buildroot.uclibc.org/ and compile for ARM (generic ARM).
Eric
Thanks!!
I have port it to Androd, but the mod_* is *.so, e.g. mod_indexfile.so.
How to build it static, how to link the mod_* all into a singal binary?
viulian
You need to know
scons
and use that to compile lighttpd, just patchingconfigure
script didn’t work for me. Scons generates more thanconfigure
it also generatesplugin-static.h
file. BUT it generates it badly.Internally, scons uses a dictionary data structure to store what plugins need to be statically compiled; when it writes out the plugin-static.h file, it doesn’t keep the correct order (since dictionaries in Python are not ordered). I’ve described the bug here: http://redmine.lighttpd.net/issues/2343
Please read the description and solution there. You still need to edit the plugin-static.h file per description above.
π Hope it helps…
Also, I found it helpfull to work with the
ldd
command (built for your target) as well asstrace
on the phone itself.Eric
Thanks so much!!! It’s very helpful.
phpdevloper
There are no binaries included.
viulian
@phpdevloper – where did you look for them π ? They are there, please check
/system/xbin
folder in the archive.phpdeveloper
@viulian: I got it it was symlinked.
But now I am finding out to get it at work, I got a 503 error because of port 9001.
2011-10-17 17:39:05: (src/log.c.166) server started
2011-10-17 17:39:27: (src/mod_fastcgi.c.2904) establishing connection failed: Connection refused socket: tcp:127.0.0.1:9001
2011-10-17 17:39:27: (src/mod_fastcgi.c.2910) backend is overloaded; we’ll disable it for 1 seconds and send the request to another backend instead: reconnects: 0 load: 1
2011-10-17 17:39:29: (src/mod_fastcgi.c.2852) fcgi-server re-enabled: tcp:127.0.0.1:9001
phpdeveloper
Works fine but some PHP sites run very slowly (20 seconds or more to load page). I use lots of regexp thay maybe the problem ?
On other devices I used lighttpd as well with success : the Nokia N810 and iPad 2 (the latter I stell have).
viulian
1. It is compiled for ARMv6 without FPU support (so it should be slow for math operations). Dunno about regexp – but it might be that they are slow too ?
2. I also noticed that if processing is involved, phone tends to be slow. I put in some -O3 optimisations and so on, but since it is not using any advanced ARM instructions (but generic ARM) it might be the reason why it is slow.
I will try to compile these days using ARMv7 (since the goal was to have a release that runs on many phones), and also fix the system bug (PHP has the /bin/sh path hardcoded) – and will post an update. But probably towards the end of the week.
phpdevloper
Thanks ! Well done !
And I also had to change the paths as the /system partition is nearly full (rooted Galaxy S2 with Busybox), so I put the logging, configs and the php (10MB) and lighttpd binaries on the /data partition which also has the advantage of reverting the /system partition readonly after installing.
Even on a ‘normal’ unrooted Galaxy the /system partition is nearly full.
I symlinked the htdocs (var/www) to a user-accessible folder on /mnt/sdcard.
phpdevloper
@Viulian: If you are interested in a test script you can send me an email (email address is logged here).
phpdeveloper
After some research, the slowness of my sites running on your PHP / lighttpd is not your server software, but a bug in Android / busybox which does not resolve hostnames. That results in that the PHP gethostbyname() function waits for 10-20 seconds which makes the webserver seemingly slow.
The same issue occurs when you open a terminal to a rooted Android device, (e.g. via ssh) and then run “ping google.com” or “wget facebook.com” which result in “Bad address”.
I think your compiled version can even run on non-rooted devices, as long the software is installed on user-accessible folders such as /mnt/sdcard, and therefore no symlinks are used (this is a FAT filesystem). Maybe /data/data can be used as well because this folder is ext3 and thus does allow symlinks and running shellscripts. E.g. the sshdroid app from the Market has a ‘busybox’ which can be used on non-rooted devices. Moreover the port number should be above 1024. That is all.
@viulian if you have questions, feel free to mail me.
viulian
@phpdeveloper – thank you for all the feedback π I was busy these days.
I did not want to make a complex installer (messing with SD Card, partitioning and so on) so that the PHP is available for most phones out there.
So far the requests were about startup scripts as well as being able to locate it somewhere else. I have the installer that installs Midnight Commander, and I will probably update it to install all the apps that I’ve manage to cross-compile. One of the options would indeed be where to extract all the archives (but if you won’t use /system/xbin – then probably it’s up to the user to add the PATHs to the environment, etc).
Rafael
When I try to untar the file on my phone it says “tar: invalid tar magic”.
what do i do?
viulian
What extraction command are you using ?
With a version of busybox that I have
tar xf
does the job.viulian
system(…) but is fixed!
Actually, even if PHP has /bin/sh hardcoded within proc_open.c, it seemed not used in case of system/exec. It is in fact delegating to the underlying libc , by using the standard system() call of libc. I have recompiled the libc with the /system/bin/sh and now it is working.
The archive is updated, please redownload.
Hosh
Anyone know of a MySQL server as well?
krzych
@phpdeveloper – it’s not android bug, it’s just yours busybox bug (probably included with sshdroid – mine buggy version was from there). Try to download TitaniumBackup (it has busybox compiled by their dev’s and it’s working well with resolving, additionally it’s optimised). Remember to change PATH and symlinks if you want to use their busybox systemwide.
We need real sshd… Viulian? π
viulian
I wanted to mention that the libc used to build this PHP is uClibc – and not Android’s libc (the default one).
However, uClibc is actually following the standard and using /bin/sh for system(..) calls.
The trouble is the Google decided to use a specific /system/bin/sh instead of /bin/sh – so I had to change the source code of uClibc to hardcode /system/bin/sh instead of /bin/sh – to obtain an executable that works properly on Android.
haiyyu
Hey.
I hope you’re reading this.
I have tried installing PHP and lighttpd by following the instructions in your post.
Unfortunately I couldn’t extract the tar.gz archive using the tar command on my phone (BusyBox is installed) as it kept telling me the “magic number” of the archive was invalid.
So what I did is I extracted every single file to the specific folder (example: archive.tar/system/etc/lighttpd/lighttpd.conf to /system/etc/lighttpd/lighttpd.conf) after extracting the archive on my computer (it worked there). My problem is that I seem to be unable to copy “php-cgi” to the folder it’s supposed to be copied into (/system/xbin). I keep getting told copying the file failed.
I’m running Android 2.3.5 on a rooted Samsung Galaxy S2.
I would really appreciate it if you helped me as I would really like to run a webserver on my phone. π
haiyyu
What I forgot to mention in my last comment: Yes, I’m copying it as root. Every other file worked. I could even copy all the other files that were supposed to go into /system/xbin. Only “php-cgi” is refused to get copied.
adoet_t
can’t extract tar file,,
tar xf /sdcard/php-5.3.8_lighttpd_1.4.29_armv5.tar.gz
tar: invalid tar magic
which version busybox you use?
sorry my poor english
Paula
Thanks
phpdevloper
@haiyyu:
You must make the /system partition r/w as it is readonly be default. This can be done by SuperManager file browser in the Options.
A better option is to put cgi-bin in the /data partition and symlink /system/xbin/php-cgi to the copy on the /data partition (You still need to r/w the system partition for one time). This keeps the system partition clean and it is already nearly full.
Salvatore Bianchi
When i try to copy a file in paw server directory from a web site URL fails, why?
This is error message:
Warning: copy(): php_network_getaddresses: gethostbyname failed. errno=111
There seems to be a problem with the name resolution.
viulian
About gethostbyname failed. errno=111
I remember a similar issue when reading about OpenVPN. The static glibc that is bundled with OpenVPN needs to have access to /etc/resolv.conf, but Android doesn’t have it. You can manually add it.
I suspect a similar problem happens with this PHP too, please check /etc/resolv.conf or /etc/hosts to make sure they have valid data.
I will also check it out.
Little Zhao
There are some devices that the /system/xbin directory can’t be mounted r/w.So I tried to copy the php-cgi , lighttpd , fcgiserver to /system/bin. And it works!
viulian
Thank you for feedback! Can you please tell an example of the said device ?
I expect them to work since the path is not hardcoded, and everything is statically linked, so they should run on any ARMv5 CPU from wherever you have the rights to execute them. Only the default configuration files might need change.
But is true, I could modify the installer to allow user to specify other install folder.
Little Zhao
It’s “HTC magic”,the second android phone of the world. “/system/xbin” is not a normal directory of “/system”,it’s another partition and it can’t be mounted r/w, leastways I cannot!
Another questions was that the php process have a high CPU load and all php pages will be halt, only the static pages work will.
My English is not well, I hope you can understand!
Pinoy
Wow! this is so cool! I will try this on my android tablet later!
Joris
Hi, I’m using PAW for Android which is using your PHP as a plugin. I’m trying to use fopen() to open another website but I’m getting this error (Same problem as Salvatore Bianchi):
Warning: fopen(): php_network_getaddresses: gethostbyname failed. errno=111
You responded with:
“… please check /etc/hosts to make sure they have valid data.”
I did check the hosts file, and there is only one line:
127.0.0.1 localhost
Is that what you call “valid data”?
I’m not using a rooted Tablet, could that be the problem?
Is there any other way to open or get the contents of another website (file_get_contents() gives the same error)?
viulian
@Joris, what about /etc/resolv.conf ?
I’ve wrote a small script to test:
[sourcecode language=”php”]
<?php
$time = file_get_contents(‘lovetime.ro/time.php’);
echo($time);
?>[/sourcecode]
and it hanged for a while then died with:
[sourcecode lang=”php”]failed to open stream: php_network_getaddresses: gethostbyname failed. errno=111[/sourcecode]
I’ve then created the /etc/resolv.conf and checked again:
[sourcecode lang=”php”]
[root@arc]/system/var/www# cat /etc/resolv.conf
nameserver 208.67.220.220
nameserver 208.67.222.222
[root@arc]/system/var/www# php time.php
X-Powered-By: PHP/5.3.8
Content-type: text/html
Original Time: 01:50:08
<br/>New Time: 01:50:08
[/sourcecode]
Joris
Hi viulian,
Thanks for your answer. I tried your solution, but as I said: I haven’t rooted my Samsung Galaxy tab 8.9, so I don’t have write acces in the directory /etc/. The App PAW Server that I’m using also has an ‘etc’ folder in ‘/mnt/sdcard/paw/etc/’ folder, so I put resolv.conf in that folder, but that didn’t help. I also tried creating an ‘etc’ folder in the webroot folder of PAW: ‘/mnt/sdcard/paw/html/etc/’. Didn’t work either.
I did solve the problem by opening a socket to the right IP address with fsockopen() and then create a HTTP request with the right headers. This worked for me. But the ‘file_get_contents’ function would be easier in use.
Does this mean it isn’t possible to solve this problem without a rooted device?
Thanks for your support.
viulian
Good workaround π
Well, I think the trouble with
/etc/resolv.conf
is that I guess it is hardcoded into ucLibc (as it follows glibc standard which assumes/etc/
exists).I had a similar issue in the past, where the PHP exec() would call
/bin/sh
to invoke the script – and the trouble was not in PHP but in the glibc – again hardcoded value for/bin/sh
– I had to recompile and have it hardcoded to/system/bin/sh
..I would probably have to search glibc for
/etc/resolv.conf
(and/etc/hosts
,/etc/nsswitch.con
f) and made them configurable somehow – but I still need to figure out a way – since I can’t assume anything if the Android device is not rooted.Joris
Thanks. Well, that explains it a bit. I hope you’ll come up with a solution. I’ll just check back on your website once in a while to see if there is a new version. For now, the socket solution works good enough.
And if you need a new build to be (bΓ©ta) tested on a non-rooted device, I’m happy to help.
shxish
No armV7 architecture version
aks
when will be a curl library included…???
Dean
Do you think php5.4 can be compiled for android? 5.4 has it’s own built-in webserver!
I’ve tried with buildroot but it seems to ignore php’s configure.in file…
viulian
@Dean: I will give it a try in the weekend to see.
I will also investigate about curl issue to see what’s up with it.
viulian
I have successfully build 5.4.1 with curl and SSL option π
It was nasty, I think I will put a “Donate” button on the page.
Anyway, here’s an update:
[sourcecode lang=”bash”]
[root@arc]/system/var/www# php -v
PHP 5.4.1 (cgi-fcgi) (built: Apr 28 2012 03:52:49)
Copyright (c) 1997-2012 The PHP Group
Zend Engine v2.4.0, Copyright (c) 1998-2012 Zend Technologies
[root@arc]/system/var/www# php -m
[PHP Modules]
cgi-fcgi
Core
ctype
curl
date
dom
ereg
fileinfo
filter
ftp
gd
hash
iconv
json
libxml
openssl
pcre
PDO
pdo_sqlite
Phar
posix
Reflection
session
SimpleXML
soap
sockets
SPL
sqlite3
standard
tokenizer
xml
xmlreader
xmlwriter
zlib
[Zend Modules]
[/sourcecode]
shxish
$ su
# reload_fcgi.sh
could not kill pid -9: No such process
# reload_lighttpd.sh
could not kill pid -9: No such process
How to solve this problem???(ARMv7 cpu οΌandroid2.3.4)
viulian
I think those message only mean that the processes are not found (debug messages) and thus it had nothing to kill (probably the processes were not running).
If they are not running, then you have to check the logs to see why they failed to start.
Dean
Hi, that’s great about 5.4! So are you going to open-source it or otherwise document how to get it done?
I tried a bit the other week but I’m still quite new to cross-compiling…
A donate button would be a great idea π
phpdevloper
Where can I download 5.4.1 ?
And is it affected by the PHP bug depicted here ?
http://www.php.net/archive/2012.php#id2012-05-03-1
viulian
I did not release it yet since I got caught up in other ports … I’m working to see if I can get GCC running on Android itself and compiling things directly on the phone.
If 5.4.1 had the bug, then yes, but I will actually cross compile 5.4.2 then to not have the issue.
viulian
[sourcecode lang=”bash”]
[root@arc]/system/xbin# php-cgi -v
PHP 5.4.2 (cgi-fcgi) (built: May 6 2012 10:40:15)
Copyright (c) 1997-2012 The PHP Group
Zend Engine v2.4.0, Copyright (c) 1998-2012 Zend Technologies
[/sourcecode]
About the source code, I did not modify anything … only that the build scripts that are heavily depended on my environment so not really reusable.
phpdevloper
You meant did not change anything since 5,3,8 ?
But you have a workable binary ?