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

Autor wpisu: batman, dodany: 15.03.2011 16:37, tagi: php

Jeśli regularnie śledzicie mój blog, nie mogliście nie zauważyć serii zatytułowanej “PHP w chmurze”. Jej celem było zapoznanie się z chmurą Windows Azure oraz wszystkimi wadami i zaletami tego rozwiązania. Zacząłem również tworzyć pierwsze projekty działające w chmurze lub z jej zasobów korzystające. Najbardziej dojrzały z nich, wykorzystujący wszystkie dostępne mechanizmy przechowywania danych w chmurze znajdziecie w ostatniej części serii.

Dlaczego o tym piszę? Ponieważ dzisiaj na łamach serwisu MSDN ukazał się pierwszy artykuł poświęcony tematyce PHP na Windows Azure. Artykuł znajdziecie pod adresem http://msdn.microsoft.com/pl-pl/library/php-na-windows-azure. Kolejne części będą ukazywać się w regularnych odstępach. Zachęcam do lektury.

Autor wpisu: Śpiechu, dodany: 14.03.2011 22:34, tagi: php

Domknięcia i funkcje anonimowe to nowa rzecz w PHP 5.3. Nie będę pisał teorii, bo szkoda czasu (Google sporo wie jakby co). Za to skupię się na praktycznym wykorzystaniu. Przykłady w necie zawierają zazwyczaj bardzo proste rzeczy. Dzisiaj pokażę coś trochę trudniejszego.

Napiszemy sobie klasę Liczydlo, w której da się zapisywać różne algorytmy liczące np. jak policzyć średnią arytmetyczną, medianę i największy wspólny dzielnik. Algorytmy będą zapisywane w jednej zmiennej obiektu w postaci tablicy asocjacyjnej. Ostateczne rozwiązania będą wykonywane poprzez metodę przypominającą wzorzec projektowy Strategia.

Do napisania ~100 linijek. Start!

<?php
class Liczydlo {
 
   protected $algorytmy = array();
 
   public function setAlgorytm($nazwa, $funkcja) {
      // sprawdzamy czy uzytkownik rzeczywiscie podaje nam
      // funkcje anonimowa
      if (is_callable($funkcja)) {
         // algorytm latwo daje sie zapisac w tablicy
         $this->algorytmy[$nazwa] = $funkcja;
      }
      else {
         throw new Exception("{$funkcja} nie da sie wywolac jako funkcja");
      }
   }
 
   // glowna metoda liczaca, przyjmuje stringa z nazwa algorytmu
   // i zestaw liczb, na ktorych ma byc wykonane dzialanie
   public function rozwiaz($ciag) {
      $rozpoznany = $this->rozpoznajCiag($ciag);
      $algorytm = $this->zwrocAlgorytm($rozpoznany['algorytm']);
      return $algorytm($rozpoznany['liczby']);
   }
 
   // rozdziela ciag na nazwe algorytmu i tablice z liczbami do policzenia
   protected function rozpoznajCiag($ciag) {
      $ciag = preg_split('/[\s,;]+/', $ciag);
      return array('algorytm' => strtolower($ciag[0]), 'liczby' => array_slice($ciag, 1));
   }
 
   protected function zwrocAlgorytm($nazwa) {
      if (empty($this->algorytmy[$nazwa])) {
         throw new Exception("Nie znaleziono algorytmu o nazwie {$nazwa}");
      }
         return $this->algorytmy[$nazwa];
   }
}

Tyle na temat klasy. Póki co wie ona jak rozdzielić podany jej ciąg na działanie i liczby, ale nie zna żadnych algorytmów. Tutaj na scenę wchodzą domknięcia.

$liczydlo = new Liczydlo();
 
// na poczatek banal, ktory przyda sie pozniej
// czyli suma wszystkich liczb
$liczydlo->setAlgorytm('suma', function(array $liczby) {
   $wynik = '';
   foreach ($liczby as $liczba) {
      $wynik += $liczba;
   }
   return $wynik;
});
 
// teraz uzyjemy use() do wlaczenia w cialo funkcji zmiennej
// spoza zasiegu
$liczydlo->setAlgorytm('srednia', function(array $liczby) use ($liczydlo) {
   $liczbaElementow = count($liczby);
   if ($liczbaElementow < 2) throw new Exception('Podaj co najmniej 2 liczby');
   // skoro liczydlo potrafi policzyc sume to skorzystamy z tej mozliwosci
   $suma = $liczydlo->rozwiaz('suma ' . implode(',', $liczby));
   return $suma / $liczbaElementow;
});
 
// tutaj pojdziemy krok dalej, czyli policzymy mediane,
// ktora z kolei skorzysta ze sredniej (ktora z kolei korzysta z sumy)
$liczydlo->setAlgorytm('mediana', function(array $liczby) use ($liczydlo) {
   $liczbaElementow = count($liczby);
   if ($liczbaElementow < 2) throw new Exception('Podaj conajmniej 2 liczby');
   sort($liczby,SORT_NUMERIC);
   if (($liczbaElementow % 2) == 0) {
      return $liczydlo->rozwiaz('srednia ' .
         $liczby[($liczbaElementow/2)-1] . ',' .
         $liczby[$liczbaElementow/2]);
   }
   else {
      return $liczby[floor($liczbaElementow/2)];
   }
});
 
// no i to co tygryski lubia najbardziej, czyli
// liczenie najwiekszego wspolnego dzielnika za pomoca
// funkcji anonimowej zagniezdzonej w funkcji anonimowej
$liczydlo->setAlgorytm('nwd', function(array $liczby) {
   $nwdAlg = function($liczba1, $liczba2) {
      $liczba1 = (int) $liczba1;
      $liczba2 = (int) $liczba2;
      $liczba3 = 1;
      while ($liczba2 != 0) {
         $liczba3 = $liczba1 % $liczba2;
         $liczba1 = $liczba2;
         $liczba2 = $liczba3;
      }
      return $liczba1;
   }; // tutaj koniec zagniezdzonej f. anonimowej
   $liczbaElementow = count($liczby);
   if ($liczbaElementow < 2) throw new Exception('Podaj conajmniej 2 liczby');
   $nwd = $nwdAlg($liczby[0],$liczby[1]);
      if ($liczbaElementow > 2) {
         for ($i = 2 ; $i < $liczbaElementow ; $i++) {
            // rekurencyjne wywolanie funkcji $nwdAlg            
            $nwd = $nwdAlg($nwd,$liczby[$i]);
         }
      }
      return $nwd;
});

Jak tego ustrojstwa używać? Np. tak:

echo $liczydlo->rozwiaz('nwd 6,9,90');
echo $liczydlo->rozwiaz('mediana 1,3,4,5,6');

Otrzymujemy wyniki zgodne z przewidywaniami: 3 i 4.

Na koniec wnioski:

  • możemy sprawdzić czy zmienna nadaje się do wywołania za pomocą funkcji is_callable()
  • jedna funkcja anonimowa może zawierać inne funkcje anonimowe
  • aby dostarczyć coś spoza zasięgu funkcji używamy use()

Zażalenia lub prośby o dodatkowe wyjaśnienia pisać w komentarzach. Klasę pisałem w ramach relaksu niedzielnego, to mogą pojawić się jakieś błędy.

P.S.: Sposób liczenia NWD podpieprzyłem z jakiegoś forum dla gimnazjalistów :-) (tak to jest jak się śpi na matematyce)

Autor wpisu: Zyx, dodany: 13.03.2011 11:08, tagi: php

Mój ostatni wpis na temat Symfony wywołał spory odzew. Kilka osób poprosiło mnie, bym przygotował podobną charakterystykę także i innych platform, co też niniejszym, mimo pewnych obaw postanowiłem uczynić. Dlaczego? Otóż wypadałoby, by na tapetę poleciał w końcu Zend Framework. Z jednej strony, to właśnie w nim zrobiłem najwięcej projektów, a z drugiej - ostatni projekt wykonałem więcej niż rok temu i nieco wypadłem z obiegu, jeśli chodzi o nowsze wersje. Dlatego nie będę wchodzić głęboko w szczegóły techniczne, a skoncentruję się na tych aspektach, które zmienić się nie mogły.

Autor wpisu: singles, dodany: 12.03.2011 23:56, tagi: php

Wbrew pozorom, wpis ten nie jest skierowany tylko i wyłącznie do początkujących programistów. Spotkałem już kilka osób, które piszą w PHP od kilku lat i do dzisiaj wykorzystują do tego celu tzw. edytory programistyczne – EditPlus, Notepad++, PSPad itp. Żeby było jasne – wcale nie mówię, że to źle. Sam używam Notepada++ do szybkich poprawek czy też małych skryptów. Jednak przy kilku(nastu) godzinach pracy z kodem dziennie, IDE staje się narzędziem bardzo ułatwiającym pracę.

Wracając do pełnoetatowych programistów PHP. Kiedy pytam takie osoby, dlaczego nie używają IDE to odpowiedź brzmi zazwyczaj:

bo to wielka wolna kobyła.

Jest w tym stwierdzeniu trochę prawdy, aczkolwiek zależy to od IDE, a raczej języka, w jakim zostało napisane. Drugą grupą osób są ludzie, którzy poużywali trochę IDE, a potem wrócili do swoich edytorów, bo nie widzieli różnicy, a chodziło to wolniej. Problem w tym, że osoby te używały IDE jako edytora programistycznego, a nie jako IDE.

Wydaje mi się, że taki stan rzeczy wynika z następującego faktu – spora część ludzi nie wie co takie IDE potrafi.

Poniżej zawarłem listę funkcjonalności najczęściej spotykanych w zintegrowanych środowiskach programistycznych – z punktu widzenia programisty PHP. Abstrahuje od konkretnego produktu, ponieważ większość narzędzi, z którymi się spotkałem udostępniała wymienione niżej funkcje. Tak więc zaczynamy! Wartym odnotowania jest fakt, że edytory programistyczne także mogą posiadać niektóre z wymienionych funkcjonalności.

Podział na projekty

W IDE operujemy zazwyczaj pojęciem projektu – zestawu klas i komponentów, które są częściami jednej aplikacji (aczkolwiek nie jest to obligatoryjne). W ramach plików projektu znajdą się w takim razie pliki .php, .(x)html, obrazki, skrypty JavaScript czy też arkusze stylów. Dlaczego wspominam o tak prostej rzeczy – ponieważ wiele funkcjonalności opiera się właśnie na indeksowaniu zawartości tych plików.

Szybkie otwieranie plików projektu

IDE (a także niektóre edytory) udostępniają funkcję, którą w skrócie można nazwać: „Przejdź do danego pliku”. Funkcja ta nazywana jest różnie: Go To File, Go to Resource, ale jej działanie jest bardzo podobne. Wciskamy prostą kombinację klawiszy (np. Ctrl + Shift + O) i otwiera nam się małe okno z polem wyszukiwania na górze oraz listą plików poniżej. I tak, w miarę wpisywania kolejnych liter danej nazwy zostają tylko pliki pasujące do wpisanego wzorca. Następnie wystarczy wybrać plik, nacisnąć Enter i plik zostaje otwarty.

Go to file window

Lista plików pasujących do podanego wzorca

Przejście do deklaracji klasy/funkcji/metody

Wiele razy zdarzała mi się sytuacja, że patrząc na cudy kod prosiłem kogoś o pokazanie definicji użytej klasy/metody/funkcji. Co ta osoba wtedy robiła? Chwytała myszkę i nawigowała po drzewie projektu w poszukiwaniu tej pliku zawierającego wspomnianą definicję. W przypadku klas sytuacja była zazwyczaj prostsza – zakładając, że plik miał nazwę odpowiadającą nazwie klasy. Niestety, czasami poszukiwane były funkcje, a wtedy byłem świadkiem przeglądania kilku plików typu: basic_functions.php czy też html_helpers.php i wyrazu twarzy pt. „gdzie to było?”. Niektóre z osób używały wyszukiwania ciągu tekstowego w plikach. Co ciekawe, sytuacja takie zdarzały się wśród ludzi korzystających z IDE jak i z edytorów programistycznych. Jednak dzięki indeksowaniu zawartości plików projektu, IDE rozwiązują ten problem w prosty sposób – udostępniając polecenie: Go to Declaration. Naciśnięcie jednej kombinacji klawiszy automatycznie przenosi nas do odpowiedniego pliku i poszukiwanej deklaracji. Osobiście, często korzystam z tej funkcjonalności podczas pracy z ZF – kiedy chce się dowiedzieć jak działa dana metoda, błyskawicznie przechodzę do jej deklaracji i po krótkiej analizie kodu moja ciekawość zostaje zaspokojona :) Warto zauważyć, że funkcjonalność ta nie jest ograniczona tylko do plików PHP – działa tak samo w przypadku skryptów JavaScript czy też w niektórych IDE w przypadku CSS (przejście z kodu HTML do definicji klasy w innym pliku .css).

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

Autor wpisu: sokzzuka, dodany: 10.03.2011 19:36, tagi: php

Witam w drugiej części cyklu „Język Scala dla programistów PHP”. Dzisiaj weźmiemy pod lupę jedno z podstawowych zagadnień każdego języka programowania – strukturę jego kodu.

Każdy język programowania, posiada pewne archetypy, które pozwalają nam systematyzować nasz kod i czynić go czytelnym. Elementami takimi w językach proceduralnych są procedury i funkcje. Języki funkcyjne posiadają funkcję i przestrzenie nazw. Języki obiektowe – klasy i paczki.

Język Scala jako język wieloparadygmatowy posiada trzy główne elementy strukturyzujące kod – paczki, klasy i funkcje. Jednak w przeciwieństwie do „klasycznych modeli obiektowych” znanych chociażby z Javy czy PHP, oprócz „zwykłych” klas, mamy jeszcze trzy ich odmiany. Klasy w Scali dzielą się na:

  • klasy (class)
  • singletony (object)
  • cechy (trait)
  • rekordy (ciekawe czy to właściwe tłumaczenie) (case class)

Poniżej postaram się pokrótce omówić każdy rodzaj klasy wraz z kontrprzykładem z PHP/i lub Javascriptu.

Klasa:


class SampleClass(foo: Int, bar:Double) {

    private var _foo = foo;
    private var _bar = bar;

    def showFooAndBar: String = {
      return foo.toString + " i " + bar.toString;
    }

}

Standardowe klasy w Scali definiowane są podobnie jak w Javascripcie – przez konstruktor. Jak widzimy na załączonym przykładzie mamy zdefiniowany konstruktor klasy SampleClass, który przyjmuje jako argumenty zmienne foo i bar. Argumenty te przypisywane są do prywatnych zmiennych _foo i _bar. Konstruktor ten definiuje również jedną metodę – showFooAndBar , który zwraca obiekt typu String. Dla porównania kontrprzykład w javascripcie:


function SampleClass(foo, bar) {

   var _foo = foo
   var _bar = bar

   this.showFooAndBar = function(){
        return _foo + ' i ' + _bar;
   }

}

Użycie:

Scala:


object Main {
  def main(args: Array[String]): Unit = {

    val sample = new SampleClass(1,5.5)
    println(sample.showFooAndBar)
  }

}

Javascript:


var sample = new SampleClass(1, 5.5)
console.log(sample.showFooAndBar())

Jak widzimy podobieństwo jest uderzające. Dla tych, dla których model obiektowy Javascriptu jest okropny i niezrozumiały mam dobrą wiadomość – mimo podobieństwa w tym przypadku kodu jednego i drugiego języka, Scala nie bazuje na prototypach.

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

Autor wpisu: sokzzuka, dodany: 10.03.2011 09:46, tagi: php

Jarrod Nettles w niedawnym wpisie na php.internals zgłosił propozycję wprowadzenia  modyfikatorów widoczności dla klas. Propozycja postuluje, by podobnie jak w przypadku elementów klas (właściwości i metod), mieć możliwość ograniczenia widoczności klasy względem przestrzeni nazw. Jak miało by się to odbywać ? Przed deklaracją klasy można by umieścić jedno ze słów kluczowych – public, internal, lub private (albo public, protected, private):


private class Foo {
    private $_bar;

    public function bar(){
        return $this->_bar;
    }

}

Działanie:

  • public – obecny stan, posiadają bo również klasy bez zdefiniowanego modyfikatora
  • internal – klasa może być tylko wywoływane z tej samej głównej przestrzeni nazw, czyli jeżeli zdeklarujemy ją np. w Foo\Bar, to możemy ją również używać w Foo\Baz
  • private – klasa może być tylko wywoływana z tej samej przestrzeni nazw, czyli, jeżeli zdeklarujemy ją w Foo\Bar to mogę ją tylko używać w Foo\Bar i nigdzie indziej

Nie jest to ostateczny kształt propozycji, ponieważ, cały czas trwają dyskusje na ten temat na liście. Także to co napisałem może się jeszcze zmienić. Natomiast generalnie widać, że raczej większość osób jest jej przychylna. Na pewno ten „ficzer” będzie pomocny dla autorów frameworków, którzy będą mogli bardziej precyzyjnie kształtować API swoich bibliotek. Nie trudno również zauważyć, że propozycja ta jest tak naprawdę ściągnięta z języków typu C# i Java, gdzie takie modyfikatory dostępu już istnieją od dawna. Ze swojej strony mogę tylko powiedzieć, że osobiście wole model obiektowy oparty na bardziej ogólnym mechanizmie (świetnym przykładem jest Javascript).

Jestem ciekaw co Wy myślicie o tej propozycji ?

Autor wpisu: l3l0, dodany: 10.03.2011 00:33, tagi: php, symfony

Ostatnio miałem nie powtarzalną okazję przeanalizować prezentacje przygotowane na Symfony Live 2011 – konferencję Symfony która odbyła się w Paryżu. Na listę prezentacji udostępnionych na slideshare natrafiłem poprzez post @caefer-a oraz post Jakuba Zalasa. Postanowiłem napisać kilka słów o slajdach które przeczytałem.

1. Symfony 2 from the trenches

Prezentacja opisuje podstawowe koncepcje stojące za nowym frameworkiem z SensioLab. Nauczyłem się z niej wiele o kontenerze wstrzykiwania zależności oraz komponentach do cachowania no i oczywiście dowiedziałem się dlaczego Symfony2 rządzi.

2. Apostrophe (imporved Paris edition)

Myśle żę Apostrophe może być alternatywą dla Drupala czy WordPressa. Jest to całkiem porządny CMS oparty i napisany na symfony 1.4. Polecam go szczególnie tym programistom PHP którzy mają dość “poezji” Drupala i WordPressa. Mam nadzieję że będę mógł poznać i nauczyć się tego CMF-a w najbliższym czasie.

3. Leveraging Symfony2 Forms (Bernhard Schussek)

O nowych formularzach w Symfony 2 czytałem już wcześniej, jednak pierwszy raz spotkałem się w tej prezentacji z obiektami Configa w Symfony 2. Taki obiekt może być obsłużony przez mechanizm wstrzykiwania zależności (w przeciwieństwie do obiektu formularza). Wstrzykiwanie zależności jest bardzo dobym mechanizem który może pomóc nie powtarzać kodu, jednak nie wiem czy ma to sens w wypadku bardzo scustomizowanego formularza. Myśle jednak że może poprostu potrzebuje się z tym oswoić i nabrać praktyki.

4. Assetic (Symfony Live Paris)

Pierwszy raz słyszałem o Assetic-u. Bardzo mi się spodobał. Jest to optimizer do wszystkich rzeczy związanych z frontend-em czyli minimalizacji stylów, javascriptów oraz całej reszty. Ma on bardzo dobrą integrację z Symfoniowym Twigem przez TwigExtension. Napewno przyjrzę się Assetic-owi bliżej.

Podsumowanie

Nie widziałem jeszcze wszystkich prezentacji z Symfony Live. Uważam że takie slajdy są ogromną bazą wiedzy, jednak uczestnictwo w konferencji daje jeszcze więcej – nawet gdy wykłady nie są interesujące lub są dla nas oczywiste. Konferencja daje nam możliwość wymiany doświadczeń i poznania innego spojrzenia niż nasze – moim zdaniem to jest to bardzo wartościowe, dlatego polecam wszystkie konferencje. Żałuję tylko tego że nie mogłem wziąść udziału w Symfony Live, no nic może następnym razem.

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