To może najpierw kilka uwag:
#2: Klasa 'User' dziedziczy po 'functions' (może jakaś konsekwencja w nazewnictwie?) co wydaje mi się nieco dziwne. W jaki sposób użytkownik jest rozszerzeniem funkjci?
#4,5: Dlaczego te pola są publiczne? Przecież z tego co widzę stworzyłeś dla nich magiczne gettery/settery.
#6: SQL to skrót odnoszący się do języka zapytań, a z tego co widzę to używasz tego jako referencji do czegoś co pełni rolę API do komunikacji z bazą... niepotrzebne nieporozumienia się rodzą w takiej sytuacji
#11,12: Dlaczego nie ustawisz sobie wartości domyślnych odrazu w momencie deklarowania składowych klasy?
#35: Jak do tej pory ta klasa wygląda na taką, która ma reprezentować użytkownika... a tu nagle wyskakuje jakaś metoda do walidacji nazwy użytkownika. Powinieneś wydzielić te (i podobne) metody do innego obiektu będącego walidatorem dla użytkownika używanym podczas rejestracji. Poza tym kod tej metody jest bez sensu... najpierw sprawdzasz czy długość nazwy jest mniejsza od 3-ech. Jeśli tak to wyświetlasz komunikat (co już jest błędem, bo obiekt niepotrzebnie bierze na swoje barki dodatkową kwestię jaką jest prezentowanie treści użytkownikowi). Jeżeli nazwa jest dłuższa lub równa podanym 3-em znakom to metoda kończy działanie zwracając TRUE. To po jakie licho jest jeszcze później ten drugi warunek? Przecież jeżeli nazwa jest krótsza od tych 3-ech znaków to już nie będzie dłuższa niż 20, a sytuacja gdy nazwa jest dłuższa niż 2 znaki po czym następuje sprawdzenie czy aby przypadkiem nie jest dłuższa niż 20 znaków nie może nigdy zajść...
#58: Tutaj znów obiekt reprezentujący użytkownika pełni rolę kolekcji użytkowników... pobieranie użytkowników wydziel do osobnego obiektu odpowiedzialnego za to konkretne zadanie (tj. reprezentację kolekcji i operacji na niej)
#60: W jakim celu każdorazowo robisz: $db = $this->sql? Po co ta dodatkowa referencja?
#76: Zauważyłeś, że ta metoda robi dokładnie to co wcześniejsza tylko różni się drobnym fragmentem wykorzystywanego zapytania? Google: DRY. Innymi słowy: wydziel sobie jakąś prywatną metodę pobierającą użytkowników i z poziomu getById, getByUsername zwracaj jej wynik (jako argument przekazując coś w stylu:
"id = 3" lub "username = 'abc'"
#103: Nie widzę żadnej filtracji danych przed wprowadzeniem ich do treści zapytania. Co więcej te zapytania nie mają prawa działać - w ich treści masz:
...username = abc my username...
Przeczytaj w dokumentacji jak w MySQL (bo chyba z tego korzystasz) reprezentuje się tekst - podobnie jak w kodzie PHP podpowiem.
#124: Poczytaj o różnicy pomiędzy: "blah blah $variable blah blah", a 'blah blah $variable blah blah'
Cytat
rejestruje ale nie sprawdza czy nazwa użytkownika się powtarza
1) Nie pokazujesz jak używasz obiektu tej klasy
2) Nie widzę też w tym kodzie niczego co by mogło sprawdzać unkalność nazwy użytkownika...