Get started with 33% off your first certification using code: 33OFFNEW

An Introduction to Serverless PHP

10 min read
Published on 27th March 2023

Serverless architecture is a paradigm shift in the way we think about building and deploying applications. The main idea behind serverless is to abstract away the underlying infrastructure, allowing developers to focus solely on writing code. This approach has gained popularity due to its scalability, cost-effectiveness, and ease of deployment. In this article, we'll introduce serverless PHP, discuss the advantages of serverless, explore various providers, and walk through creating a basic serverless application with code examples.

Architecture

In a traditional single server architecture you would have a single server, either a dedicated box or a VPS, that housed all of your services such as the web server (including PHP), a database, key-value store, session storage, file storage, etc. Although this works, it does have a number of problems, most notably being the difficulty to upgrade (you'd have to shut down a server to upgrade a component) and a large single point of failure (anything happens to that server and your whole infrastructure is gone). This architecture was popular perhaps a decade ago, but most infrastructure has moved to cloud-based architecture, especially since the introduction of AWS.

In cloud-based infrastructure you generally have a mixture of serverless resources and multiple, low-powered servers. The idea is to introduce multiple low-powered resources than have one high powered resource. This is known as horizontal scaling (as opposed to vertical scaling where you make one server more powerful).

AWS traditional cloud infrastructure

A lot of cloud infrastructure is already available as serverless. Using AWS as an example you have services such as S3 (serverless file storage), RDS Aurora (serverless database), SES (serverless email), and Cloudfront (serverless CDN) already available to you, and are often used in conjunction with EC2 servers, which are AWS's VPS.

In order to go fully serverless it is necessary to remove EC2 from the equation, which is where your application's code lives. To do that we must use a service called AWS Lambda, which is the same technology that runs on Amazon Echo's/Alexa. Lambda works as short-lived serverless functions, you can imagine them being like a little server that, when requested; turns on, runs your code, returns a response, turns off. This all happens with very little latency as there are always Lambda instances available, so the turning on and off doesn't actually happen, but it's the best way to illustrate the point.

Section 1: Advantages of Serverless

Serverless architecture offers several advantages compared to traditional server-based approaches:

Scalability: Serverless platforms automatically scale your application based on demand. This means you don't have to worry about provisioning and managing servers, as the platform takes care of this for you. You have true horizontal scaling with serverless and can, in theory, handle unlimited traffic, as you are only limited by the service's infrastructure capacity (which in AWS and Google's case is far larger than any website would ever need).

Cost-effective: With serverless, you only pay for the compute time your application consumes. This is a significant cost-saving compared to traditional server-based models, where you pay for pre-allocated resources regardless of actual usage.

Reduced operational overhead: As the infrastructure is managed by the service provider, you don't need to spend time on tasks like server maintenance, patching, and monitoring. This frees up resources to focus on developing and improving your application. There is a caveat with this which we'll go over in more detail later on; there can be a significant learning curve to using serverless as well as you needing to approach the build of your application slightly differently in some cases, and with it being a relatively new technology the support resources available are fewer than more traditional processes. There are also more moving parts involved, and some of them aren't as transparent as you might like, so it's not always obvious what is happening when something goes wrong.

Faster time-to-market: Serverless applications can be deployed quickly, as they don't require the setup and configuration of servers. This enables you to bring your application to market faster and respond to changing business requirements more efficiently.

Section 2: Serverless PHP Providers

There are several providers that offer serverless PHP support. Some of the most popular ones include:

AWS Lambda: Amazon Web Services (AWS) Lambda is one of the most popular serverless platforms. It supports PHP through custom runtime environments, allowing you to run PHP code in a serverless environment. AWS Lambda integrates seamlessly with other AWS services, making it an attractive choice for developers already using AWS. We'll be using Lambda throughout this article as the example service.

Google Cloud Functions: Google Cloud Functions is another popular serverless platform that supports PHP. Like AWS Lambda, it allows you to run your PHP code in a serverless environment and easily integrate with other Google Cloud services.

Azure Functions: Microsoft Azure Functions is a serverless platform that supports PHP through custom handlers. It enables you to build and deploy PHP applications that can scale automatically and integrate with other Azure services.

Vercel: Vercel is a serverless platform that focuses on frontend development and supports PHP. It provides a simple deployment process and integrates with popular frontend frameworks like Next.js and Gatsby. Vercel is geared more towards static sites and JavaScript frameworks, but PHP support is there. Depending on your use-case Vercel might be a great option, but may also be limiting.

Section 3: How Serverless Works

Serverless architecture is built on the concept of Functions as a Service (FaaS). In a FaaS model, your application is composed of individual, stateless functions that are triggered by events, such as an HTTP request or a message in a queue. Each function runs in a separate, isolated environment, and the underlying infrastructure is abstracted away by the service provider.

When a function is triggered, the serverless platform automatically provisions the necessary resources, executes the function, and then scales back down when the execution is complete. This allows for efficient resource utilization and cost savings, as you only pay for the actual compute time your functions consume.

Most functions have a small timeout time, so if your application takes longer than this to finish executing then it will be shut down prematurely. This is a complex topic, but in simple terms you need to understand the lifecycle of a request. Lambda functions aren't available to the web, they must pass through other services such as Amazon API Gateway. Lambda's timeout is 15 minutes, which should be enough for any application to run, but Amazon's API Gateway waits a maximum of 29 seconds before closing the connection. That is more than enough time for a web page to run, but it might not be enough time for a background task to run, such as an overnight backup. There are ways around this, such as instigating the Lambda function via another means, or breaking the task up into small chunks. The approaches to this are outside of the scope of this article, but it's important to remember that although one of the key advantages or serverless is to make infrastructure simpler it can sometimes have the opposite effect.

Section 4: Getting Started with Serverless PHP

To get started with serverless PHP, we'll use the popular serverless framework called Bref. Bref is a PHP library that makes it easy to deploy PHP applications on AWS Lambda. It provides pre-configured runtime environments and simplifies the process of creating and deploying serverless PHP applications.

First, ensure you have an AWS account and the AWS CLI installed and configured on your machine. Next, install the Serverless Framework globally using npm:

npm install -g serverless

Now, let's create a new PHP project and install Bref (the below assumes you have composer installed globally):

composer create-project --prefer-dist bref/bref my-serverless-php-app
cd my-serverless-php-app

This command creates a new PHP project with Bref as a dependency. Bref is a project that makes running PHP on serverless infrastructure much easier. Bref has bridges for both Laravel and Symfony, although Laravel has it's own solution available called Vapor (more below). The generated project contains a serverless.yml file, which is the configuration file for the Serverless Framework.

Section 5: Building a Basic Serverless PHP Application

Let's create a simple serverless PHP application that returns a JSON response. Create a new file named index.php in the project's root directory and add the following code:

<?php

require __DIR__ . '/vendor/autoload.php';

use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;

$handler = function (ServerRequestInterface $request): ResponseInterface {
    $response = new \Nyholm\Psr7\Response();
    $response->getBody()->write(json_encode(['message' => 'Hello, Serverless PHP!']));
    return $response->withHeader('Content-Type', 'application/json');
};

return $handler;

This code defines a simple request handler that returns a JSON response with a greeting message. Bref uses the PSR-7 and PSR-15 standards for handling HTTP requests and responses.

Next, update the serverless.yml file to configure the function:

service: my-serverless-php-app

provider:
  name: aws
  runtime: provided.al2
  region: eu-west-1

plugins:
  - ./vendor/bref/bref

functions:
  hello:
    handler: index.php
    layers:
      - ${bref:layer.php-81}
    events:
      - http: 'ANY /'
      - http: 'ANY /{proxy+}'

This configuration defines an AWS Lambda function named hello that uses the provided PHP runtime and the index.php file as the handler. The events section specifies that the function should be triggered by any HTTP request. We're using PHP 8.1 here, in EU West 1 region, which you can update to whatever is most appropriate to you.

Section 6: Deploying the Serverless PHP Application

With the application and configuration in place, it's time to deploy our serverless PHP app. Run the following command:

serverless deploy

The Serverless Framework will package and deploy your application to AWS Lambda. Once the deployment is complete, you will receive an endpoint URL for your function. You can test your function by sending an HTTP request to the provided URL:

curl https://your-api-gateway-url.amazonaws.com/dev

You should see the JSON response with the greeting message:

{"message": "Hello, Serverless PHP!"}

Conclusion

Serverless PHP offers an attractive solution for building scalable, cost-effective, and easy-to-deploy applications. With the help of serverless platforms and tools like Bref and the Serverless Framework, you can quickly develop and deploy PHP applications without worrying about the underlying infrastructure.

In this article, we've introduced serverless PHP, discussed its advantages, explored various providers, and walked through creating a basic serverless PHP application using Bref and the Serverless Framework. You can now build upon this foundation to create more complex serverless PHP applications tailored to your needs.

Serverless gotchas

As alluded to in this article, although one of the key advantages of serverless is to make managing infrastructure easier is sometimes makes things more complex. If you're aware of that going into things then you can appropriately manage your application code.

Timeouts

Lambda has a 15 minute timeout, and AWS API Gateway has a 29 seconds timeout. This can lead to unexpected outcomes, especially for long-lived sessions. It's obviously more than enough for serving a web page, but any background API tasks can take longer than 29 seconds. This is only really applicable for certain applications, but if you're migrating to serverless from a traditional setup then you should be aware of it.

File uploads

You don't have a server, so if you accept file uploads within a form on your application then you'll need somewhere to upload those files to. In traditional cloud server architecture the file is often uploaded to the server first and then uploaded to S3. Serverless functions have no file system to upload to, and even if they did your file would be destroyed as soon as the request finishes, so this isn't an option. Instead you'll need to upload directly to the hosting service. There are plenty of tutorials available on how to do this, but just ensure you follow good security practices as to not expose any private keys to your users. You can check out our tutorial on how to upload files directly to S3 using JavaScript for a good starting point on how to do this, just always ensure you're following security best-practices.

Understanding infrastructure and limitations

In traditional cloud infrastructure you have quite basic services, and more options. With serverless your request lifecycle is more complex, passes through more services, and if something goes wrong you have less visibility on what happened. You'll need to set up logging via something like AWS Cloudwatch, because if there is an application error then your error log will be destroyed at the end of the request lifecycle, but it's still possible to have issues before getting to the point where you can log to Cloudwatch, and in those instances debugging can be challenging.

You need to be comfortable that you'll need to get up to speed with more AWS services than you did before and understand what each piece of the puzzle is doing.

You are also forced to use the serverless providers services for certain things. For example, when using AWS Lambda you couldn't use Cloudflare for your DNS, you'll need to use AWS Route 53. Although interestingly, Cloudflare does have its own serverless platform called Cloudflare Workers, but they are currently JavaScript-only.

Reduced community support

Serverless for web applications is a relatively new concept and it is nowhere near as popular as traditional cloud architecture. As such, you need to expect to wait longer for answers on the likes of Stackoverflow/ServerFault, and you'll have fewer resources available to you online.

As your application grows you may want to employ external help to manage your infrastructure. It is going to be more challenging to find engineers with serverless experience. That said, one of the benefits of serverless is you can try and forget about it once it's working properly. There are also managed services such as Vapor which makes this an almost non-issue.

Vapor

If you're a fan of Laravel then they have their own product for serverless called Vapor. Vapor allows you to deploy your application to a full serverless environment infrastructure, including:

  • AWS Lambda for code hosting
  • RDS serverless databases
  • Manage caches such as DynamoDB and ElastiCache redis. These aren't serverless but Vapor handles the scaling for you
  • Queue management. Jobs scale horizontally so the queue is effectively always empty as all jobs are instantly processed
  • S3 file management, including a frontend script to upload directly to S3
  • Cloudfront CDN configured for you
  • DNS and certificates managed for you
  • Staging environment management