Asterisk™: будущее телефонии Второе издание
Шрифт:
$agi[$name] = trim($s[1]);
}
Далее считываем все AGI-переменные, передаваемые нам Asterisk. Использование в PHP команды fgets для чтения данных из STDIN обеспечит сохранение каждой переменной в хеше $agi. Эти переменные могли бы использоваться в логике сценария AGI, но в данном примере мы не будем этого делать.
# вывести все переменные AGI в целях отладки
foreach($agi as $key=>$value) {
fwrite(STDERR,"-- $key = $value\n"); fflush(STDERR);
}
Здесь переменные возвращаются в STDERR для целей отладки.
# извлечь эту веб-страницу $weatherPage=file_get_contents($weatherURL);
Эта
# получить температуру в градусах по Фаренгейту
if (preg_match("/<temp_f>([0-9]+)<\/temp_f>/i",$weatherPage,$matches)) {
$currentTemp=$matches[1];
}
Данный фрагмент кода извлекает данные о температуре (в градусах по Фаренгейту) из сводки погоды с помощью команды preg_match. Для получения необходимых данных эта команда использует совместимые с Perl регулярные выражения [103] .
# получить направление ветра
if (preg_match("/<wind_dir>North<\/wind_dir>/i",$weatherPage)) {
$currentWindDirection='northerly';
elseif (preg_match("/<wind_dir>South<\/wind_dir>/i",$weatherPage))
103
Полный справочник по регулярным выражениям - Джеффри Фридл «Регулярные выражения», 3-е издание.
– Пер. с англ.
– СПб: Символ-Плюс, 2008.
В противоположность Asterisk Gateway Interface (AGI), который обеспечивает Asterisk возможность запускать внешнюю программу из диалплана. Интерфейсы AGI и AMI во многом дополняют друг друга.
$currentWindDirection='southerly'; elseif (preg_match("/<wind_dir>East<\/wind_dir>/i",$weatherPage))
$currentWindDirection='easterly'; elseif (preg_match("/<wind_dir>West<\/wind_dir>/i",$weatherPage))
$currentWindDirection='westerly'; elseif (preg_match("/<wind_dir>Northwest<\/wind_dir>/i",$weatherPage))
$currentWindDirection='northwesterly'; elseif (preg_match("/<wind_dir>Northeast<\/wind_dir>/i",$weatherPage))
$currentWindDirection='northeasterly'; elseif (preg_match("/<wind_dir>Southwest<\/wind_dir>/i",$weatherPage))
$currentWindDirection='southwesterly'; elseif (preg_match("/<wind_dir>Southeast<\/wind_dir>/i",$weatherPage)) $currentWindDirection='southeasterly';
Направление ветра извлекаем посредством команды preg_match, а полученное значение (заключенное в теги wind_dir) присваиваем переменной $currentWindDirection.
# получаем скорость ветра
if (preg_match("/<wind_mph>([0-9.]+)<\/wind_mph>/i",$weatherPage,$matches)) {
$currentWindSpeed = $matches[1];
}
Наконец получаем текущую скорость ветра и присваиваем ее значение переменной $currentWindSpeed.
# сообщить вызывающему абоненту текущие погодные условия
if ($currentTemp) {
fwrite(STDOUT,"STREAM FILE temperature \"\"\n"); fflush(STDOUT);
$result = trim(fgets(STDIN,4096)); checkresult($result); fwrite(STDOUT,"STREAM FILE is \"\"\n"); fflush(STDOUT);
$result = trim(fgets(STDIN,4096));
checkresult($result);
fwrite(STDOUT,"SAY NUMBER $currentTemp \"\"\n"); fflush(STDOUT);
$result = trim(fgets(STDIN,4096)); checkresult($result);
fwrite(STDOUT,"STREAM FILE degrees \"\"\n"); fflush(STDOUT);
$result = trim(fgets(STDIN,4096)); checkresult($result);
fwrite(STDOUT,"STREAM FILE fahrenheit \"\"\n"); fflush(STDOUT);
$result = trim(fgets(STDIN,4096)); checkresult($result);
}
if ($currentWindDirection && $currentWindSpeed) {
fwrite(STDOUT,"STREAM FILE with \"\"\n"); fflush(STDOUT);
$result = trim(fgets(STDIN,4096)); checkresult($result);
fwrite(STDOUT,"STREAM FILE $currentWindDirection \"\"\n"); fflush(STDOUT);
$result = trim(fgets(STDIN,4096)); checkresult($result);
fwrite(STDOUT,"STREAM FILE wx/winds \"\"\n"); fflush(STDOUT);
$result = trim(fgets(STDIN,4096)); checkresult($result); fwrite(STDOUT,"STREAM FILE at \"\"\n";) fflush(STDOUT);
$result = trim(fgets(STDIN,4096)); checkresult($result);
fwrite(STDOUT,"SAY NUMBER $currentWindSpeed \"\"\n"); fflush(STDOUT);
$result = trim(fgets(STDIN,4096)); checkresult($result);
fwrite($STDOUT,"STREAM FILE miles-per-hour \"\"\n"); fflush(STDOUT);
$result = trim(fgets(STDIN,4096)); checkresult($result);
}
Теперь,
собрав все необходимые данные, можно отправить AGI-коман- ды в Asterisk (проверяя результаты по ходу), которые доставят информацию о текущих погодных условиях вызывающему абоненту. Это будет реализовано с помощью AGI-команд STREAM FILE и SAY NUMBER. Мы говорили об этом раньше, повторим еще раз: при вызове команд AGI в них должны передаваться все необходимые аргументы. В данном случае обе команды, STREAM FILE и SAY NUMBER, требуют второго аргумента. Передадим пустые кавычки, экранированные символом обратного слэша.Также следует обратить внимание, что при каждой записи в STDOUT вызывается команда fflush. Вероятно, это лишнее, но не будет вреда в том, чтобы гарантировать немедленную отправку AGI-команды в Asterisk, без буферизации.
function checkresult($res) {
trim($res);
if (preg_match('/"200/',$res)) {
if (! preg_match('/result=(-?\d+)/',$res,$matches)) {
fwrite(STDERR,"FAIL ($res)\n");
fflush(STDERR);
return 0;
}
else {
fwrite(STDERR,"PASS (".$matches[1].")\n");
fflush(STDERR);
return $matches[1];
}
}
else {
fwrite(STDERR,"FAIL (unexpected result '$res')\n");
fflush(STDERR);
return -1;
}
}
Назначение функции checkresult аналогично подпрограмме checkresult из нашего примера на Perl. Как следует из ее имени, она проводит проверку
результатов, возвращаемых Asterisk, при каждом вызове команды AGI.
?>
В конце файла располагается закрывающий тег PHP. После закрывающего тега PHP не должно быть никаких пробелов, поскольку это может сбить с толку интерфейс AGI.