Back

Meilisearch PHP v2 (beta) release notes

February 20, 2026

This article summarize all changes coming to the meilisearch-php v2 SDK.

This pages list changes from v1.x and v2.0.0-beta.5.

Highlights

This release focuses on improving the developer experience for SDK users by integrating the newest PHP features. We're updating the minimum requirements to PHP 8.1.

  • Bump requirements to PHP 8.1
  • Improve Task management with types
  • Improve type safety by adding typehints, and moving from array access to objects with getters
  • Streamline exceptions types (remove wrapping of native exceptions, add types to SDK exceptions)
  • Implement ArrayAccess on Tasks for Symfony and Laravel backward compatibility

Future Meilisearch features will be integrated into the v2.x branch, but we will backport major features and security updates. If we missed something, please open an issue to request backporting a feature.

Migration guide

Ensure you are running PHP 8.1+ and upgrade your meilisearch-php dependency:

composer require meilisearch/meilisearch-php:2.0.0-beta.5

🟠 Task methods now return types

Impact: moderate

$client->getTasks() and $index->getTasks() now return a TaskResults object.

// Before (v1.x)
$tasks = $client->getTasks();
$results = $tasks['results']; // Accessing as array

// After (v2.x)
$tasks = $client->getTasks(); // Returns TaskResults
$results = $tasks->getResults(); // Returns an array of Task objects

Additionally

  • The internal task manager all() method now returns an array of Task objects.
  • The TaskResults class is now final

🟠 Refactor tasks as objects, and task status and type as enums

Impact: moderate

This introduces two changes:

  • Asynchronous operations now return Tasks as an object instead of an array
  • Tasks can be awaited with the new wait(int $timeoutInMs = 5000, int $intervalInMs = 50): Task method

Awaiting tasks:

// Before
$promise = $this->client->createIndex('new-index', ['primaryKey' => 'objectID']);
$this->index->waitForTask($promise['taskUid']);

// After
$this->client->createIndex('new-index', ['primaryKey' => 'objectID'])->wait();

Asserting task status:

// Before
$task = $this->client->getTask($taskUid);
if ($task['status'] === 'succeeded') {
    // do something
}

// After
if ($task->getStatus() === TaskStatus::Succeeded) {
    // do something
}

Asserting task types:

// Before
$task = $this->client->getTask($taskUid);
if ($task['type'] === 'indexCreation') {
    // do something
}

// After
$task = $this->client->getTask($taskUid);
if ($task->getType() === TaskType::IndexCreation) {
    // do something
}

🟢 Remove custom exception for JSON parsing

Impact: minor

Before: catching SDK-specific JSON exceptions

<?php

try {
    $client->index('books')->addDocuments([["title" => "\xB1\x31"]]);
} catch (JsonEncodingException | JsonDecodingException $e) {
    // handle JSON errors
}

After: catching native PHP JsonException

<?php

try {
    $client->index('books')->addDocuments([["title" => "\xB1\x31"]]);
} catch (\JsonException $e) {
    // handle JSON errors
}

🟢 Database stats now return a typed Stats object

Impact: minor

$stats = $client->stats();

// Before (v1.x) - accessing stats as array
$databaseSize = $response['databaseSize'];
$usedDatabaseSize = $response['usedDatabaseSize'];
// etc...

// After (v2.x) - use getter methods
$databaseSize = $stats->getDatabaseSize();
$usedDatabaseSize = $stats->getUsedDatabaseSize();

🟢 Version is now a typed Version object

Impact: minor

$version = $client->version();

// Before (v1.x) - access as array
$commitSha = $version['commitSha'];
$commitDate = $version['commitDate']; // String
$pkgVersion = $version['pkgVersion'];

// After (v2.x) - use getter methods
$commitSha = $version->getCommitSha();
$commitDate = $version->getCommitDate(); // \DateTimeImmutable
$pkgVersion = $version->getPkgVersion();

🟢 Removed legacy MeiliSearch namespace

Impact: minor

We removed MeiliSearch (capital S) namespace.

// Before (v1.x) - MeiliSearch with capital S
use MeiliSearch\Client;

// After (v2.x) - Meilisearch without capital S
use Meilisearch\Client;

🟢 Removed Indexes::parseDate() public method

Impact: minor

This only affects you if you were using this utility method directly.

// Before (v1.x) - If you used this method in your code
$dateTime = \Meilisearch\Endpoints\Indexes::parseDate('2021-01-01T01:23:45.123456Z');

// After (v2.x) - Use native PHP instead
$dateTime = new \DateTimeImmutable('2021-01-01T01:23:45.123456Z');

🟢 Improved exception types DX

Impact: minor

The custom $message property has been removed from custom exceptions. Use the getMessage() method instead:

try {
    // ...
} catch (\Meilisearch\Exceptions\ApiException $e) {
   // Before (v1.x)
    echo $e->message;
    // After (v2.x)
    echo $e->getMessage();
}

Also:

  • Exception classes are now final
  • Exception public properties are now read-only and strictly typed.
  • The rethrowWithHint static method now returns a \RuntimeException instead of a generic \Exception.

More information

You can read more by taking a look at the open-source repository:


Shout-out to @norkunas for his massive contributions to this release. 💙