Migrating Your PHP Application from 4.x to 5.x

Deprecation notice: New functionality will only be added to the new libraries (PHP 5.x). The old libraries (PHP 4.x) will be officially supported until 11/30/16. After that day, Twilio will stop providing bug fixes and Support might ask you to upgrade before debugging issues.

The Twilio PHP SDK has undergone significant changes from version 4.x to 5.x - we'll break down the major changes here to make migrating to the new version as painless as possible. If you're integrating Twilio in your PHP app for the first time, you can skip straight to the install page.

PHP Version Compatibility

The 5.x version of the Twilio SDK is compatible with PHP versions 5.3 and higher. As of August 2016, it is recommended that you upgrade your applications to at least PHP 5.6 to receive the latest security updates.

Namespaces

The new SDK takes advantage of PHP namespaces for proper autoloading. This means classes are no longer prepended by "Services_" or contain long class names as they did in version 4.x of the SDK. After the 5.x SDK has been autoloaded, you will be able to use namespaces as in the following example.

<?php
// Composer autoload file
require_once '/path/to/vendor/autoload.php';
use Twilio\Rest\Client;

Utility classes (used to generate TwiML, or mint auth tokens for Video or Twilio Client) have also been refactored in this way. Check out the generated API reference doc to browse the available namespaces.

Accessing REST API Resources

The way you interact with REST API resources in the 5.x version of the SDK is also significantly changed (we believe improved) from version 4.x. The abstraction in the 4.x API over REST API resources sometimes resulted in inefficient network requests, occasionally making 2 or 3 API requests when only one would have been necessary. The 5.x SDK introduces two new concepts to address this.

  • Resource Context: A reference to a resource in the REST API that has not yet been operated on or fetched
  • Resource Instance: A representation of a resource that has been retrieved from the API after some operation has been performed

Consider the following example from the IP Messaging REST API.

<?php
require '/path/to/vendor/autoload.php';
use Twilio\Rest\Client;

// Create REST API Client
$sid = 'ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX';
$token = 'your_auth_token';
$client = new Client($sid, $token);

// 1.) Service instance context
$service = $client->ipMessaging->services('ISXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX');

// 2.) Channel context
$channelContext = $service->channels('CHXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX');

// 3.) Channel instance
$channel = $channelContext->fetch();
echo $channel->friendlyName;

Let's break down what happened in the code above, by the numbers.

  1. We create a "context" for the IP Messaging service instance we'd like to operate on. We know its SID ahead of time. No HTTP requests have been made to the API.
  2. We create a "context" for the actual IP Messaging channel we'd like to retrieve from the API. We know its SID ahead of time also. Still, no HTTP requests have been made.
  3. Finally, we use "fetch" to return an instance of a channel resource from the API. Under the covers, this makes an HTTP GET request to the REST API. The $channel object returned is populated with properties of the channel, retrieved from the Twilio back end.

In the 4.x helper library, this type of interaction would have cost two HTTP requests - one to fetch the service instance, and another to fetch the channel. This is a fluent interface, so you can chain these method calls together if desired.

<?php
require '/path/to/vendor/autoload.php';
use Twilio\Rest\Client;

// Create REST API Client
$sid = 'ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX';
$token = 'your_auth_token';
$client = new Client($sid, $token);

// All together now!
$channel = $client->ipMessaging
    ->services('ISXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX')
    ->channels('CHXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX')
    ->fetch();

echo $channel->friendlyName;

Creating and deleting resources work in a similar way - you can see examples of each type of operation in the API docs.

Listing and Paging Resources

Getting lists of resources from the API follows a similar pattern, this time using the "read" method.

<?php
require '/path/to/vendor/autoload.php';
use Twilio\Rest\Client;

// Create REST API Client
$sid = 'ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX';
$token = 'your_auth_token';
$client = new Client($sid, $token);

// Get a list of channels
$channels = $client->ipMessaging
    ->services('ISXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX')
    ->channels
    ->read();

// List ALL the channels
foreach ($channels as $channel) {
    echo $channel->friendlyName;
}

To page through larger result sets, you can use the "stream" method, which returns an iterator that will transparently loop through all the possible results for your resource context, even if there are more results than the (configurable up to 1,000) page size.

<?php
require '/path/to/vendor/autoload.php';
use Twilio\Rest\Client;

// Create REST API Client
$sid = 'ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX';
$token = 'your_auth_token';
$client = new Client($sid, $token);

// Get a stream of channels
$channelStream = $client->ipMessaging
    ->services('ISXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX')
    ->channels
    ->stream();

// List ALL the channels
foreach ($channelStream as $channel) {
    echo $channel->friendlyName;
}

Passing Arguments to the API

When passing query parameters for a "read" operation or adding parameters for a "create" or "update", you'll notice differences from 4.x to 5.x as well. All universally required parameters for an operation are positional - all other parameters (including required parameters where either one value or another may be passed, like a text message "Body" or "MediaUrl") are passed in an array.

Consider the following example of sending a text message (creating a Message resource). The only argument that is always required is a "To" phone number. Two more arguments are required:

  • Either a "From" phone number or a "MessagingServiceSid"
  • Either (or both of) a "Body" and a "MediaUrl"

The code to do this is the following.

<?php
require_once '/path/to/vendor/autoload.php';
use Twilio\Rest\Client;

// Create a client with your Account SID and Auth Token from twilio.com/console
$sid = 'ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX';
$token = 'your_auth_token';
$client = new Client($sid, $token);

$client->messages->create(
    '+15558675309',
    array(
        'from' => '+15017250604',
        'body' => 'Hey Jenny! Good luck on the bar exam!',
        'mediaUrl' => 'http://farm2.static.flickr.com/1075/1404618563_3ed9a44a3a.jpg',
    )
);

Here's an example of querying for calls that were completed between midnight July 4th, 2009 and midnight July 6th, 2009.

<?php
require_once '/path/to/vendor/autoload.php';
use Twilio\Rest\Client;

// Create a client with your Account SID and Auth Token from twilio.com/console
$sid = 'ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX';
$token = 'your_auth_token';
$client = new Client($sid, $token);

// Read an array of calls from the REST API between two dates
$calls = $client->calls->read(
    array(
        'status' => 'completed',
        'starttimeAfter' => '2009-07-04',
        'starttimeBefore' => '2009-07-06'
    )
);

// Loop over the list of calls and echo a property for each one
foreach ($calls as $call) {
    echo $call->to;
}

The REST API documentation contains a listing of required parameters, and code samples for every API operation.

Getting Help

We'd love to hear your feedback on the PHP SDK, and help you past any issues you may encounter. Feel free to drop us a line, and we'll make sure to get you sorted!