Niezalogowany [ logowanie ]
Subskrybuj kanał ATOM Kanał ATOM

Autor wpisu: Śpiechu, dodany: 16.05.2012 19:26, tagi: php

Od tygodnia na poważnie wziąłem się za rozpracowywanie protokołów sieciowych. Dzisiaj schodzimy na poziom najniższy jaki się da w programowaniu, czyli zer i jedynek. Ja jako osoba za 2 miesiące rozpoczynająca zawodowo przygodę z programowaniem (ojej, wydało się ;-) ) muszę mieć dosyć dobre pojęcie jak to się dzieje, że wpisuję adres www w pasku adresu przeglądarki, naciskam enter i pokazuje się Fejsbuk. Oczywiście zwykli użytkownicy internetu nie muszą wiedzieć jak to dokładnie działa w myśl zasady „nie muszę być mechanikiem samochodowym żeby jeździć autem”.

Wobec tego na warsztat wziąłem na początek rzecz dosyć prostą: ICMP, a nawet tylko jego wycinek pod nazwą Echo request/Echo reply. Komunikaty ICMP stanowią podstawę działania internetu. Każda maszyna podłączona do sieci potrafi zadawać pytania i otrzymywać odpowiedzi w postaci ICMP. Tak naprawdę zdubluję funkcjonalność wbudowaną w każdy system operacyjny pod powszechnie znaną nazwą ping.

Ręczne tworzenie pakietów w PHP nie ma oczywiście większego sensu poza edukacyjnym (no chyba, że tworzymy coś nietypowego lub dostosowujemy się do już istniejącego protokołu). Jeśli potrzebujemy coś „pingnąć”, wywołujemy polecenie ping shella z poziomu skryptu PHP i tyle.

W Gist zamieściłem klasę gotową do użytku. Na Linuksie będzie problem z jej odpaleniem, gdyż bez roota nie wywołamy funkcji socket_create(). Ten temat jest na tyle ciekawy, że zostawię sobie na następny wpis.

Sama struktura protokołu jest dosyć prosta. Mamy 6 elementów:

  • 8 bitów typ żądania (0x08 w przypadku echo request, 0x00 w przypadku echo reply),
  • 8 bitów kod żądania (0x00),
  • 16 bitów suma kontrolna (tzw. internet checksum, o którym trochę niżej),
  • 16 bitów identyfikator (losowa liczba z zakresu 0x000 - 0xFFFF),
  • 16 bitów nr sekwencyjny (0x00),
  • 8– bitów dane (znaki ASCII).

Operując niskopoziomowo musimy zaprzyjaźnić się z funkcjami pack() i unpack() w celu stworzenia i odczytu reprezentacji bitowej ciągu. W przypadku ICMP będzie to wyglądało tak:

const PACKET_REQUEST_TEMPLATE = 'CCnnnA*';
const PACKET_RESPOND_TEMPLATE = 'Ctype/Ccode/nchecksum/nuid/nseq/A*message';

Widać, że 1 bajt możemy odzwierciedlić w postaci typu unsigned char, a 2 bajty w postaci unsigned short.

Teraz może nasunąć się pytanie jak wypełnić pole checksum, skoro jest gdzieś w środku? Odpowiedź jest prosta: w pole wpisujemy tymczasowo 0x00, obliczamy sumę kontrolną dla całości, a następnie zastępujemy wynikiem. Jest to dokładnie 3 i 4 bajt. Jak obliczyć sumę kontrolną? Jest do tego RFC z 1988 r. pod nazwą Computing the Internet Checksum. Jednak zanim zniechęcicie się suchym żargonem informatycznym wytłumaczę po ludzku:

  1. Cały pakiet ćwiartujemy na kawałki po 16 bitów,
  2. sumujemy wszystko,
  3. jeśli w wyniku powstaje nam jakaś nadwyżka w postaci 17 i więcej bitu, odcinamy ją, a następnie dodajemy do pozostałych 16tu,
  4. ponownie sprawdzamy czy nie powstała nam nadwyżka,
  5. odwracamy wynik.

Zapis w PHP:

protected function computeChecksum($packet) {
 
  // treat the whole packet as 16 bits unsigned short integers
  $seqPer16bits = unpack('n*', $packet);
  $sum = array_sum($seqPer16bits);
 
  // if there is a carry above 16 bit, add it at the beginning
  $sum = ($sum >> 16) + ($sum & 0xFFFF);
 
  // double check if there is no new carry after previous addition
  $sum += ($sum >> 16);
 
  // return 16 bits negate
  return pack('n', ~$sum);
}

Jak „wkleić” wynik w dobre miejsce? Mała sztuczka:

Czytaj dalej tutaj (rozwija treść wpisu)
Czytaj dalej na blogu autora...

Autor wpisu: Łukasz, dodany: 16.05.2012 00:14, tagi: php

W dniu dzisiejszym udało mi się zdać egzamin Zend Certified Engineer w PHP 5.3.

Myślę, że przyda się kilka słów na temat tego egzaminu – może komuś się przydadzą.

Egzamin, co można przeczytać na oficjalnej stronie trwał 90 minut, w tym czasie do rozwiązania było 70 zadań. Były to zarówno pytania teoretyczne, pytania o nazwy funkcji, jak i fragmenty kodu, które trzeba zanalizować. Niektóre z pytań były otwarte (podanie nazwy funkcji, bądź nazwy indeksu w jakiejś tablicy), niektóre zamknięte (jeśli trzeba było zaznaczyć więcej niż jedną odpowiedź, zawsze było to zaznaczone). Pytania były dość trudne, niektóre podchwytliwe, jeśli w pytaniu chodziło o podanie funkcji, to szczerze powiedziawszy były to jedynie takie funkcje, z jakich NIGDY w karierze programisty nie korzystałem :D . Generalnie polecałbym powtórzenie wszystkich funkcji do obsługi stringów, oraz array_* :) . Co ważne, nie trafiłem na żadne pytanie, gdzie ważna byłaby kolejność podawanych parametrów.

Do egzaminu pomogły mi się przygotować:

  • Książka Davey’a Shafika i Bena Ramseya „Zend php5 certification study guide”
  • Manual PHP ;)
  • Wpisy na blogach
  • Wszelkie testy – jak np. strona http://test.php.pl

Przygotowania zacząłem od poczytania zakresu egzaminu i zdecydowaniu, w których tematach czuje się najsłabiej. Z nich też zrobiłem sobie metodą kopiuj-wklej z manuala PHP mini-kompendium. Zebrało mi się tego około 70 stron. Bardzo dobrą rzeczą jest darmowy ebook, który Zend przesyła po wykupieniu vouchera na egzamin (można bez strachu kupić go wcześniej, gdyż na wykorzystanie mamy rok, a centra egzaminacyjne można znaleźć w każdym dużym mieście – we Wrocławiu w którym mieszkam obecnie jest ich 3, a w rodzinnym Krakowie o ile dobrze pamiętam jeszcze więcej), w którym można znaleźć zarys tego, co czeka nas na egzaminie i kilka przykładowych testów. Kilka pytań, na które trafiłem były bardzo podobne do niektórych pytań z tego ebooka oraz z mojej pomarańczowej study guide.

Do egzaminu warto podejść skoncentrowanym, bo niektóre pytania są naprawdę ciężkie, aczkolwiek przy odrobinie szczęścia i kierowanego doświadczeniem „nosa” i z nimi można sobie poradzić. Ja np. w piątek oraz w dniu egzaminu wziąłem wolne, aby mieć trochę spokoju, i czasu na ostatnie przygotowania, dobrze też sobie pojeść, aby nie móc skoncentrować się na pytaniach. Egzamin w całości odbywa się na przygotowanym przez centrum egzaminacyjne komputerze. Oczywiście nie możemy mieć nic ze sobą, choć mnie pozwolno wnieść na czekoladę i picie z racji że zdawałem sam :) .

Jak wspominałem na egzamin jest 90 minut, i jest to dużo. Niewarto się spieszyć, dobrze jest za to sprawdzić po kilka razy odpowiedzi na pytania w których czujemy się trochę gorzej. Pomaga w tym sam program egzaminacyjny. Każde pytanie możemy sobie oznaczyć „flagą”, która oznacza, że chcemy do niego jeszcze wrócić. Po ostatnim pytaniu pokazuje się lista pytań, gdzie pokazane są wszystkie pytania oznaczone flagą, bądź też te na które nie udzieliliśmy odpowiedzi i możemy się jeszcze raz na spokojnie nad nimi zastanowić. Oczywiście nie ma też problemu powrócić do każdego innego pytania. Po zakończeniu testu zostaniemy dwa razy zapytani, czy na pewno chcemy już skończyć, i na ekranie ukaże się wynik:)

To z grubsza wszystko, co mogę napisać, chętnie odpowiem na ewentualne pytania :) .

Autor wpisu: Łukasz, dodany: 16.05.2012 00:13, tagi: jquery, javascript

Zacząłem dziubać ostatnio po godzinach w domu nad pewnym projektem. Gdy doszło do tematu moderacji, pomyślałem: „Hmm, po kliknięciu na usuń użytkownik powinien to przecież jakoś potwierdzić… Ale to standardowe okienko wygląda okropnie!”. Jako że i tak w projekcie było już użyte jQuery, postanowiłem do tego dołożyć faceboxa, i zrobić własny confirmation box.

Całość była bardzo prosta, dlatego, że facebox jako parametr może przyjąć kod html, który następnie pojawia się w „ramce”. Kod ten należy wykonać dopiero po załadowaniu się rozszerzenia facebox, które można pobrać stąd.

$.facebox.confirm = function(params)
{
    // pominąłem tutaj ustawianie domyślnych wartości parametrów

    // wyświetlamy faceboxa z pytaniem i odpowiedziami tak i nie
    $.facebox('<div class="'+params['class']+'">'+params['question']+' <a class="yes'+params['yesClass']+'">'+params['labelYes']+'</a> <a class="no'+params['noClass']+'">'+params['labelNo']+'</a></div>');
    $('a.yes').click(function()
    {
        // Po kliknięciu w yes wykonaj funkcję z parametru callbackYes z parametrami z paramsYes
        fn = params['callbackYes'];
        fn(params['paramsYes']);
    });
    $('a.no').click(function()
    {
        // Wykonaj callbacks analogicznie do yes, i zamknij faceboxa
        fn = params['callbackNo'];
        fn(params['paramsNo']);
        $.facebox.close(); });
    }
}

Użycie również jest banalne:

$(function()
{
    $('a.delete-user').click(function(event)
    {
        paramsYes = { "user_id" : $(this).attr('rel')};
        $.facebox.confirm({
            "question" : "Are you sure you want to delete that user?",
            "callbackYes" : function(params)
            {
               // wywołuję odpowiedniego ajaxa
            },
            "paramsYes" : paramsYes
        });
    });
});

Mam nadzieję, że komuś się przyda :) . Enjoy!

Autor wpisu: Łukasz, dodany: 16.05.2012 00:13, tagi: php

W ostatnim czasie we wszelkiego rodzaju aplikacjach zintegrowanych z portalami społecznościowymi, modne staje się logowanie przez Facebook’a, przez Flickr’a, etc. To ostatnie robiłem ostatnio w pracy i szczerze powiedziawszy – było łatwiejsze, niż myślałem.

Jako, że tym razem biblioteka Zend_Services_Flickr okazała się zbyt uboga, a nie było sensu wymyślać koła na nowo, znalazłem bardzo fajnie napisany pakiet o nazwie Phlickr. Cały mechanizm logowania jest banalny.

$flickrApi = new Phlickr_Api($apiKey, $apiSecret);
$flickrLoginUrl = $flickrApi->buildAuthUrl('read');

W pierwszej linijce tworzymy obiekt Phlickr_Api, używając api_key i api_secret. Możemy je zdobyć rejestrując nową aplikację na naszym koncie na Flickr pod adresem: . W drugiej linijce pobieramy adres logowania. To pod ten adres należy przekierować użytkownika naszej strony. Natomiast po zalogowaniu użytkownik zostanie przeniesiony pod adres zdefiniowany przez nas na Flickr jako Callback URL.

$flickrApi->setAuthTokenFromFrob($_GET['frob']);
$flickrToken = $this->flickrApi->getAuthToken();

Pod adresem Callback URL nasza aplikacja otrzymuje zmienną „frob”, za pomocą której możemy uzyskać następnie token, który warto zapamiętać np. w sesji. Możemy uzyskać też dane użytkownika, np.:

$user_id = $flickrApi->getUserId();
$user = new Phlickr_User($flickrApi, $user_id);
$username = $user->getName();

Dane te, można np. wrzucić do bazy danych, aby powiązać konto na Flickr z użytkownikiem zarejestrowanym w naszym systemie. Ostatnią rzeczą, o którą należy się zatroszczyć jest kwestia wygaśnięcia tokenu – kiedy nadal mamy token zapisany w sesji, natomiast przez Flickr będzie on już traktowany jako nieaktualny. I to jest bardzo proste ;) .

$flickrApi->setAuthToken($flickrToken);
$user = $flickrApi->getUserId();

Jeśli pod zmienną $user otrzymamy wartość null tzn. że użytkownik musi zalogować się od nowa. Po takim zalogowaniu użytkownik może bez problemu np. wrzucać na naszą stronę swoje zdjęcia z Flickra. Możliwości integracji są tu praktycznie nieograniczone.

Autor wpisu: Łukasz, dodany: 16.05.2012 00:13, tagi: zend_framework, mysql, php

Bardzo często, zwłaszcza przy bardziej skomplikowanych aplikacjach i zapytaniach do bazy danych ciekawszych niż:

SELECT * FROM users WHERE id = 1

zachodzi potrzeba sprawdzenia, jak wygląda nasze zapytanie, i jakie dane są do niego przekazywane. O ile przy ręcznym pisaniu zapytań wystarczy do tego zwykłe echo, o tyle przy korzystaniu z Zend_DB – niekoniecznie. Z pomocą przychodzą nam profilery.

Domyślnym profilerem jest Zend_Db_Profiler, który włączamy w ten sposób:

$db->getProfiler()->setEnabled(true);

Jeśli ustawienia bazy danych trzymamy w pliku .ini, to można zamiast powyższego kodu, dopisać do niego 2 linie:

db.profiler.class = "Zend_Db_Profiler"
db.profiler.enabled = true

Następnie za pomocą kodu:

$profiler = db->getProfiler();

dostajemy się do obiektu profilera i już możemy korzystać z całego bogactwa jego funkcji :) .

Jednak nadal korzystanie z niego może być niezbyt wygodne. I na to jest rozwiązanie. Któż nie zna FireBuga? Myślę, że każdy programista PHP używa częściej lub rzadziej tego narzędzia. Aby zmienić używany profiler na Zend_Db_Profiler_Firebug, możemy zmienić wpis w pliku konfiguracyjnym .ini:

db.profiler.class = "Zend_Db_Profiler_Firebug"
db.profiler.enabled = true

bądź też zmienić używany profiler w naszym kodzie:

$profiler = new Zend_Db_Profiler_Firebug();
$profiler->setEnabled(true);
$db->setProfiler($profiler);

Od tej pory wszystkie zapytania będą nam się pojawiały w konsoli Firebuga.

Autor wpisu: singles, dodany: 06.05.2012 19:51, tagi: php

„Słyszałem, że programiści dobrze zarabiają, to kupię sobie jedną książkę, naucze się i ja też będę tyle zarabiał. W końcu jestem zaj****sty. ” Niektórzy z Was tak myślą. Naprawdę. Po przeprowadzeniu ponad 20 rozmów kwalifikacyjnych, nie przychodzi mi do głowy inne wyjaśnienie fenomenu tego, co się dzieje podczas rekrutacji. Albo ze mną jest coś nie tak, a nie z tymi, z którymi rozmawiam.

Wpis ten kieruję raczej do początkujących programistów (aczkolwiek, wg ich CV to wcale takimi nie są) planujących szukać pracy. Nie będzie tutaj nazwisk (chociaż niektóre pamiętam do dzisiaj) – jednak niektóre sytuacje (w tym wszystkie cytaty) opisane sytuacje prawdziwe. Jeśli to czytasz, a miałeś podobą sytuację (a jest nawet bardzo mała szansa, że jeden z przypadków jest właśnie o Tobie), to mam prośbę – nie obrażaj się na mnie, tylko zrób coś dla siebie – wyciągnij wnioski.

Wpis oczywiście 100% subiektywny, przedstawiający MOJE podejście do kandydatów na rozmowie. Nie twierdzę, że jest ono jedyne słuszne – jest MOJE. Tylko tyle i równocześnie aż tyle.

Tak więc, lecimy z listą „grzechów głównych” programistów popełnianych na rozmowach kwalifikacyjnych (nie ogólnie, to temat na inny wpis).

Papier toaletowy

Tak, to Twoje CV. I nie mam na myśli tego, do czego służy, bo nie ma takiego przeznaczenia jak papier toaletowy. Mam na myśli raczej jego długość. Ogólnie, ludzie na siłę próbują wcisnać tutaj jak najwięcej. I robią to na dwa sposoby.

Wersja pierwsza: opisują każdą firmę, w której pracowali na pół strony (w tym takie rzeczy, jak przerabianie strony internetowej na temat kota szefa, bo ten tak go uwielbiał, że zrobił mu takową). Z tego wychodzi 8 stron doświadczenia, którego nie mam ani czasu i ochoty czytać. A jeśli kandydat nie ma dużo doświadczenia, a ma na liście ma sporo firm, to zastanówcie się – jakbyście to zinterpretowali?

Wersja druga: wypisują rzeczy, które są totalnie niepowiązane z pracą, którą chcą dostać – np. stanie na promocji mleka dla dzieci w Tesco 3,5 roku temu jak był studentem. Nie interesuje mnie to. Jeśli zależy mi na dużym doświadczeniu, to i tak ten fragment pominę, a na resztę spojrzę podejrzliwie, skoro ktoś na siłe dodaje coś jeszcze.

Problemy z liczeniem

Dla tych, którzy piszą ile mają lat doświadczenia w danej technologii. Na przykładzie i krótko.

Swój pierwszy skrypt PHP napisałem jakoś w roku 2002 w technikum. Potem nie pisałem w nim kilka lat. Pracuje programując w PHP powiedzmy od roku 2007. To nie znaczy, że mam 10 lat doświadczenia w PHP, tylko ok. czterech.

„Oooo. Mogę wszystko!”

Dosłownie. Ile już CV widziałem, gdzie ludzie programowali w 1532 językach i w ogóle znali wszystkie technologie (oczywiście, wszędobylski Pascal). Patrząc na takie CV często zastanawiam się, czy na takiej rozmowie nie powinniśmy się zamienić miejscami i to ja nie powinienem być po drugiej stronie biurka. Do czasu, aż rozmowa się nie zacznie.

Czytaj dalej tutaj (rozwija treść wpisu)
Czytaj dalej na blogu autora...

Autor wpisu: Łukasz Socha, dodany: 06.05.2012 10:19, tagi: php

pobierz w .pdf(przeznaczone do wydruku)

PHP ze względu na swoją specyfikę (brak wskaźników) nie ułatwia tworzenia abstrakcyjnych struktur danych, takich jak drzewa, grafy (możemy opierać się tylko na tablicach). Tworząc aplikacje internetowe relatywnie rzadko istnieje potrzeba użycia bardziej zaawansowanych struktur danych (Ba! Programiści piszący tylko w PHP w znacznej części nie słyszeli nigdy o B-Drzewach, drzewach AVL, grafach i innych tego typu strukturach). Mimo tego warto zaznajomić się z typami struktur jakie oferuje podstawowa biblioteka SPL.

Lista dwukierunkowa

Lista dwukierunkowa jest jedną z najprostszych struktur. Umożliwia przemieszczanie się po liście do przodu oraz do tyłu. Dlaczego do tego nie użyć zwykłych tablic? W PHP tablice są dynamiczne, więc nie ogranicza nas ich stały rozmiar. Jednak, jeżeli chcielibyśmy wstawić element pośrodku, musielibyśmy przesuwać pozostałe elementy tablicy co nie jest zbyt wygodne.

Jeżeli chcemy stworzyć listę dwukierunkową wystarczy zainicjować obiekt klasy SplDoublyLinkedList.

Kolejka

Kolejka rożni się od listy tylko tym, że dane pobierane są z początku kolejki, a zapisywane na końcu (bufor typu FIFO, First In, First Out; pierwszy na wejściu, pierwszy na wyjściu).

Jeżeli chcemy stworzyć kolejkę wystarczy zainicjować obiekt klasy SplQueue.

Kolejka priorytetowa

Kolejka priorytetowa jest szczególnym przypadkiem kolejki. Dodając element podajemy wartość priorytetu, według którego kolejka jest uporządkowana. Na wyjściu mamy element o najwyższym priorytecie.

Jeżeli chcemy stworzyć kolejkę priorytetową wystarczy zainicjować obiekt klasy SplPriorityQueue.

Stos

Stos jest strukturą danych, w której dane dokładane są na wierzch stosu i z wierzchołka stosu są pobierane (bufor typu LIFO, Last In, First Out; ostatni na wejściu, pierwszy na wyjściu). Ideę stosu danych można zilustrować jako stos położonych jeden na drugim talerzy – nowy talerz kładzie się na wierzch stosu i z wierzchu stosu zdejmuje się kolejne talerze. Elementy stosu poniżej wierzchołka można wyłącznie obejrzeć, aby je ściągnąć, trzeba najpierw po kolei ściągnąć to, co jest nad nimi.

Czytaj dalej tutaj (rozwija treść wpisu)
Czytaj dalej na blogu autora...

Wszystkie wpisy należą do ich twórców. PHP.pl nie ponosi odpowiedzialności za treść wpisów.