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 URLhttp://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 theindex.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 thelib/dropbox
directory and consists of three classes.
The REST Object
The lowest level class of our library is the REST client (seelib/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
TheDropboxSession
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.
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.
$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
TheDropboxClient
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.
- Check and prepare the argument list.
- Perform the HTTP call.
- Parse and return the response.
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 FotoliaFrequently 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 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.