Balin
20.03.2004, 16:54:29
Witam, ostatnio zastanawiam sie w jaki sposob napisac jadro systemu webowego w php - doszedlem do wniosku, ze najlepiej uzyc singletonow do tworzenia instancji klas (db, io, klasa sesji, szablonow itp.) czy jednak lepiej aby jadro bylo rozproszone (wiele klas, kazda posiadajaca metode instance() ) czy raczej napisac jeszcze jednak klase Kernela, ktora to klasa przechowywala by w sobie metody tworzenia instancji i instancje wszystkich podsystemow, oraz kontrolowala wszelkie proby uzyskania takiej instancji ?
Jestem ciekaw jak wy to widzicie ? w jaki sposob wy pisaliscie rdzen systemu ?
Bora
20.03.2004, 20:17:35
Engone
|--Biblioteki
| |-Error
| |-DB (ja napisałem włąsną klase ale z składnią podobną do adodb)
| |-Sesje
| |-IO
| |-Smarty
| |-Page (includje moduł dzięki temu że ina klasa niż kernel dane są w pewnym stopniu bezpieczne)
|--Moduły (inicjowane przez engine)
|--Templates (przyjąłem zasade że domyślny plik ma taką samą nazwe jak moduł)
|--lang (łądowany domyślnie główny + z możiwością zainocjownaiania przez kernel pliku do modułu)
Wykorzystany singleten. Engine inicjuje wszystkie moduły przed zainicjowaniem sprawdza tylko uprawneinia. Wszelkie dane wysyąłnie do przeglądark (POST GET SESSION COOKIE) są przerabiaje przez odpowiedną klase dzięki czemu moge formuowac wąłsne linki np (index.php/modul/news/nr/1). Jest to snandardowy sposób ale działą popreawnie z chęcią sam poczytam jak można to innaczej rozwiązac.
MaKARON
21.03.2004, 10:46:57
W tym zastosowaniu, to chyba kazdy ma swoj sposob i swoje pomysly.
Cytat
| |-Error
Co u Ciebie robi ta klasa? Czy jest sens? Ja nie widze. Zwracam odpowiednie wartosci bool w kazdej metodzie swoich klas i dla funkcji/klas obslugujacych wygladu okreslam komunikaty.
Cytat
| |-DB (ja napisałem włąsną klase ale z składnią podobną do adodb)
Hm... adodb i tak jest szybkie... i tylko przy na prawde obciazonych systemach jest sesns ja modyfikowac (to dla innych).
Cytat
| |-Smarty
Proponuje klase dziedziczaca - chocby po to, zeby ulatwic sobie wyswietlanie. Do wyswietlenia malej tabelki z komunikatem wystarczy wtedy $mySmarty->Komunikat("Tytul","Tresc") i nie trzeba wszedzie kojarzyc zmiennych
Cytat
| |-Page (includje moduł dzięki temu że ina klasa niż kernel dane są w pewnym stopniu bezpieczne)

Nie wiem co to
Cytat
|--Moduły (inicjowane przez engine)
Ja mam takie sposob wywolania modulu, ze ustawiam go na podstwie adresu (jak podales nizej) - pierwszy parametr po okreslonym jest nazwa modulu, pozniej nazwa funkcji itd itp. (dodatkowo jest ograniczenie na metody ktore moga byc wywolywane).
Cytat
|--Templates (przyjąłem zasade że domyślny plik ma taką samą nazwe jak moduł)
Ja zas zasade, ze jest domyslna funkcja, a nie plik szablonu. Jest to wygodniejsze, bo ona juz sobie zadecyduje co robic.
Cytat
|--lang (łądowany domyślnie główny + z możiwością zainocjownaiania przez kernel pliku do modułu)
Jezeli korzystasz ze smarty to mozna wykorzystac .conf do robienia wersji jezykowych. Szybko latwo i skutecznie. Wiem, ze mozna by to przyspieszyc... ale tak mozna mowic o wszystkim. Kiedys optymalizowalismy na zajeciach petle for!!!

/i nie zartuje z ta petla

/
Cytat
Engine inicjuje wszystkie moduły przed zainicjowaniem sprawdza tylko uprawneinia.
A czemu wszystkie? Proponuje inne rozwiazanie. Iniciuje tylko ten wykorzystywan, a do wspolpracy z innymi proponuje system zdarzen. Moduly podlaczaja sie do zdarzen, ktore wywoluja (uwalniaja, powoduja) inne moduly - tak wspolpracuja tylko te, ktore sa potrzebne w danej stronie.
Cytat
Wszelkie dane wysyąłnie do przeglądark (POST GET SESSION COOKIE) są przerabiaje przez odpowiedną klase dzięki czemu moge formuowac wąłsne linki np (index.php/modul/news/nr/1).
Troche innaczej to zrobilem (mod_rewrite). Wywolania wszystkich nieistniejeacych plikow sa przekierowywane do index.php, on sprawdza to tak jak u Ciebie. Czemu nieistniejace? Musze jakos wyslac do przegladarki obrazki i CSS'y
Pozdrawiam!
Bora
21.03.2004, 11:43:03
[quote]
[quote]
| |-Error
[/quote] Co u Ciebie robi ta klasa?
[/quote]
Ma ona za zasade obsługe błedów czyli zbieranie dodatkowych informacji (debug_backtrace()) sprawdza poziom błędu i w zależności od niego decyduje czy dalej ma być przetwarzany engine.
[quote]
[quote]
| |-DB (ja napisałem włąsną klase ale z składnią podobną do adodb)
[/quote] Hm... adodb i tak jest szybkie... i tylko przy na prawde obciazonych systemach jest sesns ja modyfikowac (to dla innych).
[/quote]
Odpalenie adodb to tylko zmiana jednej linijki. Ta klasa powstała raczej jako rozgrzewka przed pisaniem engine'u
[quote]
[quote]
| |-Smarty
[/quote]
Proponuje klase dziedziczaca - chocby po to, zeby ulatwic sobie wyswietlanie. Do wyswietlenia malej tabelki z komunikatem wystarczy wtedy $mySmarty->Komunikat("Tytul","Tresc") i nie trzeba wszedzie kojarzyc zmiennych
[/quote]
hmm ciekawe, trzeba będzie sprawdzić
[quote]
[quote]
| |-Page (includje moduł dzięki temu że ina klasa niż kernel dane są w pewnym stopniu bezpieczne)
[/quote]

Nie wiem co to
[/quote] Dugo sie nad tym zastanawiałem czy potrzeba. Czyli jednak jedt to zbędne.
[quote]
|--Moduły (inicjowane przez engine)
[quote]
[/quote] Ja mam takie sposob wywolania modulu, ze ustawiam go na podstwie adresu (jak podales nizej) - pierwszy parametr po okreslonym jest nazwa modulu, pozniej nazwa funkcji itd itp. (dodatkowo jest ograniczenie na metody ktore moga byc wywolywane).
[/quote]
Sorrka zę sformuowałem. Mam klase sprawdzającą uprawnienia acces. Ma ona za zadanie sprawdzić uprawneinia a w przypadku braku modułu albo braku uprawniem przekierowanie na odpowiedni domyślny lub logowanie.
Schemat klas wyglada tak:
Kod
Engine
|--Biblioteki
| |-Error
| |-DB
| |-Acces
| |-Sesje
| |-IO
| |-Smarty
|-Page
[quote]
[quote]
|--Templates (przyjąłem zasade że domyślny plik ma taką samą nazwe jak moduł)
[/quote] Ja zas zasade, ze jest domyslna funkcja, a nie plik szablonu. Jest to wygodniejsze, bo ona juz sobie zadecyduje co robic.
[/quote] To jest katalog z plikami modułów. Schemat przedstawia bardziej rozmieszczenie plików.
[quote]
[quote]
|--lang (łądowany domyślnie główny + z możiwością zainocjownaiania przez kernel pliku do modułu)
[/quote] Jezeli korzystasz ze smarty to mozna wykorzystac .conf do robienia wersji jezykowych. Szybko latwo i skutecznie. Wiem, ze mozna by to przyspieszyc... ale tak mozna mowic o wszystkim. Kiedys optymalizowalismy na zajeciach petle for!!!

/i nie zartuje z ta petla

/
[/quote] Kolejna rzecz do przemyślenia
[quote]
[quote]
Engine inicjuje wszystkie moduły przed zainicjowaniem sprawdza tylko uprawneinia.[/quote]
A czemu wszystkie? Proponuje inne rozwiazanie. Iniciuje tylko ten wykorzystywan, a do wspolpracy z innymi proponuje system zdarzen. Moduly podlaczaja sie do zdarzen, ktore wywoluja (uwalniaja, powoduja) inne moduly - tak wspolpracuja tylko te, ktore sa potrzebne w danej stronie.
[/quote] Żle sie wyraziłem oczywiście tyko wybrany który otrzymna od klasy acces..
Wielkie dzięi za krytyke i wskazówki. Kiedyś na forum był artykuł jak to miało wyglądać w vortalu php.pl ale niestety nie mogłem znależć.
Ozzy
21.03.2004, 15:03:22
Cytat
Troche innaczej to zrobilem (mod_rewrite).
A koledze nie pomożesz?
MaKARON
21.03.2004, 20:18:15
Zajrzyj do tamego tematu, troche tam wkleilem.
Cytat
Ma ona za zasade obsługe błedów czyli zbieranie dodatkowych informacji (debug_backtrace()) sprawdza poziom błędu i w zależności od niego decyduje czy dalej ma być przetwarzany engine.
To chyba ma sens tylko w przypadku rozwoju aplikacji...
Cytat
Odpalenie adodb to tylko zmiana jednej linijki. Ta klasa powstała raczej jako rozgrzewka przed pisaniem engine'u
Mialem ochote kiedys napisac taka miniadodbmysql - dla zastosowan juz na serwer. Zrezygnowac ze wszystkiego co jest mozliwe - a do rozwoju uzywac ado. Mozesz to podeslac?
Cytat
Sorrka zę sformuowałem. Mam klase sprawdzającą uprawnienia acces. Ma ona za zadanie sprawdzić uprawneinia a w przypadku braku modułu albo braku uprawniem przekierowanie na odpowiedni domyślny lub logowanie.
A jak masz zrealizowane uprawnienia?
Cytat
Kolejna rzecz do przemyślenia
Myślę, ze warta, bo jezeli dobrze to jeszcze pogrupowac albo 'rozmodulowac' - czyli dla kazdego modulu osobny plik.. to byloby latwe w tlumaczeniu.
Cytat
A jak masz zrealizowane uprawnienia?
Dołączam do pytania, bardzo mnie to ciekawi i myślę od kilku dni nad tym.
MaKARON
22.03.2004, 14:53:05
A Ty co wymysliles/jak to zaplanowales?
Balin
22.03.2004, 16:54:04
ciekawe jest to co piszecie, ale nadal nie wiem czy jestescie za centralizacja czy decentralizacja jadra, czy u waz jadro to po prostu zbior kilku klas inicjowanych juz w skrypcie, czy odrebna klasa, ktora sama inicjuje te wszystkie klasy podsystemow ?
ja raczej skoncentrowalem sie nad tym, zeby napisac jedna klase, ktora bedzie odpowiadala za tworzenie innych klas, czyli inicjowanie nowych modulow.
maulus
22.03.2004, 20:18:45
a właściwie co wżucacie do jądra za co są tam odpowiedzialne classy
Balin
22.03.2004, 20:27:38
na pewno takie klasy jak:
config
input/output
baza danych
sesje (jesli nie kozystasz z tych wbudowanych)
templates
Jenym slowem takie podstawowe klasy bez ktorych nie moze dzialac zadna czesc systemu, pozniej na ich podstawie buduje sie taki sterownik, ktory zarzadza żądaniami i na ich podstawie odpala odpowiednie moduly itp.
MaKARON
22.03.2004, 22:07:26
Cytat
ja raczej skoncentrowalem sie nad tym, zeby napisac jedna klase, ktora bedzie odpowiadala za tworzenie innych klas, czyli inicjowanie nowych modulow.
Tak, ale jest jeszcze wyswietlanie, wersje jezykowe, rozne bazy danych, programowanie zdarzeniowe, cachowanie, SHM i wiele innych rzeczy... nie wepchniesz wszystkiego w jedno miejsce. Czasem trzeba robic klasy, ktore dopiero obsluguja klasy dziedziczace po abstrakcyjnych

W sumie to i tak cieszcie sie

ostatnio siedze w j2me i mimo ze jest to micro to mnie zaczyna draznic ilosc klas i polaczen miedzy nimi, a do tego interfacy i inne duperle

... no ale w koncu bede mogl grac na swoich gierkach
Makaron : ok rozumiem, ale w moim przypadku ogranicza sie to do kilku klas, lecz dopiero co zaczynam tworzyc system CMS, pisze silnik, ktory ma za zadanie tworzyc moduly, wykorzystac je w dzialaniu, kilka wbudowanych modulow np : user register, lub profil, klasa dotyczaca uprawnien danego urzytkownika. Narazie nie zastanawiam sie nad wersjami jezykowymi, cachowanie mam zrobione w swoim autorskim systemie szablonow, lecz on ma jeszcze jedna wade, funkcjia warunkowa... wiec gdyby nie to, to w moim szablonie byl by support dla smarty i AcEmplates ;] co do wersji jezykowej, to dodam ja gdy zrobie panel administracyjny... chodz do kazdego modulu oddzielnie bede musial robic wersje jezykowa, to moze teraz zaczne... Ale dla db nie przewiduje innej bazy niz mysql. Wiec akurat moje myslenie okresla sie do czegos malego na poczatek, z czasem moze napisze cos bardziej rozbudowanego. W chwili obecnej to sa moje ambicje.
MaKARON
24.03.2004, 14:10:27
Nie pozostało nic, tylko życzyć wytrwałości i czekać na publikację wyników!
Bora
25.03.2004, 13:16:13
ja stworzyłem jedną główną klase zarządzającą wszystkim i łączącą to w całość. Bardzo przydatne są singleton'y dzięki nim sie ięknie pisze moduły.
Przykłąd:
[php:1:675cf4027c]<?php
class news {
/**
* news::news()
*
* Konstruktor
*/
function news() {
$this -> error = &engine::getInstance('error');
$this -> db = &DB::get_DB();
$this -> io = &engine::getInstance('io');
?>[/php:1:675cf4027c]
Dodatkowo wykorzystałem stos zapisujący strony gdzie sie chciał dostać odwiedzający i nie miał uprawnień. Dzięki temu zaraz po zalogowanu wraca na te strony.
Uprawnienia są sprawdzane jescze przed odpaleniem modułu wszystko prawa są przechowywane w bazie mysql. Brak uprawnień dla jakiejś grupy użytkowników powoduje przydzienienie domyślnych.
Strz@łka
1.04.2004, 19:52:05
No to teraz ja zadam wam pytanie. Jak już pisać jądro to jak

Obiektowo (klasy) czy nie ?
kwiateek
1.04.2004, 19:56:44
Cytat
No to teraz ja zadam wam pytanie. Jak już pisać jądro to jak

Obiektowo (klasy) czy nie ?
Nie wyobrażam sobie pisania jądra nie używając klas.
Pozdrawiam.
halfik
1.04.2004, 20:23:42
Panowie debatujecie tutaj na temat jądra - i dobrze, temat cokolwiek ciekawy. Ale dlaczego nikt nie wspomni w temacie, że jądra jako takiego pisać nie trzeba, aby stworzyć dobry, stabilny system. Dlaczego nikt nie poruszy tutaj tematu zalet jakie niesie ze sobą napisanie jądra, problemów z tym związanych i w drugą stronę: co się stanie jeśli napiszemy system średnich rozmiarów (no np. od 10 tys. linii kodu w zwyż) bez konkretnej klasy zarzadzającej itd. ? Myślę, że temat na tym poziomie może być równie ciekawy jak zagadnienei "jak pisać jądro"?
P.S Jądro należy pisać z głową
Cytat
co się stanie jeśli napiszemy system średnich rozmiarów (no np. od 10 tys. linii kodu w zwyż) bez konkretnej klasy zarzadzającej itd. ?
Hmm - nic sie nie stanie

moim zdaniem silink / jadro aplikacji webowej to ma byc cos co ulatwi nam pisanie modulow (ograniczenie ich do kodu czysto spelniajacego zadanie - reszte powinen realizowac wspomniany silnik).
Dla mnie musi to byc wygodne - w swoim robie sobie coraz wiecej udogodnien i coraz wygodniej mi sie tworzy (np. wczoraj napisalem cos na wzor rejestru windows w dosyc nietypowy sposob - ulatwia mi to zapis konfiguracji itp. do granic mozliwosci!).
Bardzo wazny jest tez czas generowania, co za tym idzie ograniczenie liczby zapytan, uzywanie static przy powtornych wywolaniach niektorych funkcji (po co wysylac zapytanie drugi i nty raz?).
halfik
1.04.2004, 20:37:54
Cytat
A ja jak najbardziej chociaz lepiej chocby objac funkcje w klase by uniknac konfliktow nazw...
Naturalnie, że kodowanie obiektowe niesie ze soba wielkei możliwości i jedną z nich jest ta o której wspominasz. Naturalne jest, że napisać jądro jak i sam serwis prościej bedzie w OOP, bo tutaj łatwiej utrzymać pewną hierarchię, zależności itd. - czytelność, zwięzłość kodu etc. Z drugiej jednak strony: wszyscy wiemy, że bez php 5 nie mamy prawdziwego OOP - pozsotaje nam tylko czekać z nadzieją na powiększenie możliwości, które i tak są ogromne
robert_b
4.04.2004, 22:34:18
Wow!!!
Ale wy wszyscy jesteście mądrzy! Chyba źle trafiłem...
Ale będę się uczył i niedługo też sobie napiszę "jądro" albo nawet dwa!! :wink:
Sh4dow
5.04.2004, 15:37:44
no dobra temu panu juz podziekujemy

Joke !
A tak wracajac do sprawy. To nie do konca musze sie zgodzi z wami jesli chodzi o oop. Nie mowie ze nie ma wielu zalet, ale jesli chodzi mi o ta czytelnosc którą tutaj tak chwalicie. Czytelnosc kodu nie zalezy od sposobu pisania, ale od samego piszącego.
Wlasnie skonczylem pisać swoj silnik do strony. Z paroma modulami zajelo mi to miesiac. caly slilnik jest rozplanowany w 4 podstawowe pliki i katalog z bibliotek wspomagajacych. Wszystko napisanie strukturalnie i moim zdaniem jest w miare przejzysty pomimo paru braków w komentarzach. oczywiscie wykozystuje pare mniejszych klas w niektorych miejscach, ale ogolnie kod jest czytelny. Ale to jest moje osobiste zdanie.
halfik
5.04.2004, 17:53:54
Cytat
Wlasnie skonczylem pisać swoj silnik do strony. Z paroma modulami zajelo mi to miesiac. caly slilnik jest rozplanowany w 4 podstawowe pliki i katalog z bibliotek wspomagajacych. Wszystko napisanie strukturalnie i moim zdaniem jest w miare przejzysty pomimo paru braków w komentarzach. oczywiscie wykozystuje pare mniejszych klas w niektorych miejscach, ale ogolnie kod jest czytelny. Ale to jest moje osobiste zdanie.
Owszem, to czy kod będzie czytelny w dużej mierze zależy od kodera. aLe nam akurat nie o to chodziło. Srpawa jest taka, że patrząc na kod w OOP po prostu czytasz co tam jest napisane np. patrzysz news->dodaj($tresc) - wiadomo co to robi. wiadomo też ze jeśli zechcesz usunąc newsa to będzie odpowiednia metoda w klasie news itd. A przy kodowaniu strukturalnym musisz poszukać, sprqawdzić która funkcaj jest od czego. Choć można tutaj oszedzić używając odp. nazw np. addNews($text) itd. jednak to nie będzie ta sama przejrzystośc kodu. Sam w PHPie po dziś dziań koduje strukturalnie, mój site cały jest strukturalny - wyjątek to kalsy SMARTY - i kod jest czytelny na ile to możliwe. Zawsze jest skrypt głowny od doczepia pliki konfiguracyjne, pliki funkcyjne, a sam dba tylko o sprawdzanie warunków, wywoływanie odp. funkcji, przekazywanie wyników gdzie trzeba oraz przypisywanie wartości do zm. szablonowych itd. Także mam osobny katalog na funkcje, osobny na szablony, osobny na konfigi do szablonów, osobny na konfigi do skryptów itd. - mimo wszystko to nie to samo co można uzyskać dzięki OOP.
Ja tez nie koduje obiektowo, narazie badam (dla mnie) nowy teren - wiedza juz jakas jest, teraz raczej zastanawiam nad samym zastosowaniem.
Dziedziczenie - napewno przydatna zabawka

Jak narazie uczytelniam swoj kod do postaci news::add($tresc) (wzorujac sie na przykledzie przedmowcy

).
Cieszy mnie rowniez takie rozwiazanie bo licznik czasu generowania na to nie reaguje, gdy stworze obiekt jest juz spora roznica (w tym momencie system wysyla 7-10 zapytan na strone, jest juz mocno rozbudowany i generuje sie okolo 0,02s - wlasciwie to co zwalnia to zapytania i obiekty - z zapytaniami sobie poradzilem (np. pre ladowanie danych i zapis w zmiennej globalnej - moduly, biblioteki, userzy - dalej nie ma juz zadnych zapytan zwiazanych z tymi danymi)
halfik
5.04.2004, 23:04:40
Cytat
Dziedziczenie - napewno przydatna zabawka

Jak narazie uczytelniam swoj kod do postaci news::add($tresc) (wzorujac sie na przykledzie przedmowcy

).
Ja tam wolę określenie mechanizm

A tak na serio do tematu: pawdziwe zabawki dostaniemy dopiero z pojawieniem się 5, z tego co się przyglądałem wnioskuje, że wzorcem była tutaj JAVA. Obecnie morduje "Thinking in JAVA" B.Eckela i naprawde niezłe jazdy można robić w pełnym OOP
P.S Ktoś na forum pisał, że gdzieś tam w PHPie do czegoś tam używał Singletonu - ciekawi mnie jak, bo bez modyfikatorów dostępu nie da się zrobić czystego Singletonu, a uzycie w tym celu sztucznego licznika obiektów to raczej nie to samo...
Inna sprawa: ciekwe o ile po wejściu 5, skrypty napisane w OOP będą wolniejsze od ich odowiednich kodowanych strukturalnie?
seaquest
6.04.2004, 15:26:16
@jaco: ale jak rozwiązujesz problem kiedy potrzebne ci jest kilka obiektów jednej klasy...
to mnie ciekawi, bo robie CMS'a pod php 4 i 5. I mam zamiar zrobić ładowanie osobnych sterowników do bazy (SQLite - tylko dla PHP5, MySQL, MySQLi oraz Postgree) i to mogą być klasy oparte na singletonach, ale np. klasa FormGenerator musi mieć stworzonych czasem kilka instancji, a zastosowanie wtedy zmiennych i metod statycznych staje się po prostu niemożliwe.
Balin
6.04.2004, 17:34:53
Wiec nie tworz metod statycznych - stworz obiekt, z 1 metoda statyczna obj::GetInstance() i skladowa statyczna static private $Instance, jesli bedziesz chcial odwolac sie do istniejacej instancji obiektu wywolasz metode obj::GetInstance, ktora sprawdzi czy istnieje juz instancja tego obiektu i zwroci ja.
A jesli bediesz chcial utworzyc nowy egzemplaz obiektu skozystasz z new.
seaquest
6.04.2004, 18:02:33
Balin wogule mnie nie zrozumiałeś. Chodzi mi o to, że jaco pokazał że korzysta ze zmiennych i metod statycznych. A ja się pytałem jak rozwiązuje to w klasach, w których potrzebne mu kilka obiektów...
@Balin: To złe rozwiązanie. Bo którą instancję ma zwrócić getInstance()? Przy kilku istniejących instancjach to bez sensu, bo musi być jedna wyróżniona instancja, więc po co inne?
@seaquest: IMHO jeżeli potrzbujesz kilku instancji klasy to singleton po prostu nie pasuje i tyle. W twoim przypadku każda klasa, która używa tego FormGeneratora, musi wiedzieć, której akurat instancji używa - więc musi mieć referencję do tej instancji (albo jakiś inny dostęp do tej właśnie referencji). To po co jej dodatkowo singleton?
Cytat
ale jak rozwiązujesz problem kiedy potrzebne ci jest kilka obiektów jednej klasy...
Nie ma takiej sytuacji bo to co ja robie nie ma nic wspolnego z OOP

Ja poprostu wkladam kod silnika w klase aby uniknac konfluktu nazw, jak narazie jestem baaardzo zadowolony z wynikow - jak wspominalem nie znam do konca zalet programowania obiektowego i jakos nie potrafie sie do tego przekonac jak widze czas generowania strony - narazie nie odpowiada mi wspolczynnik predkosci do zalet (moze dlatego, ze do konca ich nie znam).
A ja, tak może nieco OT, powiem, ze nie rozumiem ludzi, którzy zarzekają się, ze nie będą pisać w OOP, ponieważ jest to 'wolne'.
Na poparcie swojego stwierdzenia przytoczę przykład konkursu programistycznego z przed jakiegoś roku, polegającego na napisaniu jakiegoś złozonego algorytmu operującego na kartach do gry w php.
Ocenie podlegało to, by skrypt a) robił to co ma zrobić

działał jak najszybciej.
Zadanie spotkało się ze sporym odzewem, tym bardziej, że nagroda była całkiem ciekawa (chyba Zend Studio i jakieś spore konto www)
Pojawilo się wiec bardzo dużo rozwiazań.
Ludzie też bardzo poważnie potraktowali zagadniania przyśpieszania skryptó. Widziałem nawet kod, który był napisany bez żadnych dodaktowych spacji, oraz znaków nowych lini, aby.. działał jak najszybciej.
Co ciekawe jednak - wygrał skrytp napisany supełnie inaczej.
Był to zresztą chyba kod chłopaka z Polski, kod napisany w pełni w oparciu o OOP, wraz z dokładnymi komentarzami oraz pięknie sformatowanym kodem.
A żeby było jeszce śmieszniej - kod ten wykonywał się od 5 do 50 razy szybciej, niż rozwiazania konkurencyjne, napisane oczywiście strukturalnie .
Może jest to nieco skrajny przypadek, ponieważ nie ma wątpliwości, że ten sam agorytm napisany przy wykorzystaniu OOP, i strukturalnie, zawsze będzie minimalnie szybszyw tym 2 przypadku.
Są to jednak na tyle minimalne różnice, że tak naprawdę nie powinno się o nich wspominać.
Czasem co najwyżej pojawia się inny problem. Pisząć obiektowo, znacznie łatwiej zapomnieć o bagarzu kodu, który pociąga uruchomienie naszej aplikacji. W kodzie strukturalnym jesteśmy zmuszeni do ciągłego przglądania kodu, co skłania nas do cpytamalizawania go (choćby dlatego, by mniej go przepisywać

)
Korzystając z przygotowanych wcześniej klas znacznie łatwiej o tym zapomnieć.
Ale w takim przypadku - problem tkwi nie w budowie php, albo w filozofi OOP, a w ... programiście.
Cytat
A ja, tak może nieco OT, powiem, ze nie rozumiem ludzi, którzy zarzekają się, ze nie będą pisać w OOP, ponieważ jest to 'wolne'.
Ja tego nie robie i jestem swiadom, ze to problem mojej osoby

Poprostu za malo znam te technike (nie da sie ukryc, ze dla zaczynajacego jest troche zawila) zeby odrazu pisac na nowo, obiektowo gdy praktycznie zakonczylem prace nad platforma systemu - napisanego strukturalnie oczywiscie.
Zreszta wcale nie przeszkadza to w zrobieniu hybrydy, silnik dziala niezaleznie od modulu zas API moze byc klasa (tego bedzie uzywac programista piszacy modul).
KirkoR
11.04.2004, 14:09:39
Można gdzieś znaleźć na necie do ściągnięcia taki Engine. Tzn. architekturę na któej można opierać swoje apliacjie? Jesli tak to prosze o linki.
marcin96
11.04.2004, 14:44:09
poczytaj sobie o tym:
http://www.php.pl/index.php/phppl/artyku_y...wadzenie_do_mvc
..na końcu Hawk podał kilka różnych frameworków opartych o wzorzec MVC

)
Ja mam pytanie z innej beczki. Mianowicie, czy przechowywanie danych w tablicy zmiennych globalnych $GLOBALS jest dobrym rozwiazaniem ? ma to jakies przeciwskazania ? Przy pisaniu silnika bardzo latwo dodaje moduly, tworze z nich referencje, nie musze miec dodatkowych klas czy funkcji ktore zwracaja mi referencje, tylko odwoluje sie bezposrednio do zmiennych/obiektow/tablic ktore znajduja sie w zbiorze tablic globalnych...
np:
[php:1:6c9a871414]<?php
class silnik
{
function login()
{
if ( $login == $wynik['login'] && $haslo == $wynik['haslo'] )
$GLOBALS['_USER']['login'] = $login;
$GLOBALS['_USER']['access'] = $access;
}
}
?>[/php:1:6c9a871414]
a w innej czesci silnika daje np:
[php:1:6c9a871414]<?php
// ...
if ( $GLOBALS['_USER']['access'] > '2' )
echo 'masz dostep do panelu administracyjnego';
// ...
?>[/php:1:6c9a871414]
co myslicie o takim rozwiazaniu ?
hawk
11.04.2004, 20:31:47
1. Jest nieobiektowe (ale to sam wiesz...)
2. Sypie się, gdy developerów jest więcej, bo jeden nie wie gdzie co wstawił drugi, a obiekt jednak ma swój interfejs i łatwiej jest zorientować się jak się do tego dostać.
3. Może się sypać, gdy nie tylko ty masz taki pomysł, ale też twórca drivera do bazy danych, systemu szablonów, itd. i pechowo 2 ludzi wybierze sobie te same nazwy -> wtedy systemy są całkowicie niekombatybilne.
4. Mało modyfikowalne. Jak już masz to zaimplementowane to zmiana rozwala cały kod. A np. treść metody możesz wymienić, byleby tylko dalej zwracała co trzeba.
5. Mało dokumentowalne. Jak masz metodę getLogin() to dokumentacja tego jest prosta. Ale jak masz tablicę w $GLOBALS, to np. nie ma gdzie podczepić komentarzy phpdoc. A nawet jak już gdzieś się je umieści, to wyjasnienie, co będzie wstawiane w poszczególne pola, wymaga dłuższych elaboratów. A z metodą - proste.
6. Powiązania każdy-każdy. Nie masz pojęcia które pliki/klasy korzystają z których, bo jak coś siedzi w $GLOBALS to każdy kawałek kodu ma do tego dostęp. Łatwość dodawania modułów, o której piszesz, wynika właśnie z tego, że wszystko ma dostęp do wszystkiego. A design obiektowy wymusza zastanowienie się, komu dać dostęp (referencję) do danego obiektu. Jak zrobisz coś podobnego w podanym przykładzie, to wyjdzie z tego chaos.
Czyli ogólnie... nie, nie mam przeciwwskazań jeżeli system jest na tyle mały (w sensie ilości kodu i liczby developerów) że da się tym zarządzać przy użyciu kodu nieobiektowego.
ok to milo, bo w sumie to tylko jedna osoba to pisze -> ja

ale latwo mi jest dojsc do danego obiektu, a tak czy inaczej obiekty sa przypisywane wedlug konkretnych regul, module inaczej, clasy glowne inaczej, wiec z tym problemu nie mam...
jaco
11.04.2004, 23:59:59
Wroce do tematu mojego silnika i jego "obiektowosci" otoz dzis przepisalem prawie caly na OO i bardzo mile sie zaskoczylem (wsumie to moje poczatki z OO i stara zasada nie zrozumiesz jak nie sporobojesz) - poczatkowo cyferki na liczniku generowania pomnozone byly 3-4 razy...
Okazalo sie, ze istota OO pozwala na wyeliminowanie blokow niezbednego kodu strukturalnego i w tym momencie licznik generowania odczuwa zmiane tylko na 3 miejscu po przecinku (wzrost o 0,003-0,006 - wymarzony efekt!!).
Z przykroscia stwierdzam jedynie, ze dziedziczenie jednej klasy przez druga spowalnia caly system okolo dwa razy w prownaniu z dwoma osobnymi obiektami.
jeszcze wroce do wypowiedzi HAWK'a
Cytat
wynika właśnie z tego, że wszystko ma dostęp do wszystkiego. A design obiektowy wymusza zastanowienie się, komu dać dostęp (referencję) do danego obiektu
hm, przyszlo mi na mysl, ze w sumie chyba nie ma sensu branie pod uwage dostepnosci. Przeciez chyba wszystkie zmienne sa dostepne w zmiennej $GLOBALS...
wiec jesli ja tworze sobie w obietk np: silnik, to w GLOBALS bedzie dostep do tej funkcji, ja tak to robie. Wiec czemu ktos kto nie ma dostepu do jednej klasy nie zdobedzie go ? zaden problem napisac
[php:1:634880fed1]<?php
$nowy_obiekt = & $GLOBALS['nazwa_obiektu'];
?>[/php:1:634880fed1]
?
hawk
12.04.2004, 15:08:53
Cytat
jeszcze wroce do wypowiedzi HAWK'a
Nie zrozumieliśmy się. Wstawianie referencji do $GLOBALS ułatwia dostęp do odpowiedniego obiektu. Ułatwia aż za bardzo, tzn. coś się może do niego odwoływać z dowolnego miejsca w dowolnym pliku, i nie masz możliwości wymuszenia jakiegoś ograniczenia. W przypadku czystego OOP, musisz samemu zapodać jakiemuś obiektowi referencję do innego obiektu, aby mógł w ogóle z nim coś zrobić. Więc łatwiej jest kontrolować, gdzie dany obiekt jest używany.
A zalety podejścia obiektowego objawiają się, gdy obiektów jest dużo, kod trzeba modyfikować i nie pamięta się, gdzie dany obiekt był potrzebny. Aplikacje w php raczej nie osiągają setek klas i dziesiątek tysięcy linii kodu, więc można się tym nie przejmować i też działa.
Seth
12.04.2004, 15:11:52
Cytat
jeszcze wroce do wypowiedzi HAWK'a
Cytat
wynika właśnie z tego, że wszystko ma dostęp do wszystkiego. A design obiektowy wymusza zastanowienie się, komu dać dostęp (referencję) do danego obiektu
hm, przyszlo mi na mysl, ze w sumie chyba nie ma sensu branie pod uwage dostepnosci. Przeciez chyba wszystkie zmienne sa dostepne w zmiennej $GLOBALS...
wiec jesli ja tworze sobie w obietk np: silnik, to w GLOBALS bedzie dostep do tej funkcji, ja tak to robie. Wiec czemu ktos kto nie ma dostepu do jednej klasy nie zdobedzie go ? zaden problem napisac
[php:1:5a2c012149]<?php
$nowy_obiekt = & $GLOBALS['nazwa_obiektu'];
?>[/php:1:5a2c012149]
?
W ten spsob nie stworzysz powiazan klas.
Po drugie to nie jest to zgodne z OOP - aby dawac dostep do wszystkich obiektow systemu wszystkim obiektom.
Nie kazdy obiekt powinen ingerowac - miec dostp - np do klasy ustawien, czy parsera konfiguracji.
Dotgo dochodzi bezpieczenstwo oraz wieksze prawdopodobienstwo, ze bedzie gdzies blad... i tak jak wczesniej wspomnial hawk: "Mało modyfikowalne. Jak już masz to zaimplementowane to zmiana rozwala cały kod. A np. treść metody możesz wymienić, byleby tylko dalej zwracała co trzeba."
Takie sa poprostu zasady, ktorych trzeba sie trzymac, aby wykorzystac OOP i nie polpelniac bleddow, ktore pozniej moga byc trudne do wykrycia.
ok, zrozumialem, lecz nadal jest kwestia dostepu, ze zawsze dobiore sie do obiektu poprzez $GLOBALS... czy nie jest tak ?
Seth
12.04.2004, 18:10:03
Tak, ale wlasnie to jest zlym nawykiem i nie trzymaniem sie OOP.
Balin
12.04.2004, 20:30:57
Czy dobrym pomyslem jest wg. was stworzenie klasy jadra, ktora tworzy instancje wszystkich obiektow (singletonow), bibliotek i sprawdza ew. skad zostalo przyslane rzadanie o instancje danego obiektu ? U mnie taka klasa wyglada mniej wiecej tak:
[php:1:8cbc7c0737]<?php
class Kernel
{
static private $arrInstances = array();
static function GetInstance( $strInstanceName = 'Kernel' )
{
if( empty( self::$arrInstances[$strInstanceName] ) )
{
self::$arrInstances[$strInstanceName] = new $strInstanceName;
}
return self::$arrInstances[$strInstanceName];
}
static function CreateDBInstance( $objDBConfig )
{
require_once( 'db_drivers/' . $objDBConfig->GetUsedDB() . '.class.php' );
if( empty( self::$arrInstances['DB'] ) )
{
self::$arrInstances['DB'] = new DB( $objDBConfig->GetHostName(), $objDBConfig->GetUserName(), $objDBConfig->GetPassword(), $objDBConfig->GetDBName() );
}
return self::$arrInstances['DB'];
}
}
?>[/php:1:8cbc7c0737]
i przykladowe uzycie w aplikacji:
[php:1:8cbc7c0737]<?php
class App
{
private $objDB = null;
private $objIO = null;
private $objConfig = null;
private $objSession = null;
private $objTemplate = null;
private $objTimer = null;
private $objPage = null;
function __construct()
{
$this->objTimer = Kernel::GetInstance( 'Timer' );
$this->objTimer->CreateTimer( 'main_timer' );
$this->objDB = Kernel::CreateDBInstance( Kernel::GetInstance( 'DBConfig' ) );
$this->objIO = Kernel::GetInstance( 'IO' );
$this->objConfig = Kernel::GetInstance( 'Config' );
$this->objSession = Kernel::GetInstance( 'Session' );
$this->objTemplate = Kernel::GetInstance( 'Template' );
$this->objPage = Kernel::GetInstance( 'Page' );
}
}
?>[/php:1:8cbc7c0737]
moze lepiej byloby to rozwiazac inaczej ? Czy w ogole warto tworzyc osobna klase reprezentujaca jadro systemu, czy moze umieszczac wszystko bezposrednio w kodzie aplikacji ?
Ozzy
12.04.2004, 22:27:04
U mnie jak na razie (a pewnie zmieni się 100 razy) wygląda to tak:
Użycie:
[php:1:650229d311]<?php
@require 'Main.php';
Main::set('Controller', new Controller);
?>[/php:1:650229d311]
Klasa Main:
[php:1:650229d311]<?php
final class Main {
private static $references = array();
public static function set($className, $reference) {
self::$references[$className] = $reference;
}
public static function get($className) {
if(array_key_exists($className, self::$references)) {
return self::$references[$className];
}
}
public static function load($name, $notClass = false, $notReport = false) {
[ciach]
}
}
function __autoload($className) {
Main::load($className);
}
?>[/php:1:650229d311]
Klasa Controller:
[php:1:650229d311]<?php
final class Controller {
public function __construct() {
Main::load('functions/main', true);
Main::load('functions/page', true);
Main::set('Page', new Template('Main'));
Main::set('ErrorHandler', new ErrorHandler);
Main::set('Client', new Client);
$cfg = new Cfg('db');
Main::set('SQL',
new mysqli(
$cfg->get('host'),
$cfg->get('user'),
$cfg->getDecoded('pass'),
$cfg->get('db')
)
);
Main::set('SessionHandler', new SessionHandler);
Main::set('Rewrite', new Rewrite('sdd'));
Main::get('Rewrite')->set(0, 'home');
Main::get('Rewrite')->set(1, 0);
Main::get('Rewrite')->set(2, 0);
}
}
?>[/php:1:650229d311]
Główna różnica w porównianiu z Twoją (Balin) klasą polega na tym, że obiekty można konstruować z parametrami (czasem się przydaje).
Nie tak dawno używałem czegoś podobnego do Twojego, jednak uznałem, że obecne rozwiązanie ma więcej zalet.
Można na przykład przechowywać dowolną ilość instancji tej samej klasy pod innymi nazwami.
Napisz co o tym myślisz.
Balin
13.04.2004, 00:20:10
Rozwiazanie ciekawe, ale wg mnie troche niebezpieczne - kozystajac z metody, ktora zastosowales tracisz kontrole nad tym ile egzemplarzy obiektow zostalo utworzonych, ja wykorzystuje jadro tylko do tworzenia singletonow, wiec nie potrzebuje mozlwosci tworzenia kilku egzemplarzy jednej klasy, planuje zaimplamentowac u siebie mechanizm, ktory bedzie sprawdzal skad nastapilo rzadanie przekazania referencji do obiektu i na tej podstawie ocenial czy dany modul ma uprawnienia aby otrzymac taka referencje.
Chce sie jednak wczesniej dowiedziec czy takie rozwiazanie ma sens w duzym, elastycznym projekcie nastawionym na rozwoj ?
Ozzy
13.04.2004, 08:54:03
Cytat
wg mnie troche niebezpieczne
Tak jak mówie, zmieni się jeszcze 100 razy, bo na razie tak jak Ty szukam jakiegoś rozsądnego rozwiązania.
Update: Korzystając z okazji, ile wykonuje Ci się ten kod? (z wszystkimi klasami) i do czego służy klasa IO?
hawk
13.04.2004, 10:01:45
Cytat
Czy dobrym pomyslem jest wg. was stworzenie klasy jadra, ktora tworzy instancje wszystkich obiektow (singletonow), bibliotek i sprawdza ew. skad zostalo przyslane rzadanie o instancje danego obiektu ?
Po pierwsze, instancji singletona nie da się stworzyć z zewnątrz. Singleton sam tworzy sobie instancję kiedy jest mu potrzebna. Na tym właśnie polega singleton i twój kod - mówiąc wprost - nie ma z nim nic wspólnego.
Po drugie, jak chcesz sprawdzić, "skąd przyszło żądanie"?
(btw: żądanie, nie rządanie
) Takie coś potrafi natywnie zrobić tylko error handler, ew. debug_backtrace(), ale nie sądzę, aby o to chodziło.
Po trzecie, samo w sobie takie sprawdzanie jest złe. Bo wprowadzasz dodatkową warstwę - jakieś ograniczenia i zasady, których nie widać na diagramie klas i w ogóle nie wiadomo do czego przynależą. Wzrost chaosu. A to (brak kontroli) wcale nie jest wielkim zagrożeniem. Bo w dobrym systemie i tak nie można nic zepsuć - masz metodę getX(), ale nie masz setX() i nie zepsujesz obiektu. A poza tym takie zepsucie jest działaniem świadomym. Jeżeli założymy, że programista nie chce sam rozwalić sobie kodu, to nie jest to potrzebne. Wiesz, że dany moduł nie potrzebuje bazy danych - nie używasz, bo po co?
Po czwarte, po co ci obiekt którego jedynym zadaniem jest tworzenie innych obiektów? Jeżeli nie wnosi nic dodatkowego, to singletony załatwiają sprawę i są prostsze. Chyba że wnosi on dodatkową "inteligencję".
Po piąte, bardzo się cieszę że widzę wreszcie kod w PHP5, a nie tylko ciągle stary paskudny PHP4

.
e-Gandalf
13.04.2004, 18:49:51
Ja sie ostatnio sklaniam ku pelnej modularyzacji z trzema centralnymi interfejsami.
1) Input
2) Output
3) Processing
I tak, modul jadra po uruchomieniu na podstawie danych srodowiskowych (ustawienia systemu+argumenty) decyduje o zwracanym pakiecie danych (szablony danych w xml) i zwracanym formacie danych (html,xhtml,wap, sidebar, rss). Nastepnie sprawdza czy posiada "swierzy" cache z takim outputem, jesli tak, uzywa go, jesli nie wybiera format danych wejsciowych (input - baza danych, rdf, xml, remote xml), uruchamia klase dziedziacza interfejs Processing odpowiedzialna za dany szablon, ktora zwraca xml, ktory po sprawdzeniu na zgodnosc z DTD parsowany jest klasa dzidziczaca po interfejsie Output (np XHTMLOutput albo WAPOutput) korzystajaca z transformantow xsl. Wynik jest cachowany i wypluwany.
Generalnie przy budowie mocno wzorowalem sie na Gecko przy takich sprawach jak podzial na Serwisy i Interfejsy (serwis to klasa nie posiadajaca instancji - jak np. output), i staralem sie wprowadzic maksymalna ilosc kontroli przy uzyciu specjalizowanych XMLi w transporcie danych miedzy modulami. Mam swiadomosc narzutow czasowych, ale rekompensowane jest to przez cache.
Mam nadzieje, ze choc troche zrozumiale to brzmi

To moja pierwsza proba z xml->xslt jako generatorem wyjscia, ale dziala to to ladnie i nawet szybko
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.