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

Autor wpisu: sokzzuka, dodany: 09.05.2011 09:53, tagi: php

Wczoraj Stas Malyshev ponownie podniósł kwestię rozwoju PHP 5.4.  Zaproponował następujący plan:

  • od obecnej chwili do 18 maja mają być zgłaszane propozycje cech, które są pożądane w tej wersji
  • 18 maja – początek dyskusji i głosowania nad cechami, które się znajdą w wersji finalnej
  • 15 czerwiec – wersja alfa, wydzielenie brancha 5.4 z trunka, koniec z dodawaniem nowych ficzerów, tylko poprawki błędów i rozwój zaakceptowanych cech
  • 20 lipiec – beta tylko poprawki błędów
  • 24 sierpień – Release Candidate 1 i kolejne RC co 2 tygodnie
  • Październik / Listopad – wersja finalna

Plan jaki zaproponował Stas wydaje się dość realistyczny i zyskał już poparcie Rasmusa Lerdorfa (BDFL PHP). Wszystkich ciekawych, co znajdzie się w PHP 5.4 zachęcam do czytania dokumentu „TODO„.

Autor wpisu: Tomasz Kowalczyk, dodany: 08.05.2011 19:40, tagi: php, mysql, framework, symfony2

Ze wszystkich języków programowania, jakich tematykę poruszam / poruszałem na tym blogu, PHP zajmuje zaszczytne, pierwsze miejsce pod względem liczby wpisów. Zastanawiający jest zatem fakt, że w Linkdumpie jest go relatywnie najmniej. W ramach poprawy tej statystyki zapraszam do zapoznania się z listą dziesięciu wyselekcjonowanych linków o PHP właśnie. Fotografia: totalAdo, CC-BY. Linkdump: Chłopcy PeHaPowcy. [...]

Autor wpisu: Śpiechu, dodany: 07.05.2011 12:56, tagi: php, mysql

Dzisiaj kończę temat wstrzykiwania zależności. Punktem wyjścia będzie poprzedni kod. Kontener posłuży do skonfigurowania jeszcze dwóch obiektów. Napisałem sobie 2 proste klasy: SelectQuery, który odpyta bazę danych na podane zapytanie oraz SelectQueryCache, który zachowa wynik zapytania do pliku. Wynik będzie ważny tylko przez podany czas.

Przy okazji zmieniłem trochę formatowanie składni na bardziej „Zend-Frameworkowe”. Mam nadzieję, że bardziej czytelne. Kolejną zmianą jest używanie w nazwach klas/zmiennych wyłączenie języka angielskiego. Wam to nie będzie przeszkadzać, a mnie oszczędzi masę czasu gdybym chciał coś kiedyś rzucić na szerokie wody.

W metodzie loadDefaults() dorzucamy zmienne konfigurujące obiekt cachujący i dwa domknięcia potrafiące wyprodukować gotowe obiekty:

//zmienne konfigurujące pdo z poprzedniego wpisu
 
$this->cache_filename = 'queries.cache';
$this->cache_interval = 30;
$this->cache_class = 'SelectQueryCache';
 
$this->selectQueryCache = function (DBKontener $k)
{
  return new $k->cache_class($k->cache_filename , k->cache_interval);
};
 
$this->selectQuery = function (DBKontener $k)
{
  $q = new SelectQuery($k->pdo_getPDO);
  // wstrzykujemy zaleznosc
  $q->setCache($k->selectQueryCache);
  return $q;
};

Właściwie to wpis można by teraz zamknąć. Widać jak cache tworzony jest na podstawie zmiennych oraz widać wstrzyknięcie zależności w postaci metody setCache(). Innym sposobem wstrzykiwania jest konstruktor. Nie zrobiłem tak z uwagi na to, że SelectQuery może sobie radzić bez obiektu cachującego, więc po co wymuszać.

Poniżej załączam kod dwóch wspomnianych wyżej klas.

class SelectQuery
{
  /**
   * @var PDO
   */
  protected $pdo;
 
  /**
   * @var SelectQueryCache 
   */
  protected $cache = null;
 
  public function __construct(PDO $pdo)
  {
    $this->pdo = $pdo;
  }
 
  /**
   * @param SelectQueryCache $sqc dependency injection
   */
  public function setCache(SelectQueryCache $sqc)
  {
    $this->cache = $sqc;
  }
 
  /**
   * @param string $query
   * @return array
   */
  public function getResults($query)
  {
    if ($this->cache)
    {
      $cachedResults = $this->cache->getCachedResults($query);
      if ($cachedResults !== null)
      {
        return $cachedResults;
      }
    }
    $q = $this->pdo->prepare($query);
    $q->execute();
    $rows = array();
    while ($row = $q->fetch(PDO::FETCH_ASSOC))
    {
      $rows[] = $row;
    }
    if ($this->cache)
    {
      $this->cache->cacheQuery($query , $rows);
    }
    return $rows;
  }
}
 
class SelectQueryCache
{
  /**
   * @var array contains all cached queries
   */
  protected $cachedQueries = array();
 
  /**
   * @var SPLFileInfo
   */
  protected $cacheFile;
 
  /**
   * @var int time interval in secs to check if cache is still valid
   */
  protected $validTime;
 
  public function __construct($filename , $validtime = 60)
  {
    $this->cacheFile = new SplFileInfo(__DIR__ . '/' . $filename);
    $this->validTime = (int) $validtime;
    $this->loadCache();
  }
 
  protected function loadCache()
  {
    if (!file_exists($this->cacheFile))
    {
      touch($this->cacheFile);
    }
    $file = $this->cacheFile->openFile('r');
    if ($file->flock(LOCK_SH))
    {
      $this->cachedQueries = json_decode(file_get_contents($file) , true);
      $file->flock(LOCK_UN);
    }
    else
    {
      throw new Exception('Cannot acquire file lock to read file');
    }
  }
 
  public function cacheQuery($query , $result)
  {
    $this->cachedQueries[$query] = array(
      'time' => time() ,
      'result' => $result);
  }
 
  public function getCachedResults($query)
  {
    if ($this->isValidCache($query))
    {
      return $this->cachedQueries[$query]['result'];
    }
    else
    {
      return null;
    }
  }
 
  protected function isValidCache($query)
  {
    if ($this->cachedQueries !== null
      && array_key_exists($query , $this->cachedQueries)
      && $this->isValidTime($this->cachedQueries[$query]['time']))
    {
      return true;
    }
    else
    {
      return false;
    }
  }
 
  protected function isValidTime($timestamp)
  {
    return ((time() - $this->validTime) < $timestamp);
  }
 
  protected function cleanUpOldCache()
  {
    foreach ($this->cachedQueries as $key => $cq)
    {
      if (!$this->isValidTime($cq['time']))
      {
        unset($this->cachedQueries[$key]);
      }
    }
  }
 
  protected function save()
  {
    $serializedData = json_encode($this->cachedQueries);
    $file = $this->cacheFile->openFile('w');
    if ($file->flock(LOCK_EX))
    {
      $file->fwrite($serializedData);
      $file->flock(LOCK_UN);
    }
    else
    {
      throw new Exception('Cannot acquire exclusive file lock to save file');
    }
  }
 
  public function __destruct()
  {
    $this->cleanUpOldCache();
    $this->save();
  }
}

Myślę, że w SelectQuery nie ma nic specjalnego, no może poza getResults(), które najpierw sprawdza czy jest cache i jakiś wynik, a jak nie to odpytuje bazę danych i zapisuje wynik do cache.

Za to w SelectQueryCache znajdzie się trochę mięska:

  1. Do serializacji danych używam json_encode, które jest ponoć trochę szybsze od zwykłej serializacji, a zapisane dane mają formę strawniejszą dla humanoidów.
  2. Dane w pliku trzymam w postaci tablicy asocjacyjnej, której kluczem jest zapytanie, a wartościami wynik zapytania i czas utworzenia.
  3. Do sprawdzania czy cache nie jest przeterminowany odejmuję liczbę sekund od obecnego czasu i sprawdzam czy jest wcześniejsza od czasu utworzenia danego klucza.
  4. Oczyszczam cache sprawdzając czy poszczególne klucze nie są już przeterminowane i w razie czego wywalam cały klucz.
  5. Do zapisu do pliku używam destruktora. Mam pewność, że obiekt zaraz przed zakończeniem żywota zapisze dane do pliku.

Na koniec przykład użycia całości:

$c = new DBKontener();
$query = $c->selectQuery;
$results = $query->getResults('SELECT nazwa_pola FROM jakas_tabela');

Za pierwszym razem dane zostaną pobrane z bazy, a następnie przez 30 sekund z pliku cache.

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

Chmura jaka jest, każdy widzi. Ot zbieranina serwerów, opakowana w nowy papierek, opatrzona nowym bilecikiem z marketingowym wierszykiem. Z jedną zasadniczą różnicą. Nie musimy się grzebać w zarządzanie inwentarzem, nie musimy martwić się o load balancing, a pojęcie “zasoby sprzętowe” zostaje zastąpione pojęciem “instancja”. Tak na prawdę my jako programiści jesteśmy w stanie zrobić wszystko sami, bez konieczności angażowania administratora do skonfigurowania serwera, postawienia firewalla i całej tej magii, od której powinniśmy trzymać się z daleka. Jeśli śledzicie mój blog, na pewno zauważyliście, iż od dłuższego czasu interesuję się tematyką cloud computing, a dokładniej Windows Azure. Ostatnio zainteresowałem się kolejnym projektem związanym z PHP w chmurze – PHP Fog.

Otrzymałem właśnie zaproszenie do beta testów i od razu założyłem konto oraz zagłębiłem się lekturę dokumentacji oraz FAQ. Udało mi się również pomęczyć na czacie Macieja Skierkowskiego, product managera w PHP Fog i jak się okazało byłego pracownika Microsoftu pracującego przy Windows Azure. Jaki ten świat jest mały :)

Do rzeczy. Czym jest PHP Fog? Jest to “chmurowa” wersja LAMP-a, najpopularniejszej platformy wśród deweloperów tworzących aplikacje internetowe. Tak na prawdę, PHP Fog działa w chmurze Amazonu (tak tak, tej samej, która zaliczyła ostatnio niezły fuck up). Najważniejszą dla nas jako programistów informacją jest to, że nie musimy robić nic ponad wykonanie komendy git push na lokalnej maszynie, tej samej, na której tworzymy aplikację. Niestety (a może i stety) PHP Fog nie daje żadnej innej możliwości uploadowania kodu do chmury. Dlatego jeśli jeszcze nie zaczęliście korzystać z gita, najwyższa pora, aby nadrobić zaległości.

W chwili obecnej PHP Fog dostarcza dwa sposoby tworzenia aplikacji – skorzystanie z gotowca (WordPress, Drupal, Joomla lub SugarCRM) lub własnoręczne tworzenie przy użyciu jednego z dostępnych w chmurze frameworków (CakePHP, Zend Framework lub CodeIgniter). Oczywiście mamy również możliwość utworzenia Cusom App bez konieczności wybierania żadnego wbudowanego frameworka.

Po wybraniu rodzaju aplikacji stajemy przed kolejnym wyborem – plan taryfowy. Do dyspozycji mamy cztery plany – pierwszy działający na zasadzie współdzielonego hostingu (darmowy przez pół roku dla jednej aplikacji), dedykowany mikro (za 29$ miesięcznie), dedykowany mały (79$ miesięcznie) oraz dedykowany duży (249$ miesięcznie). Oczywiście wszystkie plany różnią się dostępnymi zasobami, niestety poza podstawowymi informacjami, nie udało mi się odnaleźć szczegółowego opisu każdego planu.

Podobnie jak w przypadku każdej chmury, PHP Fog oferuje możliwość prostego skalowania naszej aplikacji w zależności od bieżących potrzeb. Na obecną chwilę możemy skorzystać z maksymalnie pięciu serwerów (instancji), będących w stanie obsłużyć ruch w naszej aplikacji. Oczywiście za każdą instancję musimy dodatkowo zapłacić. Jeśli będziemy potrzebować dodatkową moc obliczeniową lub przestrzeń dyskową, nie musimy się o to martwić. Jeśli zasoby PHP Fog zaczną się wyczerpywać, zawsze możemy przenieść część naszej aplikacji bezpośrednio do chmury Amazona.

Jeśli chodzi o technikalia, to w skład PHP Fog wchodzi PHP 5.3.2, Apache 2.2.14 oraz MySQL 5.1.41. Do tego dochodzi cron uruchamiany co 10 minut (nie można tego zmienić). W kwestii wysyłania maili jest drobny problem. Niestety musimy wspomóc się zewnętrznym rozwiązaniem. FAQ proponuje Gmaila działającego w ramach Google Apps. W przypadku potrzeby zmiany jakichkolwiek ustawień php.ini, możemy to zrobić w pliku .htaccess lub przy pomocy funkcji ini_set. Niestety PHP Fog nie pozwala ustawić wskazania domeny na podkatalog i musimy sobie radzić przy pomocy .htaccess.

Czy PHP Fog na dobre zagości na blogu? Okaże się po pierwszej aplikacji, umieszczonej w tej chmurze. Jeśli cena za najtańszy plan taryfowy nie byłaby taka wysoka, powiedziałbym w ciemno, że tak. Niestety dosyć spory miesięczny koszt w porównaniu z tradycyjnym hostingiem, każe się dobrze zastanowić nad tym rozwiązaniem.

Autor wpisu: batman, dodany: 04.05.2011 16:53, tagi: php

Pod koniec kwietnia pojawiła się informacja o wydaniu bety trzeciej wersji Windows Azure SDK for PHP. Ponieważ jest to wersja beta, lista funkcjonalności została już zamknięta. Jedyne zmiany jakie się mogą pojawić to bugfixy oraz drobna kosmetyka. Nowa wersja SDK przynosi szereg nowości, pozwalających na wygodniejsze korzystanie z chmury Microsoftu.

Wprowadzone zmiany to:

  • możliwość zarządzania usługą z poziomu kodu
  • logowanie oparte o mechanizm tabel
  • możliwość zapisywania sesji w tabelach oraz blobach
  • tabele zwracają obiekt DateTime, a nie string
  • szereg drobnych usprawnień

Najciekawszą zmianą jest wprowadzenie mechanizmu zarządzania usługą. Jest to o tyle interesujące, że w końcu będzie można z poziomu PHP np. modyfikować ilość instancji działających w ramach roli. Umożliwi to stworzenie panelu administracyjnego, w którym będzie można dowolne zmieniać ilość instancji, w zależności od zapotrzebowania na zasoby.

SDK można pobrać pod adresem http://phpazure.codeplex.com/releases/view/64047

Autor wpisu: Tomasz Kowalczyk, dodany: 03.05.2011 23:00, tagi: php

Sprawdzanie poprawności adresu email to częsty problem, z jakim zmagają się programiści stron internetowych [i nie tylko]. Jest to dosyć zaawansowane i nietrywialne zagadnienie, jeśli chcemy przeprowadzić całościową walidację tego typu danych. Większość artykułów, jakie w tym temacie możemy znaleźć w Internecie skupia się na sprawdzeniu, a przynajmniej próbie sprawdzenia poprawności samej struktury adresu. W [...]

Autor wpisu: Zyx, dodany: 03.05.2011 21:28, tagi: php

W ostatnich dniach czołowi twórcy ogłosili, że PHP 5.4 jest już praktycznie gotowe i będą robić wszystko, aby proces wydawniczy rozpoczął się jak najszybciej. W artykule podkreślano też, że nowa wersja znacząco zmniejsza zużycie pamięci oraz dodaje szereg innych optymalizacji. Jako że w tym samym czasie rekompilowałem moją farmę webdeveloperską, dla zabawy postanowiłem sobie sprawdzić czy i jak bardzo jest to prawda. Wyniki są lekko oszałamiające.
Wszystkie wpisy należą do ich twórców. PHP.pl nie ponosi odpowiedzialności za treść wpisów.