Recipes by Category

App Distribution (2) Bundle logic, interface and services for distribution. App Logic (37) The Apex programming language, workflow and formulas for logic. Collaboration (6) The Salesforce Chatter collaboration platform. Database (29) Data persistence, reporting and analytics. Integration (33) Web Service APIs and toolkits for integration. Security (9) Platform, application and data security. Tools (4) Force.com tooling User Interface (36) Visualforce MVC and metadata-drive user interfaces. Web Sites (12) Public web sites and apps with optional user registration and login.
Beta Feedback
Cookbook Home » Interact with the Force.com REST API from PHP

Interact with the Force.com REST API from PHP

Post by Pat_Patterson  (2010-10-30)

Status: Unverified
Level: intermediate

Problem

You're writing a PHP web application, and you want to call the REST API to create, read, update and/or delete Force.com records.

Solution

Prerequisites

The sample implements a minimal PHP web application able to obtain an OAuth 2.0 access token and interact with the Force.com REST API. You will need the cURL and JSON PHP modules (available by default in most modern PHP environments).

Since the Force.com OAuth2 implementation requires that the web application redirect URI be secured by SSL, you will need to configure your web server accordingly. This O'Reilly article describes how to configure SSL on Apache Web Server.

You will also need to configure a Remote Access Application - the 'Setup' section of the 'Getting Started with the Force.com REST API' article contains detailed steps. Use https://localhost/resttest/oauth_callback.php as the Callback URL.

Source

Create a directory named resttest in your Web server document root. Save the following five files to the resttest directory.

index.html

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>REST/OAuth Example</title>
</head>
<body>
<script type="text/javascript" language="javascript">
    if (location.protocol != "https:") {
        document.write("OAuth will not work correctly from plain http. "+
                        "Please use an https URL.");
    } else {
        document.write("<a href=\"oauth.php\">Click here to retrieve accounts from Salesforce via REST/OAuth.</a>");
    }
</script>
</body>
</html>

config.php

<?php
define("CLIENT_ID", "PUT_YOUR_CONSUMER_KEY_HERE");
define("CLIENT_SECRET", "PUT_YOUR_CONSUMER_SECRET_HERE");
define("REDIRECT_URI", "https://localhost/resttest/oauth_callback.php");
define("LOGIN_URI", "https://login.salesforce.com");
?>

oauth.php

<?php
require_once 'config.php';

$auth_url = LOGIN_URI
        . "/services/oauth2/authorize?response_type=code&client_id="
        . CLIENT_ID . "&redirect_uri=" . urlencode(REDIRECT_URI);

header('Location: ' . $auth_url);
?>

oauth_callback.php

<?php
require_once 'config.php';

session_start();

$token_url = LOGIN_URI . "/services/oauth2/token";

$code = $_GET['code'];

if (!isset($code) || $code == "") {
    die("Error - code parameter missing from request!");
}

$params = "code=" . $code
    . "&grant_type=authorization_code"
    . "&client_id=" . CLIENT_ID
    . "&client_secret=" . CLIENT_SECRET
    . "&redirect_uri=" . urlencode(REDIRECT_URI);

$curl = curl_init($token_url);
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $params);

$json_response = curl_exec($curl);

$status = curl_getinfo($curl, CURLINFO_HTTP_CODE);

if ( $status != 200 ) {
    die("Error: call to token URL $token_url failed with status $status, response $json_response, curl_error " . curl_error($curl) . ", curl_errno " . curl_errno($curl));
}

curl_close($curl);

$response = json_decode($json_response, true);

$access_token = $response['access_token'];
$instance_url = $response['instance_url'];

if (!isset($access_token) || $access_token == "") {
    die("Error - access token missing from response!");
}

if (!isset($instance_url) || $instance_url == "") {
    die("Error - instance URL missing from response!");
}

$_SESSION['access_token'] = $access_token;
$_SESSION['instance_url'] = $instance_url;

header( 'Location: demo_rest.php' ) ;
?>

demo_rest.php

<?php
session_start();

function show_accounts($instance_url, $access_token) {
    $query = "SELECT Name, Id from Account LIMIT 100";
    $url = "$instance_url/services/data/v20.0/query?q=" . urlencode($query);

    $curl = curl_init($url);
    curl_setopt($curl, CURLOPT_HEADER, false);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($curl, CURLOPT_HTTPHEADER,
            array("Authorization: OAuth $access_token"));

    $json_response = curl_exec($curl);
    curl_close($curl);

    $response = json_decode($json_response, true);

    $total_size = $response['totalSize'];

    echo "$total_size record(s) returned<br/><br/>";
    foreach ((array) $response['records'] as $record) {
        echo $record['Id'] . ", " . $record['Name'] . "<br/>";
    }
    echo "<br/>";
}

function create_account($name, $instance_url, $access_token) {
    $url = "$instance_url/services/data/v20.0/sobjects/Account/";

    $content = json_encode(array("Name" => $name));

    $curl = curl_init($url);
    curl_setopt($curl, CURLOPT_HEADER, false);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($curl, CURLOPT_HTTPHEADER,
            array("Authorization: OAuth $access_token",
                "Content-type: application/json"));
    curl_setopt($curl, CURLOPT_POST, true);
    curl_setopt($curl, CURLOPT_POSTFIELDS, $content);

    $json_response = curl_exec($curl);

    $status = curl_getinfo($curl, CURLINFO_HTTP_CODE);

    if ( $status != 201 ) {
        die("Error: call to URL $url failed with status $status, response $json_response, curl_error " . curl_error($curl) . ", curl_errno " . curl_errno($curl));
    }
    
    echo "HTTP status $status creating account<br/><br/>";

    curl_close($curl);

    $response = json_decode($json_response, true);

    $id = $response["id"];

    echo "New record id $id<br/><br/>";

    return $id;
}

function show_account($id, $instance_url, $access_token) {
    $url = "$instance_url/services/data/v20.0/sobjects/Account/$id";

    $curl = curl_init($url);
    curl_setopt($curl, CURLOPT_HEADER, false);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($curl, CURLOPT_HTTPHEADER,
            array("Authorization: OAuth $access_token"));

    $json_response = curl_exec($curl);

    $status = curl_getinfo($curl, CURLINFO_HTTP_CODE);

    if ( $status != 200 ) {
        die("Error: call to URL $url failed with status $status, response $json_response, curl_error " . curl_error($curl) . ", curl_errno " . curl_errno($curl));
    }

    echo "HTTP status $status reading account<br/><br/>";

    curl_close($curl);

    $response = json_decode($json_response, true);

    foreach ((array) $response as $key => $value) {
        echo "$key:$value<br/>";
    }
    echo "<br/>";
}

function update_account($id, $new_name, $city, $instance_url, $access_token) {
    $url = "$instance_url/services/data/v20.0/sobjects/Account/$id";

    $content = json_encode(array("Name" => $new_name, "BillingCity" => $city));

    $curl = curl_init($url);
    curl_setopt($curl, CURLOPT_HEADER, false);
    curl_setopt($curl, CURLOPT_HTTPHEADER,
            array("Authorization: OAuth $access_token",
                "Content-type: application/json"));
    curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "PATCH");
    curl_setopt($curl, CURLOPT_POSTFIELDS, $content);

    curl_exec($curl);

    $status = curl_getinfo($curl, CURLINFO_HTTP_CODE);

    if ( $status != 204 ) {
        die("Error: call to URL $url failed with status $status, curl_error " . curl_error($curl) . ", curl_errno " . curl_errno($curl));
    }

    echo "HTTP status $status updating account<br/><br/>";

    curl_close($curl);
}

function delete_account($id, $instance_url, $access_token) {
    $url = "$instance_url/services/data/v20.0/sobjects/Account/$id";

    $curl = curl_init($url);
    curl_setopt($curl, CURLOPT_HEADER, false);
    curl_setopt($curl, CURLOPT_HTTPHEADER,
            array("Authorization: OAuth $access_token"));
    curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "DELETE");

    curl_exec($curl);

    $status = curl_getinfo($curl, CURLINFO_HTTP_CODE);

    if ( $status != 204 ) {
        die("Error: call to URL $url failed with status $status, curl_error " . curl_error($curl) . ", curl_errno " . curl_errno($curl));
    }

    echo "HTTP status $status deleting account<br/><br/>";

    curl_close($curl);
}
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>REST/OAuth Example</title>
    </head>
    <body>
        <tt>
            <?php
            $access_token = $_SESSION['access_token'];
            $instance_url = $_SESSION['instance_url'];

            if (!isset($access_token) || $access_token == "") {
                die("Error - access token missing from session!");
            }

            if (!isset($instance_url) || $instance_url == "") {
                die("Error - instance URL missing from session!");
            }

            show_accounts($instance_url, $access_token);

            $id = create_account("My New Org", $instance_url, $access_token);

            show_account($id, $instance_url, $access_token);

            show_accounts($instance_url, $access_token);

            update_account($id, "My New Org, Inc", "San Francisco",
                    $instance_url, $access_token);

            show_account($id, $instance_url, $access_token);

            show_accounts($instance_url, $access_token);

            delete_account($id, $instance_url, $access_token);

            show_accounts($instance_url, $access_token);
            ?>
        </tt>
    </body>
</html>

Restart your browser to clear out any session cookies, then browse to https://localhost/resttest/ and click the link. Login as usual, and you will be presented with a screen requesting authorization for the sample app to access your data. On approving access, you will see the app's output in the browser, similar to the following:

12 record(s) returned

0015000000VALDtAAP, GenePoint
0015000000VALDuAAP, United Oil & Gas, UK
0015000000VALDvAAP, United Oil & Gas, Singapore
0015000000VALDwAAP, Edge Communications
0015000000VALDxAAP, Burlington Textiles Corp of America
0015000000VALDyAAP, Pyramid Construction Inc.
0015000000VALDzAAP, Dickenson plc
0015000000VALE0AAP, Grand Hotels & Resorts Ltd
0015000000VALE1AAP, Express Logistics and Transport
0015000000VALE2AAP, University of Arizona
0015000000VALE3AAP, United Oil & Gas Corp.
0015000000VALE4AAP, sForce

HTTP status 201 creating account

New record id 0015000000WywDHAAZ

HTTP status 200 reading account

attributes:Array
Id:0015000000WywDHAAZ
IsDeleted:
...

Discussion

The sample code in demo_rest.php executes a query for the first 100 Account records, then creates a new Account record, reads it back, updates it, and finally deletes it, running the query after each operation to see the changes in the list of Account records.

Since there is not yet a PHP OAuth 2.0 client library, we implement the protocol directly in oauth.php and oauth_callback.php. Getting Started with the Force.com REST API contains a detailed discussion of this area of the OAuth 2.0 protocol, working through a Java sample with equivalent functionality.

We implement the PATCH HTTP method in update_account() very simply:

curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "PATCH");

We use the same mechanism for the DELETE method in delete_account().

References

Share

Recipe Activity - Please Log in to write a comment

A colleague and I used this recipe, and it works beautifully to bring down the data for the client's WordPress web site (http://californiaconvergence.org/join-our-network/network-directory).

It does, however, take a very long time to get there - 15 seconds, and that is for only 50 records at the moment. Any tips on how to improve delivery time?

Thanking you in advance,

Willa

by a093000000YGieD  (2014-05-08)

Hi everything works good ,i got return value as NULL  i meant this $response = json_decode($json_response, true);

by a093000000WbnmZ  (2013-01-04)

Easy test to see if cURL is installed:

echo 'cURL is'.(function_exists('curl_open') ? '' : ' not').' installed<br />';

Note: it doesn't look like xampp for windows has cURL installed.
http://www.apachefriends.org/en/xampp-windows.html

by egranger05182009  (2012-03-30)

Contrary to this statement in the cookbook "You will need the cURL and JSON PHP modules (available by default in most modern PHP environments)." cURL is NOT installed in the out-of-the-box Ubuntu LAMP set up.

Do this:

sudo apt-get install php5-curl

sudo service apache2 restart

by egranger05182009  (2012-02-23)

I have tried to do it but this error is displayed!!!!!!!!
Fatal error: Call to undefined function curl_init() in C:\xampp\htdocs\Resttest\oauth_callback.php on line 20 

by a093000000P5y17  (2012-02-20)

X

Vote to Verify a Recipe

Verifying a recipe is a way to give feedback to others and broaden your own understanding of the capabilities on Force.com. When you verify a recipe, please make sure the code runs, and the functionality solves the articulated problem as expected.

Please make sure:
  • All the necessary pieces are mentioned
  • You have tested the recipe in practice
  • Have sent any suggestions for improvements to the author

Please Log in to verify a recipe

You have voted to verify this recipe.