Różnica między private i public wynika z podejścia dostępu do zawartości klasy.
Zmienne i funkcje publiczne klasy są dostępne zawsze dla wszystkich z zewnątrz i możesz się do nich dobrać poprzez proste odwołanie do obiektu jak choćby obiekt.zmienna bo jest na to zezwolenie. Jeśli coś jest zadeklarowane jako prywatne, możesz się do tego dobrać
tylko i wyłącznie odpowiednimi funkcjami tej klasy. Ty dałeś __set i __get jako publiczne bez sprawdzania jaką zmienną wywołano by. Tym samym udostępniłeś możliwość odczytu i zapisu wszystkich zmiennych klasy, w tym prywatnych (!). Musisz zrobić dodatkowy warunek, który w razie odwołania do zmiennej nie istniejącej poinformuje o braku takowej lub wyświetli info o braku dostępu dla prywatnych danych. W tym momencie wszyscy mają dostęp do jakich chcą, nawet do tych, których nie chciałeś upubliczniać. Można to potraktować jako lukę bezpieczeństwa. Właśnie do tego zostały te funkcje w dużej mierze wymyślone... By reagować na wywołania czegoś co nie istnieje i są niejako idealne do wykorzystywania przy obsłudze wyjątków