Was this page helpful?

Getting started with Contentful and PHP

This PHP CMS tutorial will show you how to get started using our PHP client library to consume content. The client library requires PHP 7.0 or higher.

Contentful's Content Delivery API (CDA) is a read-only API for retrieving content from Contentful. All content, both JSON and binary, is fetched from the server closest to a user's location by using our global CDN.

We publish client libraries for various languages to make developing applications easier.


This tutorial assumes that you understand the Contentful data model.


For every request, clients need to provide an API key, which is created per space and used to delimit applications and content classes.

You can create an access token using the Contentful web app or the Content Management API.


The easiest way to install the Contentful PHP client library is to use Composer and run the following command:

composer require contentful/contentful

If you haven't done already, add the Composer autoloader at the beginning of your project:

require_once 'vendor/autoload.php';

Setting up the Contentful client

Once you have installed the client library you need to create a Client.

Initialize the client

You need an API key and a space ID to initialize a client. You can use the API key and space ID pre-filled below from our example space or replace them with your own values.

$client = new \Contentful\Delivery\Client('<access_token>', '<space_id>', '<environment_id>');

Getting your content

Contentful separates content between entries, which contain your data and relationships with other content or images, and assets, which represent static content, like images, and are served as files. You can read more about this in our data model concepts guide.


With the client created, you can start consuming data from the API.

The code below retrieves all entries in your space from the API, but don't print the output yet, as this will result in a lot of JSON, you will learn how to filter the output later:

$entries = $client->getEntries();

Whereas this code retrieves a single entry specified by an ID.

$entry = $client->getEntry('<entry_id>');
echo $entry->getName();
Playsam Streamliner Classic Car, Espresso

To specify more complex queries you can use the query builder. The example below filters results to a specific content type (the product) and sorts them by price:

$query = new \Contentful\Delivery\Query();

$products = $client->getEntries($query);

Using the entry

Once you've got the entry, you can access its field values in a few different ways:

foreach ($products as $product) {
    // Virtual getter methods, just use "get" and the field ID
    echo $product->getName();

    // Virtual properties
    echo $product->name;

    // Using array-like syntax
    echo $product['name'];

    // Using the actual getter method
    echo $product->get('name');

If an entry contains a link to an asset or another entry, the client library will automatically load it. The example below shows the name of the brand linked to the product:

foreach ($products as $product) {
    // Virtual getter methods, just use "get" and the field ID
    echo $product->getName().', Brand: '.$product->getBrand()->getCompanyName().PHP_EOL;

    // Virtual properties
    echo $product->name.', Brand:'.$product->brand->companyName.PHP_EOL;

    // Using array-like syntax
    echo $product['name'].', Brand:'.$product['brand']['companyName'].PHP_EOL;

    // Using the actual getter method
    echo $product->get('name').', Brand:'.$product->get('brand')->get('companyName').PHP_EOL;

While virtual properties and array-like access don't allow further parameters, virtual getters and the get method allow you futher refinement, as both allow you to specify the field locale—remember though that this only works when the entry was built using the locale=* query parameter, so all locales were fetched from the API:

$query = new \Contentful\Delivery\Query();

$products = $client->getEntries($query);

foreach ($products as $product) {
    echo $product->getName('it-IT');
    echo $product->get('name', 'it-IT');

Finally, the get methods allows you to pass a third, boolean parameter, which determines whether links will be resolved automatically (defaults to true). If it's set to false, a Contentful\Core\Api\Link object will be returned instead of a full entry:

$link = $product->get('brand', null, false);
// Contentful\Core\Api\Link
echo $link->getId();
echo $link->getLinkType();

$brand = $client->resolveLink($link);

All methods for accessing fields support a special field, when working with links. In fact, you just need to append Id to the field name, and the link ID (or array of IDs, if working with an array of links) will be returned:

// These are all equivalent, they return the ID of the linked entry

// With the field "pictures" being an array of links to assets,
// an array of strings will be returned,
// containing a list of IDs of the linked assets

Using assets

Querying assets works similarly to querying entries. You can retrieve all assets from a space with the following:

$assets = $client->getAssets();

Or to get a single asset:

$asset = $client->getAsset('<asset_id>');

As with entries you can also use more complex queries:

$query = (new \Contentful\Delivery\Query())
$assets = $client->getAssets($query);

Once you have an asset, you can access its metadata and an URL for the actual file:

echo $asset->getTitle().PHP_EOL;
echo $asset->getFile()->getUrl();

Using the Images API you can control how Contentful serves images. For example, to convert an image to JPEG and resize it to a height of no more than 100 pixels:

$options = (new \Contentful\Core\File\ImageOptions());
echo $asset->getFile()->getUrl($options);

Next steps

Not what you’re looking for? Try our FAQ.