FAQ
Common questions about Zenith-powered applications and the framework's capabilities.
General Questions
Zenith is a modern PHP framework specifically designed for building multi-tenant SaaS applications. It provides database-per-tenant isolation, subdomain routing, and a comprehensive SuperAdmin portal for managing multiple organizations from a single codebase.
Built with modern PHP 8.4+ features, it offers type safety, modern syntax, and enterprise-grade security out of the box.
Yes, absolutely! While Zenith is optimized for multi-tenant applications, it works perfectly for single-tenant applications too.
- Simply create one tenant for your application
- All the core features (routing, ORM, authentication, etc.) work independently
- You can ignore the multi-tenant features if not needed
- The framework is lightweight and doesn't impose multi-tenancy overhead
Minimum: PHP 8.1
Recommended: PHP 8.4 (latest features and best performance)
Zenith uses modern PHP features including readonly properties, enums, match expressions, and constructor property promotion. These features require PHP 8.1 or higher.
Yes! Version 1.2.0 is production-ready and includes:
- 238+ unit and integration tests
- Enterprise-grade security (CSRF, login throttling, encryption)
- Comprehensive error handling
- Performance optimizations
- Stable API with semantic versioning
Multi-Tenancy
Zenith uses a database-per-tenant isolation strategy:
- Tenant Identification: Each tenant is identified by subdomain (e.g., acme.yourdomain.com) or custom domain
- Database Switching: The framework automatically switches to the tenant's database based on the incoming request
- Complete Isolation: Each tenant has their own database, ensuring complete data isolation
- Central Management: SuperAdmin portal manages all tenants from a central database
This approach provides maximum security and allows per-tenant customization, backups, and scaling.
- SuperAdmin:
- Platform-level administrator
- Manages tenants (create, edit, delete)
- Access to platform settings
- Stored in central database
- Can create new tenants and users
- Admin (Tenant Admin):
- Organization-level administrator
- Manages users within their tenant
- Access to tenant-specific data only
- Stored in tenant database
- Cannot access other tenants
Via SuperAdmin Dashboard:
- Log in to SuperAdmin portal at
/superadmin/login - Navigate to Tenants → Create New
- Fill in tenant details (name, subdomain, database info)
- System automatically provisions the tenant database and initial schema
Via CLI:
php zenith create:tenant --name="Acme Corp" --subdomain="acme"
The system handles all database creation, migration, and initialization automatically.
Yes! Zenith supports custom domains for tenants.
Each tenant can have:
- Default subdomain (e.g., acme.zenith.app)
- Custom domain (e.g., acme.com)
- Multiple domains pointing to the same tenant
Simply configure the custom domain in the tenant settings, and point the DNS to your server. Zenith's domain routing middleware handles the rest.
Database & ORM
Zenith supports multiple database drivers through PDO:
- MySQL/MariaDB - Recommended for production (fully tested)
- PostgreSQL - Full support with type safety
- SQLite - Perfect for development and testing
The framework includes a DatabaseDriver enum for type-safe driver selection.
Zenith uses schema-based migrations defined directly in models:
protected static array $schema = [
'columns' => [
'ID' => ['type' => 'integer', 'primary' => true, 'autoIncrement' => true],
'name' => ['type' => 'string', 'length' => 255, 'nullable' => false],
// ...
],
'indexes' => [...],
'foreignKeys' => [...]
];
Run migrations with:
php zenith init:database # Initialize/sync all schemas
The system automatically creates tables, adds columns, and updates indexes based on schema definitions.
Yes! While the Active Record ORM covers most use cases, you can write raw SQL when needed:
// Single row
$result = Database::queryOne('SELECT * FROM users WHERE id = ?', [$id]);
// Multiple rows
$results = Database::query('SELECT * FROM users WHERE active = ?', [1]);
// Execute (INSERT, UPDATE, DELETE)
Database::execute('UPDATE users SET status = ? WHERE id = ?', ['active', $id]);
All queries use prepared statements for SQL injection protection.
Deployment & Production
Deployment Checklist:
- Server Setup: PHP 8.1+, web server (Apache/Nginx), database
- Environment: Set
DEV_MODE = falsein.env - Database: Create production database, run
php zenith init:database - SuperAdmin: Create with
php zenith create:superadmin - Security: Generate strong
ZENITH_CRYPTO_KEY - Permissions: Set proper file permissions (755 for directories, 644 for files)
- Web Server: Point document root to
/Publicdirectory
See full deployment guide in documentation.
Minimum Requirements:
- PHP 8.1 or higher (8.4 recommended)
- PDO extension with desired database driver
- OpenSSL extension (for encryption)
- mbstring extension
- JSON extension
- MySQL 5.7+ / PostgreSQL 10+ / SQLite 3.8+
Recommended:
- Apache with mod_rewrite or Nginx
- 2GB RAM minimum
- SSD storage
- PHP OPcache enabled
With database-per-tenant architecture, you have flexible backup options:
- Per-Tenant Backups: Backup each tenant database separately (allows restore of individual tenants)
- Scheduled Backups: Use cron jobs to automate tenant database backups
- Central Database: Don't forget to backup the central SuperAdmin database
- Storage: Backup uploaded files in storage directories
This approach allows you to restore individual tenants without affecting others.
Security
Zenith includes enterprise-grade security:
- CSRF Protection: Token-based protection on all forms
- Login Throttling: Brute force prevention (5 attempts per 15 min)
- Password Security: bcrypt hashing with strength validation
- XSS Prevention: Output escaping in views
- SQL Injection: Prepared statements throughout
- Encryption: AES-256-GCM for sensitive data
- Session Security: Secure cookies with HttpOnly and SameSite
- Security Headers: X-Frame-Options, X-Content-Type-Options, etc.
If you discover a security issue in a Zenith-powered application:
- Email security details to: [email protected]
- Include detailed information and steps to reproduce
- I will respond within 48 hours
- Security fixes are prioritized and addressed immediately
Responsible disclosure is appreciated and will be acknowledged.
Performance
Database-per-tenant architecture scales differently than shared databases:
- Database Limit: Most servers can handle 1000+ databases
- Connection Pooling: One connection per request (not per tenant)
- Performance: Each tenant gets isolated resources
- Scaling: Can distribute tenant databases across multiple servers
In practice, server resources (RAM, CPU, disk I/O) become the limiting factor before the number of databases. Proper server sizing and caching can support thousands of tenants.
Zenith supports multiple caching strategies:
- OPcache: PHP opcode caching (recommended for production)
- Route Caching: Compiled routes for faster lookup
- Container Caching: Singleton pattern for services
- Database Caching: PDO persistent connections
Additional caching layers (Redis, Memcached) can be integrated through custom service providers.
Still Have Questions?
Can't find what you're looking for? We're here to help!