laravel/surveyor
Beta Laravel tool for mostly static analysis of PHP/Laravel apps. Parses files/classes to extract rich metadata (classes, methods, properties, types) and can inspect models and container bindings for extra detail. Returns structured results for other tools.
Eloquent Builder & Query Method Resolution (PR #44, #46):
where(), orderBy(), and select() in builder mixins (e.g., @mixin in Blade or custom traits).whereBetween(), whereIn() with array ranges), improving SQL injection detection and query optimization suggestions.User::where('active', true)->with('posts')->get()), critical for API response validation and DTO generation.@mixin usage in Blade or service providers.Model::query()->where(...)->get()).Interface & Class Analysis (PR #40):
Illuminate\Contracts\Auth\Authenticatable).RepositoryInterface).PHP Keyword Resolution (PR #43):
class, abstract, final), which are common in Laravel:
getClass() or setAbstract() in model attributes.Illuminate\Container\Container::make()).Eloquent Query Safety:
DB::raw() or whereRaw() usage.fillable/guarded against query-generated data.select() to avoid N+1 queries in with()").Interface & Contract Compliance:
find()/create() methods adhere to RepositoryInterface.before()/authorize() against Illuminate\Auth\Access\HandlesAuthorization.Backward Compatibility:
Eloquent Builder Complexity:
October\Rain\Database\Builder or Spatie\QueryBuilder.call_user_func_array()-based query builders.where() macros clashing with standard methods).// Custom builder example
$query->macro('customWhere', fn($field) => $query->where($field, 'test'));
// Verify Surveyor resolves `customWhere` correctly.
Interface Analysis Edge Cases:
#[\ReturnTypeWillChange]).new class implements Foo { ... }).composer survey --rules=Interfaces --profile
Performance Impact:
$builder = User::query();
for ($i = 0; $i < 100; $i++) {
$builder->where("field_$i", $i);
}
$builder->get();
PHP Keyword Collisions (PR #43):
getAbstract() might trigger unexpected warnings..surveyor.php:
return [
'rules' => [
'Methods' => [
'ignore' => ['getAbstract', 'setFinal'], // If intentional
],
],
];
Eloquent Query Reliability:
Interface & Contract Enforcement:
RepositoryInterface, Policy)? PR #40 may expose missing implementations in existing code.PHP Keyword Usage:
getClass, setAbstract)? PR #43’s fix may alter their analysis.Performance Trade-offs:
Migration Strategy:
0.2.4 immediately, or wait for v1.0 for broader stability?Failure Mode Testing:
// Test custom macro resolution
DB::macro('unsafeWhere', fn($field) => DB::where($field, 'hack'));
// Ensure Surveyor flags this as unsafe.
trait HasTimestamps {}
class Model extends Illuminate\Database\Eloquent\Model {
use HasTimestamps;
}
// Verify `created_at`/`updated_at` are correctly resolved.
Eloquent Ecosystem:
Resource::collection() with filtered queries.observables() and dispatchesEvents().retrieved(), saved()).Interface-Driven Development:
NovaResource implementations.Authenticatable compliance.Billable interfaces.assertImplements() or PHPUnit’s implementsInterface().PHP Static Analysis Tools:
How can I help you explore Laravel packages today?