Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP] Jak programować
Forum PHP.pl > Forum > Przedszkole
Jo-Jo
Zabrałem się za prace Inżynierską (specjalistyczny CMS)
Zacznę od tego ze moja znajomość PHP pozwala żeby go napisać
Pytanie brzmi czy moje rozwiązanie jest tym najlepszym

Parę pytań na początek:

(chodzi o wprowadzanie danych w Panelu Admina)
Walidacja formularzy
Czy sprawdzać każdą zmienną przez preg_match?
a może warto robić to w Java Script?
lub wystarczy za pomocą PDO chronić się przed sql injection, a co wprowadzi użytkownik w danym polu jest nie ważne?
a może inna metoda?

Sephirus
Cytat
Czy sprawdzać każdą zmienną przez preg_match?


NIE. A po co? Do tego podchodzi się inaczej. Pamiętaj, że najlepsza możliwa walidacja jest wówczas gdy dokładnie wiemy czego się mamy spodziewać. Jeżeli przykładowo ma to być liczba - to preg_match jest zbędny. Staraj się "przewidywać" i planować to co użytkownik może wprowadzić - w przypadku takich rzeczy jak na przykład imię, które nie jest może tak istotne można sobie walidacje nieco uprościć ale i tak musisz zabezpieczać się przed XSS czyli eliminować wpisy zawierające podejrzane znaki - nikt przecież nie ma w imieniu znaku > ani < itd.. Tutaj przyda się preg_match.

Cytat
a może warto robić to w Java Script?


Walidacja musi być po stronie serwera przed podaniem jej do bazy (zakładając, że używasz PDO w taki sposób by eliminować SQL-inj.). Dodanie walidacji po stronie klienta czyli javascript zależy od chęci i czasu nad projektem - należy też pamiętać, że walidacja JS musi być taka sama jak walidacja PHP i zmiana w jednej musi ciągnąć za sobą zmianę w drugiej. Jest to ogólnie zabieg pomagający użytkownikowi. Jeżeli nie chcesz robić pełnej walidacji JS to zrób przynajmniej sprawdzanie czy są wypełnione wymagane pola przed wysłaniem tego do PHP.

Cytat
lub wystarczy za pomocą PDO chronić się przed sql injection, a co wprowadzi użytkownik w danym polu jest nie ważne?


To podejście jest strasznie nie zdrowe - bardzo szybko okazuje się, że ludzie wpisują rozmaite głupoty a silnik MySQL przykładowo pozwala na wprowadzanie dziwnych danych innego typu pod dany typ bez wyrzucania błędów zatem zapisują się jeszcze większe idiotyzmy nie wspominając o XSS itp... Nie myśl sobie że jeśli robisz panel administracyjny dla "zaufanych" użytkowników, którzy raczej nie będą chcieli sobie samemu zrobić krzywdę, to możesz odpuścić bezpieczeństwo (nikt przecież nie będzie próbował zrobić sql-injection w panelu admina...). Jeśli ktoś niechcący dostanie się do takiego panelu to ma otwartą drogę - PA powinien zatem być porządnie zabezpieczony.

Co do innych metod poszukaj info o
filter_var
czy
validate filters

Walidację można wykonywać na wieeeele sposobów:

  1.  
  2. $liczba = '12345';
  3.  
  4. if(is_numeric($liczba)) // ...
  5.  
  6. if(preg_match('/^\d+$/',$liczba)); // ... totalna bzdura - ale można
  7.  
  8. if($liczba == (int) $liczba)) // ...
  9.  
  10. // itd...
  11.  
wNogachSpisz
Wyrażenia regularne trzeba jeszcze potrafić pisać.
Na krótkim stringu, błędnie napisane wyrażenie prześlizgnie się niezauważone.
Na długim stringu zawiesi system.

Kilka przykładów:
http://blogs.msdn.com/b/bclteam/archive/20.../10/370690.aspx
http://stackoverflow.com/questions/1930135...n-large-matches

Podsumowując:
Samodzielne pisanie wyrażeń odpada o ile ktoś napisał i przetestował je wcześniej.

Zawsze polecam biblioteki PEAR. Tym razem nie będzie inaczej:
http://pear.php.net/package/Validate
Pierwsza wersja została opublikowana 2002-08-18.
Blisko 10 lat temu! Gwarancja stabilności jakiej nie znajdziesz nigdzie indziej.

abort
Cytat(wNogachSpisz @ 31.07.2012, 10:16:48 ) *
Wyrażenia regularne trzeba jeszcze potrafić pisać.

Truizm, pasujący do wszystkiego: do pisania wyrażeń regularnych, do pisania obiektowego, aż w końcu do pisania programów w ogóle.

Cytat(wNogachSpisz @ 31.07.2012, 10:16:48 ) *
Na krótkim stringu, błędnie napisane wyrażenie prześlizgnie się niezauważone.
Na długim stringu zawiesi system.
Kilka przykładów: [CIACH]

Doskonałe przykłady, które pokazują, jak nie należy pisać wyrażeń regularnych. W obu przypadkach użyto patternów, które spowodowały nieoptymalne obliczanie/dopasowywanie wyrażenia, i powodując gigantyczne zapotrzebowanie na zasoby (pamięć/cpu). Jak dla mnie jest to kwintesencja "jak nie pisać wyrażeń regularnych".

Cytat(wNogachSpisz)
Podsumowując:
Samodzielne pisanie wyrażeń odpada o ile ktoś napisał i przetestował je wcześniej.

Trochę niegramatycznie, ale zakładam, że chodzi Ci o to, by nie próbować pisać wyrażeń, lecz korzystać z gotowców? No to piękny model proponujesz. Nie uczmy się sami lecz korzystajmy z gotowców. Nie piszmy prac dyplomowych sami, lecz korzystajmy z gotowców. Mało tego: zamknijmy wszystkie szkoły, po co młodych uczyć czegoś nowego (dla nich) - niech korzystają z gotowców. Dziękuję, ale to podejście dla mnie jest nieakceptowalne.
wNogachSpisz
Cytat(abort @ 31.07.2012, 12:32:51 ) *
zakładam, że chodzi Ci o to, by nie próbować pisać wyrażeń, lecz korzystać z gotowców? No to piękny model proponujesz. Nie uczmy się sami lecz korzystajmy z gotowców. Nie piszmy prac dyplomowych sami, lecz korzystajmy z gotowców. Mało tego: zamknijmy wszystkie szkoły, po co młodych uczyć czegoś nowego (dla nich) - niech korzystają z gotowców. Dziękuję, ale to podejście dla mnie jest nieakceptowalne.

W biznesie nie ma miejsca na eksperymenty. Kod produkcyjny powinien być dobrze zdebugowany.
Praca nie musi polegać na napisaniu kazdego najdrobniejszego elementu samodzielnie, opłaca się budować z małych, dobrze przetestowanych klocków.

Cytat(abort @ 31.07.2012, 12:32:51 ) *
Truizm, pasujący do wszystkiego: do pisania wyrażeń regularnych, do pisania obiektowego, aż w końcu do pisania programów w ogóle.

Truzim, tyle że na tym zdaniu nie skończyłem wypowiedzi, więc nie wiem dlaczego się przychrzaniasz.
abort
Cytat(wNogachSpisz @ 31.07.2012, 12:49:44 ) *
Truzim, tyle że na tym zdaniu nie skończyłem wypowiedzi, więc nie wiem dlaczego się przychrzaniasz.

Zgadza się, nie skończyłeś. Bo od tego zacząłeś. Poparłeś to przykładami źle napisanych wyrażeń regularnych, a na końcu podsumowałeś, że (ja tak zrozumiałem): jak nie umiesz pisać wyrażeń regularnych, to lepiej się za to nie bierz (i weź coś innego).
Tymczasem ja nie tyle "przychrzaniam się", co po prostu z takim podejściem walczę. Warto się nauczyć czegokolwiek (choćby dyskutowanych tu wyrażeń regularnych). Jest to bowiem element języka, więc elementarną wiedzę warto mieć. A czym będziemy sprawdzać dane z formularzy, to już jest inna bajka. Nie twierdzę, że regexp jest panaceum na wszystko.

Cytat(wNogachSpisz @ 31.07.2012, 12:49:44 ) *
Praca nie musi polegać na napisaniu kazdego najdrobniejszego elementu samodzielnie, opłaca się budować z małych, dobrze przetestowanych klocków.

Tylko że ktoś te klocki też musi zbudować (i przetestować). Zresztą, skoro ludzie robią sobie własne frameworki, nie widzę przeszkód, by samemu robić sobie zestaw funkcji/obiektów do walidacji danych z formularzy...
wNogachSpisz
Cytat(abort @ 31.07.2012, 13:48:31 ) *
z takim podejściem walczę

Co jest złego w podejściu polegającym na korzystaniu z przetestowanego softu?
abort
Cytat(wNogachSpisz @ 31.07.2012, 14:34:06 ) *
Co jest złego w podejściu polegającym na korzystaniu z przetestowanego softu?

Generalnie to nic. "Problemem" (choć może to nie problem, ale chwilowo brakuje mi słowa, by to poprawnie nazwać) jest to, że namawiasz do użycia Validate pomimo tego, że:
1. nie wiesz, czy w danym oprogramowaniu (Jo-Jo napisał o "specjalistycznym CMSie") Validate się sprawdzi
2. Validate to jednak nadal beta. Zawiera błędy niepoprawione od ponad dwóch lat: http://pear.php.net/bugs/bug.php?id=16897
3. dla mnie z całego pakietu Validate jedyne sensowne testy to testy IBAN i testy na poprawność emaila (choć i tu są błędy)

Nie twierdzę, że zrobiłbym to lepiej. Nie twierdzę, że te błędy są krytyczne (choć w oprogramowaniu OpenSource taki czas reakcji... kłuje w oczy). Dla mnie najistotniejsze jest, że raczej tego nie będę potrzebował. I jestem dość mocno przekonany, że Jo-Jo też nie.

P.S.
Ja kończę tę dyskusję, za bardzo odbiegła od sedna i w zasadzie wszystko już powiedziałem.
wNogachSpisz
Cytat(abort @ 31.07.2012, 16:16:19 ) *
1. nie wiesz, czy w danym oprogramowaniu (Jo-Jo napisał o "specjalistycznym CMSie") Validate się sprawdzi

PEAR:Validate to dobre miejsce do poszukiwania odpowiedzi na pytanie jak powinna wyglądać walidacja.

Cytat(abort @ 31.07.2012, 16:16:19 ) *
2. Validate to jednak nadal beta. Zawiera błędy niepoprawione od ponad dwóch lat: http://pear.php.net/bugs/bug.php?id=16897

Jak dla mnie to problem opisywany w tym tickecie nie jest bugiem. Kwestia gustu.
10 lat developowania i nadal wersja beta, świadczy to o ostrożności autora i potwierdza moją tezę, mianowicie nie da w któtkim czasie stworzyć stabilnego sofu i o ile jest możliwość trzeba sięgać do sprawdzonych rozwiązań. Zbór bibltiek PEAR to prowdopodobnie najlepiej sprawdzone i przetestowanie oprogramowanie PHP jakie tylko istnieje.

Cytat(abort @ 31.07.2012, 16:16:19 ) *
3. dla mnie z całego pakietu Validate jedyne sensowne testy to testy IBAN i testy na poprawność emaila (choć i tu są błędy)

Patrz wyżej.
Jo-Jo
Wywołałem chyba małą wojnę smile.gif
napisałem sobie taką klasę
wątpię żeby byłą idealnie ale zasadniczo rzecz biorąc to co przetestowałem to działa smile.gif

  1. <?php
  2. class validForm
  3. {
  4. public $alphabet="a-zA-ZąśćężźńłóĄŚĆĘŻŹŃŁÓ";
  5.  
  6. public function alphabet($tekst=null, $min=0, $max=25 )
  7. {
  8. $w="{".$min.",".$max."}";
  9. if (preg_match("/^[a-zA-ZąśćężźńłóĄŚĆĘŻŹŃŁÓ]$w$/", $tekst))
  10. return 1;
  11. else
  12. return 0;
  13. }
  14. public function checke($tekst=null )
  15. {
  16. if ($tekst==1 || $tekst==FALSE)
  17. return 1;
  18. else
  19. return 0;
  20. }
  21. public function number($tekst=null, $min=0, $max=25 )
  22. {
  23. $w="{".$min.",".$max."}";
  24. if (preg_match("/^[0-9]$w$/", $tekst))
  25. return 1;
  26. else
  27. return 0;
  28. }
  29. public function price($tekst=null, $min=0, $max=25 )
  30. {
  31. $w="{".$min.",".$max."}";
  32. if (preg_match("/^[0-9\,]$w$/", $tekst))
  33. return 1;
  34. else
  35. return 0;
  36. }
  37. public function login($tekst=null, $min=3, $max=15 )
  38. {
  39. $w="{".$min.",".$max."}";
  40. if (preg_match("/^[a-zA-Z0-9\-\_]$w$/", $tekst))
  41. return 1;
  42. else
  43. return 0;
  44. }
  45. public function email($tekst=null, $min=3, $max=15 )
  46. {
  47. $w="{".$min.",".$max."}";
  48. if (preg_match("/^[_a-z0-9.-]*[a-z0-9]@[_a-z0-9.-]*[a-z0-9].[a-z]{2,3}$/", $tekst))
  49. return 1;
  50. else
  51. return 0;
  52. }
  53. public function password($tekst=null,$tekst2=null, $min=3, $max=15 )
  54. {
  55. $w="{".$min.",".$max."}";
  56. if (preg_match("/^[a-zA-Z0-9\-\@\#\$\_]$w$/", $tekst))
  57. if ($tekst==$tekst2)
  58. return 1;
  59. else
  60. return 0;
  61. else
  62. return 0;
  63. }
  64. public function text($tekst=null, $min=0, $max=25 )
  65. {
  66. $w="{".$min.",".$max."}";
  67. if (preg_match("/^[a-zA-Z0-9ąśćężźńłóĄŚĆĘŻŹŃŁÓ\s\(\)\?\:\.\,\!]$w$/", $tekst))
  68. return 1;
  69. else
  70. return 0;
  71. }
  72. public function adres($tekst=null, $min=0, $max=45 )
  73. {
  74. $w="{".$min.",".$max."}";
  75. if (preg_match("/^[a-zA-Z0-9ąśćężźńłóĄŚĆĘŻŹŃŁÓ\s\-\/\\\.\(\)\?]$w$/", $tekst))
  76. return 1;
  77. else
  78. return 0;
  79. }
  80. public function kod($tekst=nul)
  81. {
  82.  
  83. if (preg_match("/[a-zA-Z0-9ąśćężźńłóĄŚĆĘŻŹŃŁÓ\s\(\)\<\>\/\?\%\"\}\{\_\'\=\&\;\*\$\#\:\.\,\-]$/", $tekst))
  84. return 1;
  85. else
  86. return 0;
  87. }
  88. public function mobilephone($tekst=null, $min=0, $max=12 )
  89. {
  90. $w="{".$min.",".$max."}";
  91. if (preg_match("/^[0-9\s]$w$/", $tekst))
  92. return 1;
  93. else
  94. return 0;
  95. }
  96. public function phone($tekst=null, $min=0, $max=9 )
  97. {
  98. $w="{".$min.",".$max."}";
  99. if (preg_match("/^[0-9\s]$w$/", $tekst))
  100. return 1;
  101. else
  102. return 0;
  103. }
  104. public function pesel($tekst=null, $min=0, $max=11 )
  105. {
  106. $w="{".$min.",".$max."}";
  107. if (preg_match("/^[0-9\s]$w$/", $tekst))
  108. {
  109. $suma=($tekst[0]*1)+($tekst[1]*3)+($tekst[2]*7)+($tekst[3]*9)+($tekst[4]*1)+($tekst[5]*3)+($tekst[6]*7)+($tekst[7]*9)+($tekst[8]*1)+($tekst[9]*3);
  110. $suma=$suma%10;
  111. $suma=10-$suma;
  112. # if ($suma==$tekst[10])
  113. if (10==10)
  114. {
  115. $rok = substr($tekst,0,2);
  116. $miesiac = substr($tekst,2,2);
  117. $dzien = substr($tekst,4,2);
  118. if ($tekst[0]==0)
  119. {
  120. $rok="20".$rok;
  121. $miesiac=$miesiac-20;
  122. }
  123. else
  124. {
  125.  
  126. $rok="19".$rok;
  127.  
  128. }
  129. if (checkdate($miesiac ,$dzien ,$rok))
  130. return 1;
  131. else
  132. return 0;
  133.  
  134.  
  135. }
  136. else
  137. return 0;
  138. echo $suma;
  139. }
  140. else
  141. return 0;
  142. }
  143.  
  144. }
  145. ?>
wNogachSpisz
Ja wysiadam.
Skrypty muszą być odporne na zmiane kodowania, nie mogą zawierać polskich znaków!
Tylko ASCII.
abort
Cytat(Jo-Jo @ 31.07.2012, 21:34:31 ) *
Wywołałem chyba małą wojnę smile.gif

Etam "wojnę". Po prostu mała różnica zdań smile.gif
@wNogachSpisz już jedną rzecz napisał, ja dołożę kilka uwag:
1. funkcja number zwróci fałsz dla liczb ujemnych i ułamkowych - to zgodne z Twoimi założeniami?
2. funkcja price zadziała TYLKO dla przecinka "," jako separatora części całkowitej i ułamkowej. Tak miało być?
3. funkcja email wyłoży się na adresach mailowych z wielkimi literami (a taki adres jest całkowicie poprawny). Ponadto tłucze mi się po łbie (ale uciąć sobie go nie dam), że:
a) fragment adresu mailowego przed "@" powinien zaczynać się od litery
cool.gif domena powinna zaczynać się od litery
Tak czy inaczej, jeśli na siłę chcesz wyrażenie regularne, które zweryfikuje adres mailowy, to przeszukaj forum na okoliczność słowa "weryfikacja adresu email" lub podobnych - na pewno był ładny, kilkulinijkowy regexp smile.gif
4. funkcje phone i mobilephone wyglądają mi na identyczne smile.gif I obie wyłożą się zarówno na separowaniu spacją lub myślnikiem (111-111-111), jak i na międzynarodowej notacji telefonicznej: +48 22 111 1111 (ze znakiem plusa)
Jo-Jo
Cytat
1. funkcja number zwróci fałsz dla liczb ujemnych i ułamkowych - to zgodne z Twoimi założeniami?

Nie zwróciłem uwagi ale mimo wszystko liczby i tak zawsze będą dodatnie
panuje zmienić na is_numeric()

Cytat
2. funkcja price zadziała TYLKO dla przecinka "," jako separatora części całkowitej i ułamkowej. Tak miało być?

wydaje mi się że tak będzie lepiej i zawsze będę miał spójne dane w bazie

Cytat
a) fragment adresu mailowego przed "@" powinien zaczynać się od litery
domena powinna zaczynać się od litery

planuje poprawić na
filter_var($_POST["email"], FILTER_VALIDATE_EMAIL)
co do domeny można normlanie rejestrować domeny które mają cyfrę na początku smile.gif

Cytat
4. funkcje phone i mobilephone wyglądają mi na identyczne I obie wyłożą się zarówno na separowaniu spacją lub myślnikiem (111-111-111), jak i na międzynarodowej notacji telefonicznej: +48 22 111 1111 (ze znakiem plusa)

muszę dopracować


Co do kolegi wNogachSpisz
geniuszem nie jestem wszystkie rozwiązania jakie znalazłem na walidacje polskich liter właśnie tak wyglądały
i o ile kody ASCII liter sobie wyciągnę, to nie wiem jak je zastosować w preg_match

Pozdrawiam
wNogachSpisz
Cytat(Jo-Jo @ 31.07.2012, 22:24:17 ) *
wszystkie rozwiązania jakie znalazłem na walidacje polskich liter właśnie tak wyglądały

Smutne ale prawdziwe. Jakość sniptów produkcji krajowej jest zatrważająca.

Cytat(Jo-Jo @ 31.07.2012, 22:24:17 ) *
i o ile kody ASCII liter sobie wyciągnę, to nie wiem jak je zastosować w preg_match

Musisz zrobić normalizację UTF-8, a potem już z górki :-]

Gotowca nie dam, ale polskie znaki usuwam tym sposobem:
  1. <?php
  2.  
  3. require 'I18N/UnicodeNormalizer.php';
  4. $normalizer = new I18N_UnicodeNormalizer(); // z PEAR
  5.  
  6. function diacritic_replace( $s ) {
  7.  
  8. global $normalizer;
  9.  
  10. // maps German (umlauts) and other European characters onto two characters before just removing diacritics
  11. $s = preg_replace( '@\x{00c4}@u' , "AE", $s ); // umlaut � => AE
  12. $s = preg_replace( '@\x{00d6}@u' , "OE", $s ); // umlaut � => OE
  13. $s = preg_replace( '@\x{00dc}@u' , "UE", $s ); // umlaut � => UE
  14. $s = preg_replace( '@\x{00e4}@u' , "ae", $s ); // umlaut � => ae
  15. $s = preg_replace( '@\x{00f6}@u' , "oe", $s ); // umlaut � => oe
  16. $s = preg_replace( '@\x{00fc}@u' , "ue", $s ); // umlaut � => ue
  17. $s = preg_replace( '@\x{00f1}@u' , "ny", $s ); // ń => ny
  18. $s = preg_replace( '@\x{00ff}@u' , "yu", $s ); // ˙ => yu
  19.  
  20. // maps special characters (characters with diacritics) on their base-character followed by the diacritical mark
  21. // exmaple: � => U�, � => a`
  22.  
  23. $s = $normalizer->normalize($s, 'NFD', 'UTF-8');
  24.  
  25. $s = preg_replace( '@\pM@u' , "", $s ); // removes diacritics
  26.  
  27. $s = preg_replace( '@\x{00df}@u' , "ss", $s ); // maps German � onto ss
  28. $s = preg_replace( '@\x{00c6}@u' , "AE", $s ); // Ć => AE
  29. $s = preg_replace( '@\x{00e6}@u' , "ae", $s ); // ć => ae
  30. $s = preg_replace( '@\x{0132}@u' , "IJ", $s ); // ? => IJ
  31. $s = preg_replace( '@\x{0133}@u' , "ij", $s ); // ? => ij
  32. $s = preg_replace( '@\x{0152}@u' , "OE", $s ); // Œ => OE
  33. $s = preg_replace( '@\x{0153}@u' , "oe", $s ); // œ => oe
  34.  
  35. $s = preg_replace( '@\x{00d0}@u' , "D", $s ); // Đ => D
  36. $s = preg_replace( '@\x{0110}@u' , "D", $s ); // Đ => D
  37. $s = preg_replace( '@\x{00f0}@u' , "d", $s ); // đ => d
  38. $s = preg_replace( '@\x{0111}@u' , "d", $s ); // d => d
  39. $s = preg_replace( '@\x{0126}@u' , "H", $s ); // H => H
  40. $s = preg_replace( '@\x{0127}@u' , "h", $s ); // h => h
  41. $s = preg_replace( '@\x{0131}@u' , "i", $s ); // i => i
  42. $s = preg_replace( '@\x{0138}@u' , "k", $s ); // ? => k
  43. $s = preg_replace( '@\x{013f}@u' , "L", $s ); // ? => L
  44. $s = preg_replace( '@\x{0141}@u' , "L", $s ); // L => L
  45. $s = preg_replace( '@\x{0140}@u' , "l", $s ); // ? => l
  46. $s = preg_replace( '@\x{0142}@u' , "l", $s ); // l => l
  47. $s = preg_replace( '@\x{014a}@u' , "N", $s ); // ? => N
  48. $s = preg_replace( '@\x{0149}@u' , "n", $s ); // ? => n
  49. $s = preg_replace( '@\x{014b}@u' , "n", $s ); // ? => n
  50. $s = preg_replace( '@\x{00d8}@u' , "O", $s ); // Ř => O
  51. $s = preg_replace( '@\x{00f8}@u' , "o", $s ); // ř => o
  52. $s = preg_replace( '@\x{017f}@u' , "s", $s ); // ? => s
  53. $s = preg_replace( '@\x{00de}@u' , "T", $s ); // Ţ => T
  54. $s = preg_replace( '@\x{0166}@u' , "T", $s ); // T => T
  55. $s = preg_replace( '@\x{00fe}@u' , "t", $s ); // ţ => t
  56. $s = preg_replace( '@\x{0167}@u' , "t", $s ); // t => t
  57.  
  58. // remove all non-ASCii characters
  59. $s = preg_replace( '@[^\0-\x80]@u' , "", $s );
  60.  
  61. return $s;
  62. }
alegorn
tylko jedna korekta do dyskusji


@abort::od kiedy domena musi sie zaczynac od litery??

sprawdz np.: 1.pl , 2.pl itd..

j.
abort
Cytat(alegorn @ 1.08.2012, 11:37:17 ) *
@abort:ohmy.gifd kiedy domena musi sie zaczynac od litery??

Nie wiem dlaczego mnie zaćmiło, ale faktem jest, że to co napisałem o domenach, nie jest prawdą. Tobie dzięki za naprostowanie a innych przepraszam, jeśli wprowadziłem w błąd. Sorry.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.