Access Dropbox Using PHP

Share this article

In this article we’ll explore the Dropbox PHP API by building a simple client for accessing files in a Dropbox account. The client will perform some basic operations, such as authentication, listing files, and uploading and downloading files. To keep the article short and readable, I’ll keep the included code to a minimum and instead refer you to the full code available on GitHub. To run the code, you’ll need PHP with cURL support and obviously a Dropbox account. Your starting point for anything related to development with Dropbox should be the Dropbox Developers Center where you can find the API reference along with its basic concepts and best practices. You can also download the official SDKs, but PHP isn’t listed among the supported languages. There’s a link to a third party PHP SDK on Github. Our client will be structured more like the official Python client, but I took some ideas and code from the PHP SDK above, especially for the OAuth part. We’ll have a DropboxSession object and a DropboxClient object. The first will take care of the hard part: obtaining and managing access credentials from Dropbox. The client object will then use the session object to perform the API calls and get the data. Underneath the session object there is a DropboxRESTClient object to perform the HTTP calls using cURL.

Tell Dropbox About your App

First of all we need to register our application with Dropbox in order to obtain a unique API key pair. We’ll need these keys to “introduce” our application and ask for authorization. Log into the Developers Center and follow the “MyApps” link, then select “Create an App”. Dropbox will ask you for a name, description, and access type for your application.

The access type parameter specifies where your application will be able to read and write files. The recommended value is “App folder”, a sandbox directory that will be created inside the user’s home. By selecting “Full Dropbox” the application will see the user’s entire Dropbox. Once your application is created, there will be an options page where you can edit its details and find its access credentials.

Newly created application are in “Development status”. This allows us to start developing immediately and enables up to five other users to test it. When the app is ready for release, we can apply for productions status and the Dropbox team will review it to make sure that it conforms to their terms and conditions and branding guidelines.

Coding the Application

I placed my code in a subdirectory of my local Apache set-up so that it’s reachable at the URL http://localhost/mydropbox. The directory structure is:

The bootstrap.php file performs the application’s start-up and will be included in each of the front-end files, so let’s start by discussing that. I initialize a global $config variable as an empty array and then specify some configuration values. The first three are Dropbox-related: the access key, secret key, and access type from your app’s details page. I then define some other useful settings: the base root path of the application, the path to save some data, and the path of a PHP file that will contain the access token for the application. This access token file file doesn’t exist in the beginning; it’s created by the authorize.php page and is filled with the credentials provided by Dropbox. It will be a standard PHP file, and if exists will be included later by this script. The contents of the token file will be similar to:
<?php
$access_token = array (
  "oauth_token_secret" => "abcdefghilmnopqr",
  "oauth_token" => "stuvwxyzabcdefgh",
  "uid" => "1234567"
);
oauth_token and oauth_token_secret are the access credentials, and uid is the unique ID of the user. In the next section of the bootstrap file I set PHP error behavior and perform some requirements check; in order to run the application the data directory must exists and be writable and the auth.php file must be writable if it exists. This ensures the application can do its job freely. Finally, I include our libraries, initialize the PHP session, set an empty $access_token (which will be filled later), and, if it exists, include the auth.php file. Each frontend script will run inside a main try/catch block. Before digging into the library code we first need to understand the flow, so I’ll start with the authorization cycle.

Authorization

The first time our application is run, the following condition in the index.php file will be true:
<?php
if (!isset($access_token)) {
    header("Location: authorize.php");
    exit;
}
The access token is empty so I’m redirecting the user to the authorize.php page that will manage the authorization process. After the bootstrap phase, I make another check for an existing token. This ensures that this script is run only if we don’t have a token. In order to avoid an infinite redirect loop, the auth.php file is deleted by the main catch block of a script if the error code returned is 401 (invalid token). The first thing I do in every script is create a new DropboxSession object with our API keys. When we call the script directly, the first condition will be false and the else block is executed. The session object connects to Dropbox and asks for a temporary token. The token is then parsed into an array and stored into the $_SESSION variable for the next phase. We build the authorization URL using this token. The user should be redirected or prompted to visit the URL where he will decides whether to allow or deny access to his data. The authorization URL can contain the return URL as an optional parameter. I just pass the current script’s URL, so if the user authorizes the application he’s redirected back to our script, this time with the oauth_token and uid values passed by query string. The first condition now evaluates true, so we can go on and request a permanent access token. The $token array for this request is built with this new oauth_token and the previous oauth_token_secret, this is then passed to the obtainAccessToken() method. In case of success we have our permanent (until revoked) access token. This must be stored somewhere; the obvious choice is a database, but for this example we’ll export it as valid PHP code using the native var_export() function and write it to our auth.php file. Then the user is redirected to the index page which is the simplest script. At the beginning of our try/catch
block a new DropboxSession object is created, this time with the permanent $access_token as fourth argument. This object is used to create the DropboxClient object. These two steps are common for all the other scripts. The public methods of the client are mapped to the corresponding Dropbox API calls. I’m calling the accountInfo() method that returns an array containing the user’s details: unique id, name, email, quota info and referral link (refer to the official documentation for more details).

Behind the Scenes: the REST and Session Objects

Now that we have an overview of the surface flow, let’s see what happens under the hood, our Dropbox library is contained in the lib/dropbox directory and consists of three classes.

The REST Object

The lowest level class of our library is the REST client (see lib/dropbox/rest.php). This class is a simple wrapper for cURL. It performs the HTTP calls and return the output in raw or encoded format, or throws an exception in case of an error. The constructor checks if cURL is installed on the system, or throws an exception. Then it tries to initialize the internal $curl handler with the $curlDefaults setting. The handler is unset inside the destructor. The error(), errno(), and close() methods are self-explanatory. Then, we have a series of utility methods, get(), post(), and put(), all simple wrappers for the main request() method that does the real work. First we set the URL to fetch, then the HTTP method and the required parameters, additional headers and POST fields (if any). The parameters for the GET and PUT methods are passed along the URL by the caller method. Before making the call, we need to tell cURL to retrieve the full content including HTTP headers (set option CURLOPT_HEADER) because some API methods (ex file_get()) put their information in the headers. The cURL request is executed with curl_exec() storing the result into $response and the $info variable is filled by curl_info() with the details about the last execution. If the method is PUT we’ll also have to close the input file handle. With the $response content and the $info values we parse the result and separate the HTTP headers from the body. By default, the body is returned as JSON-decoded unless the $raw argument is set true. Before going on, there’s an error check. The Dropbox API uses HTTP error codes for error notifications. If the status code is greater than 400 then something went wrong and an error message is stored in the body content. I extract this message and throw an exception. If there are no errors the HTTP headers are parsed and the result is returned as array containing the status code, the headers, and the body.

The Session Object

The DropboxSession object extends the basic REST client to fill our needs:
  • perform the initial authentication/authorization flow,
  • include the obtained authentication data in each subsequent REST request.
The constructor simply initiazlizes the internal variables. Another simple method is buildAuthorizeURL() which builds the authorization URL from the temporary token. The most important methods of the class are:
  • obtainRequestToken() – request a temporary OAuth access token.
  • obtainAccessToken() – request the permanent OAuth access token for the application.
  • fetch() – perform a REST call including all the necessary authentication and signature parameters.
These three methods have a similar flow. First they build the basic destination URL and fill the $params associative array with the required oauth_* keys/values to send. Every API call must provide a timestamp and a unique random-generated hash, the $nonce parameter. Then the signature is generated using the HTTP method name, the URL, and the parameters. It’s then queued to the $params array using the oauth_signature key. The URL is fetched with the given HTTP method and the body part of the response is returned. For the GET and PUT methods, the query string is generated and appended to the URL using the native http_build_query()
function. The obtainRequestToken() and obtainAccessToken() are nearly identical: the first doesn’t use a token and is called with a GET HTTP method. The second is called with a POST HTTP method and must include the token obtained with the previous call. This token is then used as part of the signature key for all the following API calls. The fetch() method performs some additional tasks. First it takes an array called $args with any additional arguments required by the specific API, for example the path of the resource to list or the file to upload/download. These parameters are merged with the $params array before the signature is generated. The only exception is the input file argument, used by the PUT method to upload a file, which is extracted and kept for later. A switch statement is used to tell the right HTTP method to call. The DropboxSession class has also two utility methods, encodeParams() and getSignature(), called by the main methods above. encodeParams() prepares the request’s parameters to be signed, while getSignature() generates an OAuth request signature for the given API call.

The Final DropboxClient Object

The DropboxClient object is our high-level interface with Dropbox. It exposes the public API methods, uses the mid-level DropboxSession object to perform the API calls, and returns a processed output to the calling script. For this article I’ve implemented a limited suite of methods:
  • accountInfo() – fetch the current Dropbox user’s details.
  • metadata() – fetch information about a Dropbox object (file or folder) and retrieve a list of the content for folder objects.
  • getFile() – download a file and its metadata and optionally saves it to disk.
  • putFile() – upload a local file to a remote Dropbox path.
The session object and the base API URLs are stored as internal variables and initialized by the constructor. All the methods follow more or less the same approach, so I’ll point out the differences. All methods that deal with a path must prepend the Dropbox root path to each call. The root path depends on the access type of the application, and can be “dropbox” if the application has full access or “sandbox” if the application has limited access. If this value doesn’t match the application’s remote settings, an error is returned. The common steps performed by each method are:
  1. Check and prepare the argument list.
  2. Perform the HTTP call.
  3. Parse and return the response.
The accountInfo() method is the simplest; it calls its URL with no arguments and returns the associative array with the response. The metadata() method is used by list.php file to fetch and display the contents of the directory. The only required parameter is the path of the file or directory to check, but it allows us to specify all of the other parameters of the corresponding API call. If the $path argument is a file, the returned array contains its metadata. If it’s a folder, the content key contains the list of its files unless the $list argument is false. We can limit the size of the content with the $fileLimit argument (up to a maximum of 25,000) and we can ask for a specific revision of the file or folder (see the API reference for details). It’s important to note that the Dropbox API returns a hash value for each call. If we want to list the contents of a folder and provide a $hash parameter to our method, the API checks whether the output has changed since the last call. If not, it returns a status code of 301 (not modified). The Dropbox team recommends caching the results and relying on these values for folder listings to optimize performance. The getFile() method is used to retrieve a file stored in the user’s Dropbox. The entire file content is returned by the call in case of success, and its metadata is stored in the custom HTTP header x-dropbox-metadata as a JSON string. The return value of this method is an associative array that contains the name, mime type, metadata and content. In addition I’ve added an $outFile parameter to save the file directly on disk. The download.php file shows a demo of this method in action. In this example, the downloaded file is saved directly to the application’s data directory and the content part of the response is emptied. The putFile() method uploads a file from our local storage to the user’s Dropbox using the PUT HTTP method, which is preferred by the Dropbox team instead of POST. This method checks that the local file exists and doesn’t exceed the 150MB API limit before any other common action. The supported parameters for this method, in addition to the source file path, are the destination folder, an optional alternative name and an overwrite option. If this last option is false and the remote file exists, the uploaded file is renamed with a progressive number (for example, test.txt becomes test (1).txt). The API also allows for an optional parent_rev parameter to manage revisions, but in order to keep things simple I decided to omit it.

Summary

This is just a small part of the Dropbox API, but it can be enough as a starting point to develop your own applications. For me, it was also a good occasion to play with OAuth. Feel free to refine and expand the code that accompanies this article to suit your needs and, as always: happy coding! Image via Fotolia

Frequently Asked Questions (FAQs) about Accessing Dropbox Using PHP

How can I install the Dropbox PHP SDK?

To install the Dropbox PHP SDK, you need to use Composer, a dependency management tool in PHP. First, ensure that you have Composer installed on your system. If not, you can download it from the official Composer website. Once installed, you can add the Dropbox PHP SDK to your project by running the following command in your project root: composer require kunalvarma05/dropbox-php-sdk. This command will download the SDK and its dependencies into your project.

How do I authenticate my application with Dropbox?

To authenticate your application with Dropbox, you need to create an app on the Dropbox App Console. After creating the app, you will receive an App Key and App Secret. Use these credentials to authenticate your application using the Dropbox API. You can do this by creating an instance of the Dropbox Client and passing your App Key and App Secret as parameters.

How can I upload a file to Dropbox using PHP?

To upload a file to Dropbox using PHP, you need to use the upload method provided by the Dropbox API. This method requires two parameters: the path where you want to upload the file on Dropbox and the file content. You can get the file content using PHP’s built-in function file_get_contents.

How can I download a file from Dropbox using PHP?

To download a file from Dropbox using PHP, you can use the download method provided by the Dropbox API. This method requires the path of the file on Dropbox as a parameter. The method will return the file content, which you can then save to your local system using PHP’s built-in function file_put_contents.

How can I list all files in a Dropbox folder using PHP?

To list all files in a Dropbox folder using PHP, you can use the listFolder method provided by the Dropbox API. This method requires the path of the folder on Dropbox as a parameter. The method will return an array of metadata for each file in the folder.

How can I delete a file from Dropbox using PHP?

To delete a file from Dropbox using PHP, you can use the delete method provided by the Dropbox API. This method requires the path of the file on Dropbox as a parameter. The method will return the metadata of the deleted file.

How can I move a file to a different folder in Dropbox using PHP?

To move a file to a different folder in Dropbox using PHP, you can use the move method provided by the Dropbox API. This method requires two parameters: the current path of the file on Dropbox and the new path where you want to move the file.

How can I create a shared link for a file on Dropbox using PHP?

To create a shared link for a file on Dropbox using PHP, you can use the createSharedLinkWithSettings method provided by the Dropbox API. This method requires the path of the file on Dropbox as a parameter. The method will return a shared link for the file.

How can I handle errors when using the Dropbox API with PHP?

The Dropbox API uses HTTP status codes to indicate the success or failure of a request. You can handle errors by checking the status code of the response. For example, a status code of 200 indicates a successful request, while a status code of 400 indicates a bad request.

How can I monitor the usage of my Dropbox app?

You can monitor the usage of your Dropbox app through the App Console on the Dropbox website. The App Console provides various metrics such as the number of active users, the number of API calls, and the amount of data stored. This information can help you understand how your app is being used and identify any potential issues.

Vito TardiaVito Tardia
View Author

Vito Tardia (a.k.a. Ragman), is a web designer and full stack developer with 20+ years experience. He builds websites and applications in London, UK. Vito is also a skilled guitarist and music composer and enjoys writing music and jamming with local (hard) rock bands. In 2019 he started the BlueMelt instrumental guitar rock project.

Advanced
Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week