Szukaj na tym blogu

Postaram się przekazać swoje doświadczenia z PHP, oraz innych dziwnych rzeczach, typu MySQL, DB2. Czyli to co umiem. Blogoczytelników o słabych nerwach proszę o nieczytanie tego blogu. Dlaczego? Jeszcze nie wiem. W razie pytań z dziedziny PHP proszę pytać, jest cień możliwości że akurat to wiem. ;)

poniedziałek, 26 marca 2012

Jak skonfigurować prosto w Apache mod_proxy?

Dość krótko. Jak włączyć modproxy? Na 99% Apache jest standardowo włączony. Jak nie wpisujemy w httpd.config:

LoadModule proxy_module modules/mod_proxy.so
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
ProxyRequests Off
Jesteśmy twardziele i sami kompilujemy Apache, czyli rzadkość wśród adminów musimy skompilować z parametrem

./configure --enable-proxy=shared
Oczywiści plus swoje parametry. Prefix, php itd...
W pliku konfiguracyjnym np w wirtualnych hostach wpisujemy:

ProxyPass /jakis_katalog http://ip:port/jakis_katalog
ProxyPassReverse /jakis_katalog http://ip:port/jakis_katalog
Dlaczego ProxyRequests Off? Jest dużo robotów wykorzystujących mod_proxy do spamowania.
Zamiast ip, może być host.
ProxyPass jest potrzebny do zmianynagłółków od klienta do serwera.
ProxyPassReverse jest potrzebny do zmiany nagłówków z serwera do klienta.
Jeszcze jedna istotna rzecz, jeżeli macie włączony SElinux i proxowany prot jest inny niż 80, np 8080, w logach pojawia się:
(13)Permission denied: proxy: HTTP: attempt to connect to 192.168.1.19:8080 (192.168.1.19) failed
Na pewno to dotyczy Fedora Linux, wiem, sam to przerabiałem niedawno.
Należy jako ROOT wpisać:

setsebool -P httpd_can_network_connect 1
Wtedy będzie na 100% działać. Powodzenia.

sobota, 24 marca 2012

Proxy balancer w Apache i jego konfiguracja

Mamy serwer z jedynym słusznym PHP, niestety sukces przerósł nas i maszyna dymi co zrobić? Postawić cztery! Jak to zrobić? Banalnie prosto.
Jednemu z czterech serwerów nadajemy mu ciężką funkcję balancera. Jeżeli jest jakieś logowanie przez HTTPS, albo inne tajne czynności, szyfruje strony tylko i wyłącznie ten serwer. Reszta serwerów o HTTPS'ie nie ma pojęcia że w ogóle takie coś jest. HTTPS zżera dość duże zasoby procesora. Tamte niech zajmują się liczeniem, kryptografia tylko balancer.
Załóżmy że nasz balancer ma IP 10.10.10.10 jako master of flamaster. Reszta od 10.10.10100 do 10.10.10.102. Nazywamy je sbn1, do sbn3 dla przykładu. Proponuje je nazwać inaczej i żeby nazwa mało co sugerowała.
W Apachu naszego balancera wpisujemy w httpd.conf, albo w jakimś naszym takie coś:

Header add Set-Cookie "IDB=.%{BALANCER_WORKER_ROUTE}e; path=/" env=BALANCER_ROUTE_CHANGED
ProxyPass / balancer://nasz_balancer/ stickysession=IDB scolonpathdelim=On nofailover=Off lbmethod=byrequests
ProxyPassReverse / balancer://nasz_balancer/
<Proxy balancer://nasz_balancer>
 BalancerMember http://10.10.10.100 route=sbn1
 BalancerMember http://10.10.10.101 route=sbn2
 BalancerMember http://10.10.10.102 route=sbn3
</Proxy>
Header add Set-Cookie jest linią bezcenną. Dodaje ciasto które może identyfikować który klient jest do którego naszego balancera, poza tym przekazuje ciastka choćby sesji PHP.
ProxyPass definiuje ruch od klienta do jednego z naszych serwerów.
ProxyPassReverse definiuje ruch z serwera do klienta. Jest to dość ważna rzecz zwłaszcza kiedy zamiast niezawodnego PHP mamy coś takiego jak Tomcat. Tomcaty charakteryzują się tym że projekt jest zawsze w jakimś katalogu. Żeby to ukryć piszemy to tak:

ProxyPass / balancer://nasz_balancer/nasz_projekt/ stickysession=IDB scolonpathdelim=On nofailover=Off lbmethod=byrequests
ProxyPassReverse / balancer://nasz_balancer/nasz_projekt/
Muszą być dwie linie, żeby nasz balancer przetłumaczył wszystkie nagłówki Apacha z http://www.naszastrona.pl/bla.html zrozumiała dla klienta, na http://10.10.10.100/nasz_projekt/bla/html zrozumiała dla Tomcata i odwrotnie.
<Proxy balancer://nasz_balancer> wpisujemy wszystkie nasze trzy serwery. BalancerMember http://ip:jak_inny_niż_80_to_podać_port route=naza_nazwa_serwera.
I.... to wszystko. Powodzenia.

piątek, 16 marca 2012

Programowanie obiektowe w PHP. (cz. 2)

Trzeba oderwać się od Javy i napisać coś o języku który lubię. Dobra. Udało zmienić się w template tytuł, na laurach nie ma co spoczywać. Trzeba zrobić coś bardziej zaawansowanego. Choćby w DIV dodać jakiś tekst, albo coś większego.
Mamy bardzo skomplikowaną stronę:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Obiektowe herezje</title>
</head>
<body>
<h1>To jest strona z tytułem</h1>
<div id="diwek"></div>
</body>
<html>
Z góry przepraszam jak w HTML'u jakimś pożrę w napadzie szału jakiś tag. Muszę go konwertować na coś wyświetlanego przez serwis, a z konwersjami różnie bywa. Ale do rzeczy. Mamy DIV, który ma swój ID. Po pierwsze przydaje się taki wynalazek, żeby grafik mógł się na pastwić w CSS'ach na konkretnym DIV, a dla nas przyda się co by mieć pewność że chodzi nam o dokładnie ten DIV a nie jakiś inny. W HTML/XHTML obowiązuje teza nieśmiertelnego „There can be only one!” i bardzo dobrze. Wrzucić tam jakiś tekst jest dość prosto. Oto i przykład:
<?php
$dom = new DOMDocument('1.0', 'UTF-8');
$dom->validateOnParse = TRUE;
$dom->loadHTMLFile("blog.html");
$div = $dom->getElementById('diwek');
$div->nodeValue = "Tu nastąpi wstawienie światłego tekstu, który oświeci ciemności, o ile nie wyłączyli prądu.";
echo $dom->saveHTML();
?>
Już. Działa. Gorzej jak w napadzie szału zachce się naw wstawić coś takiego:
<strong>Tu nastąpi wstawienie światłego tekstu, który oświeci ciemności, o ile nie wyłączyli prądu.</strong>
Wyświetli się nam coś takiego:
&lt;strong&gt;Tu nastąpi wstawienie światłego tekstu, który oświeci ciemności, o ile nie wyłączyli prądu.&lt;/strong&gt;
No jak śmiało!!! To jakaś niedorzeczność!
Otóż to jest dorzeczność. Ponieważ wartość HTML'a, XHTML'a XML'a i innego podobnego składem ela nie może mieć znaków specjalnych. Sprytny DOM żeby nie mieć problemów konwertuje znaki specjalne. Więc żeby dodać STRONG należy się ciut bardziej wysilić.
A oto wysiłek przekraczający ludzkie pojęcie:
<?php
$dom = new DOMDocument('1.0', 'UTF-8');
$dom->validateOnParse = TRUE;
$dom->loadHTMLFile("blog.html");
$div = $dom->getElementById('diwek');
$strong = $dom->createElement('strong', 'Tu nastąpi wstawienie światłego tekstu, który oświeci ciemności, o ile nie wyłączyli prądu.');
$div->appendChild($strong);
echo $dom->saveHTML();
?>
Ale... zawsze musi być jakieś ale. Ale załóżmy że z jakiś powodów element STRONG musimy wstawić teraz, a wartość gdzieś tam daleko daleko. Żaden problem.
<?php
$dom = new DOMDocument('1.0', 'UTF-8');
$dom->validateOnParse = TRUE;
$dom->loadHTMLFile("blog.html");
$div = $dom->getElementById('diwek');
$strong = $dom->createElement('strong');
$do_daleko = $div->appendChild($strong);
// załóżmy że tu jest dużo kodu PHP, który jest niezbędny do funkcjonowania.
// bla bla bla
// i jeszcze jedna linijka dla lepszego samopoczucia!
$do_daleko->nodeValue = "A jednak wstawiłem!";
echo $dom->saveHTML();
?>
CUD! DZIAŁA!
W następnej części popastwię się nad tabelą jak ją zmajstrować i po co. ;)
Obiecuję napisać to trochę szybciej niż za pół roku. :D

sobota, 13 sierpnia 2011

Programowanie obiektowe w PHP.

Złośliwi opowiadają że Java jest obiektowa, Obcjective-C jak w samej nazwie jest obiektowy. Tylko jakiś ten PHP nie ma obiektów jest prostacki i dla amatorów. Dopiero jak przesiądziesz się na Java lub te drugie, to dopiero czujesz że pracujesz obiektowo. Ja na to odpowiadam że to stek bzdur. Co do Objective-C nie mogę nic napisać, bo nie programuję (jak będę chciał wywalać 100$ Applowi za konto deweloperskie co rok, wtedy będę pyskował), za to Javie mogę wytknąć kilka bzdurnych i przyprawiających o zawał obiektów, dzięki którym nasz króciutki programik działa z „zawrotną prędkością”, jak by procesor był taktowany zegarem z kukułką która właśnie zdechła. Już nie wspominam że owa obiektowość może wygenerować błąd składający się z 50 linii, z czego każda linia dotyczy czego innego, coś do poćwiczenia prekognicji (jasnowidzenia). Zdarzyło się kilka razy iż błąd nie miał nic wspólnego rzeczywistością.

Dość tego jadu, teraz pokaże jak obiektowo można pracować w PHP. Pierwszym jaki rzuca się w oczy i jest oczywisty jest podłączenie się do bazy danych.


<?php
$mysqli = new mysqli("localhost", "juzer", "pasłord", "baza");
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}

if (!$mysqli->query("SET zmienna=1")) {
printf("Errorcode: %d\n", $mysqli->errno);
}

$mysqli->close();
?>


Jak zwykle większość kodów to jest obsługa błędów. Złośliwi mówią że 90% kodu to obsługa błędów i kod idioto odporny co by użytkownik bzdur nie wpisywał. W sumie coś w tym jest.
Nie będę się pastwił nad MySQL'em, tam można pomęczyć się ze statemantami i takimi tam dziwactwami, ale ja po pastwię się nad DOMDocument. Nawet uzasadnię zaraz dlaczego.

Otóż jest kilka filozofii pisania stron. Pierwsza prostacka tworzenie HTML/XHTML od początku. Na początku <html> potem <head>. W <head> mamy różne metatagi takie jak kodowanie strony, kto to popełnił, mamy również gdzie są CSS, tytuł parę JS do AJAX'a Google Analitics oraz inne dziwolągi. Potem mamy <body>. W body mamy tabelki, <div>, <strong>, <b> i inne dziwne rzeczy. Trzeba pamiętać żeby to wszystko pozamykać w odpowiedniej kolejności i tak dalej. Programowanie tego przypomina programowanie liniowe i jak okaże się że z jakiegoś powodu tytuł strony wynika nam z zawartości strony i nie możemy go ustalić w head, zostaje nam strzelić se w łeb.
Druga metoda to template. W nich umieszczone są różnego rodzaju zmienne, np. $tytuł i tam się objawi tytuł jak puścimy przez jakiś kombajn zwany CRM'em, albo PEAR'em. Można oczywiście robić pętelki typu coś się powtarza, ale moim skromnym zdaniem jakoś mi to nie podchodziło od samego początku.

Moja zwariowana metoda (najwyżej ktoś mnie odwiezie do Tworek, wreszcie odpocznę) jest to wpakowanie do DOM. Co prawda opiera się na template, ale po co tworzyć całą stronę w DOOM. Kod będzie długi, a żaden grafik tego nie zrobi. Niech DOM martwi się o zamykanie wszystkich tagów i poprawności zawartości i innymi zgodnościami RSS których normalny człowiek nie jest w stanie ogarnąć. Choćby w linkach powinny zmienne GET dzielone &apm; a nie jak większość robi samym &.
Oto króciutki przykład o co mnie chodzi, dalej będę pastwił się w części drugiej. Mamy prosty HTML.


<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title></title>
</head>
<body>
<h1>To jest strona z tytułem</h1>
Jak widać tytuł jest, a w templacie nie.
</body>
</html>


Jak widać <title> jest puste. To straszne! Trzeba coś z tym zrobić! Spokojnie, o to prościutki skrypt pozujący idee mojego mądrzenia się na łamach bloga.


<?php
$dom = new DOMDocument('1.0', 'UTF-8');
$dom->validateOnParse = TRUE;


To coś tworzy dokument DOM. ValidateOnParse jest na true co by ładnie był HTML poukładany i nie walił wszystkiego w jednej linii.
Teraz trzeba załadować nasz wspaniały przykład HTML ku uciesze gawiedzi. Robi się to tak:


$dom->loadHTMLFile($plik);


Prawda że skomplikowane? Teraz trzeba wyłapać <title> i wrzucić tam nasz wspaniały tytuł. Oczywiście najprościej było by w title umieścić id i już, ale to nie przystoi prawdziwemu wojownikowi, więc zrobimy to tak:


$title = $dom->getElementsByTagName('title')->item(0);
$title->nodeValue = 'Oto wspaniały tytuł, który każdemu się spodoba.”


To wszystko. Zaletą tego rozwiązania jest że tytuł można dodać, zmienić, dopisać w każdej chwili. Nie trzeba się martwić jak w pierwszym przykładzie innych rozwiązań, kiedy to się programuje a'la liniowyo, że na początku tytuł, a potem reszta strony. Teraz można zrobić jak kto chce.

Teraz najważniejszy fragment zabawy, mianowicie wyświetlenie zawartości DOM jako HTML:


echo $dom->saveHTML();


To wszystko. W dalszych częściach mojego mądrzenia się pokaże jak można robić inne rzeczy za pomocą tej biblioteki. Chciałem tylko ostrzec, ona jest dość mocno uzależniająca. ;)

Także pomyśl jak potworzysz sobie z tego klasy własnej produkcji i pomysłu jakie będziesz miał ułatwione życie. Inne CRM pognasz precz i nie będziesz chciał o nich słyszeć.

Na koniec zdradzę moje motto. Im mniej używasz gotowców, tym mniej masz włamań na stronę. Lepiej napisać coś samemu, na to nie ma gotowych pakietów do włamań przez serwisy w internecie.

środa, 1 czerwca 2011

Testowe PESELe wygenerowane automatem

Podsyłam kilka PESEL'i testowych. Tylko 9003 sztuki więc można szaleć.
Są to wygenerowane automatycznie. Są niczyje. Chyba że ktoś go dostanie w 2499 roku jak nie później. ;)
Link do pliku tekstowego jest TU.

Miłego testowania i powodzenia.

wtorek, 3 maja 2011

Sprawdzanie poprawności NIP

Kiedyś w napadzie szału musiałem napisać sprawdzanie NIP. Oczywiście w PHP. Bardzo mnie zdziwiło jak ludzie często pamiętają swój NIP z błędem. Przekonałem się o tym jak wdrożyłem to rozwiązanie na serwer. Oto i one:

<?php
$nip = $_POST['nip']; //albo skadś tam wziąć zmienną
if (strlen($nip) == 10) {
$nip_waga = '657234567';
$nip_suma = 0;
if (ereg ('[0-9]{10,10}', $nip) ){
for ($a = 0; $a <= 8; $a++) {
$nip_suma = $nip_suma + (substr ($nip, $a, 1) * substr ($nip_waga, $a, 1));
}
$nip_suma2 = $nip_suma - (intval($nip_suma/11) *11);
if ($nip_suma2 == substr ($nip, -1, 1)) {
echo "Nip OK";
}
else {
echo 'Nip do bani!';
}
}
else {
echo "Nip ma lipną długość.";
}
?>


Tradycji musi się stać zadość, żeby ten przykład zobaczyć. Jest on tu.
Oczywiście dane są nigdzie zapisywane, więc śmiało.

Oczywiście musi być wersja Java Script. Praca z AJAX'em, czystym... nie wiem czy userzy będą nazywali to relaks, jak komputer będzie pisał z upartością maniaka, że NIP który podają jest dobry, ale nie do końca i żeby wpisali ten poprawny.
Oto wersja JS:

if (nip.length == 10) {
nip_waga = '657234567';
nip_suma = 0;
for (a = 0; a <= 8; a++) {
nip_suma = nip_suma + (nip.substr(a, 1) * nip_waga.substr(a, 1));
}
nip_suma2 = nip_suma - (parseInt(nip_suma/11) *11);
if (nip_suma2 == nip.substr(-1, 1)) {
document.getElementById('wynik').innerHTML = "Nip OK";
}
else {
document.getElementById('wynik').innerHTML = 'Nip do bani!';
}
}
else {
document.getElementById('wynik').innerHTML = 'Nip ma lipną długość.';
}


Wersja do klikania jest tu.
W NIP ostatnia cyfra jest sumą kontrolną. Wystarczy 9 odpowiednio pomnożyć, modulo i porównać z ostatnią dziesiątą. Od tej pory źle wpisujący NIP będą karceni.
Jak mnie nawiedzi, wygrzebię jeszcze do sprawdzania poprawności numeru konta bankowego. Dla wstępu napiszę że pełny numer konta zaczyna się on dwóch znaków kraju. W Polsce od PL. Da się to zrobić, kwestia samozaparcia. ;)

środa, 23 marca 2011

Jak można skomplikować skrypt (cz.2)

Kto to w ogóle powymyślał nad silnikiem PHP? Tacy programiści którzy stwierdzili po co czytać miliard książek, dokumentacji, chodzić na drogie szkolenia, jak wystarczy przeczytać kilka moich zdań skleconych powiedzmy że po polsku żeby zorientować się w czym rzecz.
Na początek nie podoba mi się możliwość zmiany zmiennych w klasie. Omijając elegancką funkcję która nam to robi. Nie mówię o wywołanie tekstu też ma wiele do życzenia. Kto to będzie pamiętał że w tej klasie tekst znajduje się w zmiennej text. Więc od początku.

W poprzedniej części zrobiłem klasę tekst i w środku funkcje tekst. To jest właśnie __construct z PHP 4 (dla tych co znają C++ konstrukcja siekierą wyrąbana właśnie stąd). W napadzie szału zmienisz nazwę klasy i trzeba wszystko zmieniać. To bez sensu. Dlatego funkcja tekst będzie nazywała się __construct().
Po po drugie po co pisać jakieś funkcje zmieniające zmienne skoro można to zrobić bez nich. To trzeba zmienić. Dlatego panowie od PHP wymyślili hasła public i private. Kiedy użyjesz private $text już jej nie zmienisz, nie wyświetlisz nic. Ona jest dostępna tylko i wyłącznie w klasie. Wadą tego rozwiązania jest obowiązek napisania funkcji wyświetlającą ją, ale co to dla prawdziwego wojownika. Różni ludzie różnie nazywają ta funkcję np. save, print, echo... kto to spamięta. Na szczęście panowie od PHP nie zasypują gruszek w popiele i wymyślili coś takiego jak __toString() (też C++). Teraz wystarczy zrobić echo $tekst i klasa wyświetli się jak zwykły tekst. Oto przykład.

<?php
class tekst{
private $imie = 'Ala';
private $czynnosc = 'ma';
private $zwierz = 'psa';
private $text = '';

public function __construct() {
$this->text = "{$this->imie} {$this->czynnosc} {$this->zwierz}!";
}
public function zmiana($imie= NULL, $czynnosc = NULL, $zwierz = NULL) {
$this->imie = $imie==NULL ? $this->imie : $imie;
$this->czynnosc = $czynnosc==NULL ? $this->czynnosc : $czynnosc;
$this->zwierz = $zwierz==NULL ? $this->zwierz : $zwierz;
$this->__construct();
}
public function __toString(){
return $this->text;
}
}
$tekst = new tekst;
$tekst->zmiana ('Ola');
echo $tekst;
?>


Jak widzimy wszystkie zmienne są prywatne, wszystkie funkcje są publiczne, zmienna $tekst sama się uzupełnia odpowiednim tekstem, oraz wyświetla się ją też prosto. Czy da się to jeszcze skomplikować? Ależ oczywiście że tak. Napiszmy teraz funkcje która będzie dodawać wykrzyknik. Zrobimy ją prywatną, co by byle kto nie dodawał wykrzykników ile wlezie. Oto i on.

<?php
class tekst{
private $imie = 'Ala';
private $czynnosc = 'ma';
private $zwierz = 'psa';
private $text = '';

public function __construct() {
$this->text = "{$this->imie} {$this->czynnosc} {$this->zwierz}";
$this->wykrzyknik();
}
public function zmiana($imie= NULL, $czynnosc = NULL, $zwierz = NULL) {
$this->imie = $imie==NULL ? $this->imie : $imie;
$this->czynnosc = $czynnosc==NULL ? $this->czynnosc : $czynnosc;
$this->zwierz = $zwierz==NULL ? $this->zwierz : $zwierz;
$this->__construct();
}
public function __toString(){
return $this->text;
}
private function wykrzyknik() {
$this->text .='!';
}
}
$tekst = new tekst;
$tekst->zmiana ('Ola');
echo $tekst;
?>


Teraz prosta rzecz jest wystarczająco złożona. Prywatne zmienne nie pozwalają nam na swobodne zmiany przez kogoś, publiczne funkcje które służą do zmian tekstu w sposób kontrolowany, prywatna funkcja która dodaje wykrzyknik i nie może być wywołana celem siania zamętu.
Czy da się jeszcze to skomplikować? Ależ oczywiście. Jest jeszcze __destruct, __unset, __call, __clone... ale to kiedy indziej.
Kiedyś pisząc zadanie w zawodach, gdzie główną wygraną była praca specjalnie nie użyłem konstrukcji jak w ostatnim przykładzie z nadzieją że facet się zorientuje że se jaja robię, nie zorientował się. Za to Ty możesz wykorzystać ten przykład i możesz mieć moją fuchę. ;)