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

Wp Config Laravel Package

roots/wp-config

Roots WP Config provides a clean, code-first way to define WordPress constants and environment-specific settings. It integrates with Bedrock and Dotenv, letting you manage wp-config values safely and consistently across environments.

Deep Wiki
Context7

Getting Started

Roots wp-config is the fluent, class-based config layer that Bedrock (and by extension the Sage stack) uses in place of the procedural top of wp-config.php. It collapses all the define() calls, getenv() reads, and if (defined(...)) guards into a tiny static API:

  • Config::define($name, $value) — register a constant
  • Config::get($name) — read a registered value
  • Config::set($name, $value) — update the value without redefining
  • Config::apply() — materialize queued constants via PHP define()

Install

composer require roots/wp-config

You'll almost always pair it with vlucas/phpdotenv and Roots' oscarotero/env wrapper (env()), which gives you Laravel-style type coercion. On Bedrock it's already wired up — don't install anything.

First use case — replace your wp-config.php

  1. Make wp-config.php a thin bootstrap: require __DIR__ . '/vendor/autoload.php'.
  2. Load .env if present, then Env::init().
  3. Define WP_ENV with plain define() so later code can branch on it.
  4. Config::define() every WordPress constant, deriving values from Config::get() where needed.
  5. require an environment file: config/environments/{WP_ENV}.php.
  6. Call Config::apply() at the bottom, then require_once ABSPATH . 'wp-settings.php'.

Minimal shape:

<?php
use Roots\WPConfig\Config;

require __DIR__ . '/vendor/autoload.php';
if (file_exists(__DIR__ . '/.env')) {
    Dotenv\Dotenv::createUnsafeImmutable(__DIR__)->load();
}
Env::init();

define('WP_ENV', env('WP_ENV') ?: 'production');

Config::define('DB_NAME', env('DB_NAME'));
Config::define('DB_HOST', env('DB_HOST') ?: 'localhost');
Config::define('WP_HOME', env('WP_HOME'));

Config::define('CONTENT_DIR', '/app');
Config::define('WP_CONTENT_DIR', __DIR__ . Config::get('CONTENT_DIR'));
Config::define('WP_CONTENT_URL', Config::get('WP_HOME') . Config::get('CONTENT_DIR'));

$table_prefix = env('DB_PREFIX') ?: 'wp_';

require __DIR__ . '/config/environments/' . WP_ENV . '.php';

Config::apply();

if (!defined('ABSPATH')) {
    define('ABSPATH', __DIR__ . '/wp/');
}
require_once ABSPATH . 'wp-settings.php';

Where to look first: the Bedrock repo's wp-config.php and config/environments/*.php are the canonical reference. The package README is intentionally terse — copy Bedrock's patterns rather than inventing your own.

Implementation Patterns

1. Layered config (base + environment). Keep wp-config.php for constants that never change (charset, collation, content dir, salts location) and one file per environment (development.php, staging.php, production.php, plus a gitignored local.php). WP_ENV picks which to require. This mirrors Laravel's per-environment config and keeps the diff surface small.

2. .env-driven values. Read everything sensitive from .env via env(). oscarotero/env returns real booleans/ints/null, so WP_DEBUG=false actually works. Commit .env.example; never commit .env.

3. Derived values through Config::get(). Because define() registers values before they are applied, you can compose them:

Config::define('WP_CONTENT_URL', Config::get('WP_HOME') . Config::get('CONTENT_DIR'));

This is the main reason to route every constant through Config rather than raw define().

4. Config::set() for late overrides. Use it when local.php or a guard clause needs to adjust a queued value (WP_DEBUG, WP_HOME) without redefining it. The final value is what apply() defines.

5. Environment files with guard clauses. A typical config/environments/development.php:

<?php
use Roots\WPConfig\Config;

Config::define('WP_DEBUG', true);
Config::define('WP_DEBUG_LOG', true);
Config::define('WP_DEBUG_DISPLAY', false);
Config::define('SCRIPT_DEBUG', true);
Config::define('DISALLOW_INDEXING', true);

if (env('WP_MULTISITE')) {
    Config::define('WP_ALLOW_MULTISITE', true);
}

6. Local overrides. Require a gitignored local.php last (before apply()) so developers can set their own WP_HOME (e.g. https://myproject.test) without touching shared files.

7. Salts. Keep the eight *_KEY / *_SALT constants routed through Config::define() so they can rotate per environment. Generate with wp config shuffle-salts into .env, or copy from the WordPress salt API into your .env.example.

8. Plain define() for WordPress-mandated values. ABSPATH and $table_prefix should stay as plain PHP — they're needed before the Config flow, or they're variables rather than constants. WP_ENV itself is often plain too, so early code can branch before Config loads.

9. WP-CLI aware. wp-config.php runs on every CLI invocation. Guard expensive work (HTTP, DB) behind if (defined('WP_CLI') && WP_CLI) { ... }.

10. Multisite. Enable WP_ALLOW_MULTISITE first, then add the full MULTISITE / SUBDOMAIN_INSTALL / DOMAIN_CURRENT_SITE / PATH_CURRENT_SITE / SITE_ID_CURRENT_SITE / BLOG_ID_CURRENT_SITE set in one block inside the environment file.

Gotchas and Tips

  • apply() must be called, and last. Forget it and no constants exist — WordPress falls back to defaults or dies on the DB. Call it too early and subsequent Config::define() calls are silently ignored.
  • Config::get() reads the Config store, not arbitrary PHP constants. define('FOO', 'bar'); Config::get('FOO') returns null. Route anything you want to read back through Config::define() / Config::set().
  • Already-defined constants win. apply() (and define() with the standard guard) skips names PHP has already defined. A stray define('WP_DEBUG', true) earlier in the bootstrap silently defeats your environment file. grep -R "define(" . is your first debug step.
  • .env values are strings by default. Use env() (oscarotero/env) rather than raw getenv(), or cast explicitly: env('WP_DEBUG') === 'true'.
  • Ordering matters for derived constants. WP_CONTENT_URL depends on WP_HOME and CONTENT_DIR; custom UPLOADS depends on both. Define bases first, then derive.
  • $table_prefix is not a constant. It must remain the PHP variable WordPress reads — do not try Config::define('table_prefix', ...).
  • Multisite constants are order-sensitive. WP_ALLOW_MULTISITE before MULTISITE, and the DOMAIN_CURRENT_SITE / PATH_CURRENT_SITE / SITE_ID_CURRENT_SITE / BLOG_ID_CURRENT_SITE set must be complete together. Split across files and you get redirect loops.
  • Debugging one-liner: var_dump(Config::get('DB_NAME')) before apply(), then defined('DB_NAME') ? constant('DB_NAME') : 'unset' after, to confirm the constants actually landed.
  • No deep merge, no dot notation. This is flat constants — not Laravel's config(). If you want Config::get('app.host')-style access, write your own wrapper.
  • Extension point: a two-line helper in your config files (function env_or($k, $d) { return env($k) ?: $d; }) or a thin subclass of Config for WP_HOME-derived URLs pays for itself quickly. The class is small and stable — wrap, don't patch.
  • Bedrock users: you almost never touch the package. Edit .env, config/environments/*.php, and config/application.php. Do not edit wp-config.php — it explicitly warns you not to.
  • Version pinning: the API surface is tiny and changes rarely; pin the major that your Bedrock release ships with and let Renovate/Dependabot bump it.
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.
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle