Idzie nowe…

kwiecień 1st, 2007

Ponieważ wczoraj ostatecznie rozstałem się ze swoim dotychczasowym pracodawcą, postanowiłem iść za ciosem i dokonać w swoim życiu jeszcze większych zmian in plus. Rezygnuję z pracy związanej z internetem gdyż jest on zupełnie pozbawiony przyszłości i nie daje sensownych perspektyw rozwoju. Z tym niszowym (i ciągle tracącym na popularności) medium nie można wiązać żadnych nadziei.

Dlatego właśnie zmieniam branżę na garmażerię. W naszym pędzącym świecie, w którym ludzie mają coraz mniej czasu nie tylko na odpoczynek ale także na przygotowanie zdrowych i pożywnych a zarazem smacznych i regenerujących posiłków, tylko przemysł garmażeryjny daje jakiekolwiek nadzieje na rozwój zawodowy.

Jedną z konsekwencji mojej decyzji, będzie oczywiście zmiana tematyki tego bloga. Już teraz mogę zdradzić tematy przyszłych wpisów:

  • Naleśniki - optymalizacja procesu smażenia
  • Kopytka - bezpieczeństwo gotującego
  • Klient - kuchnia - zarządzanie relacjami
  • Jaja na miękko - wydajniejsza kontrola czasu gotowania
  • Pierogi - optymalizacja struktury farszu
  • Patelnia przemysłowa - przykładowa konfiguracja
  • Kelnerzy i dostawcy - zasadność użycia proxy

Smacznego!

Wydajniejsza kontrola dostępu do plików - virtual()

luty 23rd, 2007

Problem

Bardzo często istnieje potrzeba zrealizowania zaawansowanej kontroli dostępu do plików, przy czym standardowe mechanizmy Apache nie wystarczają. Dzieje się tak, gdy decyzja o tym, czy plik należy udostępnić jest podejmowana przez aplikację na podstawie informacji niedostępnych dla serwera (np. stan punktowy konta użytkownika lub inne warunki wynikające z logiki aplikacji).

Szybkie rozwiązanie

Pierwszym rozwiązaniem, które przychodzi na myśl, jest użycie PHP i funkcji operujących na plikach - np. file_get_contents():


<?php
if(allowFileDownload($sFile)){
echo file_get_contents($sFile);
}else{
echo '403';
}
?>

W tym rozwiązaniu, za podjęcie decyzji, czy użytkownik ma prawo pobrać plik, odpowiada funkcja allowFileDownload(). Całość jest oczywista - jeżeli funkcja zwróci true, wysyłamy do przeglądarki zawartość pliku.

Większość z was zauważy pewnie, że powyższy przykład jest cokolwiek niekompletny. Należałoby uzupełnić go o wysyłanie nagłówków HTTP - przedewszystkim Content-type oraz Content-length. Wpis ten ma jednak traktować o czym innym, dlatego pominąłem wszystko co nie jest niezbędne. Kompletne podejście do udostępniania plików z wykorzystaniem PHP jest tematem na oddzielny wpis.

Szybsze rozwiązanie

PHP działające jako moduł Apache udostępnia funkcję virtual(). Funkcja ta wykonuje wewnętrzne żądanie Apache i przekazuje na wyjście jego wynik. Po zmodyfikowaniu powyższego przykładu, uzyskamy:


<?php
if(allowFileDownload($sFile)){
virutal($sFile);
}else{
echo '403';
}
?>

Co zyskujemy?

Przedewszystkim zyskujemy na wydajności, przy wysyłaniu większych plików. Aby porównać wydajność obu rozwiązań, wykorzystałem program ab.exe, o którym pisałem wcześniej. Podczas wykonywania testów, ustawiłem paramety programu na: ilość żądań - 100, równoległość żądań - 3. Testy przeprowadziłem dla 3 plików o różnej wielkości. Oto wyniki:

Rozmiar pliku file_get_contents() virtual()
650 b 88 ms 102 ms
1.15 mb 1241,99 532,97
1.80 mb 1789,07 ms 781,72 ms

Tabela zawiera średnie czasy odpowiedzi serwera. Jak widać, dla większych plików wydajność virtual() jest znacznie większa niż file_get_contents().

Zyskujemy także elastyczność i możliwość wykorzystywania wielu języków server-side w aplikacji. Jak? Należy pamiętać, że żądanie wykonane przez virtual() jest obsługiwane przez Apache. Jeżeli żądanie odnosi się do pliku CGI, to zostanie on wykonany. Dzięki temu możemy włączyć do strony, wynik działania np. skryptu Perla.

Co tracimy?

Przedewszystkim przenośność kodu. Funkcja virtual() jest dostępna tylko, gdy PHP działa jako moduł Apache lub jako moduł NSAPI w serwerach Netscape, iPlanet, SunONE. Odpadają więc wszystkie inne serwery oraz serwery gdzie PHP działa za pośrednictwem CGI.

Ponieważ pliki są udostępnione przez wywołanie żądania Apache, nie można przenieść ich poza drzewo dokumentów serwera. Dochodzi więc konieczność zabezpieczenia katalogu z chronionymi plikami przed dostępem z zewnątrz w taki sposób, aby jednak możnabyło wywołać żądanie z poziomu PHP. W manualu znalazłem rozwiązanie, polegające na odmowie dostępu do katalogu, z wyjątkiem tych żądań, które mają ustawioną zmienną PHP_ALLOW:


<directory katalog_z_plikami>
Order Allow,Deny
Allow from env=PHP_ALLOW
</directory>

W skrypcie PHP, przed wywołaniem funkcji virtual(), ustawiamy zmienną:

<?php
if(allowFileDownload($sFile)){
apache_setenv('PHP_ALLOW', '1');
virutal($sFile);
}else{
echo '403';
}
?>

O aspektach wykorzystania funkcji virtual() możnaby jeszcze conieco napisać, ale jestem pewien, że sięgniesz do manuala. Liczę na to, że wyniki wydajności, które przedstawiłem skłonią Cię do własnych testów. Jeżeli już je wykonasz, mam nadzieję, że się nimi podzielisz. Czekam zresztą na wszystkie uwagi, a nie tylko te, dotyczące wydajności.

Nadszedł 2007 rok

styczeń 1st, 2007

Oby Nam się!

Nareszcie: czyżby TODO idealne?

grudzień 3rd, 2006

TODO: znaleźć TODO

Od bardzo długiego czasu, poszukiwałem programu, który pomógłby mi zarządzać listą zadań do zrobienia - TODO. Zainstalowałem wiele programów dla Windows, oraz systemów stworzonych w PHP i opartych o MySQL. Niestety, żaden z nich nie spełnił moich wymagań. Jak się okazało, autorzy popadali z jednej skrajności w drugą. Programy były albo bardzo ubogie, oferując jedynie możliwość tworzenia prostego spisu zadań, albo były bardzo rozbudowane. Przy czym wadą tych rozbudowanych było to, że wymagały od użytkownika podawania wszystkich istnejących parametrów zadań.

Jednym z bardziej złożonych systemów, był Eventum, udostępniony przez MySQL AB. Jego rozbudowane opcje budziły szacunek, niestety, aby rozpocząć używanie systemu, należało skonfigurować bardzo dużo parametrów - projekty, uczestnicy, klienci, statusy, priorytety itp. Skończyłem używać ten system zanim jeszcze tak naprawde zacząłem.

DONE: znaleźć TODO

W końcu, dzięki - o ile dobrze pamiętam - serwisowi dzone.com - znalazłem program, który ma szansę zostać moim TODO idealnym. Jest to ToDoList (obecnie w wersji 5.0.1) udostępniony przez AbstractSpoon Software.

ToDoList

Główne okno programu zawiera:

Todo - okno główne

  • listę zadań w postaci drzewa
  • panel z parametrami aktualnie wybranej pozycji
  • pole komentarza (RTF)
  • panel wyszukiwania

Dla każdego z zadań, można zdefiniować parametry:

  • priorytet (0-10)
  • ryzyko (0-10)
  • procent wykonania
  • przewidywany czas potrzebny na wykonanie
  • rzeczywisty czas poświęcony na wykonanie
  • datę rozpoczęcia pracy
  • datę rzeczywistego zakończenia pracy
  • termin wykonania
  • osobę, której przypisano zadanie
  • osobę, ktora przypisała zadanie
  • status (dowolnie definiowana lista)
  • kategoria (dowolnie definiowana lista)
  • zewnętrzne ID
  • koszt
  • zależność od innego zadania
  • kolor
  • komentarz

Dodatkowo, każde z zadań można oznaczyć flagą, oraz przypisać do niego plik.
Bardzo ważną zaletą programu jest to, że wszystkie parametry zadania są opcjonalne. Dzięki temu o wiele łatwiej można dostosować program do własnych potrzeb. Jeżeli nie mamy w zwyczaju określania terminu wykonania zadania - to go nie musimy definiować. Co nie oznacza, że gdy przyjdzie taka potrzeba, nie będziemy mogli tego zrobić.

Wszystkie parametry zadania definiujemy w panelu znajdującym się pod listą:
szczegóły zadania

Zadania można organizować w hierarchiczne drzewo z wieloma poziomami zagłębienia.
lista zadań
Zaznaczenie nadrzędnego zadania jako wykonanego, może powodować zaznaczenie poniższych zadań jako wykonane. Zadania można przemieszczać na liście względem innych, używając klawiszy kursora z wciśniętym klawiszem Control.

Kilka parametrów zadań zasługuje na dodatkowe kilka zdań:

priorytet
każdemu priorytetowi można przypisać kolor, lub wszystkim można przypisać kolejne etapy przejścia tonalnego między dwoma kolorami. Dodtakowo, zadanie nadrzędne może automatycznie otrzymać najwyższy priorytet zadań podrzędnych (można wykluczyć priorytet zadań wykonanych)
procent wykonania
ten parametr można oznaczać ręcznie, może on być też wyliczony na podstawie wykonania zadań podrzędnych. Podstawą obliczeń może być albo ilość zadań wykonanych/niewykonanych lub czas potrzebny i poświęcony na ich wykonanie.
rzeczywisty czas poświęcony na wykonanie
może być wyrażony w kilku jednostkach (minuty, godziny, dni, tygodnie, miesiące, lata). Dodatkowo program umożliwia automatyczne mierzenie czasu poświęconego na zadanie (pomiar jest wstrzymywany na czas działania wygaszacza ekranu).
status/kategoria
można przypisać dowolny status/kategorię. Wcześniej wprowadzone wartości tworzą listę, z której można szybko wybrać status/kategorię.
zależność
można zdefiniować ID zadania, które musi być wykonane przed wybranym zadaniem. Jeżeli spróbujemy oznaczyć zadanie zależne jako wykonane, a zadanie nadrzędne nie będzie wykonane, zostanie wyświetlone ostrzeżenie.
komentarz
jest edytowany w polu RTF, pozwalającym na formatowanie tekstu, a także na wstawianie odnośników do innych zadań, w postaci tdl://xxx gdzie xxx jest identyfikatorem zadania. Odnośnik może prowadzić także do zadań zdefiniowanych w innych plikach. Pole komentarza wygląda tak:
komentarze
Praca zespołowa

ToDoList umożliwia także współdzielenie pliku przez kilka osób. Wystarczy plik z listą zadań umieścić na dysku sieciowym. Aby wykluczyć konflikty w trakcie edycji, przed edycją pliku, należy wcześniej zablokować możliwość edycji innym użytkownikom:
Tryb blokowania
Wcześniej w opcjach trzeba włączyć opcję “Enable simple source control“. Pracę kilku osób ułatwiają dodatkowe opcje:

  • automatyczne ponawianie próby zablokowania pliku do edycji, w przypadku gdy edycję zablokował inny użytkownik
  • automatyczne odblokowywanie edycji przy zamykaniu listy
  • odblokowywanie listy, gdy nie dokonano zmian przez ustalony czas
  • automatyczne sprawdzanie statusu listy co ustalony czas i automatyczne wczytywanie aktualnego pliku
Dodatkowe opcje

W ustawieniach można zdefiniować globalny skrót klawiaturowy przywołujący i minimalizujący program, który może minimalizować się do ikony systemowej. Dzięki temu łatwo operuje się programem, który czekając w gotowości, nie rozprasza uwagi, nie zabiera miejsca na pasku systemowym, i co ważniejsze - na liście okien (Alt-Tab).

Warto także wspomnieć o tym, że:

  • istnieje możliwości eksportu/importu list zadań (HTML, MLO, Outline, GanttProject, iCalendar, …)
  • istnieje możliwości dodawania pluginów i narzędzi zewnętrznych (tu można wykorzystać parametr external ID)
  • lista jest przechowywana jako plik XML, można więc z łatwością stworzyć własne narzędzie potrafiące odczytywać plik
  • można w samym programie przetwarzać listę przy użyciu szablonu XSLT

To jest tylko pobieżne przedstawienie programu ToDoList. Zainstalowałem naprawdę sporo programów tego typu, ten jednak wydał mi się najlepszy z dotąd testowanych i godny polecenia. Nie twierdzę jednak, że jest najlepszy ze wszystkich istniejących. Dlatego właśnie chciałbym dowiedzieć się, czego używacie jako menadżera zadań? Co lubicie w tych programach, a co was drażni? Jakie macie wymagania względem takich programów? A może macie jakieś własne rozwiązania?

Zapraszam na moje aukcje allegro

listopad 16th, 2006

Zapraszam wszystkich na moje aukcje Allegro - obecnie oferuję dwa kupony wartościowe vision express o wartości 100 i 200 zł. Szczegóły - http://allegro.netcoffee.pl

październik 9th, 2006

” Wciąż niepewni siebie
siebie niewiadomi
pytać wciąż będziemy
pytać po kryjomu ”

Dzisiaj zmarł wspaniały artysta - Marek Grechuta.

Launchy - szybkie uruchamianie

wrzesień 18th, 2006

Launchy, od kiedy zainstalowałem go pierwszy raz, stał się narzędziem, bez któego trudno mi jest się obejść. Dzięki temu małemu programowi zapomnisz o menu start i skrótach porozrzucanych po pulpicie i na pasku zadań.

Po zainstalowaniu programu, działa on w tle. Po wciśnięciu skrótu ALT + SPACJA (skrót można zmienić), na ekranie pojawia się przyjemne w wyglądzie okienko programu:

Launchy - okno programu

Po pojawieniu się okienka możemy zacząć wpisywać nazwę programu lub pliku, który chcemy otworzyć. Domyślnie Launchy indeksuje Menu Start. Gdy wpisywany tekst będzie pasował do nazwy przynajmniej jednego zindeksowanego pliku, Launchy wyświetli propozycje na rozwijalnej liście, z której można wybrać program/plik który chcemy uruchomić/otworzyć.

Konfigurując program, możemy zdefiniować, które katalogi i pliki z jakimi rozszerzeniami należy indeksować. Dzięki temu możemy uruchamiać nie tylko wszystkie programy, ale także np. pliki MP3 w domyślnym programie.

Samo dopasowywanie wpisanej nazwy do nazw w indeksie jest bardzo dopracowane i elastyczne. Dzięki temu możemy wpisać tylko fragment nazwy pliku/programu. Co więcej Launchy jest odporny na literówki i łatwo domyśla się, jaki program chcemy uruchomić.

Naprawdę polecam!

mod_security: testowanie konfiguracji

sierpień 2nd, 2006

mod_security to moduł serwera Apache będący systemem wykrywania włamań. mod_security analizuje przychodzące dane (metody GET i POST a także cookies) a także dane odsyłane do klienta. Po wykryciu zdefiniowanych w konfiguracji fraz (np. zapytań sql, kodu html, kodu javascript), mod_security wykonuje jedną ze zdefiniowanych akcji. Może to być np. wysłanie do klienta kodu błędu, przekierowanie klienta, wstrzymanie odpowiedzi na ustaloną ilość milisekund (przydatne w walce z botami) lub zablokowanie rządania. Tyle tytułem wstępu.

Sam moduł może być dla aplikacji którą chroni tyle zbawienny, co niebezpieczny. Zastosowanie zbyt restrykcyjnych reguł filtrowania może doprowadzić aplikację do stanu nieużywalności. Dlatego warto już na etapie tworzenia aplikacji skonfigurować moduł i testować konfigurację, na samym początku jako akcje podejmowane po wykryciu potencjalnie niebezpiecznych danych ustawić jedynie logowanie zdarzeń. W trakcie pracy można przeglądać logi serwera i korygować ustawienia mod_security lub zmieniać działanie aplikacji.

Innym, wygodniejszym sposobem wykrywania konfiliktów między konfiguracją mod_security a wymaganiami aplikacji (np. gdy w systemie CMS edytujemy kod html strony, mod_security nie powinien podejmować żadnych działań), jest poniższy kod PHP wklejony w sekcji BODY dokumentu HTML:

<?php
if(isset($_SERVER['HTTP_MOD_SECURITY_MESSAGE'])
		and $_SERVER['REMOTE_ADDR'] == '192.168.0.32'){?>
	<img style='position: fixed; top: 10px; right: 10px;'
		src='style/error.png'
		alt=''
		title='<?php echo htmlspecialchars(stripslashes($_SERVER['HTTP_MOD_SECURITY_MESSAGE'])) ?>'
	/>
<?php } ?>

Rozwiązanie to bazuje na tym, że po wykryciu potencjalnie niebezpiecznych danych, mod_security ustawia zmienną systemową, której zawartość możemy odczytać w zmiennej $_SERVER['HTTP_MOD_SECURITY_MESSAGE']. W warunku sprawdzamy, czy ta zmienna jest ustawiona i czy rządanie nadeszło z komputera admina (ten warunek możemy oczywiście dostosować do naszych wymagań i sprawdzać np. czy zalogowany jest administrator itp). Jeżeli tak, do strony dodajemy mały obrazek, który prawdziwe przeglądarki wyświetlą zawsze w górnym prawym rogu. Jako tytuł obrazka wstawiona jest treść błędu zgłoszonego przez mod_security.

Dzięki takiemu rozwiązaniu, już podczas tworzenia, testowania lub w trakcie normalnej, codziennej pracy z aplikacją, na bieżąco będziemy wiedzieli, czy wprowadzone dane spowodują błąd zabezpieczeń.

Oczywiście to proste rozwiązanie jedynie ułatwi testowanie aplikacji - nadal konieczne będzie sprawdzanie logów serwera.

Polecam uwadze

Zarządanie relacjami w phpMyAdmin

kwiecień 17th, 2006

Jedną z mniej znanych funkcji phpMyAdmin jest zarządzanie relacjami w bazie danych. Na małą popularność tej opcji wpływa konieczność przeprowadzenia dodaktowej konfiguracji aby była ona widoczna.

phpMyAdmin informacje o relacjach między tabelami przechowuje w tabelach w zdefiniowanej bazie danych. Dlatego najlepiej jest utworzyć oddzielną bazę danych, tylko na potrzeby phpMyAdmin. Domyślna nazwa bazy to phpmyadmin.

Aby utworzyć tabele niezbędne do dzialania zaawansowanych funkcji phpMyAdmin, wystarczy uruchomić instrukcje SQL znajdujące się w pliku scripts/create_tables.sql w archiwum z phpMyAdmin. Skrypt ten zakłada, że istnieje użytkownik pma, z poziomu którego będzie odbywało się zarządanie danymi.

Skrypt:

  • usuwa bazę phpmyadmin (jeżeli istnieje)
  • zakłada ją ponownie
  • nadaje prawa do wykonywania SELECT, INSERT, UPDATE i DELETE użytkownikowi pma w bazie phpmyadmin
  • tworzy potrzebne tabele

Kolejnym krokiem jest uaktualnienie pliku config.inc.php. Dla każdego z używanych serwerów, należy podać wartość zmiennych:

# nazwa bazy danych phpMyAdmin
$cfg['Servers'][$i]['pmadb'] = 'phpmyadmin';

# nazwa tabeli z opisem relacji
$cfg['Servers'][$i]['relation'] = 'pma_relation';

Po przeprowadzeniu tych operacji, w interfejsie phpMyAdmin zobaczymy nową opcję: Widok relacyjny w widoku struktury tabeli: Nowa opcja: widok relacyjny

Po wybraniu opcji “Widok relacyjny” otrzymujemy dostęp do formularza, w którym możemy zdefiniować relacje między tabelami:
Definiowanie relacji między tabelami

Dla każdego pola tabeli, możemy zdefiniować, któremu polu w innej tabeli odpowiada. Robimy to wybierając odpowiednie pole z listy rozwijalnej. Dodatkowo, dla każdej tabeli możemy wybrać, zawartość którego pola będzie pokazywana jako etykieta rekordu.

Dla przykładu rozważmy takie dwie tabele, zawierające dane menedżera projektów.

Tabela project

  • id - int(10)
  • name - char(100)

Tabela item

  • id - int(10)
  • project_id - int(10)
  • name - char(100)

W tabeli ‘project’ przechowujemy nazwy projektów, w tabeli ‘item’ - nazwy poszczególnych elementów projektów. Każdy ‘item’ ma przypisany także id projektu, do którego należy. Po wejściu do widoku relacyjnego tabeli ‘item’, dla pola ‘project_id’ należy wybrać pozycję ‘project -> id’ (co oznacza pole ‘id’ w tabeli ‘project’).

W widoku relacyjnym tabeli ‘project’ wybieramy wyświetlane pole: ‘name’.

Dzięki temu, podczas edycji rekordu z tabeli ‘item’, zamiast pola tekstowego, dla ‘id’ zobaczymy listę rozwijalną, z której będzie można wybrać odpowiedni projekt:
Formularz edycji danych

W widoku tabeli danych, zawartość pól w kolumnie ‘project_id’ będzie odnośnikiem:
Widok tabeli danych
Po jego kliknięciu zobaczymy szczegóły odpowiedniego projektu.

W oparach absurdu: Forum znoszące złote posty

kwiecień 6th, 2006

Z reguły staram się unikać na tym forum tematów polityczno-aferalno-obyczajowych. Niestety, nie zawsze jestem w stanie przejść obojętnie obok tego, co się w naszym kraju dzieje.

Wczoraj, 5 kwietnia 2006r. Polska Agencja Prasowa poinformowała o uruchomieniu Internetowego forum dyskusyjnego poświęconego sprawom Pomorza.

Co zobaczymy po wizycie na ForumPomorze.pl? Niewiele. Stronę “wejściową” z odnośnikami do informacji o inicjatywie, odnośnikami do poszczególnych for i formularz rejestracji. Oprawa graficzna strony nie powala na kolana. Więcej. Zaryzykuję stwierdzenie, że oprawa graficzna tej strony nie istnieje. Pseudokod HTML zaprezentowany na stronie jest najeżony błędami. Podstrona zawierająca dwa loga, napis “Współpraca:” oraz odnośnik “Wstecz”, zawiera 9 błędów składniowych. O semantyce kodu lepiej nie wspominać.

Całe forum oparte jest na darmowym skrypcie phpBB, który wg. opisu w stopce, urósł do technologii (”Oparte na technologii phpBB © 2001, 2005 phpBB Group”).

Dlaczego więc wspominam o kiepskiej stronie internetowej z forum, jakich są miliony w Internecie? O stronie, której koszt przygotowania (”grafika”, strona główna, przygotowanie tekstów, instalacja darmowego skryptu) nie może przekroczyć 2000zł. O stronie, której przygotowanie zajęłoby przeciętnemu webmasterowi maksymalnie tydzień. Dlaczego warto o niej pisać?

Odpowiedź jeży włos na głowie. Dlatego, że Uruchomienie projektu Forum Pomorze kosztowało 75 tys. euro. (za PAP). Przeliczając tę kwotę na złotówki wg. dzisiejszych średnich kursów NBP podanych przez serwis waluty.onet.pl (3,98 zł za 1 euro), otrzymamy absurdalny koszt instalacji forum phpBB wynoszący 298 500zł. 75% tej kwoty wyłożył budżet państwa oraz Unia Europejska. Pozostałą część - miasto Gdańsk, Międzynarodowe Targi Gdańskie oraz Instytut Badań nad Gospodarką Rynkową.

Czy bez mała 300 tysięcy złotych za samo uruchomienie forum internetowego to dużo? Policzmy.

Koszty uruchomienia i utrzymania forum
usługa koszt brutto
Razem 62500zł
niewielka strona internetowa - wizytówka 500zł
instalacja phpBB* 180zł
serwer dedykowany** 8700zł
obsługa forum*** 53000zł
domena **** 120zł

Objaśnienia

* instalacja phpBB
koszt 3 godzin pracy administratora pracującego w jednej z polskich firm hostingowych
** serwer dedykowany
koszt rocznego utrzymania serwera dedykowanego w jednej z najbardziej znanych polskich firm hostingowych
*** obsługa forum
roczne pensje dwóch pracowników - administratorów forum (2200 zł brutto miesięcznie)
**** domena
roczny koszt utrzymania domeny .pl

Wiele osób zarzuci mi (zapewnie słusznie) wielkie nadużycie, które popełniłem podczas wyliczania kosztów. Wiem, że instalacja phpBB nie zajmuje więcej niż 30 minut. Zdaję sobie sprawę z tego, że stworzenie strony podobnej do strony głównej z forum, nie jest warte 500zł. Wiem też, że serwer dedykowany obsługujący zwykłe forum można zastąpić o wiele tańszą usługą serwera wirtualnego.

Cenniki usług są jednak bardzo rozpięte. Chciałem jednak, aby wszystkie wątpliwości były rozsztrzygane na korzyść tych, którzy wydali 300 tysięcy złotych na coś, co jest warte sto razy mniej.

Z moich wyliczeń wynika, że koszt uruchomienia i rocznego utrzymania forum podobnego do ForumPomorze.pl (wliczając w to hosting i pensje dwóch osób), jest niemal pięciokrotnie niższy niż nasze państwo wydało tylko na uruchomie forum.


statystyki