Download? Configuration Fallbacks System
Overview
upMVC uses a five-level fallback system that allows the system to work even without complete configuration. This enables quick testing, gradual configuration, and flexible deployment strategies.
Core Philosophy: Start simple, configure as you grow.
? Why Fallbacks?
Benefits
? Quick Start - System works immediately without full configuration
? Gradual Configuration - Add settings only when you need them
? Flexible Deployment - Different configs for dev/staging/production
? No Breaking Errors - Missing config? Fallback handles it
? Development Friendly - Code defaults for rapid development
Use Cases
-
? Quick testing without .env setup
-
? Static sites or API-only projects (no database needed)
-
? Local development with default settings
-
? Production with secure .env configuration
? Fallback Priority Summary
| Setting | Priority 1 (Highest) | Priority 2 (Fallback) | File Location |
|---------|---------------------|----------------------|---------------|
| Paths & Domain | .env SITE_PATH, DOMAIN_NAME | Config.php $fallbacks | /etc/Config.php |
| Protected Routes | .env PROTECTED_ROUTES | start.php $defaultProtectedRoutes | /etc/start.php |
| Database Credentials | .env DB_* variables | ConfigDatabase.php | /etc/ConfigDatabase.php |
| Session Configuration | Config::get('session') | Hardcoded defaults | /etc/Config.php line 215 |
| Security/Middleware | .env via ConfigManager | Hardcoded defaults | /etc/Start.php line 158+ |
1?? Path & Domain Fallbacks
Location: /etc/Config.php
Configuration Array
/
* Fallback configuration values for path and domain
*
* Used only if .env file is missing or values are not set.
* In normal operation, .env values are always used.
*/
private static $fallbacks = [
'site_path' => '/upMVC', // Installation folder or '' for root
'domain_name' => 'http://localhost', // Domain URL without trailing slash
];
Priority Logic
1. Check .env for SITE_PATH and DOMAIN_NAME
? If found: Use .env values ?
? If missing: Continue to fallback
2. Use Config.php $fallbacks array
? Returns default values
How It Works
// In Config.php
public static function getSitePath(): string
{
// Priority 1: .env file
// Priority 2: $fallbacks array
return Environment::get('SITE_PATH', self::$fallbacks['site_path']);
}
public static function getDomainName(): string
{
return Environment::get('DOMAIN_NAME', self::$fallbacks['domain_name']);
}
Used For
-
? `BASE_URL` constant construction
-
? Routing and URL processing
-
? Asset paths (CSS, JS, images)
-
? Redirect URLs
-
? Link generation in views
Configuration Examples
Production (.env): SITE_PATH=
DOMAIN_NAME=https://mysite.com
Development (.env): SITE_PATH=/upMVC
DOMAIN_NAME=http://localhost
Quick Testing (no .env): Uses Config.php fallbacks automatically
No configuration needed!
When to Edit
Edit .env: Production, staging, or when deploying
Edit Config.php fallbacks: Default development values for your team
2?? Protected Routes Fallbacks
Location: /etc/start.php
Configuration Array
/
* Default protected routes requiring authentication
*
* These routes require user authentication before access.
* Can be overridden via PROTECTED_ROUTES in .env (comma-separated list)
*/
private static $defaultProtectedRoutes = [
'/dashboardexample/*', // Dashboard example module
'/admin/*', // Admin panel (all routes)
'/users/*', // User management (all routes)
'/moda' // Modal example route
];
Priority Logic
1. Check .env for PROTECTED_ROUTES
? If found: Parse comma-separated list ?
? If missing: Continue to fallback
2. Use start.php $defaultProtectedRoutes array
? Returns default protected routes
How It Works
// In start.php
private function getProtectedRoutes(): array
{
// Priority 1: .env file (comma-separated)
$envRoutes = Environment::get('PROTECTED_ROUTES', '');
if (!empty($envRoutes)) {
return array_map('trim', explode(',', $envRoutes));
}
// Priority 2: $defaultProtectedRoutes array
return self::$defaultProtectedRoutes;
}
Used For
-
? `AuthMiddleware` route protection
-
? Session-based authentication checks
-
? Redirect to login for unauthorized access
-
? Wildcard pattern matching (`/admin/*`)
Configuration Examples
Production (.env): PROTECTED_ROUTES=/admin/,/users/,/dashboard/,/api/secure/
Development (.env): PROTECTED_ROUTES=/admin/,/users/
Quick Testing (no .env): Uses start.php defaults:
- /dashboardexample/*
- /admin/*
- /users/*
- /moda
Wildcard Patterns
/admin/* ? Matches /admin, /admin/users, /admin/settings/edit
/users/* ? Matches /users, /users/profile, /users/123
/exact-route ? Matches only /exact-route (no children)
When to Edit
Edit .env: Production security policies, specific project needs
Edit start.php defaults: Default security for your project template
3?? Database Credentials Fallbacks
Location: /etc/Database.php
Priority Logic
1. Check .env for DB_* variables
? If DB_HOST exists: Use all .env DB_* vars ?
? If DB_HOST missing: Continue to fallback
2. Use ConfigDatabase.php values
? Returns fallback credentials
How It Works
// In Database.php
private function loadConfig()
{
// Priority 1: .env file (production recommended)
if (isset($_ENV['DB_HOST']) && !empty($_ENV['DB_HOST'])) {
$this->host = $_ENV['DB_HOST'];
$this->databaseName = $_ENV['DB_NAME'] ?? '';
$this->username = $_ENV['DB_USER'] ?? '';
$this->password = $_ENV['DB_PASS'] ?? '';
$this->port = $_ENV['DB_PORT'] ?? 3306;
$this->charset = $_ENV['DB_CHARSET'] ?? 'utf8mb4';
} else {
// Priority 2: ConfigDatabase.php (fallback)
$this->host = ConfigDatabase::get('db.host');
$this->databaseName = ConfigDatabase::get('db.name');
$this->username = ConfigDatabase::get('db.user');
$this->password = ConfigDatabase::get('db.pass');
$this->port = ConfigDatabase::get('db.port', 3306);
$this->charset = ConfigDatabase::get('db.charset', 'utf8mb4');
}
}
Environment Variables
# .env database configuration (production)
DB_HOST=prod-server.com
DB_NAME=production_db
DB_USER=prod_user
DB_PASS=secure_password_here
DB_PORT=3306
DB_CHARSET=utf8mb4
Used For
-
? PDO database connections
-
? Model database operations
-
? Migration scripts
-
? Seed data scripts
Configuration Examples
Production (.env): DB_HOST=mysql.production.com
DB_NAME=prod_database
DB_USER=prod_user
DB_PASS=strong_password_123
DB_PORT=3306
DB_CHARSET=utf8mb4
Development (.env): DB_HOST=localhost
DB_NAME=dev_database
DB_USER=root
DB_PASS=
DB_PORT=3306
Quick Testing (ConfigDatabase.php fallback): // /etc/ConfigDatabase.php
return [
'db.host' => 'localhost',
'db.name' => 'test_db',
'db.user' => 'root',
'db.pass' => '',
'db.port' => 3306,
'db.charset' => 'utf8mb4'
];
Security Best Practices
? Production:
- ? Use .env file (not committed to Git)
- ? Strong passwords
- ? Limited user privileges
- ? Encrypted connections if possible
? Development:
- ? Use ConfigDatabase.php with dummy data
- ? Never commit real credentials
- ? Use different credentials than production
When to Edit
Edit .env: Production, staging, any real database
Edit ConfigDatabase.php: Development defaults, local testing
4?? Session Configuration Fallbacks
Location: /etc/Config.php (line 215)
Configuration Logic
Session cookie parameters use array fallback with hardcoded defaults:
$sessionConfig = self::get('session', []);
if (isset($sessionConfig['name'])) {
session_name($sessionConfig['name']);
}
session_set_cookie_params([
'lifetime' => $sessionConfig['lifetime'] ?? 3600, // Default: 1 hour
'secure' => $sessionConfig['secure'] ?? false, // Default: HTTP allowed
'httponly' => $sessionConfig['httponly'] ?? true, // Default: JS blocked
'samesite' => 'Strict' // Always Strict
]);
session_start();
Priority Logic
1. Config::get('session') from ConfigManager (loaded from .env)
? (if not set)
2. Hardcoded defaults in session_set_cookie_params()
- lifetime: 3600 (1 hour)
- secure: false (HTTP allowed)
- httponly: true (JavaScript cannot access)
- samesite: 'Strict' (no third-party cookies)
Configuration Examples
.env Configuration (Production): SESSION_LIFETIME=7200 # 2 hours
SESSION_COOKIE=myapp_session
SESSION_SECURE=true # HTTPS only
SESSION_HTTP_ONLY=true # Block JavaScript access
SESSION_SAME_SITE=strict
Result: Secure, long-lasting sessions for production use
.env Configuration (Development): SESSION_LIFETIME=86400 # 24 hours (stay logged in)
SESSION_SECURE=false # HTTP allowed
Result: Developer-friendly with long sessions on localhost
No Configuration (Fallback):
- Lifetime: 3600 seconds (1 hour)
- Secure: false (works on HTTP)
- HTTPOnly: true (XSS protection)
- SameSite: Strict (CSRF protection)
When to Edit
Edit .env: To customize session behavior per environment
Fallback: Secure defaults work for most development cases
5?? Security & Middleware Fallbacks
Location: /etc/Start.php (lines 158-192)
Configuration Logic
Security features use ConfigManager::get() with hardcoded defaults:
// CORS Support
if (ConfigManager::get('app.cors.enabled', false)) {
$corsConfig = ConfigManager::get('app.cors', []);
$middlewareManager->addGlobal(new CorsMiddleware($corsConfig));
}
// CSRF Protection
if ($method === 'POST' && ConfigManager::get('security.csrf_protection', true)) {
$token = $_POST['csrf_token'] ?? '';
if (!Security::validateCsrf($token)) {
http_response_code(403);
echo 'CSRF token validation failed';
return false;
}
}
// Rate Limiting
$identifier = $_SERVER['REMOTE_ADDR'] ?? 'unknown';
$limit = ConfigManager::get('security.rate_limit', 100);
if (!Security::rateLimit($identifier, $limit)) {
http_response_code(429);
echo 'Rate limit exceeded';
return false;
}
Priority Logic
1. .env variables loaded into ConfigManager
? (if not set)
2. ConfigManager::get() default parameter
- app.cors.enabled: false (CORS disabled)
- app.cors: [] (empty config)
- security.csrf_protection: true (CSRF enabled)
- security.rate_limit: 100 (requests limit)
Configuration Examples
.env Configuration (Production): # CORS Settings
CORS_ENABLED=true
CORS_ALLOWED_ORIGINS=https://yourdomain.com,https://api.yourdomain.com
CORS_ALLOWED_METHODS=GET,POST,PUT,DELETE
CORS_ALLOWED_HEADERS=Content-Type,Authorization
# Security Settings
CSRF_PROTECTION=true # Always enabled in production
RATE_LIMIT=60 # 60 requests per window
Result: Strict security with CORS for specific origins
.env Configuration (Development): # CORS Settings
CORS_ENABLED=true
CORS_ALLOWED_ORIGINS=* # Allow all origins
# Security Settings
CSRF_PROTECTION=false # Easier API testing
RATE_LIMIT=1000 # High limit for development
Result: Relaxed for development, easier testing
No Configuration (Fallback):
- CORS: Disabled (no cross-origin requests)
- CSRF: Enabled (security by default)
- Rate Limit: 100 requests (reasonable default)
When to Edit
Edit .env:
- Enable CORS for frontend-backend separation
- Adjust rate limits per environment
- Disable CSRF for API-only testing (not recommended for production)
Fallback: Secure defaults protect against common attacks
? Troubleshooting Configuration Conflicts
Problem: Settings not being applied
Check in this order:
-
.env file (highest priority)
- Location: `/etc/.env`
- Is the file present?
- Are variables correctly named?
- Are there typos in variable names?
-
Config.php $fallbacks (path/domain)
- Location: `/etc/Config.php`
- Lines: ~30-33
- Check `site_path` and `domain_name` values
-
Config.php session defaults (session behavior)
- Location: `/etc/Config.php`
- Line: ~215
- Check session_set_cookie_params()
-
start.php $defaultProtectedRoutes (auth routes)
- Location: `/etc/start.php`
- Lines: ~40-46
- Check route patterns match your needs
-
start.php security settings (CORS, CSRF, rate limit)
- Location: `/etc/start.php`
- Lines: ~158-192
- Check ConfigManager::get() defaults
-
ConfigDatabase.php (database)
- Location: `/etc/ConfigDatabase.php`
- Check all `db.*` keys
Common Issues
Issue 1: Wrong BASE_URL
Symptom: Links broken, assets not loading, routing fails
Solution: 1. Check .env: SITE_PATH and DOMAIN_NAME
2. If .env missing: Check Config.php $fallbacks
3. Verify no trailing slash in DOMAIN_NAME
4. Verify SITE_PATH starts with / or is empty
Issue 2: Routes not protected
Symptom: Can access admin without login
Solution: 1. Check .env: PROTECTED_ROUTES (comma-separated)
2. If .env missing: Check start.php $defaultProtectedRoutes
3. Verify wildcard patterns: /admin/not /admin
4. Check AuthMiddleware is registered
Issue 3: Database connection fails
Symptom: "Database could not be connected" error
Solution: 1. Check .env: All DB_* variables present
2. If .env missing: Check ConfigDatabase.php values
3. Verify database server is running
4. Test credentials with MySQL client
5. Check firewall/port access
Issue 4: Session not persisting
Symptom: User logs out immediately, session data lost
Solution: 1. Check .env: SESSION_LIFETIME, SESSION_SECURE
2. If .env missing: Defaults to 3600 seconds (1 hour)
3. For HTTPS sites: Set SESSION_SECURE=true in .env
4. Check session_set_cookie_params() in Config.php line 215
5. Verify cookies are enabled in browser
Issue 5: CORS blocking requests
Symptom: Frontend can't connect to backend API
Solution: 1. Check .env: CORS_ENABLED=true
2. Set CORS_ALLOWED_ORIGINS in .env
3. Default: CORS disabled (fallback)
4. Check ConfigManager::get('app.cors.enabled', false) in Start.php
5. For development: Use CORS_ALLOWED_ORIGINS=*
Debug Mode
Enable debug mode to see configuration values:
// In etc/.env
APP_ENV=development
DEBUG=true
Then check which config source is being used:
// Temporary debugging code
echo "Site Path Source: " . (isset($_ENV['SITE_PATH']) ? '.env' : 'Config.php fallback');
echo "DB Source: " . (isset($_ENV['DB_HOST']) ? '.env' : 'ConfigDatabase.php fallback');
? Configuration Strategy
Development Workflow
Day 1 - Quick Start: 1. Install upMVC
2. Don't create .env yet
3. Framework uses all fallbacks
4. Start coding immediately ?
Day 2 - Add Database: 1. Create .env file
2. Add only DB_* variables
3. Rest uses fallbacks
4. Database now connected ?
Day 3 - Custom Config: 1. Add SITE_PATH to .env
2. Add PROTECTED_ROUTES to .env
3. All custom, no fallbacks ?
Deployment Strategy
Development:
- Use ConfigDatabase.php with local DB
- Use Config.php fallbacks for paths
- Use start.php default routes
Staging:
- Create .env with staging DB credentials
- Set SITE_PATH if in subfolder
- Set PROTECTED_ROUTES for testing
Production:
- Complete .env with all settings
- Secure DB credentials
- Custom protected routes
- Never commit .env to Git!
? Best Practices
? DO:
-
Use .env for production - Secure, not in Git
-
Keep fallbacks as sensible defaults - For quick dev setup
-
Document your .env variables - Team knows what to set
-
Use different credentials per environment - Dev ? Production
-
Version control fallback files - Team shares defaults
? DON'T:
-
Commit .env to Git - Security risk!
-
Use production credentials in fallbacks - Security risk!
-
Rely on fallbacks in production - Use .env instead
-
Mix configuration sources - Confusing to debug
-
Hardcode paths in code - Use Config methods
? Related Documentation
? Quick Reference
Check Current Configuration
// In your code, check what's being used:
// Paths
echo Config::getSitePath(); // From .env or Config.php
echo Config::getDomainName(); // From .env or Config.php
// Protected Routes
$start = new Start();
$routes = $start->getProtectedRoutes(); // From .env or start.php
print_r($routes);
// Database
$db = new Database();
// Check connection success
$conn = $db->getConnection();
if ($conn) {
echo "DB connected!"; // From .env or ConfigDatabase.php
}
.env Template
# Application
SITE_PATH=/upMVC
DOMAIN_NAME=http://localhost
APP_ENV=development
APP_DEBUG=true
# Database
DB_HOST=localhost
DB_NAME=your_database
DB_USER=your_username
DB_PASS=your_password
DB_PORT=3306
DB_CHARSET=utf8mb4
# Security & Routes
PROTECTED_ROUTES=/admin/,/users/,/dashboard/*
CSRF_PROTECTION=true
RATE_LIMIT=100
# Session Configuration
SESSION_LIFETIME=3600
SESSION_COOKIE=upmvc_session
SESSION_SECURE=false
SESSION_HTTP_ONLY=true
SESSION_SAME_SITE=strict
# CORS Configuration
CORS_ENABLED=false
CORS_ALLOWED_ORIGINS=https://yourdomain.com
CORS_ALLOWED_METHODS=GET,POST,PUT,DELETE
CORS_ALLOWED_HEADERS=Content-Type,Authorization
Last Updated: October 2025
upMVC Version: 1.4.x+
|