GRASS and PHP

From GRASS-Wiki
Revision as of 16:40, 25 May 2006 by ⚠️HuidaeCho (talk | contribs) (Changed TWiki format to MediaWiki format)
Jump to navigation Jump to search

Running Grass modules through an Webserver

For some reasons, you may want to call Grass modules within a html page instead of using the command line or a GUI. One way - among others - is to execute them out of a php script.

In the following, a few notes how to procceed for writing your own code:

Check your php installation

Save this code snipped in your server directory under the filename "doihavephp.php" and call it with a web browser:

<?php
   phpinfo();
?>

There you will see detailed informations upon your server's php installation. If you see nothing, please check http://www.php.net for details how to get and install php on your machine.

Define the environment settings

By default, there are only a few variables set in the server environment. Save the following snippet under "env.php" and see what is set as default values for your server.

<?php
//enable all error messages
error_reporting(E_ALL);
//print a line of text as a header for the following output
echo "<hr>env:<br>";
//execute the env command and redirect the output
$handle = popen('"env" 2>&1', 'r');
//wait a while for the results. this is not clean, but works for the first attempt
sleep("1");
//collect the response 
$read = fread($handle, 4096);
//print the response - if response is incomplete, increment the sleep delay
echo $read;
//don't forget to close the handle
pclose($handle);
echo "<br>done.<hr>";
?>

Note: Please be careful when modifying environment variables permanent in files like /etc/bash.bashrc. You may cause by accident security leaks. Please check with your IT manager how to grant security when your machine is visible to the internet.

The environment variables are set by using the *<verbatim>putenv("VARIABLE")</verbatim>* command. They are only valid during the runtime of the actual script, so you have to send the full set for each request.

<?php
error_reporting(E_ALL);
putenv("GRASS_WIDTH=900");
echo "<hr>env:<br>";
$handle = popen('"env" 2>&1', 'r');
sleep("1");
$read = fread($handle, 4096);
echo $read;
pclose($handle);
echo "<br>done.<hr>";
?>

The list shows some environment variables used by Grass modules. Please note, that the content has to be adapted to meet your system's specific setup and that it may be incomplete or partially false in some combinations.

Variable Value Note
GISBASE /usr/local/grass-6.1.cvs "...where the happy little creatures hide..." (Bob Ross)
LD_LIBRARY_PATH /usr/lib:/usr/local/grass-6.1.cvs/lib:/usr.. path to ALL required libraries
GISRC /gd/.grassrc6_php Grass resource file -please see related paragraph below
HOME /tmp
GRASS_PERL /usr/bin/perl
GIS_LOCK $$

Glynn clarified regarding GRASS_LD_LIBRARY_PATH:


You need to set LD_LIBRARY_PATH. GRASS_LD_LIBRARY_PATH is merely a saved copy so that the value can be restored if LD_LIBRARY_PATH is reset due to running a setuid/setgid executable (e.g. xterm). LD_LIBRARY_PATH is what the Linux loader actually uses to locate shared libraries.

Redirecting STDOUT and STDERR

When calling a function, you may either collect the output in a handle as shown in the example before or redirect it in a text file. The syntax for redirection is:

system("g.version > version.txt 2> version_err.txt");

Deleting prior output files

Remove output files immediately after use or before rewriting them to ensure that you will not work with old stuff in case of troubles.

system("rm -f version.txt");
system("rm -f version_err.txt");

The Grass Resource File

You may copy your .grassrc6 file to your script directory and e.g. name it .grassrc6_php. It contains the follwing lines and has to be adapted to fit into your setup:

file .grassrc6_php

GISDBASE: /gd
GRASS_GUI: tcltk
MAPSET: etopo5
LOCATION_NAME: smallworld
MONITOR=PNG

Access Rights

The Problem:

I can't get outside a shell access to a mapset even when calling in advance g.access with grant for both user and group. When chowning the entire location directory to user www-data, it works, but then there is no longer access from the grass shell.

Glynn wrote: You can't select a mapset as the current mapset unless you actually own it. Having write permission isn't sufficient.

This check is implemented in G__mapset_permissions() and G__mapset_permissions2() in lib/gis/mapset_msc.c. You will have to modify those functions to disable the check if you want to be able to modify mapsets which you don't own.

If your web application only reads the data, you can create a single mapset directory owned by the account under which the PHP script runs, then either use g.mapsets or explicit map@mapset references to access maps in other mapsets.

Resources and examples

A Grass Map on the fly: http://grass.itc.it/spearfish/php_grassmap.php

Earthquake epicenters dynamically inserted: http://grass.itc.it/spearfish/php_grass_earthquakes.php

related e-mails: http://grass.itc.it/pipermail/grass5/2004-August/015106.html

Many thanks to Glynn Clements, Markus Neteler and Sharyn Namnath for code and help!