![]() |
![]() ![]() |
![]() |
![]()
Post
#1
|
|
Grupa: Zarejestrowani Postów: 14 Pomógł: 0 Dołączył: 14.10.2019 Skąd: Białystok Ostrzeżenie: (0%) ![]() ![]() |
Cześć,
Zaczynam naukę OOP i w napisałem skrypt który umożliwia rejestracje/logowanie/zwrot/wypożyczenie książek. Mam świadomość istnienia SOLID oraz PSR - czytałem o PSR 1 / 2 i staram się przestrzegać. Nie znam MVC ani testów np. PHPUnit - to będą kolejne kroki w nauce. Czy taki skrypt można określić obiektowym, czy jest to jakaś hybryda? Zanim pójdę dalej jw chciałbym nauczyć się dobrych nawyków i w prawidłowy sposób posługiwać się OOP. Skrypt nie wszedł na forum, umieściłem na githubie Link do GitHub Moje dodatkowe pytania: 1. Tworzenie obiektu Database w konstruktorze innych klas, czy jest to prawidłowe? 2. Metoda checkCredentials klasy log - czy nie narusza zasady pojedynczej odpowiedzialności? Czy nie powinna np. wyszukiwać użytkownika,a następnie inna metoda powinna weryfikować dane? Dzięki za wszystkie uwagi i poświęcony czas ![]() |
|
|
![]()
Post
#2
|
|
Grupa: Zarejestrowani Postów: 6 376 Pomógł: 1116 Dołączył: 30.08.2006 Ostrzeżenie: (0%) ![]() ![]() |
Najpierw zastosuj autoloader, potem wyrzuć wszystkie htmle z plików z klasami i będzie można zacząć czytać. Jaki jest sens database?
-------------------- |
|
|
![]()
Post
#3
|
|
Grupa: Zarejestrowani Postów: 623 Pomógł: 144 Dołączył: 22.12.2010 Ostrzeżenie: (0%) ![]() ![]() |
klasa Log jest dość mocno myląca, brak namespace'ów (autoloadera j/w)
metoda "insert" z form tez jest, ze tak powiem, dosc dziwna, ponieważ insert w formularzu a insert do bazy danych to dwie rozne odpowiedzialnosci.
Coś takiego jest w ogóle niedopuszczalne (wg mnie) Ogólnie wydaje mi się że najlepiej byłoby jak byś zaczął wdrażać się w jakiś framework (np. symfony) + narzędzia typu cs fixer, i na tej podstawie zacząłbyś wyrabiałbyś sobie dobre nawyki. |
|
|
![]()
Post
#4
|
|
Grupa: Zarejestrowani Postów: 14 Pomógł: 0 Dołączył: 14.10.2019 Skąd: Białystok Ostrzeżenie: (0%) ![]() ![]() |
1. Dodałem autoloadera
2. Nie znam smarty ani innego template engine, więc HTML wrzuciłem w echo, jeśli to miałeś na myśli. Czy chodziło o rozdzielenie o tyle o ile to możliwe np. index i index_view, ale bez żadnego template engine? 3. Klasa Database w zamyśle miała być universalna do crud, nie wszystko jest z niej wykorzystywane w tym projekcie. Czy korzystając z PDO powinna ona tylko nawiązywać połączenie, a wszelkie operacje na bazie powinny być już napisane w innych klasach? np. funkcje registerUser w klasie RegistrationForm wygląda następująco:
i rzeczywiście dostrzegam trochę niepotrzebność kodu - korzystając z metod Detabase jedyne co zaoszczędziłem w tym przypadku to przy bindowaniu nie daje parametru INT, STR etc, a w pozostałych linijkach mogłem korzystać bezpośrednio z PDO. Jednak była to klasa tworzona w ramach tutorialu OOP, z którego wywnioskowałem właśnie taki sposób działania. 3. Zmieniłem klase log na LoginForm 4. Dodałem namespace, przez co przy autoloaderze się musiałem namęczyć ![]() 5. Zmieniłem insert na RegisterUser, jeśli miałeś na myśli mylącą nazwę funkcje - funkcja to zakłada konto, wsadzając rekordy do bazy. 5.
zmieniłem na inne zmienne, kiedyś ucyzłem się pythona i na potrzeby tymczasowej iteracji jak dobrze pamiętam dopuszczano właśnie takie oznaczanie zmiennych. 6. Dodałem komentarze do metod w RegistrationForm Tak, będę ogarniał frameworka, postawiłem na Symfony, ale najpierw chciałem dla świętego spokoju uporządkować to co zrobiłem i chciałem zapoznać się z jakimś template engine, żeby było przejrzyściej, ale może to niewłaściwa kolejność. Nowe pliki pod tym samym linkiem. Dzięki za wypowiedzi. |
|
|
![]()
Post
#5
|
|
![]() Grupa: Zarejestrowani Postów: 898 Pomógł: 48 Dołączył: 2.11.2005 Skąd: Poznań Ostrzeżenie: (0%) ![]() ![]() |
Niestety trochę błądzisz, ale moim zdaniem to bardzo dobra decyzja, że próbujesz coś napisać samodzielnie zamiast uczyć się frameworka. Frameworki niestety uczą złych nawyków jeśli nie umiesz w porządne OOP.
To od czego bym zaczął na Twoim miejscu to composer. Composer dzisiaj to jest standard w każdym projekcie i warto go użyć już teraz choćby po to aby mieć autoloader. Druga rzecz to PSR - pisałeś, że czytałeś i starasz się stosować, ale w kodzie tego zupełnie nie widać... Polecam zainstalować php-cs-fixer i odpalić w projekcie, a potem zobaczyć sobie jakimś diffem co zostało zmienione. Mamy PHP 7.3, a w twoim klasach tego nie widać - nie ma typowania parametrów funkcji, typów zwracanych itp. Z takich pierdół unikaj jak ognia stosowania if... else, a jeszcze bardziej zagnieżdżania ifów bo to zło wcielone. Takich rzeczy jak to nie da się czytać Kod public function checkCredentials($data){ $this->connection->query("SELECT * FROM uzytkownicy WHERE nick=:nick"); $this->connection->bind(":nick",$data['nick']); $this->connection->execute(); if($this->connection->rowCount()>0){ if(password_verify($data["password"],$this->connection->singleResult()->haslo)){ $this->isLoged=true; return $this->isLoged; }else{ $this->error="Incorect nick or password"; } }else{ $this->IsError=true; $this->error="Incorect nick or password"; } } Zobacz o ile czytelniejsza byłaby ta funkcja po refactorze (użyłem wyjątków, ale możesz tu wstawić swoją logikę ze zwracaniem false itd): Kod public function checkCredentials(array $data): bool { $this->connection->query("SELECT * FROM uzytkownicy WHERE nick=:nick"); $this->connection->bind(":nick",$data['nick']); $this->connection->execute(); if($this->connection->rowCount() == 0) { throw new \Exception('User not found'); } if(!password_verify($data["password"], $this->connection->singleResult()->haslo)) { throw new \Exception('Incorect user or password'); } $this->isLoged = true; return true; } Wewnątrz konstruktora (i ogólnie klas) nie powinieneś używać new bo to jest ukrywanie zależności. W dobrym kodzie wszystkie zależności powinny być wstrzykiwane w konstruktorze. Ale to może być dla Ciebie trudne gdy bo nie ogarniasz jeszcze zapewne wzorców projektowych typu fabryki, czy Dependency Injection. Niemniej postaraj się gdzie dasz radę raczej tworzyć klasy bez używanie w ich kodzie new. Czyli przykład: Kod /** * Źle */ public function __construct() { $this->connection = new Database(); } /** * Dobrze */ public function __construct(Database $connection) { $this->connection = $connection; } W php do komentarzy funkcji stosujemy php doc block, a jeszcze lepiej typowanie inputu/output + doc block jako uzupełnienie (np. o rzucane wyjątki, typu elementów w tablicy itp). Jeśli myślisz na poważnie o kodowaniu, to zacznij w 100% stosować angielski - czemu funkcje są po angielsku, a baza po polsku? Pokracznie to wygląda. To chyba na początek tyle. Jak to ogarniesz to na Twoim miejscu spróbowałbym przerobić jakiś tutorial MVC żeby zrozumieć jak wygląda architektura prostej aplikacji w PHP. Robiesz bardzo wiele błędów i masz ogólnie źle zorganizowany kod. Przerobienie dobrego tutoriala na pewno pomoże. Ogólnie szału nie ma, ale każdy kiedyś zaczynał, a widać że czytasz i starasz się rozwijać, więc to dobrze wróży. Już samo używanie gita i githuba na Twoim poziomie to bardzo dobry znak.Trzymam kciuki. Ten post edytował athabus 15.10.2019, 21:04:54 |
|
|
![]()
Post
#6
|
|
Grupa: Zarejestrowani Postów: 14 Pomógł: 0 Dołączył: 14.10.2019 Skąd: Białystok Ostrzeżenie: (0%) ![]() ![]() |
Tak wiem, błądzę muszę poukładać wiedze.
1. zrobiłem composera i dodałem autoloada z composera - rzeczywiście prościej niż ręcznie, podszkalam się z niego. 2. zrobiłem też php-cs-fixer - muszę tylko rozgryźć diffa bo chwilowo robię podgląd zmian ręcznie na klonie. 3. dałem type hinting 4. chyba zrozumiałem intencje z ifami i rzeczywiście wygląda lepiej, poprawiłem kod w tym zakresie jeszcze w pozostałych miejscach, nie wpadłbym na takie podejście, dzięki. 5. dependency injection wiem o co chodzi, dajemy jako argument konstruktora obiekt klasy, nie pomyślałem, żeby wykorzystać to do zrobienia połączenia z bazą danych, ale co do swojego połączenie w konstruktorze nie byłem przekonany, stad pytałem o to w pierwszym poście. ( nie tylko konstruktora oczywiście, ale generalnie jest konieczne jest dziedziczenie klas i jako argument metody w klasie która dziedziczy damy obiekt rodzica klasy ) 6. co do polskiego w bazie wiem, ale obejrzałem się za późno, a nie o bazę w tym projekcie chodziło stąd rozstawiłem 7. zmieniłem komentarze na odpowiednie znaczniki, jeśli chodzi o docblock pisząc output i input masz na myśli meta tagi param i return w dokumentacji? I w takim razie czy to byłby prawidłowy zapis?
Wrócę jeszcze z pytaniem ponieważ było poruszone po co jest klasa Database. Czy rzeczywiście jest zbędna i powinienem w niej w konstruktorze tylko tworzyć połączenie? Dzięki za rady. Dalej będę doszkalał się z coposera i z cs-fixera. Grzebie też pomału w linuxie, jednak miałem problem z localhostem i wyczytałem, że najlepiej w linuxie skorzystać z "kontenerów", jednak to zapowiada się grubszy temat. Przerobie wzorce, potem smarty i pewnie będę dalej coś tworzył. Jak ktoś ma jeszcze jakieś uwagi to ja bardzo chętnie ![]() Nowe pliki pod tym samym linkiem. Ten post edytował mrpickles 17.10.2019, 21:04:43 |
|
|
![]()
Post
#7
|
|
Grupa: Zarejestrowani Postów: 6 376 Pomógł: 1116 Dołączył: 30.08.2006 Ostrzeżenie: (0%) ![]() ![]() |
Przykładowo ta nieszczęsna klasa database. W przypadku błędu łapiesz wyjątek i w zasadzie nic z tym nie robisz. Czyli w sytuacji gdy wystąpił błąd mogę zrobić coś takiego:
$this->connection w query jest nullem - php sypie błędem. Czemu każda klasa ma require 'vendor\autoload.php';? Formy nie powinny rozszerzać Database bo i po co? Co najwyżej jakieś AbstractForm w którym można wstrzykiwać Connection (przykład bo raczej głupie rozwiązanie). public function checkCredentials(array $data) :bool - credentials zazwyczaj będzie zawsze user, pass więc czemu nie public function checkCredentials(string $user, string $pass) :bool Brakuje jakiegoś może service który obsługiwałby użytkowników. Przykładowo UserService -> checkCredentials i wtedy sprawdzasz $this->userService->check... zamiast wykonywać zapytania w klasie Form. Smarty to niekoniecznie dobry pomysł. Raczej historycznie się go używa. Twig, Blade, PHPTAL, Volt. -------------------- |
|
|
![]()
Post
#8
|
|
Grupa: Zarejestrowani Postów: 14 Pomógł: 0 Dołączył: 14.10.2019 Skąd: Białystok Ostrzeżenie: (0%) ![]() ![]() |
Usunąłem vendor/autoload w klasach - pozostałość bo tworzeniu połączenia w konstruktorze poprzez new Database. Później zrobiłem Depenedncy injection, a require zostało - dzięki za zwrócenie uwagi.
Co to rozszerzania Form o Database - w tutorialu OOP który przerabiałem Dependency injection było pokazywane tylko na klasach które po sobie dziedziczą - uznałem to za obowiązkowe, a rzeczywiście nie jest i już usunięte. Rozpisałem checkCredentials na przyjmowanie 2 stringów - w arrayu i tak siedział tam tylko user i password. Dzięki za info o smartach, przyjrzę się pozostałym. Możesz przybliżyć o co chodzi z userservice? Kompletnie nie wiem jak mogę to ugryźć.Chodzi o stworzenie nowej klasy userService i tam przeniesienie checkcredential? Tylko, że to główne zadanie klasy loginForm. Zapytam przy okazji czy to jest prawidłowe, lepsze podejście to strony index w przypadku logowania? Uzależnienie wyświetlanej treści od tego czy jesteśmy zalogowani czy nie, czy lepsze jest przekierowywanie jak wykryje, ze jesteśmy zalogowani?
|
|
|
![]()
Post
#9
|
|
![]() Grupa: Zarejestrowani Postów: 898 Pomógł: 48 Dołączył: 2.11.2005 Skąd: Poznań Ostrzeżenie: (0%) ![]() ![]() |
Ogólnie po zmianach wygląda już znacznie lepiej. Postaram się dać trochę uwag - to jeszcze nie wszystko co rzuciło mi się w oczy, ale nie chcę Cię wszystkim przytłaczać na raz.
1. GIT - w gicie masz coś takiego jak .gitignore pozwalające na nie commitowanie pewnych plików. Dla przykładu w 99% projektów nie komituje się vendorów, a już na pewno nie powinieneś commitować cachu od fixera, czy innych cachy/logów. Tu przy okazji będziesz miał fajne ćwiczenie jak przestać śledzić zmiany w repo czegoś co omyłkowo commitowałeś. No i zdecydowanie popracuj nad opisywaniem commitów - opis powinien być jasny i klarowny, a nie @Update. Jak będziesz kiedyś robił repo, które chcesz pokazać pracodawcy, to historia commitów jest często przeglądana. W firmach zazwyczaj pracuje się w systemach zadaniowych i opis kommita wygląda tak: [Task-abc] Opis taska. 2. PHP coś z tym fixerem poszło nie do końca ok, bo w wielu miejscach nadal masz kod niezgodny z PSR - np. $a=1 powinno być $a = 1; Ogólnie sporo masz tam jeszcze w kwestii PSR do poprawienia. Ale znów - jeśli myślisz o pracy zawodowo, to jest coś na co pracodawcy baaaardzo zwracają uwagę, więc wyrabiaj sobie nawyki. 3. Piszesz, że walczysz z diffem - są do tego narzędzia, które pokazują graficznie. Ja korzystam akurat z wbudowanego w PhpStorma, ale to płatne oprogramowanie, więc pewnie musisz poszukać jakiś alternatyw - może vscode ma podobne wtyczki, albo jakiś wyspecjalizowany edytor. W PphSotrm jest nawet opcja wpięcia fixera jako plugin, który sam poprawia PSR w pliku. Umiejętność pracy z Diffem jest kluczowa w pracy zespołowej, gdzie musisz sprawdzić co kto i kiedy zmieniał. Warto nad tym pracować. 4. Komentarze. Ogólnie tutaj szkoły są różne. Ja jestem zwolennikiem, że kod powinien się dokumentować sam, gdzie tylko to możliwe. Ogólnie komentarze powinny być stosowane gdy wnoszą coś nowego - jeśli są redundantne z metodą to są zbędne. Spójrz tutaj: Kod /*Row Count*/ public function rowcount():int { return $this->stmt->rowcount(); } /** * checking credentials * @param array $argument1 array structure to verify credentials * @return bool Return bool if credentials are correct */ public function checkCredentials(array $data) :bool {} Te dwa komentarze nie wniosły NIC oprócz dodatkowego kodu, który trzeba teraz utrzymywać i poprawiać jak robisz refaktor metod. Przydatne komentarze Kod /** * @return OrderItemInterface[] * @throws NoSuchEntityException */ protected function getItems(int $orderId): array {... } Tutaj komentarz coś wnosi bo informuje że w tablicy zwróconej przez metodę dostanę obiekty danego typu + że metoda może rzucić wyjątek danego typu. Zobacz, że już parametru nie ma w komentarzu, bo wszystko wynika z nagłówka metody. 5. Chyba już powoli warto zacząć się zastanawiać nad ubraniem tego w strukturę. Na początek poradziłbym Ci stworzyć wspólny entrypoint dla całej aplikacji. Pokombinuj jak to zrobić, aby wszystkei requestty uderzały w jeden punkt (index.php). W ten sposób wyeliminujesz potrzebę używania require w całej aplikacji. Na początek możesz to zrobić po prostu w formie frontcontrollera, choć docelowo pewnie raczej powinien to byś typowy plik inicjujący aplikację, a front controller już powinien być osobno. Niemniej na razie możesz to zrobić w 1 pliku i potem pomyśleć jak zrobić Refaktor. 6. Podoba mi się, że sam użyłeś strict_types - chyba o tym nie pisałem, a widzę że w klasach się pojawił. 7. Odnośnie pytania z ostatniego postu - łatwiej będzie to ogarnąć przekierowaniem na stronę z odpowiednim komunikatem bo ładnie obsłużych to na wyższym poziomie niż w szablonie. |
|
|
![]()
Post
#10
|
|
Grupa: Zarejestrowani Postów: 6 376 Pomógł: 1116 Dołączył: 30.08.2006 Ostrzeżenie: (0%) ![]() ![]() |
https://martinfowler.com/eaaCatalog/
Dlaczego głównym zadaniem loginForm ma być sprawdzanie stanu użytkownika? Klasa powinna zawierać walidację, filtrowanie danych, ewentualnie zajmować się generowaniem inputów (na zasadzie buildera $loginForm->add('input', [params]). -------------------- |
|
|
![]()
Post
#11
|
|
![]() Grupa: Moderatorzy Postów: 36 557 Pomógł: 6315 Dołączył: 27.12.2004 ![]() |
Njapierw klasa dziedziczy po Database
class RegistrationForm extends Database A potem ta sama klasa w konstruktorze dostaje obiekt Database public function __construct(Database $connection) Rozumiem, ze zapomniales usunac extednds Database ? Klasa Database
powinna byc niezalezna od jakiegos tam konfigu. Dane konfiguracyjne powinna dostac w konstruktorze Klasa Database
Powinna raczej pluc wyjatkiem na zewnatrz w przypadku braku polaczenia a nie tlumic go wewnatrz siebie. Teraz tak to masz zrobione,ze pomimo braku polaczenia, inne klasa odpalaja zapytania na polaczeniu, ktorego moze teoretycznie nie byc rowCount a nie rowcount To samo dotyczy wywolan metody rowCount z PDO. staraj sie czasami czytac co piszesz, np to: $log->getIsLoged() nie ma wiekszego sensu. Czy jak sie pytasz kogos, czy ma bulke to mowisz tak: "Daj mi czy masz bulke" Czy moze tak: "Masz bulke?" Tak samo tutaj powinno byc poprostu $log->isLoged() Juz nie wspomnie o braku jednego "g" Powinienies miec jeden plik glowny/publiczny przez ktory przechodza wszystkie akcje, np index.php i on dopiero powinien odpalac poszczegolne akcje i inicjowac mase niezbednych rzeczy. Teraz masz 6 plikow glownych a w kazdym polowa kodu jest powtorzona Naprawde nie musisz wszystkieg pchac w php. Np ten plik
Moze wygladac tak:
-------------------- "Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista "Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer |
|
|
![]()
Post
#12
|
|
![]() Grupa: Zarejestrowani Postów: 898 Pomógł: 48 Dołączył: 2.11.2005 Skąd: Poznań Ostrzeżenie: (0%) ![]() ![]() |
Jeszcze taka ogólna uwaga odnośnie dziedziczenia. Ogólnie dziedziczenie nie służy do "przekazywania" kodu do klas potomnych tak jak to robisz, czyli rozszerzając klasę o klasę Database. Dziedziczenie zazwyczaj to zło, chyba że robisz to świadomi i w przemyślany sposób. W większości przypadków lepsza od dziedziczenia jest kompozycja (wstrzyknięcie obiektu przez konstruktor). Jest to bardziej elastyczne rozwiązanie i nie blokuje rozwoju aplikacji. Dziedziczenie w prawdziwych aplikacjach używane jest dość rzadko - raczej stosuje się interfejsy + kompozycję. Na tak małym kodzie jak teraz piszesz może to być trudne do zrozumienia i wydawać się całkiem dobrym pomysłem, ale serio używaj dziedziczenia jak najrzadziej się da, bo przy większym kodzie to się szybko mści.
|
|
|
![]()
Post
#13
|
|
Grupa: Zarejestrowani Postów: 14 Pomógł: 0 Dołączył: 14.10.2019 Skąd: Białystok Ostrzeżenie: (0%) ![]() ![]() |
Ustosunkuje się tylko niektórych elementów, bo dostałem dużo wskazówek, a zanim je przerobie minie dłuższa chwila.
1) Tak, nie wrzuciłem na githuba dokonanych w plikach zmian stąd w dalszym ciągu było widoczne extends - jak pisałem już tak było wskazane w tutorialu który przerobiłem dotyczący dependency injection, że można było je stosować tylko w przypadku dziedziczenia.Odniosłem po tym tutorialu wrażenie, że dziedziczenie jest bardzo ważne i szeroko stosowane, ale jak widać nie ![]() Jak coś dopiero teraz wrzuciłem zmienione pliki. 2) Jeśli chodzi o
tak samo z tutorialu wynikało jasno, że jeśli funkcja nam coś zwraca, powinniśmy ją nazywać od get - niby przyjęta praktyka. Rozumiem,że jednak nie za wszelką cenę, na pewno cenne info. 3) Cs-Fixer nadpisał mi wszystkie elementy w katalogu, sprawdzałem po dacie modyfikacji, specjalnie przestawiałem klamry w dziwne miejsca i poprawiał je po uruchomieniu.Być może kwestia, że wyświetla mi komunikat ze korzystam z vendora fabpot, a nie friendsofphp - mam obydwa w composerze, nie umiem jednak wymusic stosowania właśnie friendsofphp. 4) Chyba zaczynam rozumieć, o co chodzi z login formem i podziałem - chwilowo dla mnie to abstrakcja do napisania, ale poszukam powalczę. 5) Jeden z pierwszych postów mówił o usunięciu HTML, więc zrobiłem to wszędzie - brak mi zarówno wiedzy jak i praktyki, stąd usunąłem wszędzie, ale znowu widzę, że i tutaj mogę stosować zasadę nie za wszelką cenę ![]() 6) co do komentarzy,trochę już mi się wyjaśniło, wydawało mi się to dziwne na przytoczonym przykładzie, też to odbierałem jako dublowanie kodu, myślałem,że tak poprostu ma być Więc po kolei: Jeśli chodzi o GITa ogarnę to, już wiem na co zwracać uwagę. Potem ogarnę diffa, żeby zadbać o czystość kodu - zależy mi na nim. Potem zaznajomię się z MVC i spróbuje przepuścić wszystko przez index i przebuduje Database, być może to mi rozjaśni wasze wskazówki. Dzięki za odzew! |
|
|
![]()
Post
#14
|
|
![]() Grupa: Zarejestrowani Postów: 898 Pomógł: 48 Dołączył: 2.11.2005 Skąd: Poznań Ostrzeżenie: (0%) ![]() ![]() |
To o czym piszesz to jest częsty błąd w tutorialach, bo prawdziwe OOP trudno ująć w krótkim tutorialu. Szybciej się go nauczysz pisząc jakąś apkę wspólnie z kimś kto temat ogarnia. Największe oszustwo OOP polega na tym, że ludzie próbują przenosić taksonomie z prawdziwego życia. Na przykład typowy przykład - mam psa i rybkę -> stworzę klasę Animal. To jest w 80% tutoriali o OOP, a jest to anty przykład jak stosować OOP. Tak jak pisałem dzisiaj będzie Ci to trudno zrozumieć bo piszesz zbyt mały kod, ale w prawdziwym kodzie to jest droga do wielkiej katastrofy.
Wpisz w Google jedną z podstawowych zasad OOP "Favor composition over inheritance" - na razie nie zaprzątaj sobie tym głowy bo w Twoim kodzie są większe problemy niż stosowanie SOLID, ale ogólnie dziedziczenia staraj się unikać to zaprocentuje w przyszłości. * tu taki disclaimer - ja nie jetem przeciwnikiem dziedziczenia. W wielu miejscach jest bardzo przydatne - np. metoda szablonowa etc. Ale na pewno nie w takiej formie jak uczą go w tutorialach dla początkujących. To tylko tworzenie złych nawyków, które potem trudno zwalczyć, a kompozycja jest bardzo łatwym konceptem do ogarnięcia więc można od razu wyrabiać dobre wzorce. Tymczasem do działa - czekam na kolejną wersję kodu. Jeszcze z 20 -30 iteracji i będzie dobrze ;-) PS. z tym HTML to chyba źle zrozumiałeś intencje kolegi - chodziło mu o zupełne wydzielenie widoku z logiki, a nie zamianę kodu html na stringi w PHP. Jak poczytasz o MVC to zobaczysz o co chodzi. Nie musisz tu używać TWIGA/SMARTY - widok możesz zrobić na prostym PHP + HTML, ale nie mieszaj widoku z logiką. |
|
|
![]()
Post
#15
|
|
![]() Grupa: Moderatorzy Postów: 36 557 Pomógł: 6315 Dołączył: 27.12.2004 ![]() |
Jak extends bylo tak nadal jest Cytat 2) Jeśli chodzi o Tak, ale to dotyczy rzeczownikow a nie pytan. isLogged to pytanie samow sobie
tak samo z tutorialu wynikało jasno, że jeśli funkcja nam coś zwraca, powinniśmy ją nazywać od get - niby przyjęta praktyka. Rozumiem,że jednak nie za wszelką cenę, na pewno cenne info. ![]() Cytat 5) Jeden z pierwszych postów mówił o usunięciu HTML, więc zrobiłem to wszędzie - brak mi zarówno wiedzy jak i praktyki, stąd usunąłem wszędzie, ale znowu widzę, że i tutaj mogę stosować zasadę nie za wszelką cenę CHodzilo o uzycie plikow szablonow a nie wstawianie tego w echo jak masz teraz. Skoro nie uzywasz plikow szablonow poki co, to nie ma sensu calego duzego html pchac bez sensu w echo![]() -------------------- "Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista "Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer |
|
|
![]()
Post
#16
|
|
Grupa: Zarejestrowani Postów: 14 Pomógł: 0 Dołączył: 14.10.2019 Skąd: Białystok Ostrzeżenie: (0%) ![]() ![]() |
Zakręciłem się i pracowałem na klonie, a zrobiłem upload nie klona z jakimiś innymi drobnymi poprawkami. Już na pewno nie ma extends.
Nie byłem pewny czy chodzi o wyechowanie htmla, czy właśnie jak pytałem o zrobienie np. index do którego includuje index_view, który to zawiera html - ale miałem problem żeby oddzielić to w 100%. Korzystając z okazji zanim będę przerabiał temat to dopytam właśnie o to. Oddzielenie html od php na przykładzie z dużym echem - chodzi mi o sam sposób, a nie czy w tym pliku to rzeczywiście było potrzebne ![]() mysite
mysite_view
Jednak w przypadku return wydaje mi się to niemożliwe z uwagi na wtopienie w html php w petli foreach.
Czy chodzi w takim przypadku o nierodzielanie do dwóch plików, a o zastosowanie składni alternatywnej dla php? Czy jednak chodzi o fizyczne rozdzielanie? |
|
|
![]()
Post
#17
|
|
![]() Grupa: Moderatorzy Postów: 36 557 Pomógł: 6315 Dołączył: 27.12.2004 ![]() |
Generalnie nie chodzi o odzielenie php od html a o odzielenie logiki aplikacji od wyswietlania. W logice aplikacji przygotowujesz wszystkie dane, ktore potem przekazujesz do widoku ktory to te dane wysweitla.
A czy widoko zrealizujesz w php czy za pomoca systemu szablonow to juz inna sprawa. -------------------- "Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista "Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer |
|
|
![]()
Post
#18
|
|
Grupa: Zarejestrowani Postów: 14 Pomógł: 0 Dołączył: 14.10.2019 Skąd: Białystok Ostrzeżenie: (0%) ![]() ![]() |
Ok czyli MVC się kłania. Dzięki za wyjaśnienia, " I'll be back "
![]() |
|
|
![]()
Post
#19
|
|
![]() Grupa: Moderatorzy Postów: 6 072 Pomógł: 861 Dołączył: 10.12.2003 Skąd: Dąbrowa Górnicza ![]() |
Wiele już zostało powiedziane ale ja dodam od siebie jedno, na co nikt wcześniej nie zwrócił uwagi. Chodzi o:
https://github.com/filipdak/libraryoop/blob...onForm.php#L103
Unikaj zapisów poleceń SQL bazujących na kolejności kolumn w bazie danych. Zmienisz strukturę tabeli, dodasz pomiędzy istniejącymi kolumnami nową i zaczną się problemy z dziwnym zachowaniem skryptu. Dużo lepiej i bezpieczniej jest zapisać (w tym pomijając NULL dla kolumny id):
czyli jawnie podać jakie dane mają trafić w jakie kolumny. |
|
|
![]()
Post
#20
|
|
Grupa: Zarejestrowani Postów: 14 Pomógł: 0 Dołączył: 14.10.2019 Skąd: Białystok Ostrzeżenie: (0%) ![]() ![]() |
Trochę mnie nie było, jednak musiałem przyswoić dość dużą dawkę wiedzy.
Napisałem praktycznie wszystko od nowa. 1) Oparte jest teraz na MVC - tak, wiem prymitywne MVC - przerabiałem też MVC oparte na wyrażeniach regularnych i preg_match, co w przyszłości tutaj wdrożę jednak w celach naukowych takie prymitywne lepiej mi wszystko ilustrowało. 2) Dodane template engine Twig 3) Usunięte zapytania SQL bazujące na kolejności kolumn w bazie 4) Dodałem obsługę wyjątków (?) czy jest to zrobione poprawnie? Wcześniej była mowa, że wyjątki są duszone w środku ![]() 5) Było mówione o dziedziczeniu klas - tutaj wszystkie Controllers dziedziczą po głównym kontrolerze Core\Controller - czy jest to akceptowalne? 6)Wiem, że muszę po upraszczać trochę kod bo miejscami if na ifie. 7)Mam problem z Type Hinting w Model User metoda authenticate - zwracam obiekt lub bool, a z tego co czytałem dopiero od php 8 będzie możliwość typowania dwóch różnych form. Wszystko wgrałem pod nowy link, ponieważ mało rzeczy jest wspólnych z poprzednim. Jak zwykle dzięki. Odwiedź moją stronę |
|
|
![]() ![]() |
![]() |
Wersja Lo-Fi | Aktualny czas: 22.05.2025 - 07:34 |