Methods from two sibling classes: traits in PHP

Содержание
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

Похожие статьи
Development with PHP
OOP in PHP
PHP 8 Classes
Inheritance in PHP
Methods from two sibling classes: traits
Изображение баннера

Поиск по сайту

Подпишитесь на Telegram канал @aofeed чтобы следить за выходом новых статей и обновлением старых

Перейти на канал

@aofeed

Задать вопрос в Телеграм-группе

@aofeedchat

Контакты и сотрудничество:
Рекомендую наш хостинг beget.ru
Пишите на info@urn.su если Вы:
1. Хотите написать статью для нашего сайта или перевести статью на свой родной язык.
2. Хотите разместить на сайте рекламу, подходящую по тематике.
3. Реклама на моём сайте имеет максимальный уровень цензуры. Если Вы увидели рекламный блок недопустимый для просмотра детьми школьного возраста, вызывающий шок или вводящий в заблуждение - пожалуйста свяжитесь с нами по электронной почте
4. Нашли на сайте ошибку, неточности, баг и т.д. ... .......
5. Статьи можно расшарить в соцсетях, нажав на иконку сети: