Расширения базовых классов действительно не лучший подход. Наследование на основе файлов (поиск в директории клиента, если нет - то выше) - это вообще не подход для php, но вполне подход для css/js. Точкой входа является клиентский каталог, css импортирует файлы ядра и перекрывает/расширяет что нужно.
Хороший подход для php - контейнеры зависимостей и сервис-локаторы, когда вы можете в клиентском коде подменять все что хотите из ядра. Заодно тестирование упрощается. Вообще Ваша задача абсолютно типична для любой кастомизируемой разработки, лучше бы взять хороший фреймворк типа симфони и использовать его архитектурные решения. Это как раз тот случай, когда изобретение велосипеда очень дорого потом встанет.