Skip to content

Contact sales

By filling out this form and clicking submit, you acknowledge our privacy policy.

How to run serverless PHP on Azure

With the arrival of Azure Functions Custom Handlers, you can run PHP serverless apps on Azure. Here's how to make use of this new capability.

Jun 08, 2023 • 3 Minute Read

Please set an alt value for this image...

With the arrival of Azure Functions Custom Handlers, you can now run PHP serverless apps on Azure. In this article, you're going to see how to make use of this new capability by getting your PHP project read for Azure Functions.

Getting started

Structure of a serverless app

Azure serverless apps have the following folder structure:

├── HttpTrigger
│   ├── function.json
│   └── index.php
├── QueueTrigger
│   ├── function.json
│   └── index.php
├── deploy.sh
├── host.json
├── local.settings.json

Each serverless function lives in folders like HttpTrigger and QueueTrigger. Inside those folders you will have two files function.json and index.php.

In functions.json you'll specify how the function is triggered, what parameters it receives, and what it returns, while index.php is the file that contains your function logic. To learn more about the structure of an Azure Functions serverless app look at this guide: Azure Functions developer guide

In case of PHP, which is what interest us here, you need to have an index.php file on you function folder, like in the HttpTrigger example above. Your PHP code must follow these conventions:

<?php
use AzserverlessContextFunctionContext;

function run(FunctionContext $context) {
    $req = $context->inputs['req'];

    $context->log->info('Http trigger invoked');

    $query = $req['Query'];

    if (array_key_exists('name', $query)) {
        $name = $query['name'];
        $message = 'Hello ' . $query['name'] . '!';
    } else {
        $name = 'EMPTY';
        $message = 'Please pass a name in the query string';
    }

    $context->outputs['outputQueueItem'] = json_encode($name);
    $context->log->info(sprintf('Adding queue item: %s', $name));

    return [
        'body' => $message,
        'headers' => [
            'Content-type' => 'text/plain'
        ]
    ];
}
?>

You need a function called run that accepts a FunctionContext parameter, which will contain the input received by your function, along with other utilities, like a Monolog logger. You can also set outputs in the $context parameter, like what that code does with outputQueueItem, adding a value that will be forwarded into a Queue in this particular case.

Now, where does that FunctionContext comes from? It comes from the new Azserverless library made specifically for Azure & PHP.

Go to your project root folder and add the following dependency in your composer.json:

"require": {
    "videlalvaro/azserverless": "*"
}

If you don't have composer installed, follow the instructions here.

Then on the command line run composer.phar install, which will get all the required dependencies.

Configuring Azure Functions for PHP

Now it's time to tell Azure Functions how to run your PHP project. Open the host.json. In that file you should add a top-level entry that specifies this project runs with a custom handler:

    "customHandler": {
      "description": {
      "defaultExecutablePath": "php",
      "arguments": [
        "-S",
        "0.0.0.0:%FUNCTIONS_CUSTOMHANDLER_PORT%",
        "vendor/videlalvaro/azserverless/bin/serverless.php"
      ]
    },
    "enableForwardingHttpRequest": false
  },

We tell Azure Functions how to execute PHP, providing the path to the vendor/videlalvaro/azserverless/bin/serverless.php file that forwards requests to our function handlers.

Finally, we need to tell azure that our app is going to run on PHP 7.4. Open the command line, and invoke the Azure CLI with the following parameters:

az webapp config set --name your_app_name --resource-group your_resource_group --php-version 7.4

Final touches

Before deploying make sure to configure your local.settings.json file by including the "FUNCTIONS_WORKER_RUNTIME": "custom" config key/value, and your AzureWebJobsStorage connection string:

{
  "IsEncrypted": false,
  "Values": {
    "FUNCTIONS_WORKER_RUNTIME": "custom",
    "AzureWebJobsStorage": "DefaultEndpointsProtocol=https;AccountName=<accountname>;AccountKey=<accountkey>;EndpointSuffix=<endpointsuffix>"
  }
}

And finally make sure to add the Kudu scripts specified in the guide Configure a PHP app for Azure App Service, so composer is run every time you deploy your app, keeping your dependencies up to date.

And that's it! You should be ready to deploy your PHP app to Azure Functions by using the new custom handlers feature.

Learn more

If you want to learn more about the topics covered in this article, be sure to visit the following websites:

Happy hacking!

About the Author

Alvaro Videla is a developer advocate at Microsoft, and he organizes DuraznoConf. He is the coauthor of RabbitMQ in Action and has written for the Association for Computing Machinery. You can find him on Twitter as @old_sound.