Background image

Product Updates

Type-Safe PHP Generation

Ian Bentley

Ian Bentley

September 10, 2024

Featured blog post image

PHP is so back

Off the back of Laravel’s $57 million Series A (opens in a new tab), we won’t be the first to observe that PHP is so back. Which makes it the perfect time to announce the beta release of our new PHP SDK Generator! We’re bringing modern type safety and a streamlined developer experience to the PHP SDKs generated on our platform.

Headline features

Before we dive into the nitty-gritty, here’s a quick rundown of what our new PHP SDK Generator brings to the table:

  • Robust type safety with carefully typed properties for all models
  • Support for union types, embracing PHP 8’s modern type system
  • Readability, a streamlined, object-oriented approach for easy debugging
  • Minimal external dependencies for a lightweight footprint
  • IDE compatibility for a superior development experience

Type safety in PHP

Humble beginnings

Born as a loosely typed language, PHP spent years as the wild child of web development, allowing developers to play fast and loose with their data types. But as applications have grown more complex, the need for stricter type checking has become apparent.

Enter PHP 7, which introduced scalar type declarations and return type declarations, marking the beginning of PHP’s type matruity. Next, PHP 8 landed, bringing union types, null-safe operators, and other type-related improvements that firmly put PHP on the path to true type-safety.

Building type safety into our SDK generation

Our PHP SDK Generator takes fullest advantage of PHP’s nascent type system. We’ve implemented a robust type-hinting system that leverages the latest PHP features to provide a truly type-safe developer experience. Here’s how we’ve done it:

  1. Native Types: Wherever possible, we use PHP’s native types like enum, string, int, float, and bool.
  2. Class-Based Objects: We generate standard PHP classes with public properties, using attributes and reflection to guide serialization.
  3. DateTime Handling: We use the native \DateTime class for timestamp handling, ensuring consistent date and time operations.
  4. Custom Types: For special cases like Date, we leverage the Brick\DateTime\LocalDate class from our minimal set of dependencies.

Let’s take a look at how this translates into real code:

class Drink
{
public string $name;
public float $price;
public ?DrinkType $type;
public ?int $stock;
public ?string $productCode;
public function __construct(string $name, float $price, ?DrinkType $type, ?int $stock, ?string $productCode)
{
// Constructor implementation
}
}

This approach ensures that your IDE can provide accurate autocomplete suggestions, that type-related errors are caught early in the development process and that developers cannot accidentally build objects with incomplete data.

Unions: Embracing PHP 8’s Type System

One of the most exciting features of PHP 8 was the introduction of union types, and our SDK Generator leverages this to provide even more precise type definitions. Union types allow properties or parameters to accept multiple types, providing flexibility while maintaining type safety.

Here’s how we’ve implemented union types in our generated SDKs:

class BeverageContainer
{
/**
*
* @var Shared\Mocktail|Shared\Cocktail $beverage
*/
public Shared\Mocktail|Shared\Cocktail $beverage;
public function __construct(Shared\Mocktail|Shared\Cocktail $beverage)
{
$this->beverage = $beverage;
}
}

A Lightweight Footprint

Warning Icon

jms/serializer fork

Union support is still new to the PHP ecosystem. We’re working with the library maintainers to add robust support for union types in the jms/serializer library. In the meantime, we’ve forked the library to provide basic support for union types in our generated SDKs. Once our changes (opens in a new tab) are merged upstream, we’ll switch back to the official library.

We understand the importance of keeping your project’s dependency tree manageable. That’s why our PHP SDK generator has been designed to rely on as few external libraries as possible. We’ve carefully selected a minimal set of dependencies:

  • guzzlehttp/guzzle: For a robust HTTP client
  • jms/serializer: To handle data serialization and deserialization
  • Brick\DateTime: For comprehensive date and time support

This lean approach ensures that integrating our generated SDK into your project won’t bloat your composer.json or introduce potential conflicts with your existing dependencies.

Laravel-compatible packages for every API

PHP generation comes with optional Laravel integration support that can be enabled in the SDK’s gen.yaml configuration. This will generate a Laravel Service Provider (opens in a new tab). The following snippet demonstrates an example of how to use the Laravel DI container with Dub’s PHP SDK (opens in a new tab).

use Dub\Dub;
use Illuminate\Contracts\View\View;
use Illuminate\Http\Request;
final readonly class LinksController
{
public function __construct(
private Dub $dub,
) {}
public function index(Request $request): View
{
return view('links.index', [
'links' => $this->dub->links->list(),
]);
}
}

Enhanced Developer Experience

We’ve gone the extra mile to ensure that working with our generated PHP SDKs is a joy for developers:

  • Improved Import Patterns: Say goodbye to namespace conflicts and hello to predictable behavior in your IDE’s type hinting.
  • Intuitive Factory Pattern: Our convenient factory pattern manages the SDK configuration, making it a breeze to get started and customize as needed.
  • Comprehensive Documentation: Each generated SDK comes with detailed markdown documentation, ensuring you have all the information you need at your fingertips.

Looking Forward

As we enter this beta phase, we’re excited to see how the PHP community puts our SDK Generator to work. We’re committed to refining and improving the generator based on your feedback, so don’t be shy – put it through its paces and let us know what you think!

CTA background illustrations

Speakeasy Changelog

Subscribe to stay up-to-date on Speakeasy news and feature releases.