symfony/json-path
Evaluate JSONPath expressions in Symfony/PHP to query and extract data from JSON documents. Lightweight library with simple API for selecting nodes, filtering arrays, and retrieving values, useful for config parsing, API responses, and data transformation.
HttpClient or Serializer). This ensures seamless compatibility with Laravel’s service container, dependency injection, and HTTP clients.Collection macros or Eloquent JSON fields.composer require symfony/json-path and no Laravel-specific setup (though a facade/service provider is recommended for consistency).Illuminate\Support\Collection).$json = json_encode(['user' => ['name' => 'John']]);
$this->assertEquals(['John'], JsonPath::search($json, '$.user.name'));
json_decode() + manual traversal for high-throughput APIs.| Risk | Mitigation |
|---|---|
| RFC 9535 Compliance | Validate edge cases (wildcards *, recursive paths) in CI tests. |
| Performance Bottlenecks | Profile with symfony/var-dumper or Xdebug for deep/nested queries. |
| Dependency Bloat | No conflicts with Laravel’s Symfony components (e.g., symfony/http-client). |
| Deprecation Risk | Monitor Symfony’s JSONPath for upstream changes; MIT license allows forks. |
$.nonexistent) be logged/handled? (Leverage Laravel’s App\Exceptions\Handler).spatie/array-to-xml or custom logic.symfony/http-client, symfony/serializer).config/app.php or a service provider:
// app/Providers/AppServiceProvider.php
public function register()
{
$this->app->singleton(\Symfony\Component\JsonPath\JsonPath::class);
}
// app/Facades/JsonPath.php
namespace App\Facades;
use Illuminate\Support\Facades\Facade;
class JsonPath extends Facade { protected static function getFacadeAccessor() => 'jsonPath'; }
Usage:
$value = JsonPath::search($json, '$.user.profile.name');
Collection for JSONPath queries:
// app/Providers/AppServiceProvider.php
use Illuminate\Support\Collection;
Collection::macro('jsonPath', function ($path) {
return JsonPath::search($this->toJson(), $path);
});
Usage:
$collection->jsonPath('$.stores[*].name');
// Before
$data = json_decode($response->getBody(), true);
$value = $data['user']['profile']['name'];
// After
$value = JsonPath::search($response->getBody(), '$.user.profile.name');
// app/Traits/UsesJsonPath.php
trait UsesJsonPath {
protected function extractJsonPath($json, string $path) {
return JsonPath::search($json, $path);
}
}
json_decode() + manual traversal:
// phpstan.neon
services:
- App\Services\LegacyJsonParser (deprecated)
json column type:
$user = User::whereJsonContains('metadata->path', '$.preferences.theme')->first();
$theme = JsonPath::search($user->metadata, '$.preferences.theme');
spatie/laravel-json (for JSON column handling).guzzlehttp/guzzle (API responses).nesbot/carbon (date parsing in JSON).| Step | Priority | Effort | Dependencies |
|---|---|---|---|
| Composer Install | High | Low | None |
| Facade/Service Setup | Medium | Low | JsonPath class |
| Pilot in API Layer | High | Medium | Existing API response handlers |
| Collection Macro | Low | Low | AppServiceProvider |
| CI Testing | High | Medium | Pest/PHPUnit JSONPath assertions |
| Documentation | Medium | Medium | Internal wiki or README updates |
git clone https://github.com/symfony/json-path.git custom-json-path
composer require your-vendor/custom-json-path
JSONPath.md to your project’s docs with:
$.array[?(@.price > 100)]).## JSONPath Queries
- Extract all book titles: `$.store.book[*].title`
- Filter books by price: `$.store.book[?(@.price > 50)].title`
- Recursive search: `$.**` (use cautiously)
JsonPath::search()’s exceptions to log malformed queries:
try {
$result = JsonPath::search($json, $path);
} catch (\Symfony\Component\JsonPath\Exception\JsonPathException $e) {
Log::error("Invalid JSONPath [$path]: " . $e->getMessage(), ['json' => $json]);
}
App\Exceptions\Handler to format errors for users:
public function render($request, Throwable $exception)
{
if ($exception instanceof \Symfony\Component\JsonPath\Exception\JsonPathException) {
return response()->json(['error' => 'Invalid JSONPath query'], 400);
}
return parent::render($request, $exception);
}
How can I help you explore Laravel packages today?