peekmo/jsonpath
peekmo/jsonpath adds JSONPath querying to PHP/Laravel, letting you select, filter, and extract values from complex JSON/arrays using familiar JSONPath expressions. Useful for API responses, config inspection, and transforming nested data quickly.
Installation Add the package via Composer:
composer require peekmo/jsonpath
No service provider or facade registration is required—use it as a standalone library.
First Use Case Query a JSON string or array with JsonPath syntax:
use Peekmo\JsonPath\JsonPath;
$json = '{"store": {"book": [{"title": "PHP", "price": 10}, {"title": "Laravel", "price": 20}]}}';
$result = JsonPath::search($json, '$.store.book[*].title');
// Returns: ["PHP", "Laravel"]
Where to Look First
Peekmo\JsonPath\JsonPath class methods: search(), evaluate(), find().Querying Nested Data
Use search() for arrays of results or evaluate() for single values:
$data = ['users' => [['name' => 'Alice'], ['name' => 'Bob']]];
$names = JsonPath::search($data, '$.users[*].name'); // ["Alice", "Bob"]
$firstName = JsonPath::evaluate($data, '$.users[0].name'); // "Alice"
Dynamic Paths Build paths programmatically (e.g., for API responses):
$path = sprintf('$.data.items[?(@.price > %d)]', $minPrice);
$expensiveItems = JsonPath::search($apiResponse, $path);
Integration with Laravel
$response = Http::get('https://api.example.com/data');
$filteredData = JsonPath::search($response->json(), '$.results[*].id');
$user = User::whereJsonContains('metadata', '$.preferences.theme')->first();
$theme = JsonPath::evaluate($user->metadata, '$.preferences.theme');
Validation Use JsonPath to validate API payloads or database records:
$requiredPath = '$.user.email';
if (empty(JsonPath::evaluate($request->json(), $requiredPath))) {
return response()->json(['error' => 'Email missing'], 400);
}
// Filter books priced > 15
$expensiveBooks = JsonPath::search($json, '$.store.book[?(@.price > 15)]');
Peekmo\JsonPath\Functions\FunctionInterface (see source).Archived Package
mtdowling/jsonpath-php if critical bugs arise.Path Syntax Strictness
$ prefix in arrays: $.store.book works, but $.book fails if book is a direct child of the root array.$.store.book[0] over $.store.book.0 for consistency.Performance
$.a.b.c[*].d[*].e).Edge Cases
JsonPath::search() returns null for missing paths; handle with isset() or array_filter().json_decode() first if unsure).json_last_error() if paths fail unexpectedly.error_reporting(E_ALL) to catch silent failures (e.g., malformed paths).Custom Functions Register a function to handle domain-specific logic:
JsonPath::addFunction('isAdmin', function ($value) {
return $value === 'admin';
});
// Usage: $.users[?isAdmin(@.role)]
Override Defaults
Extend the JsonPath class to modify behavior (e.g., case-insensitive keys):
class CustomJsonPath extends JsonPath {
protected function normalizeKey($key) {
return strtolower($key);
}
}
Laravel Helpers Create a helper trait for reusable logic:
trait JsonPathHelper {
public function jsonPath($json, $path) {
return JsonPath::search($json, $path);
}
}
How can I help you explore Laravel packages today?