[Asterisk-Users] AGI and PHP
hkirrc.patrick
hkirrc.patrick at ptl.net
Mon Nov 10 22:48:47 MST 2003
i've just spent the pass 2 days trying to get AGI to work with PHP;
i made a lot of silly mistakes along the way which could have been
avoided if only there were some kinda howto or samples. at the risk
of looking stupid, i decided to shared my experience in hopes that
it might help some newbie get going with PHP.
1. first order of business is to be aware of your php environment; i m
NOT saying you should change anything but you should be aware
of it as it may spare you some frustration along the way especially
when you are in the thick of things. look in your php config file
(usually in /etc/php.ini) for the following:
ob_implicit_flush(false);
set_time_limit(5);
; error_log = filename
the first item shows whether php should buffer output; in the case
of * agi, if you buffer your output, * will not get your instruction
for a
long time unless you flush the buffer manually (see below)
the second item is the max. allowable time to run your php script. most
* agi script will run within a reasonable time but if you have a very
lengthy script that is producing strange errors, it is possible that your
script was terminated prematurely.
the third item is Log; great for debug but a killer for production
system.
it might have been turned off by default or you may have turn it off
on purpose and don't remember.
2. put your scripts in the following directory and get it working first
before you do anything fancy
/var/lib/asterisk/agi-bin/
3. remember to chmod ALL your script to 755 as follows:
chmod 755 *.php
4. the very first 2 lines in your script should be as follows:
(assuming that your php bindery is in /usr/bin; double check now)
#!/usr/bin/php -q
<?php
notice: there are no gaps and no white space char (except a single \n)
between lines 1 and 2. otherwise strange things will be sent to stdout
and ruin your day!
5. next, you should use fopen() to create all your needed handles. i know
different versions of php have varying features to deal with stdio
streams
but fopen() will work with most new and old versions making your scripts
more portable and you don't have to fidget with the php.ini file.
besides,
fopen() does not pose any inconvenience for use with * agi, so use it.
$stdin = fopen('php://stdin', 'r');
$stdout = fopen('php://stdout', 'w');
$stdlog = fopen('my_agi.log', 'w');
6. * always sends a bunch of info each time agi is called as follows:
agi_request: test.php
agi_channel: Zap/1-1
agi_language: en
agi_type: Zap
agi_callerid:
agi_dnid:
agi_context: default
agi_extension: 1000
agi_priority: 1
.
.
if you need the info, save it; otherwise throw them away as follows:
while(($data = fgets($stdin,1024)) != "\n")
{
// codes to save the info goes here
// or do nothing
}
7. this is the point where you can start talking with *. use fputs to
send * agi commands; some people use echo but i prefer fputs:
fputs($stdout,"SAY NUMBER 1234567 '79#' \n");
fflush($stdout);
7a. use fflush() regardless of php.ini setting just to be safe, does hurt
if you don't fflush() (auto or manual), * will not receive the command
and your app will be stuck there until timeout.
7b. use of quotes;
* agi command options are not optional
i.e. they must appear on the command string
* some options MUST be enclosed in quotes
e.g. <escape digits> of SAY NUMBER and SAY DIGITS
* some options MUST NOT be enclosed in quotes
e.g. <digit string> of SAY NUMBER and SAY DIGITS
* some options can go either way.
* you can use single quote where quote is needed e.g. as above
* as a reminder, escape char such as \n in a strings within sigle
quotes
will not be resolved !!!! but i'm sure you already know that.
8. next, you'll have to pick up responses from * which is pretty
straight forward:
$msg = fgets($stdin,1024);
fputs($stdlog,$msg . "\n");
9. if your script failed for some reason (especially if you forget to
fflush()), the process
is actually hung in limbo; REMEMBER to killproc your script process
before you
test again:
killproc my_script.php
10. the purpose of this is to show the PHP aspects of * agi and not agi
in general;
there are many excellent documentation on * agi such as the following,
you should read that as well:
http://home.cogeco.ca/~camstuff/agi.html
11. sample.php
#!/usr/bin/php -q
<?php
$stdin = fopen('php://stdin', 'r');
$stdout = fopen('php://stdout', 'w');
$stdlog = fopen('my_agi.log', 'w');
while(($abc = fgets($stdin,1024)) != "\n")
{
fputs($stdlog,$abc);
// or parse the data for use
}
fputs($stdout,"ANSWER\n");
fflush($stdout);
$abc = fgets($stdin,1024);
fputs($stdlog,$abc . "\n");
fputs($stdout,"GET DATA aa-welcome '1' 1\n");
fflush($stdout);
$abc = fgets($stdin,1024);
fputs($stdlog,$abc . "\n");
fputs($stdout,"EXEC Meetme 1234|p \n"); // <=- notice the |p in 1234|p
being the option for meetme
fflush($stdout);
$abc = fgets($stdin,1024);
fputs($stdlog,$abc . "\n");
exit();
?>
More information about the asterisk-users
mailing list