Methods from two sibling classes: traits in PHP

Contents
Introduction
The sibling problem
Traits: horizontal reuse
Same method in both traits
Alternative: composition

Introduction

A base class with two children that are siblings — neither is the parent of the other — and now you need one class with methods from both branches. PHP forbids it directly; traits are the language answer (inheritance and OOP basics first if needed).

The sibling problem

<?php namespace Aredel\Demo; class Reporter { /* base: shared logging */ } class PdfReporter extends Reporter { public function pdf(): void { } } class CsvReporter extends Reporter { public function csv(): void { } } // need pdf() AND csv() in one class: // class ComboReporter extends PdfReporter, CsvReporter {} // FATAL

class X extends A, B is a fatal error: PHP has single inheritance only (it avoids the diamond problem by refusing to have it). The branches are siblings — restructuring them into a parent/child chain just to share code falsifies the model.

Traits: horizontal reuse

A trait is a bundle of methods meant to be pasted into classes with use — reuse without any parent/child relation:

<?php namespace Aredel\Demo; trait PdfExport { public function pdf(): void { } } trait CsvExport { public function csv(): void { } } class ComboReporter extends Reporter { use PdfExport; use CsvExport; }

Keep the genuine is-a relation in extends (ComboReporter still is a Reporter) and put the cross-cutting abilities in traits. Trait methods behave as if defined in the class itself, so they see $this and can use its properties.

Same method in both traits

If both traits define save(), PHP refuses to guess — resolve explicitly: insteadof picks the winner, as keeps the loser under an alias:

<?php namespace Aredel\Demo; class ComboReporter extends Reporter { use PdfExport, CsvExport { PdfExport::save insteadof CsvExport; CsvExport::save as saveCsv; } }

A method defined directly in the class always wins over trait methods — the precedence is: class beats trait, trait beats inherited.

Alternative: composition

When the siblings carry state, not just behavior, prefer holding them as properties and delegating:

<?php namespace Aredel\Demo; class ComboReporter extends Reporter { public function __construct( private PdfReporter $pdf, private CsvReporter $csv, ) { } }

Rule of thumb: shared behavior without state — traits; collaborators with their own state and lifecycle — composition.

Article author: Arthur Isaev

Related articles
Development with PHP
OOP in PHP
PHP 8 Classes
Inheritance in PHP
Methods from two sibling classes: traits

Search this site

Subscribe to Telegram channel @aofeed to follow new articles and updates to old ones

Go to channel

@aofeed

Ask a question in the Telegram group

@aofeedchat

Contacts and cooperation:
I recommend our hosting beget.ru
Write to info@urn.su, info@aredel.com if you:
1. Want to write an article for our site or translate an article into your native language.
2. Want to place thematically relevant ads on the site.
3. Ads on my site pass maximum censorship. If you see an ad block unsuitable for school-age children, shocking or misleading - please contact us by e-mail
4. Found a mistake, inaccuracy, bug, etc. on the site. ... .......
5. Articles can be shared on social media by clicking a network icon: