Object-Oriented PHP
Class and Instance
final class MyPlugin_Assets {
public function register(): void {
add_action('wp_enqueue_scripts', [$this, 'enqueue']);
}
public function enqueue(): void {
wp_enqueue_style('myplugin', MYPLUGIN_URL . 'assets/frontend.css', [], MYPLUGIN_VERSION);
}
}
$assets = new MyPlugin_Assets();
$assets->register();
Visibility
| Visibility | Meaning |
|---|---|
public | Accessible anywhere |
protected | Accessible in class and subclasses |
private | Accessible only in class |
Constructor
final class Repository {
private wpdb $db;
public function __construct(wpdb $db) {
$this->db = $db;
}
}
Typed properties require PHP 7.4+. Constructor property promotion requires PHP 8+.
Static Methods
final class Formatter {
public static function price(float $amount): string {
return '$' . number_format($amount, 2);
}
}
Formatter::price(10.5);
Use static methods for stateless helpers, not hidden global state.
Inheritance, Interfaces, Traits, Enums
interface RendererInterface {
public function render(array $data): string;
}
trait HasSettings {
protected function get_settings(): array {
return get_option('myplugin_settings', []);
}
}
enum Layout: string {
case Grid = 'grid';
case List = 'list';
}
Enums require PHP 8.1+.
WordPress OOP Hook Pattern
final class MyPlugin_Settings_Page {
public function register(): void {
add_action('admin_menu', [$this, 'add_page']);
}
public function add_page(): void {
add_options_page(
__('My Plugin', 'my-plugin'),
__('My Plugin', 'my-plugin'),
'manage_options',
'my-plugin',
[$this, 'render']
);
}
public function render(): void {
echo '<div class="wrap"><h1>' . esc_html__('My Plugin', 'my-plugin') . '</h1></div>';
}
}
Dependency Injection
final class ReportController {
public function __construct(private ReportRepository $repository) {}
}
$controller = new ReportController(new ReportRepository());
$controller->register();
Manual wiring is usually enough for small and medium plugins.
Practical Class Boundaries
| Class Type | Good Responsibility |
|---|---|
Assets | Enqueue scripts and styles |
SettingsPage | Register and render settings screens |
RestController | Register routes and handle REST requests |
Repository | Read and write data |
Renderer | Convert normalized data to HTML |
Synchronizer | Coordinate external API sync |
Common OOP Pitfalls in WordPress
- One giant plugin class that handles every feature.
- Hook registration hidden inside constructors.
- Excessive abstraction around simple WordPress APIs.
- Static state that makes tests and request behavior hard to predict.
- Using modern PHP syntax on unsupported servers.
- Forgetting that hooks need callable methods.