Skip to contentSkip to navigationSkip to topbar
Rate this page:
On this page

Gather User Input via Keypad (DTMF Tones) in PHP


In this guide, we'll show you how to gather user input during a phone call through the phone's keypad (using DTMF(link takes you to an external page) tones) in your PHP application. By applying this technique, you can create interactive voice response (IVR(link takes you to an external page)) systems and other phone based interfaces for your users. The code snippets in this guide are written using PHP language features in PHP version 4.3 or higher, and make use of Twilio PHP SDK(link takes you to an external page).

Let's get started!


Set up your web application to receive incoming phone calls

set-up-your-web-application-to-receive-incoming-phone-calls page anchor

This guide assumes you have already set up your web application to receive incoming phone calls. If you still need to complete this step, check out this guide. It should walk you through the process of buying a Twilio number, and configuring it to receive incoming calls.


Collect user input with the <Gather> TwiML verb

collect-user-input-with-the-gather-twiml-verb page anchor

The <Gather> TwiML verb allows us to collect input from the user during a phone call. <Gather> can have selected TwiML verbs nested within it, such as [<Say>(/docs/voice/twiml/say) and <Play>. In this example, we will prompt the user to enter a number to connect to a certain department within our little IVR system.

Use <Gather> to collect user input via the keypad (DTMF tones)

use-gather-to-collect-user-input-via-the-keypad-dtmf-tones page anchor

This example returns TwiML containing a <Say> tag nested within a <Gather> tag. The user will be prompted to choose sales or support.

PHP

_21
<?php
_21
// Create a route that will handle Twilio webhook requests, sent as an
_21
// HTTP POST to /voice in our application
_21
require_once '/path/to/vendor/autoload.php';
_21
_21
use Twilio\TwiML\VoiceResponse;
_21
_21
// Use the Twilio PHP SDK to build an XML response
_21
$response = new VoiceResponse();
_21
_21
// Use the <Gather> verb to collect user input
_21
$gather = $response->gather(array('numDigits' => 1));
_21
// use the <Say> verb to request input from the user
_21
$gather->say('For sales, press 1. For support, press 2.');
_21
_21
// If the user doesn't enter input, loop
_21
$response->redirect('/voice');
_21
_21
// Render the response as XML in reply to the webhook request
_21
header('Content-Type: text/xml');
_21
echo $response;

If the user doesn't enter any input after a configurable timeout, Twilio will continue processing the TwiML in the document to determine what should happen next in the call, or it will hang up. In the above example, we use the <Redirect> verb to simply have Twilio request the same URL again to prompt for input.

Now, if you were to run the example above and enter input, you would notice that you'd hear the same prompt over and over again regardless of what button you pressed. By default, if the user does enter input in the <Gather>, Twilio will send another HTTP request to the current webhook URL with a POST parameter containing the Digits entered by the user. In the sample above, we weren't handling this input at all. Let's update that logic to also process user input (if it is present).

Branch your call logic based on the digits sent by the user

branch-your-call-logic-based-on-the-digits-sent-by-the-user page anchor

By default, <Gather> will 'loop' on the current TwiML URL, requesting the same URL every time input is entered.

PHP

_35
<?php
_35
// Create a route that will handle Twilio webhook requests, sent as an
_35
// HTTP POST to /voice in our application
_35
require_once '/path/to/vendor/autoload.php';
_35
_35
use Twilio\TwiML\VoiceResponse;
_35
_35
// Use the Twilio PHP SDK to build an XML response
_35
$response = new VoiceResponse();
_35
_35
// If the user entered digits, process their request
_35
if (array_key_exists('Digits', $_POST)) {
_35
switch ($_POST['Digits']) {
_35
case 1:
_35
$response->say('You selected sales. Good for you!');
_35
break;
_35
case 2:
_35
$response->say('You need support. We will help!');
_35
break;
_35
default:
_35
$response->say('Sorry, I don\'t understand that choice.');
_35
}
_35
} else {
_35
// If no input was sent, use the <Gather> verb to collect user input
_35
$gather = $response->gather(array('numDigits' => 1));
_35
// use the <Say> verb to request input from the user
_35
$gather->say('For sales, press 1. For support, press 2.');
_35
_35
// If the user doesn't enter input, loop
_35
$response->redirect('/voice');
_35
}
_35
_35
// Render the response as XML in reply to the webhook request
_35
header('Content-Type: text/xml');
_35
echo $response;


Specify an action to take after user input is collected

specify-an-action-to-take-after-user-input-is-collected page anchor

Handling user input and prompts in the same webhook URL is fine, but you may want to have an entirely different endpoint in your application handle the processing of user input. This is possible using the "action" attribute of the <Gather> verb. Let's update our example to add a second endpoint that will be responsible for handling user input.

Handle the initial webhook request

handle-the-initial-webhook-request page anchor

Add another route to handle the input from the user

add-another-route-to-handle-the-input-from-the-user page anchor

This technique creates a separate route to handle user input.

PHP

_21
<?php
_21
// Create a route that will handle Twilio webhook requests, sent as an
_21
// HTTP POST to /voice in our application
_21
require_once '/path/to/vendor/autoload.php';
_21
_21
use Twilio\TwiML\VoiceResponse;
_21
_21
// Use the Twilio PHP SDK to build an XML response
_21
$response = new VoiceResponse();
_21
_21
// Use the <Gather> verb to collect user input
_21
$gather = $response->gather(array('numDigits' => 1, 'action' => '/gather'));
_21
// use the <Say> verb to request input from the user
_21
$gather->say('For sales, press 1. For support, press 2.');
_21
_21
// If the user doesn't enter input, loop
_21
$response->redirect('/voice');
_21
_21
// Render the response as XML in reply to the webhook request
_21
header('Content-Type: text/xml');
_21
echo $response;

The action attribute takes a relative URL which would point to another route your server is capable of handling.

Handle action url request in a different end point

handle-action-url-request-in-a-different-end-point page anchor

Implement an 'action' URL to handle user input

implement-an-action-url-to-handle-user-input page anchor

This technique creates a separate route to handle user input.

PHP

_31
<?php
_31
// Create a route that will handle Twilio Gather verb action requests,
_31
// sent as an HTTP POST to /gather in our application
_31
require_once '/path/to/vendor/autoload.php';
_31
_31
use Twilio\TwiML\VoiceResponse;
_31
_31
// Use the Twilio PHP SDK to build an XML response
_31
$response = new VoiceResponse();
_31
_31
// If the user entered digits, process their request
_31
if (array_key_exists('Digits', $_POST)) {
_31
switch ($_POST['Digits']) {
_31
case 1:
_31
$response->say('You selected sales. Good for you!');
_31
break;
_31
case 2:
_31
$response->say('You need support. We will help!');
_31
break;
_31
default:
_31
$response->say('Sorry, I don\'t understand that choice.');
_31
$response->redirect('/voice');
_31
}
_31
} else {
_31
// If no input was sent, redirect to the /voice route
_31
$response->redirect('/voice');
_31
}
_31
_31
// Render the response as XML in reply to the webhook request
_31
header('Content-Type: text/xml');
_31
echo $response;

Now, instead of conditional logic in a single route, we use actions and redirects to handle our call logic with separate code paths.


If you're building call center type applications in PHP, you might enjoy stepping through full sample applications written in PHP.


Rate this page: