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

Autor wpisu: sokzzuka, dodany: 17.02.2011 15:16, tagi: php

Jak już było wczoraj zapowiedziane. Do ściągnięcia jest najnowsza wersja Release Candidate PHP – 5.3.6RC1. Jest to Release Candidate, a więc nie należy jej używać na produkcji. Kolejny RC albo finalna wersja pojawi się prawdopodobnie za około dwa tygodnie.

Źródło: http://news.php.net/php.internals/51453

Autor wpisu: widmogrod, dodany: 16.02.2011 22:20, tagi: php

Moja pierwsza prezentacja na KrakSpotTECH, przed tak dużą publiką (ok 200 osób na sali). Dużo się nauczyłem a szczególnie to że jeżeli nie czujesz stresu to nie znaczy że go nie ma :)

Temat mojej prezentacji dotyczył zagadnienia DataGrid w PHP. Dla zainteresowanych umieszczam poniżej prezentację:

Data grid w PHP View more presentations from widmogrod.

Buzz: - http://krakspot.pl/2011/02/01/krakspot-tech-3-agenda/

Autor wpisu: sokzzuka, dodany: 16.02.2011 09:12, tagi: php

Jak niektórzy z nas wiedzą, w innych językach np. C istnieje rodzaj struktury danych zwany popularnie „enumem”. Enum jest skrótem od „enumeracja”. Taka struktura danych może przyjąć tylko kilka, z wcześniej zadeklarowanych wartości. Więcej informacji znajdziecie oczywiście w Wikipedii, natomiast tutaj chciałbym przybliżyć dwie metody jakie można użyć w PHP do osiągnięcia tej samej funkcjonalności. Pierwszą metodą jest użycie wbudowanej klasy SplEnum, tak jak zostało to pokazane w komentarzu na php.net:

class Fruit extends SplEnum
{
  // If no value is given during object construction this value is used
  const __default = 1;
  // Our enum values
  const APPLE     = 1;
  const ORANGE    = 2;
}

$myApple   = new Fruit();
$myOrange  = new Fruit(Fruit::ORANGE);
$fail      = 1;

function eat(Fruit $aFruit)
{
  if (Fruit::APPLE == $aFruit) {
    echo "Eating an apple.\n";
  } elseif (Fruit::ORANGE == $aFruit) {
    echo "Eating an orange.\n";
  }
}

eat($myApple);  // Eating an apple.
eat($myOrange); // Eating an orange.

eat($fail); // PHP Catchable fatal error:  Argument 1 passed to eat() must be an instance of Fruit, integer given

Jak widać idea jest bardzo prosta i kod właściwie mówi wszystko. Jest jednak drugi sposób, chyba troszkę mniej znany, polegający na użyciu systemu klas w php:


abstract class Fruit {}
class Orange extends Fruit {}
class Apple extends Fruit {}

function eat(Fruit $fruit)
{
  if ($fruit instanceof Apple) {
    echo "Eating an apple.\n";
  } elseif ($fruit instanceof Orange) {
    echo "Eating an orange.\n";
  }
}

eat(new Apple); //Eating an apple
eat(new Orange); //Eating an orange
eat(1) // PHP Catchable fatal error:  Argument 1 passed to eat() must be an instance of Fruit, integer given

Oba rozwiązania mają oczywiście ten sam efekt. Warto zauważyć, że rozwiązanie nr. 2 bardzo ładnie prezentuje ideę polimorfizmu i dziedziczenia. Hierarchia klas pokazuje, że zarówno Jabłko jak i Pomarańcza jest Owocem i kierunek tej zależności, tj. Jabłko jest Owocem a nie Owoc Jabłkiem :)

Autor wpisu: matipl, dodany: 16.02.2011 08:53, tagi: php

PHPCon Poland 2011Wczoraj kolejna osoba zapytała się mnie, czy wiem coś o tegorocznej edycji PHPCon, bo w Sieci cicho na ten temat. Dlatego podzielę się z Wami tym co wiem…

W tym roku konferencja dla miłośników PHP nie odbędzie się wiosną, ale dopiero jesienią. Jest to podyktowane m.in. terminami innych konferencji w Polsce i w Europie, ponieważ kilku prelegentów zgłaszało takie uwagi.

Chcieliśmy w tym roku Was zaskoczyć i zrobić konferencję jeszcze bardziej na południu Polski, ale ostatecznie PHPCon 2011 odbędzie się 15 km na wschód od Kielc (czyli nie wiele dalej niż ostatnio) w Hotelu Przedwiośnie (Mąchocice Kapitulne).

A kiedy? W dniach 21-23 października (piątek-niedziela). Teraz zostało tylko czekać na listę prelegentów oraz otwarcie zapisów :) Będę informował.

Autor wpisu: sokzzuka, dodany: 16.02.2011 08:45, tagi: php

Johannes Schlüter (release manager dla brancha 5.3.x)  zapowiedział dzisiaj wydanie PHP 5.3.6 w wersji Release Candidate na czwartek 17-tego lutego. Wszyscy chętni do testowania otrzymają więc jutro świeżą porcję kodu :)

Autor wpisu: batman, dodany: 16.02.2011 08:00, tagi: php

Windows Azure oferuje trzy podstawowe mechanizmy przechowywania danych. Każdy z nich przeznaczony jest dla innego typu danych i każdy z nich oferuje inne możliwości. Dzisiaj skupimy się na niestandardowym zastosowaniu blobów, czyli pojemników na dane binarne. Jeśli nie wiecie czym są bloby, możecie zapoznać się z ich opisem tutaj.

Problem

Problem z jakim się dzisiaj zmierzymy znany jest wszystkim, którzy mieli do czynienia z aplikacją przechowującą pliki wgrywane przez użytkowników. Najwięcej kłopotu w tego typu aplikacji przysparza przechowywanie informacji o zmianach jakie użytkownik wprowadził do pliku. Najpopularniejszym rozwiązaniem tego problemu jest przechowywanie poprzednich wersji pliku w osobnych katalogach, ewentualnie zmiana nazwy pliku i dodanie do niego znacznika czasu. Do tego dochodzi jeszcze baza danych, w której przechowywane są informacje o użytkowniku wprowadzającym zmiany (czasami więcej niż jeden użytkownik mają możliwość nadpisania pliku), dacie wprowadzenia zmian oraz szereg innych niezbędnych informacji.

Rozwiązanie

Azure Storage, a dokładniej bloby, oferują interesującą funkcjonalność nazwaną snapshot. Dzięki niej możemy stworzyć migawkę pliku wraz z jej dokładnym opisem. Następnie jeśli zajdzie taka potrzeba możemy odwołać się do dowolnej migawki oraz informacji z nią związanych. W takim modelu baza danych wymagana jest do przechowywania jedynie identyfikatora migawki. Cała reszta siedzi zaszyta w blobie.

Przygotowanie środowiska

W dzisiejszym przykładzie wykorzystamy Windows Azure jedynie jako magazyn danych. Aplikacja uzyskująca dostęp chmury będzie znajdować się w innej lokalizacji. Podobnie jak ostatnim razem zaprezentowany zostanie jedynie szkielet aplikacji, który został maksymalnie uproszczony.

Nasze środowisko będzie się składać z jednego kontenera oraz jednego bloba. Blob ten będzie posiadał dwie migawki wraz z informacją o użytkowniku, który ją wykonał. Do przygotowania środowiska wykorzystamy prosty skrypt.

require_once 'Microsoft/WindowsAzure/Storage.php';
require_once 'Microsoft/WindowsAzure/Credentials/CredentialsAbstract.php';
require_once 'Microsoft/WindowsAzure/Storage/Blob.php';

// Dane wymagane do zalogowania się na konto Windows Azure
// W przykładzie logujemy się do konta lokalnego
$host = Microsoft_WindowsAzure_Storage::URL_DEV_BLOB;
$accountName = Microsoft_WindowsAzure_Credentials_CredentialsAbstract::DEVSTORE_ACCOUNT;
$accountKey = Microsoft_WindowsAzure_Credentials_CredentialsAbstract::DEVSTORE_KEY;

$storageBlob = new Microsoft_WindowsAzure_Storage_Blob($host, $accountName, $accountKey);

// Usuń kontener i stwórz nowy
if($storageBlob->containerExists('wersjonowanie')) {
	$storageBlob->deleteContainer('wersjonowanie');
}
$storageBlob->createContainer('wersjonowanie');

// Ustawienie kontenera jako publiczny
$storageBlob->setContainerAcl('wersjonowanie', Microsoft_WindowsAzure_Storage_Blob::ACL_PUBLIC_CONTAINER);

// Kowalski uploadował plik
$storageBlob->putBlob('wersjonowanie', 'plik.jpg', '/ulopadowany/plik/1.jpg', array('user' => 'Kowalski'));

// Nowak uploadował plik
// Wykonujemy migawkę pliku. W prawdziwej aplikacja jej identyfikator powinien trafić do bazy.
echo $storageBlob->snapshotBlob('wersjonowanie', 'plik.jpg') . PHP_EOL;

// Nadpisujemy bloba
$storageBlob->putBlob('wersjonowanie', 'plik.jpg', '/ulopadowany/plik/2.jpg', array('user' => 'Nowak'));

// admin uploadował plik
// Wykonujemy kolejną migawkę pliku i zapisujemy jej identyfikator
echo $storageBlob->snapshotBlob('wersjonowanie', 'plik.jpg') . PHP_EOL;

// Nadpisujemy bloba
$storageBlob->putBlob('wersjonowanie', 'plik.jpg', '/ulopadowany/plik/3.jpg', array('user' => 'admin'));

W powyższym kodzie na uwagę zasługują dwa elementy. Pierwszym jest dodawanie bloba. W tym miejscu (a dokładniej w czwartym argumencie metody pubBlob), mamy możliwość dodania do bloba metadanych w postaci tablicy klucz –> wartość. Metadane nie mogą zawierać więcej niż 8KB informacji, a klucz nie może być dłuższy niż 1024 znaki. Mimo niewielkiego rozmiaru, metadane w zupełności wystarczą do przechowania wszystkich niezbędnych informacji o blobie (np. nazwa użytkownika).

Drugim elementem jest moment wykonania migawki. Odpowiedzialna za to metoda snapshotBlob, zwraca unikalny w obrębie bloba identyfikator w postaci wartości DateTime. Aby móc później odwołać się do konkretnej migawki, musimy ten identyfikator zapisać, np. w bazie danych.

Wyświetlanie historii pliku

require_once 'Microsoft/WindowsAzure/Storage.php';
require_once 'Microsoft/WindowsAzure/Credentials/CredentialsAbstract.php';
require_once 'Microsoft/WindowsAzure/Storage/Blob.php';

$host = Microsoft_WindowsAzure_Storage::URL_DEV_BLOB;
$accountName = Microsoft_WindowsAzure_Credentials_CredentialsAbstract::DEVSTORE_ACCOUNT;
$accountKey = Microsoft_WindowsAzure_Credentials_CredentialsAbstract::DEVSTORE_KEY;

$storageBlob = new Microsoft_WindowsAzure_Storage_Blob($host, $accountName, $accountKey);

// pobrane z bazy identyfikatory migawek
$snapshotId1 = '2011-01-25T08:15:14.7130000Z';
$snapshotId2 = '2011-02-01T16:09:04.8730000Z';

// pobranie metadanych z bloba oraz migawek
$meta = $storageBlob->getBlobMetadata('wersjonowanie', 'plik.jpg');
$metas1 = $storageBlob->getBlobMetadata('wersjonowanie', 'plik.jpg', $snapshotId1);
$metas2 = $storageBlob->getBlobMetadata('wersjonowanie', 'plik.jpg', $snapshotId2);

// wyświetlenie zdjęć oraz ich autorów
echo 'Aktualne zdjęcie (autor: ' . $meta['user'] . ')<br />';
echo '<img src="zdjecie.php" width="300" />';
echo '<br /><br />';

echo 'Snapshot 1 (autor: ' . $metas1['user'] . '):<br />';
echo '<img src="zdjecie.php?snapshotid=' . urlencode($snapshotId1) . '" width="300" />';
echo '<br /><br />';

echo 'Snapshot 2 (autor: ' . $metas2['user'] . '):<br />';
echo '<img src="zdjecie.php?snapshotid=' . urlencode($snapshotId2) . '" width="300" />';
echo '<br /><br />';

Jak widać na powyższym kodzie, operacje na migawkach przeprowadza się w identyczny sposób jak na aktualnej wersji bloba. Jedyną różnicą jest konieczność użycia zapisanego wcześniej identyfikatora migawki.

Ostatnim elementem układanki jest skrypt pobierający zawartość bloba i zwracającego go jako obrazek (zdjęcie.php).

require_once 'Microsoft/WindowsAzure/Storage.php';
require_once 'Microsoft/WindowsAzure/Credentials/CredentialsAbstract.php';
require_once 'Microsoft/WindowsAzure/Storage/Blob.php';

$host = Microsoft_WindowsAzure_Storage::URL_DEV_BLOB;
$accountName = Microsoft_WindowsAzure_Credentials_CredentialsAbstract::DEVSTORE_ACCOUNT;
$accountKey = Microsoft_WindowsAzure_Credentials_CredentialsAbstract::DEVSTORE_KEY;

$storageBlob = new Microsoft_WindowsAzure_Storage_Blob($host, $accountName, $accountKey);

header('Content-Type: image/jpg');

// jeśli nie ma identyfikatora migawki, pobierz zawartość aktualnego bloba
if(!isset($_GET['snapshotid'])) {
	echo $storageBlob->getBlobData('wersjonowanie', 'plik.jpg');
}
else {
	// pobierz zawartość migawki
	echo $storageBlob->getBlobData('wersjonowanie', 'plik.jpg', urldecode($_GET['snapshotid']));
}

Voila!

W ten oto sposób stworzyliśmy proste i skuteczne zarazem wersjonowanie plików uploadowanych przez użytkownika. Nie musimy się na tym zatrzymywać. W przypadku większej ilości informacji, które powinny znaleźć się w opisie bloba, można skorzystać z tabel. Metadane zawierałyby jedynie klucz partycji oraz klucz wiersza.

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

Autor wpisu: batman, dodany: 09.02.2011 08:00, tagi: php

Przez ostatnie trzy części “PHP w chmurze” poznawaliśmy Azure Storage, czy mechanizmy przechowywania danych w Windows Azure. Dla przypomnienia – były to bloby, kolejki oraz tabele. Ponieważ we wspomnianych wpisach skupiłem się na wyjaśnieniu jak one działają, a nie na ich praktycznych zastosowaniach, mechanizmy te mogły wydawać się nieco oderwane od rzeczywistości. Dzisiaj, zainspirowany jednym z tutoriali z serwisu Windows Azure for PHP, postanowiłem napisać jego nieco ulepszoną wersję.

Budowa aplikacji

Aplikacja nad którą będziemy pracować, nie będzie wiele robiła. Jej jedynym zadaniem będzie wysyłanie maili. W prawdziwym życiu, aplikacja taka stanowiłaby część większej całości. Aby nie zaciemniać obrazu, zastosowałem kilka skrótów, które w produkcyjnych aplikacjach nie powinny mieć miejsca.

Aplikacja będzie podzielona na dwie części – web role oraz worker role. Gwoli przypomnienia wyjaśnię, że rola typu web jest typową aplikacją internetową, jaką wszyscy znamy i lubimy – posiada graficzny interfejs użytkownika, można się do niej dostać z dowolnego miejsca Internetu, a odebrane dane zapisuje w celu dalszej ich obróbki. Z kolei rola typu worker, to tania siła robocza, która zajmuje się przetwarzaniem danych. Idealnie nadaje się do wykonywania zadań, mogących spowodować spadek wydajności roli web. W pewnym sensie workera można przyrównać do usługi, która działa w tle zawsze gotowa do pracy.

W naszej aplikacji rola web będzie formularzem odbierającym dane od użytkownika i zapisującym je w Azure Storage, a worker na ich podstawie będzie wysyłał emaile. Dlaczego wysyłką maili ma się zajmować worker, a nie web? Z bardzo prostego powodu. Jeśli serwer pocztowy nie będzie dostępny, wówczas rola web (widoczna dla użytkownika) przestanie działać lub w najlepszym wypadku będzie zgłaszała błąd w po wysłaniu formularza. Worker z kolei, mimo iż napotka ten sam problem, zgłosi go po cichu (z dala od wścibskich oczu). W ten sposób użytkownik cieszy cię, że strona działa szybko, dane nie są tracone, a my wysyłamy armię wyszkolonych małp do naprawienia problemu.

Do komunikacji między rolami, wykorzystane zostaną kolejki, załączniki będą przechowywane jako bloby, a tabele posłużą nam jako pojemnik na informacje wysłane przez użytkownika.

Na koniec warto wspomnieć, iż formularz, walidację danych oraz wysyłkę maili zleciłem Zend Frameworkowi. Szybko, elegancko, bez marnowania czasu.

Tworzenie projektu

Wiemy już jakie role będą nam potrzebne (jedna web i jedna worker) oraz z jakich mechanizmów przechowywania danych będziemy korzystać, czas rozpocząć prace nad aplikacją. Zaczniemy od utworzenia nowego projektu w Eclipse (instalację środowiska znajdziecie w pierwszym wpisie serii).

Z menu File wybieramy opcję New –> Project, a następnie Windows Azure PHP Project.

azure1

Jako nazwę projektu wpisujemy azuremail i klikamy przycisk Next. W kolejnym oknie w polu Role name wpisujemy web1, zaznaczamy checkbox Windows Azure Data Storage oraz ponownie klikamy przycisk Next

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.