Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> [php]Początki OOP
Mefiuu
post
Post #1





Grupa: Zarejestrowani
Postów: 371
Pomógł: 18
Dołączył: 23.11.2008

Ostrzeżenie: (0%)
-----


Witam. Rozpocząłem żmudne zagłębianie się w tajniki programowania zorientowanego obiektowo, przeczytałem kilka artykułów i pomyślałem że najlepiej jest sprawdzić swoją wiedzę w praktyce. Tak oto powstała klasa do uploadu plików. Przyznam się, że pobrałem sobie podobną klasę z phpclasses.org, aby zobaczyć mniej więcej jak to wygląda. Chciałbym Was zapytać czy ma to coś w ogóle wspólnego ze stylem OOP ?

class.upload.php
  1. <?php
  2. class Upload {
  3. var $folder;
  4. var $types = array('application/msword', 'application/octet-stream', 'image/jpeg');
  5.  
  6. function __construct($folder) {
  7. $this->folder = $folder;
  8. $this->upload();
  9. }
  10.  
  11. public function check() {
  12. if (isset($_POST['wyslij'])) {
  13. if($_FILES['plik']['error']>0) {
  14. echo "Wystąpił problem: ";
  15. switch($_FILES['plik']['error']) {
  16. case 1: echo "rozmiar pliku przekroczył wartość xMB.<br /><a href='java script:history.back(1)'>Wróć</a>"; break;
  17. case 2: echo "rozmiar pliku przekroczył wartość xMB.<br /><a href='java script:history.back(1)'>Wróć</a>"; break;
  18. case 3: echo "plik wysłany częściowo.<br /><a href='java script:history.back(1)'>Wróć</a>"; break;
  19. case 4: echo "nie wysłano żadnego pliku.<br /><a href='java script:history.back(1)'>Wróć</a>"; break;
  20. case 6: echo "nie można wysłać pliku: nie wskazano katalogu tymczasowego.<br /><a href='java script:history.back(1)'>Wróć</a>"; break;
  21. case 7: echo "nie zapisano pliku na dysku.<br /><a href='java script:history.back(1)'>Wróć</a>"; break;
  22. }
  23. }
  24. else {
  25. if (in_array($_FILES['plik']['type'], $this->types)) {
  26. return true;
  27. }
  28. }
  29. }
  30. }
  31.  
  32. public function upload() {
  33. if($this->check()) {
  34. if (is_uploaded_file($_FILES['plik']['tmp_name'])) {
  35. if(!file_exists($this->folder.'/'.$_FILES['plik']['name'])) {
  36. if(move_uploaded_file($_FILES['plik']['tmp_name'], $this->folder.'/'.$_FILES['plik']['name'])) {
  37. throw new Exception('Dodano plik pomyślnie');
  38. }
  39. else {
  40. throw new Exception('Nie dodano pliku!');
  41. }
  42. }
  43. else {
  44. throw new Exception('Taki plik już istnieje!');
  45. }
  46. }
  47. }
  48. else {
  49. throw new Exception('Niepoprawny typ!');
  50. }
  51. }
  52. }
  53. ?>



index.php
  1. <?php
  2.  
  3. include('class.upload.php');
  4.  
  5. try {
  6. $upload = new Upload('files');
  7. }
  8. catch (Exception $e) {
  9. echo $e->getMessage();
  10. }
  11.  
  12. ?>



Mam co do tego pytania :

1) Wiem że w stylu OOP są wyjątki. Czy to, jak ja je zastosowałem to odpowiednia metoda? Czy jest ich za dużo ? Bo mi nie pasują za bardzo ...
2) Czy wyjątki powinno się dawać do udanych operacji ?
3) Czy w konstruktorze wykonywać metodę 'upload' czy odwołać się do niej poza konstruktorem, już w pliku index?
4) Jeśli mam operacje na bazie danych bądź plikach tekstowych to czy tworzyć destruktor do ich zamykania ?

To takie ogólne pytania i byłbym bardzo wdzięczny gdyby ktoś mi to 'sprawdził', wytknął błędy i polecił dobrą literaturę (IMG:style_emoticons/default/smile.gif)

Dziękuję i pozdrawiam.

Ten post edytował Mefiuu 3.08.2011, 20:46:10
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi
Crozin
post
Post #2





Grupa: Zarejestrowani
Postów: 6 476
Pomógł: 1306
Dołączył: 6.08.2006
Skąd: Kraków

Ostrzeżenie: (0%)
-----


Na początek dwie ogólne uwagi:
1. Nie mieszaj języków (patrz: wywal polskie indeksy tablic). Angielski jest jedynym słusznym w takim miejscu. (IMG:style_emoticons/default/wink.gif)
2. Nigdy nie doprowadzaj do czegoś takiego:
  1. if () {
  2. if () {
  3. if () {
  4. if () {
  5.  
  6. } else {
  7.  
  8. }
  9. } else {
  10.  
  11. }
  12. } else {
  13.  
  14. }
  15. } else {
  16.  
  17. }
Tyle poziomów zagłębień to koszmar przy późniejszej pracy. Niemal zawsze da się to zamienić na coś w stylu:
  1. // Obsługa czterech "błędów"
  2. if (!...) {
  3.  
  4. }
  5.  
  6. if (!...) {
  7.  
  8. }
  9.  
  10. if (!...) {
  11.  
  12. }
  13.  
  14. if (!...) {
  15.  
  16. }
  17.  
  18. // Obsługa po pomyślnym przejściu przez powyższe
  19. ...
Pamiętaj, że wyrzucenie wyjątku przerywa wykonywanie bloku TRY.

Co do Twoich pytań:
1. Nie jest ich za dużo. W każdym miejscu gdzie występuje błąd, który wystąpić nie powinien masz prawo, a wręcz obowiązek skorzystać z wyjątku.
2. Nie.
3. Nie powinieneś. Konstruktor służy przygotowaniu obiektu do pracy, nie wykonywaniu samej pracy.
4. To zależy. Jeżeli plik jest otwarty na przestrzeni "działania obiektu" to w destruktorze dobrze byłoby upewnić się, że plik zostanie zamknięty. Przy czym raczej powinna być osobna metoda do zamknięcia, użytkownik powinien zawsze ręcznie ją wywoływać, a destrukor mógłby co najwyżej w ostateczności zamykać. Coś w ten deseń:
  1. class File {
  2. private $opened = false;
  3.  
  4. public function open(...) {
  5. ...
  6.  
  7. $this->opened = true;
  8. }
  9.  
  10. public function write(...) {
  11. ...
  12. }
  13.  
  14. public function close() {
  15. ...
  16.  
  17. $this->opened = false;
  18. }
  19.  
  20. public function __descruct() {
  21. if ($this->opened) {
  22. $this->close();
  23. }
  24. }
  25. }


I jeszcze kilka uwag:
1. Nazwa klasy powinna być rzeczownikiem, np. Uploader. Tworząc obiekt (new) tworzysz jakiś byt, a następnie każesz owemu bytowi wykonywać jakieś akcje, np. wgrać coś ($uploader->uploadSomething()) dlatego też nazwy metod powinny być czasownikami. Kod jest wtedy bardziej logiczny.
2. W PHP5 nie ma czegoś takiego jak "var". Masz trzy modyfikatory zasięgu: private, protected, public i to z nich powinieneś korzystać.
3. Nigdy nie powinieneś korzystać ze stanu globalnego (patrz $_POST, $_FILES). Te dane powinny zostać przekazane do obiektu z zewnątrz.
4. Akurat na kod błędu (1..7) masz ładne stałe, które są bardziej wymowne niż jakiś numerek.
5. Nigdy nie powinieneś mieć w kodzie takiej klasy żadnego ECHO. Jest błąd? To wywalasz wyjątek. Jakaś inna część aplikacji może go przechwycić i zrobić coś pożytecznego z nim (jak chcociażby wyświetlenie informacji użytkownikowi).
6. Nigdy nie stosuj bezpośrednio klasy Exception. Jest zbyt ogólna. Użyj bardziej wyspecjalizowanego typu. A jeżeli w SPL-u nie ma odpowiedniego, stwórz własny.
7. Jak już przechwytujesz wyjątek (blok CATCH) zrób z nim coś pożytecznego. Wyświetlenie treści wyjątku nie jest czymś takim. Co najwyżej całą aplikację możesz objąć blokiem TRY .. CATCH i tutaj wyświetlenie treści błędu ma sens - bo oznacza to, że aplikacja się wysypała i nic już nie da się zrobić.
Go to the top of the page
+Quote Post

Posty w temacie


Reply to this topicStart new topic
2 Użytkowników czyta ten temat (2 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 25.12.2025 - 15:44