Niezalogowany [ logowanie ]
Subskrybuj kanał ATOM Kanał ATOM    Subskrybuj kanał ATOM dla tagu php Kanał ATOM (tag: php)

Autor wpisu: matipl, dodany: 04.06.2012 21:06, tagi: php

PHPCon Poland - logoCzas pędzi, jak rakieta. Może kiedyś się zbiorę i opiszę co takiego działo się od listopada 2011, tymczasem…

Miło jest mi poinformować, że rozpoczął się nabór propozycji prelekcji na kolejną już edycję   PHPCon Poland. Ale to nie wszystko. W tym roku organizatorzy biorą urlop ;) i prelekcje wybierać będziecie Wy (precyzując – osoby zarejestrowane w serwisie PHPCon).

Na propozycje prelekcji czekamy do 20 czerwca, później zapraszamy do głosowania.

Kiedy PHPCon? W tym roku konferencja odbędzie się w dniach 28-30 września (piątek-niedziela), jak poprzednio w Mąchocicach Kapitulnych koło Kielc.

Autor wpisu: bastard13, dodany: 31.05.2012 14:38, tagi: php, oop

klasa abstrakcyjna

Czym jest klasa abstrakcyjna? Nie będę się rozpisywał na temat konstrukcji (jak zwykle:), ponieważ w internecie można znaleźć sporo definicji.We wstępie chciałbym się natomiast skupić na podziale klas abstrakcyjnych. Co prawda, z tego co się orientuję, żadnego oficjalnego podziału nie ma, ale po jakimś czasie programowania można wyróżnić trzy powtarzające się wzorce (nie w znaczeniu wzorców projektowych) klas abstrakcyjnych: Czytaj więcej »

Autor wpisu: Śpiechu, dodany: 26.05.2012 12:46, tagi: php

Zgodnie z obietnicą dzisiaj część dotycząca bezpiecznego uruchamiania zewnętrznych skryptów PHP. Od razu mówię, że nie jestem jakimś guru dot. zabezpieczeń systemów Unix. Zebrałem rozsypane po internecie informacje i spróbowałem złożyć to w całość.

Gist został uaktualniony o klasę ICMPPingProcesserrzućcie okiem. Posłuży jako baza do naszych działań.

Jak już wspomniałem w poprzednim wpisie, w Linuksie nie można wykonać polecenia socket_create() na typowym użytkowniku Apache, czyli www-data. Aby obejść ten problem skorzystałem z polecenia posix_seteuid(0) zmieniającego użytkownika procesu na roota na czas życia obiektu ICMPPing. Z kolei aby wykonać to polecenie musimy stać się rootem :-). Z terminala nic trudnego:

sudo php icmp.php http://spiechu.pl

Zostaniemy zapytani o hasło i dostajemy odpowiedź skryptu. Problem pojawia się gdy chcemy wywołać polecenie z poziomu innego skryptu PHP. W Ubuntu nie da się/nie umiem (a próbowałem na wiele sposobów) wpisać hasła dla sudo z poziomu lini komend. Wobec tego trzeba zmusić sudo aby nie pytał o hasło. Oczywiście opcja aby nadać użytkownikowi www-data wszystkie uprawnienia roota na stałe nie wchodzi w grę. Trzeba maksymalnie zawęzić „pole manewru” dla www-data.

Wobec tego przyczepiamy się do pliku /etc/sudoers, który przechowuje uprawnienia związane z poleceniem sudo. Przypominam, że plik sudoers należy edytować wyłącznie za pomocą polecenia visudo, a więc w terminalu:

sudo visudo

i jedziemy z edycją:

# Ustawiamy kilka aliasow
# gdy skryptow zrobi sie sporo
# bedzie latwiej zarzadzac tym balaganem
User_Alias APACHE_USER = www-data
Runas_Alias ROOT_USER = root
Host_Alias PHP_MACHINE = dave-ubunciak
Cmnd_Alias ICMP_SCRIPT = /usr/bin/php /home/dave/icmp.php http\://*
 
# Wlasciwe polecenie
APACHE_USER PHP_MACHINE = (ROOT_USER) NOPASSWD: ICMP_SCRIPT

Polecenie można przetłumaczyć tak: Użytkownik www-data na maszynie dave-ubunciak jako root może wykonać skrypt php o nazwie icmp.php bez hasła z parametrem rozpoczynającym się od http://. Wszelkie odstępstwa będą traktowane komunikatem sudo: no tty present and no askpass program specified Sorry, try again. Od tego momentu możemy w dowolnym skrypcie wywoływać:

// na czas developmentu warto na koncu polecenia wpisac
// 2>&1 dzieki czemu strumien stderr przekierujemy na wyjscie
$process = shell_exec('sudo php /home/user/icmp.php http://www.spiechu.pl');
echo $process;

Co jeszcze można zrobić z samym plikiem icmp.php? Możemy zmienić mu użytkownika i grupę na root i ograniczyć możliwość jego wykonania wyłącznie do roota, czyli:

sudo chown root icmp.php
sudo chgrp root icmp.php
sudo chmod 400 icmp.php

Na koniec przyczepię się do samego icmp.php. Napisałem klasę ICMPPingProcesser, która sprawdza czy podany adres www jest prawidłowy i odsiewa wszystko poza podstawowym adresem hosta. Poniżej przytaczam w całości:

class ICMPPingProcesser
{
    /**
     * @var string
     */
    protected $urlAddress;
 
    /**
     * @param string $urlAddress
     */
    public function __construct($urlAddress)
    {
        $this->urlAddress = $urlAddress;
    }
 
    /**
     * Returns 'Trying {$urlAddress}: PING RESPONSE: Everything OK'
     * when url address replied correctly
     *
     * @return string
     */
    public function ping()
    {
        try {
            $message = '';
            $urlToPing = $this->processUrl($this->urlAddress);
            if (!$this->isUrlExists($urlToPing)) {
                throw new Exception("{$urlToPing} doesn't exist!");
            }
            $icmp = new ICMPPing();
            $respond = $icmp->sendPacket($urlToPing, 'Everything OK');
            $message = "Trying {$urlToPing}: ";
            $message .= "PING RESPONSE: {$icmp->analyzeRespond($respond)}";
 
            return $message;
        } catch (Exception $e) {
            $message .= $e->getMessage();
 
            return $message;
        }
    }
 
    /**
     * Returns sanitized url host from param
     *
     * @param  string    $urlAddress
     * @return string    url host
     * @throws Exception when url address is not valid
     */
    protected function processUrl($urlAddress)
    {
        $sanitizedUrl = filter_var($urlAddress, FILTER_SANITIZE_URL);
        if ($sanitizedUrl === false || filter_var($sanitizedUrl, FILTER_VALIDATE_URL) === false) {
            throw new Exception("{$urlAddress} is not valid URL");
        }
 
        return parse_url($sanitizedUrl, PHP_URL_HOST);
    }
 
    /**
     * Checks if url address exists
     *
     * @param  string  $urlAddress
     * @return boolean
     */
    protected function isUrlExists($urlAddress)
    {
        if (gethostbyname($urlAddress) === $urlAddress) {
            return false;
        }
 
        return true;
    }
 
}
 
if (PHP_SAPI === 'cli' && isset($_SERVER['argv'][1])) {
    $pingProcesser = new ICMPPingProcesser($_SERVER['argv'][1]);
    echo $pingProcesser->ping();
} else {
    echo 'Not in cli mode or agument not set';
}

Ostatnie kilka linijek sprawdza czy skrypt odpalany jest w trybie lini komend i czy istnieje jakiś argument.

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

Autor wpisu: d3ut3r, dodany: 25.05.2012 15:44, tagi: php

Raczej każdy kto używa przeglądarki FireFox do codziennej pracy nad kodem (x)HTML/CSS/JS zna genialne narzędzie o nazwie FireBug, użytkownicy którzy dodatkowo pracują z PHP być może korzystali z FirePHP jako, że przesiadłem się z FireFox’a na Chrome szukałem odpowiednika FirePHP dla tej przeglądarki i w końcu znalazłem.

Słowem wstępu dla niewiedzących FirePHP pozwalał nam w stosunkowo prosty sposób wykorzystać konsolę FireBuga do wyświetlania komunikatów ze skryptów PHP. Rozwiązanie w moim przypadku idealne, ponieważ często przychodzi mi poprawiać błędy na istniejących już stronach gdzie nie dopuszczalne jest aby odwiedzający widział moje tajemne wiadomości pomagające w debugowaniu kodu :D

Rozszerzenie dla Chrome możemy pobrać z tego miejsca dodatkowo musimy pobrać klasę ChromePHP.

Gdy mamy już zainstalowane rozszerzenie w przeglądarce, możemy przystąpić do testów. Stworzyłem przykładowy plik test.php o zawartości:

<?php
    include('ChromePhp.php');

    for ($i=0;$i<=10;$i++){
        ChromePhp::info($i);
    }
?>

Teraz wystarczy otworzyć naszą stronę w przeglądarce, po wczytaniu za pomocą kombinacji ctrl+shift+j uruchamiamy konsolę JavaScript w której znajdziemy wynik działania naszego polecenia ChromePhp::info($i); wszystko powinno wyglądać mniej więcej w ten sposób:

Oczywiście możliwości ChromePhp nie kończą się na wyświetlaniu zwykłego tekstu ChromePhp posiada szereg metod dzięki którym informacje w konsoli będą czytelne i logicznie poukładane.

1. ::warn,::info,::error

To podstawowe i najczęściej używane metody każda z nich wyświetla inny typ komunikatu odpowiednio: ostrzeżenie , informacja , błąd. Wszystkie metody przyjmują do 2 parametrów poprawne użycie może wyglądać tak:

<?php
    include('ChromePhp.php');

    function badDay(){
      throw new Exception('To bardzo zły dzień');
    }
   
    ChromePhp::info('czas z serwera',date('d-m-Y, H:i:s'));

    try{
     badDay();
    } catch (Exception $e){
     chromePhp::error($e);
    }

     chromePhp::warn('aaaa','bbbbb');
   
?>

powyższy kod powinien dać nam taki rezultat:

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

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: 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.