Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Notoj Laravel Package

crodas/notoj

Notoj is a lightweight PHP annotation parser that reads docblock annotations with a fast tokenizer, no heavy dependencies. Define annotation classes extending Notoj's base, then parse methods, classes, and properties to build routing, validation, or metadata layers.

Deep Wiki
Context7

Getting Started

Install with Composer:

composer require crodas/notoj

There's no service provider or facade — this is a standalone parser you call directly. The two entry points you'll touch first are Notoj\File (single file) and Notoj\Dir (recursive directory scan):

use Notoj\Dir;

$dir = new Dir(base_path('app/Http/Controllers'));

foreach ($dir->getAnnotations() as $annotation) {
    echo $annotation->getName();        // e.g. "Route"
    var_dump($annotation->getArgs());   // parsed key/value arguments
    echo $annotation->getObject()->getName(); // the class/method it was attached to
}

Look here first: the Annotation\Annotation value object (getName(), getArgs(), getObject()). Everything else is a scanner that produces these.

First real use case: you want lightweight, docblock-driven discovery — e.g. scanning app/ for @FeatureFlag("...") or @OnQueue("...") markers on controller methods, then registering them in a service provider or an Artisan command. Prototype it in a tinker session against a single controller file before wiring it into a provider; docblock parsing is fiddly and you want to see the raw output early.

Implementation Patterns

Directory scan → filter by name. The common shape is a one-shot scan that filters annotations down to the ones you care about:

use Notoj\Dir;

$flags = collect((new Dir(app_path()))->getAnnotations())
    ->filter(fn ($a) => $a->getName() === 'FeatureFlag')
    ->map(fn ($a) => [
        'target' => $a->getObject()->getName(),
        'name'   => $a->getArgs()['value'] ?? null,
    ]);

Wrap it in a resolver service, cache the result. Parsing every file on every request is wasteful. Put the scan behind a class, cache the normalized array (Cache::rememberForever, keyed by a hash of the file mtimes), and only re-parse when the cache is cold or cleared in CI/deploy.

Artisan command as the entry point. A php artisan annotations:list command that dumps parsed annotations is the fastest way to debug syntax and to give teammates visibility into what the scanner actually sees. Reuse the same service the provider uses.

Bind once, resolve everywhere. In a ServiceProvider::register(), run the scan and bind a registry object into the container ($this->app->singleton(AnnotationRegistry::class)) so controllers, middleware, and commands all read from the same parsed result rather than re-scanning.

Combine with Reflection for behavior. getObject() returns a reflection handle (ReflectionClass, ReflectionMethod, ReflectionProperty, ReflectionFunction depending on where the annotation sat). Use it when you need to instantiate, invoke, or read constructor parameters of the annotated target — e.g. auto-register routes or event listeners discovered by annotation.

Targeted scans over whole-app scans. Point Notoj\Dir at app/Http/Controllers or app/Models rather than app/ or the project root. Fewer files, fewer surprises from vendor docblocks and test fixtures, and a much faster cold cache build.

Gotchas and Tips

  • DocBlocks only — no PHP 8 attributes. If you're on PHP 8+, native #[Attribute] + ReflectionAttribute is the built-in, editor-supported, static-analysis-friendly path. Use Notoj only when you're stuck on DocBlock annotations (legacy code, or you specifically want comments that don't affect reflection).
  • Annotation name resolution bites. A bare @Foo vs @\App\Annotations\Foo vs an imported alias can resolve differently than you expect. Prefer fully-qualified names in docblocks, and always dd($annotation->getName()) during prototyping rather than guessing.
  • Argument parsing is stringly-typed. Quoted strings, arrays, booleans, and nested values each have their own quirks; malformed docblocks fail silently or drop arguments rather than throwing. Validate at the boundary (?? null, filter_var) and treat getArgs() as untrusted input.
  • Cache invalidation is on you. The package doesn't know when files change. Key your cache by directory mtime or file hashes, and clear it in your deploy script — otherwise annotations added in a hotfix won't take effect until the cache TTL expires.
  • Low maintenance surface. 36 stars, unknown repo status. Treat it as a vendored utility: pin the version, keep the usage well-isolated behind one service class, and have a plan to swap to PHP attributes (or doctrine/annotations) so a single composer update can't break discovery across the app.
  • Debugging tip: when an annotation "disappears," first verify the docblock sits directly above the declaration (no blank line, no intervening code) and that the docblock is /** ... */ — /* */ and // are silently ignored.
  • Extension points: subclasses of the annotation value object and custom filter callbacks passed into getAnnotations() are the sanctioned way to add behavior. Prefer these over fork-and-patch; they survive Composer updates.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
robertmarney/lara-hierarchial-collections
simonschaufi/rule-doc-generator
emissaoja/emissaoja
blackbricksoftware/gravityforms-civicrm-form-processor
al-rahabi/fancy-crud
jinas/dhivatar-component
mltstephane/laravel-quality
bernskiold/laravel-talentlms
bernskioldmedia/laravel-form-architect