Для чего нужен отдельный пустой класс с исключением (Exception)?
Чтоб понять откуда ноги растут ошибок и как на них реагировать. Допустим завтра захотите в отделный лог писать все ошибки работы mysql, а у вас уже класс готовыйException // ошибки в php, скорее всего не в твоем коде в левых либах и т.д.

class AppException extends Exception // ошибка в твоем приложении

class MySqlException extends AppException // ошибка в твоем приложении, а именно в работе с базой

class ControllerException extends AppException // ошибка в твоем приложении, а именно работа контроллера

// и т.д.
Но ведь в итоге каждый файл пустой, почему нельзя использовать один для всех? И почему все таки он пустой?
Потому что каждый новый класс - это не новая переменная одного и того же типа, как массив, а новый тип переменной. И вот по типам их и различают. То есть, класс "не пустой" получается. В привычных тебе терминах это будет что-то вроде присвоения переменной класса каждый раз нового значение, $this->type = "Exception1";
и потом различать их по этой переменной. Но этот код избыточен. Достаточно просто написать class Exception1
- это уже будет определение типа.