чем же всё-таки на реальном примере чревато использование public
Ну смотри.
Представь себе, что ты - объект, а все твои свойства (сердце, печень, желудок) - публичные. Я могу к тебе подойти, тыкнуть пальцем в сердце и ты помрешь. Так же и в объектах - те свойства, которые ответственны за работоспособность объекта класса, которые не должны быть доступны извне, делают private/protected.
Как в закрытое свойств (желудок) поместить еду? Сделаем публичный метод ЕСТЬ(), который поместит туда еду. На вход подаем пищу.
Зачем нужен метод, если, теоретически, желудок можно было бы сделать public и класть в него пищу напрямую, с помощью лопаты? Очевидно, метод ЕСТЬ() имеет кое-какую проверку входящих данных. Например, если ты засунешь себе в рот тухлятину, то эта "еда" просто не пойдет дальше - сработает рвотный рефлекс.
Такая же аналогия с программированием - хорошая практика - делать т.н. сеттеры/геттеры методы, которые принимают и возвращают свойства объектов. На эти методы можно повесть некую логику. Например, при установки свойства проверять его корректность, а при возвращении - отдавать в определенном формате.
Когда нужны public-свойства? В очень редких случаях, например когда объект выполняет роль некого хранилища, например это \stdClass -объект верхнего уровня PHP. Но в реальной разработке это очень редкие явления.
Все классы должны иметь закрытые свойства, а для манипуляции с ними - геттеры/сеттеры. Это хорошая практика.
Ну и пример банальный:
// класс для работы с mysql
class Database
{
/**
* Ресурс соединения с mysql
* @var mysqli
*/
public $connection;
public function __construct()
{
$this->connection = mysqli_connect(/**/);
}
}
$db = new Database();
// какой-то петя в коде написал случайно:
$db->connection = 123; // все сломалось