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

Args Laravel Package

johnbillion/args

johnbillion/args provides type-safe, documented array shapes for WordPress and PHP functions like WP_Query and wp_insert_post. It adds IDE autocompletion, static analysis support, and validation for complex argument arrays, reducing typos and runtime errors in WordPress plugin and theme code.

Deep Wiki
Context7

Getting Started

johnbillion/args is a Composer library of plain PHP classes that model the array arguments accepted by WordPress APIs. There is no service provider, no bootstrap, and no runtime dependency on WordPress — the classes are just typed data holders with a toArray() bridge.

composer require johnbillion/args

Start by opening the class that matches the API you are already calling. The namespace is Args\ and there is one class per array-taking function or query: Args\WP_Query, Args\get_posts, Args\WP_Term_Query, Args\WP_User_Query, Args\WP_Meta_Query, Args\WP_Tax_Query, Args\WP_Date_Query, Args\register_post_type, Args\register_taxonomy, Args\wp_insert_post, and friends. Properties mirror the keys documented on the corresponding WordPress function, so the class doubles as inline documentation.

A first, realistic use case is replacing a long get_posts() call whose arguments are assembled conditionally:

use Args\get_posts;

$args = new get_posts();
$args->post_type      = [ 'post', 'page' ];
$args->posts_per_page = 12;
$args->orderby        = 'date';
$args->order          = 'DESC';

if ( $term_id ) {
    $args->tax_query = /* an Args\WP_Tax_Query */;
}

$posts = get_posts( $args->toArray() );

The pattern is always the same: build the object property-by-property, then hand toArray() to the WordPress function. WordPress never sees the object.

Implementation Patterns

Build incrementally, pass once. The main win over array literals is that you can set properties across a function or a series of conditionals without array_merge() chains, and without silently overwriting a key you set earlier. Keep the object alive until the call and convert at the boundary.

Wrapper helpers. In a theme or plugin, a common pattern is a small factory that returns configured args, so call sites stay readable and defaults live in one place:

function my_theme_post_args(): Args\WP_Query {
    $args = new Args\WP_Query();
    $args->post_status    = 'publish';
    $args->posts_per_page = 10;
    return $args;
}

$query = new WP_Query( ( my_theme_post_args() )->toArray() );

Accept an optional Args\WP_Query in your own functions and call toArray() only when you invoke core. This keeps your public API typed while remaining compatible with callers who still pass plain arrays.

Nested queries. Meta, tax, and date queries have their own classes. Because the outer class is typed, you get completion for nested keys too, and you avoid the classic bug of a misspelled relation or compare that silently changes nothing. Build the nested object, assign it to the property, and let toArray() flatten it.

Registration hooks. register_post_type(), register_taxonomy(), and similar APIs are where array typos are most expensive, because they fail quietly at init. Building the args object in a dedicated function and registering on init makes labels and supports easy to review.

Clone for variants. Need the same base query with one difference? clone $args and override a single property. This is much less error-prone than duplicating a twenty-key array.

Testing and static analysis. Because the classes are plain PHP with no WordPress dependency, they are easy to assert against in unit tests ($args->toArray() compared to an expected array) and they give PHPStan/Psalm and your IDE real property names. Typos become errors or at least warnings instead of runtime no-ops. Adoption can be gradual — convert one call site at a time; nothing forces a big-bang migration.

Escape hatch. When you need a key the class does not model (newer core arg, custom filter consumer), merge it in at the boundary: array_merge( $args->toArray(), [ 'my_key' => $value ] ).

Gotchas and Tips

  • No validation. These are typed property bags, not validators. Setting posts_per_page to a string that PHP coerces still reaches WordPress. The benefit is discoverability and static analysis, not enforcement.
  • Unset properties are omitted. toArray() returns only what you set, so WordPress defaults still apply. That is usually what you want, but it means an args object is not a complete description of the final query — always reason about core defaults too.
  • get_posts is not WP_Query. They have different defaults (posts_per_page, ignore_sticky_posts, suppress_filters). Pick the class matching the function you call; don't reuse a WP_Query args object for get_posts() and assume identical behavior.
  • Version drift. The classes are generated from WordPress documentation, so args added in a very recent core release may be missing until the package catches up. Keep the package version roughly aligned with your minimum supported WP version, and use the merge escape hatch for stragglers.
  • Nested structures still need care. A meta_query with multiple clauses and a relation is represented as a nested object or array of clauses; check the property's expected shape in the class rather than guessing. An empty array for post__in or tax_query behaves differently from omitting the key entirely.
  • Don't pass the object through. WP_Query, get_posts, and the registration functions expect arrays. Passing the object anywhere except toArray() (or JSON-encoding it, if the class supports that) will not do what you expect.
  • Debugging. var_dump( $args->toArray() ) or wp_json_encode() before the call is the fastest way to confirm what actually reaches core, especially when a filter or wrapper has modified arguments.
  • Licensing. The package is GPL-2.0; confirm that is compatible with your distribution model before bundling, particularly for commercial plugins.
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.
abbasudo/artisan-route
mirvan/ippanel
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package