Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [OOP]Pisanie CMS w OOP
Forum PHP.pl > Forum > PHP > Object-oriented programming
PawelC
Chcę stworzyć sobie system CMS, taki który za jakiś czas będę mógł bez problemu rozbudować, i teraz moje pytanie, czy taki podział klas jest dobry rozwiązaniem.

Klasa user.class.php
- dodawanie użytkownika
- kasowanie użytkownika
- edycja użytkownika
- banowanie użytkownika
- podgląd profilu użytkownika
- przypomnienie hasła

Klasa article.class.php
- dodawanie artykułu
- kasowanie artykułu
- edycja artykułu
- podgląd artykułu
- wylistowanie artykułów

Klasa category.class.php
- dodawanie kategorii
- usuwanie kategorii
- edycja kategorii
- podgląd wszystkich kategorii

Klasa news.class.php
- dodawanie newsa
- kasowanie newsa
- edycja newsa
- podgląd newsa
- wylistowanie newsów

Klasa plugin.class.php
- dodanie pluginu
- aktywacja/dezaktywacja pluginu
- edycja pluginu

Klasa db.class.php
W tej klasie będzie wszystko związane, z bazą danych np łącznie z bazą

Klasa validation.class.php
Będzie to klasa odpowiedzialna za walidacja wprowadzonych danych

Klasa filter.class.php
Zastosowanie tej klasy, to filtrowanie wszelkich danych wprowadzanych przez użytkowników

Za wszelkie pomysły, opinie i sugestie z góry dziękuję.
Spawnm
Cytat
Klasa plugin.class.php
- dodanie pluginu
- aktywacja/dezaktywacja pluginu
- edycja pluginu

Opiszesz dokładniej co masz na myśli, jak by miało to dokładniej działać ?
Co do reszty to jest chyba ok winksmiley.jpg
Z tym że każda klasa powinna być w stanie zwrócić tak jeden jak i wiele rekordów.
PawelC
Wgrywasz plugin do folderu plugins, logujesz się do systemu, przechodzisz do zakładki Pluginy, i tam będzie pokazany wgrany plugin, po kliknięciu na niego zostanie on zainstalowany, po instalacji będzie można go aktywować lub odinstalować, w wypadku gdy będzie aktywny, będzie można go usunąć lub wyłączyć. Coś na zasadzie, jak ma wordpress z pluginami smile.gif

Edycja pluginu, to na tej zasadzie, że wczytuje kod źródłowy pluginu, do pole tekstowego, gdzie będzie można go dostosować do własnych potrzeb, dokładnie edytować jego kod. Choć ten CMS będzie rozwiązaniem dedykowanym, gdzie wszystkie pluginy będą pod klienta, więc możliwość edycji, raczej jest nie potrzebna.

O tym, że każda klasa powinna móc zwrócić jeden lub kilka rekordów to wiem smile.gif
Crozin
Takie czynności jak dodanie użytkownika są zbyt skomplikowane dla jednego obiektu, a Ty chcesz po pięć takich wrzucać do jednego. Podstawowa zasada OOP: jeden obiekt, jedno zadanie.
Spawnm
Crozin - to zależy co masz na myśli mówiąc 'dodanie użytkownika' Jeśli chodzi o wsadzenie walidacji pól z formularza + sprawdzenie czy nick jest wolny + insert do bazy to wiadomo jedna metoda w klasie user zajmować się tym nie powinna i można by zrobić jakiś model_registration.
Ale jeśli ExPlOiTowi zależy jedynie na segregacji zapytań na bazie czyli klasa user to zbiór zapytań typu select, insert, update, delete dla tabeli / tabel user to wszystko jest ok. Chyba nie będziesz robić osobnej klasy typu
  1. class registration{
  2. public function add($name, $pass){
  3. mysql_query('insert ...'); //a raczej mysqli czy pdo. Czym się tam bawisz.
  4. }
  5. }

PawelC
Cytat
Ale jeśli ExPlOiTowi zależy jedynie na segregacji zapytań na bazie czyli klasa user to zbiór zapytań typu select, insert, update, delete dla tabeli / tabel user to wszystko jest ok
Dokładnie to mi chodzi, tak aby nie mieć w przyszłości problemów z rozbudową systemu. Dokładnie coś tego typu:
  1. class Model_User
  2. {
  3. private $db;
  4. public function __construct(database $db)
  5. {
  6. $this->db=$db;
  7.  
  8. }
  9. //Dodanie nowego użytkownika
  10. public function addUser($login,$haslo)
  11. {
  12. $this->login=htmlspecialchars($login);
  13. $this->haslo=htmlspecialchars($haslo);
  14. $result=$this->db->query("insert into `users` values('$login','$haslo')");
  15. if(!$result===false)
  16. {
  17. echo "Wystąpił błąd podczas rejestracji nowego użytkownika!";
  18. }
  19. else
  20. {
  21. echo "Zostałeś zarejestrowany poprawnie.";
  22. }
  23.  
  24. }
  25.  
  26. //Usuwanie użytkownika z bazy
  27. public function deleteUser($login)
  28. {
  29. $this->login=htmlspecialchars($login);
  30. $result=$this->db->query("delete from users where login='$login'");
  31. if(!$result===false)
  32. {
  33. echo "Wystąpił błąd podczas usuwania użytkownika!";
  34. }
  35. else
  36. {
  37. echo "Użytkownik o loginie $login został poprawnie usunięty z bazy.";
  38. }
  39. }
  40.  
  41. //Logowanie użytkownika
  42. public function userLogin($login,$haslo)
  43. {
  44.  
  45. $this->login=htmlspecialchars($login);
  46. $this->haslo=htmlspecialchars($haslo);
  47. $result=$this->db->query("select login,haslo from users where login='$this->login' and haslo='$this->haslo'");
  48.  
  49. if(mysqli_num_rows($result)==0)
  50. {
  51. echo "Brak użytkownika o podanym loginie!";
  52. }
  53. else
  54. {
  55. $_SESSION['zalogowany']="$this->login";
  56. header("Location: test.php");
  57. }
  58.  
  59.  
  60. }
  61.  
  62.  
  63. }
  64.  
  65. ?>

Zastanawia mnie jedno, jak jest dokładnie stworzone zarządzanie użytkownikiem, czy jest to jedna klasa, która wszystko robi, dodaje, kasuje itp, czy dla np dodania i kasowania, tworzone są osobne klasy? Bo szczerze mówiąc, im więcej o OOP czytam, tym bardziej się gubię.
plurr
Podziel tą logikę na dodatkowe warstwy: np User (pola name, mail itp), oraz UserDao (metody findBy, Save itp) której to np przekazujesz obiekt User do utrwalania w db.
Spawnm
Nie dawaj echo i zmian lokacji w klasach do tego nie przeznaczonych winksmiley.jpg
  1. $this->login=htmlspecialchars($login);
  2. $this->haslo=htmlspecialchars($haslo);

Po co to + brak ochrony przed sql injection
+ po co filtr na hasło ? Hasło daj w md5 z solą czy coś.
+filtrowanie przed xss dawaj przy wyświetlaniu
+
if(!$result===false)
Ten ! powinien tam być? smile.gif
PawelC
Dzięki za opinie i sugestie, a co do !, jakoś tak mi się tam wkradł smile.gif
dariuszp
Jeżeli to ma być CMS to nie radzę zaszywać artykułów czy kategorii na stałe w nim. Popracuj nad modułową budową tego.
PawelC
Powiedzcie mi, czy to jest dobrze napisana klasa:
  1. <?php
  2.  
  3. class Article{
  4.  
  5. private $db;
  6.  
  7. public function __construct(database $db)
  8. {
  9. $this->db=$db;
  10. }
  11.  
  12. //Dodawanie artykulu
  13. public function addArticle($title,$message,$author,$category)
  14. {
  15. $this->title=htmlspecialchars($title);
  16. $this->message=htmlspecialchars($message);
  17. $this->author=htmlspecialchars($author);
  18. $this->data=date('d-m-Y');
  19. $this->category=htmlspecialchars($category);
  20.  
  21.  
  22. $result=$this->db->query("insert into article values('','$this->title','$this->message','$this->author','$this->data','$this->category')");
  23. if($result===false){
  24. throw new Exception('Dane nie zostały dodane!');
  25. }
  26.  
  27. }
  28.  
  29. //Kasowanie artykułu
  30. public function removeArticle($id)
  31. {
  32. $this->id=$id;
  33.  
  34. if(!is_numeric($id))
  35. {
  36. throw new exception("ID nie jest liczbą!");
  37. }else{
  38. $result=$this->db->query("delete from article where id='$this->id'");
  39. if($result===false){
  40. throw new Exception("Wystąpił bląd podczas kasowania artykułu!");
  41. }
  42. }
  43. }
  44.  
  45. }
  46.  
  47.  
  48.  
  49. ?>
Spawnm
Nie.

Po co pchasz wszystko do $this ?
Nadal nie filtrujesz danych przed sql injection.
Ta klasa nie powinna filtrować danych przed xss + filtrujemy przy wyświetlaniu a nie zapisywaniu .
lDoran
spawnowi chodzi chyba o addslashes, a htmlspecialchars dajesz tylko przy wyciąganiu danych z bazy, bo po co zaśmiecać bazę danych.
Crozin
O prepared statements słyszał? Nie? To niech pogooglea.
PawelC
Poprawiłem kod:
  1. <?php
  2.  
  3. class Article{
  4.  
  5. private $db;
  6.  
  7. public function __construct(database $db)
  8. {
  9. $this->db=$db;
  10. }
  11.  
  12. //Dodawanie artykułu
  13. public function add($title,$message,$author,$category)
  14. {
  15. $result=$this->db->prepare("insert into article values('',?,?,now(),?,?)");
  16. $result->bind_param('ssss',$title,$message,$author,$category);
  17. if(!$result->execute()){
  18. throw new Exception('Dane nie zostały dodane!');
  19. }
  20.  
  21. $result->close();
  22.  
  23. }
  24.  
  25. //Kasowanie artykułu
  26. public function remove($id)
  27. {
  28. if(!is_int($id))
  29. {
  30. throw new exception("ID nie jest liczbą!");
  31. }else{
  32. $result=$this->db->prepare("delete from article where id=? limit 1");
  33. $result->bind_param('i',$id);
  34.  
  35. if(!$result->execute()){
  36. throw new Exception("Wystąpił bląd podczas kasowania artykułu!");
  37. }
  38. }
  39. $result->close();
  40.  
  41. }
  42.  
  43. }
  44.  
  45.  
  46.  
  47. ?>


Crozin słyszałem, o tym smile.gif

@down Poprawione smile.gif
nospor
Nie addslashes a mysql_escape_string a najlepiej mysql_real_escape_string a już najlepiej prepared statement winksmiley.jpg
Spawnm
Po co escapujesz skoro bindujesz?
+ po co w nazwach metod dajesz Article? O tym że add() dotyczy article informuje już nazwa klasy.
$data != $date + nic z tym nie robisz winksmiley.jpg

//edit
hmm widzę że poszła edycja postu ...
PawelC
Tak, międzyczasie poprawiłem kod smile.gif teraz już chyba wszystko jest ok, dzięki za pomoc wszystkim smile.gif
Spawnm
No to dalej - czemu nazwy raz zaczynasz z dużej a raz z małej litery?
Zdecyduj się (na małe z kamelem) inaczej z czasem zacznie ci to przeszkadzać winksmiley.jpg

+ czemu dajesz db->close() w dodawaniu czy edycji? Wydziel a raczej wywal bo articles się tym zajmować nie powinno.
PawelC
Ok, poprawiłem wszystko smile.gif Będę pisał, z małych + camel, czyli np addParam() to tylko przykład oczywiście.
bl4ck_b0x
A ja mam trochę inne pytanie co do tego kodu... Jestem zielony jeśli chodzi o obiektówkę ale rzuciły mi się w oczy "echa"... W klasie, metodzie dozwolone jest używanie echo, printf'ów itd.? Sądziłem, że najlepiej przekazywać takie rzeczy poprzez return false; a "na zewnątrz" jakoś to obsługiwać i wyświetlać odpowiednie błędy.
Mephistofeles
To zależy. Jeśli klasa odpowiada za widok, np. szablon, to oczywiście możesz, a nawet musisz używać echo itp. Ale nie powinno się tego robić w innych częściach logiki.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.