Jako, że nie mam możliwości dopisania komentarza do właściwego postu (o, tutaj), dodam go u siebie (czemu nie mam możliwości tam? Nie wiem, po ‘Dodaj komentarz’ pojawia mi się biała strona i tyle…). Trackbacka chyba też tam nie ma.

Ja stosuję troszkę inną sztuczkę odnośnie sytuacji opisanej u Jarosława Mężyka. Tak jak on, przetrzymuję login, hasło i inne dane dotyczące bazy w stałych. Ale samo rozdzielenie konfiguracji jest bardziej automatyczne. Mianowicie, sprawdzam wartość zmiennej $_SERVER['HTTP_HOST']. Jeśli równa jest ona ciągowi znaków ‘localhost’, to stosuje ustawienia lokalne, w przeciwnym wypadku – docelowe. Przykład kodu:

<?php
if ($_SERVER['HTTP_HOST'] == 'localhost') {
  define('DATABASE_LOGIN', 'login');
  define('DATABASE_PASSWD', 'passwd');
  define('DATABASE_HOST', 'localhost');
  define('DATABASE_NAME', 'db');
} else {
  define('DATABASE_LOGIN', 'login_docelowy');
  define('DATABASE_PASSWD', 'passwd_docelowy');
  define('DATABASE_HOST', 'host_docelowy');
  define('DATABASE_NAME', 'db_docelowa');
}
?>

Właśnie zaimplementowałem proste sprawdzanie typów w PHP5. Oczywiście, nie jest to C++, gdzie kontrola ta jest bardziej ścisła, ale myślę że w wielu wypadkach starczy. Jest to o tyle wygodne, że łatwiej nieco będzie wykrywać nieścisłości (zresztą, po to jest sprawdzanie typów).

Przykład kodu:

class Test
{
  protected $properties = array(
    'var1' => array('tralala', 'string'),
    'var2' => array(3, 'integer'),
    'var3' => array(array('tralala', 'bulcykcyk), 'array')
  );
  public function __set($key, $value)
  {
    if (!array_key_exists($key, $this->properties)) {
      throw new Exception(sprintf('"%s" property doesn\'t exists.', $key));
    }
    if (gettype($value) != $this->properties[$key][1]) {
      throw new Exception(sprintf('"%s" property must be an "%s" type, is "%s".',
          $key,
          $this->properties[$key][1],
          gettype($value)
      ));
    }
    $this->properties[$key][0] = $value;
  }
}

Najtrudniejszym elementem jest tutaj każdorazowe ustawianie właściwej konstrukcji zmiennej $properties, ponieważ ta tablica ma konkretny format:

$properties = array(
  'nazwa_zmiennej' => array('wartość', 'typ')
)

Jako ‘wartość‘ wstawiamy tam wartość właściwości (obojętnie, czy obiekt, int, string, tablicę czy coś innego), a jako ‘typ‘ – wartość zwracana przez funkcję getttype() wywołaną na przechowywanym obiekcie. Dla napisów będzie to wartość ‘string‘, dla liczb całkowitych: ‘integer‘, a dla obiektów: ‘object‘.

Ta kontrola typów jest o tyle uproszczona, że nie sprawdza, czy przechowywany obiekt jest instancją danej klasy (tej która ma być przechowywana), oraz czy tablica przechowuje żądany typ obiektów. O ile pierwsze czasem warto, i łatwo zrobić za pomocą is_a() czy też get_class(), o tyle drugie może być trudniejsze i wymagać funkcji dodatkowych (jeśli sprawdzanie ma być niezależne od ilości zagłębień tablicy).

Przykład użycia:

$a = new Test;
try {
  $a->var1 = 'asd';               //ok
  $a->var2 = 1;                   //ok
  $a->var3 = array(1, 2, 3);  //ok

  //$a->var1 = 1;              //exception!
  //$a->var2 = 'a';             //exception!
  //$a->var3 = 1;              //exception!
} catch (Exception $e) {
  echo $e->getMessage();
}

W moim wypadku najlepszym rozwiązaniem było utworzenie klasy ‘Test‘ jako abstrakcyjnej (‘abstract‘) i tworzenie kolejnych klas jako dziedziczących z niej. Każde z dzieci musi oczywiście mieć swoją wersję tablicy ‘$properties‘.


Całkiem niezła biblioteka, podoba mi się jak na razie bardzo. Oczywiście, nie jest bezbłędna, ale takie rzeczy nie istnieją. Zgłosiłem bugreporta, zobaczymy czy i jak szybko zarezgują ;)

Generalnie wrażenia jak najbardziej pozytywne. Używa się całkiem przyjemnie, trochę ułatwiają pracę w stosunku do FT (heh, całkiem dużo…). Jeszcze nie mam biegłości w posługiwaniu się OPT-ami, ale dokumentacja jest pięknie opisana, zarówno po polsku jak i po angielsku, co całkiem dobrze mówi o twórcach :)

Wspomniany wcześniej błąd dotyczy instrukcji {foreach}, a konkretnie części {foreachelse}, która powinna wykonywać się gdy tablica przekazywana jako parametr jest pusta. Aplikacja po prostu się wysypuje, gdy dyrektywa {foreachelse} występuje w kodzie szablonu… No nic, bywa.

A teraz czas spać…

AKTUALIZACJA
Nie jest źle. Wczoraj bugreport, w tej chwili sprawdziłem FlySpraya, poprawka tymczasowa podana na tacy, i obietnica naprawy w najnowszym RC ;)


Jednak mi się dziś chciało. Zrobiłem skrypta do konwersji całości WordPressa z ISO-8859-2 na UTF-8. Oczywiście może też posłużyc do konwersji całkiem innych kodowań, wystarczy zmienić argumenty w wywołaniu funkcji iconv(). Skrypt znajduje się pod adresem: urzenia.net/wp-content/iso2utf/. Można go dowolnie zmieniać i wykorzystywać do własnych potrzeb, zgodnie z zasadami GPLv2.

Skrypt zmienia tylko zawartość bazy, te tabele i pola które uznałem że trzeba zmienić, reszta (przynajmniej w wersji WP 1.5.1.2 nie musi być konwertowana.

Skrypt nie zmienia za to collation w wersjach MySQL wyższych niż 4.0, więc do tego potrzeba ręcznie pogrzebać w bazie danych. Mi zajęło to jakieś 30 minut, ale nie chciałem tego robić automatem. Poza tym wszystko działa :)

Po zakończeniu działania skryptu, w katalogu w którym on się znajduje będzie utworzony plik converted.sql, który trzeba ręcznie wrzucić do bazy – również tego nie chciałem żeby robić automatem – nigdy nie miałem do nich zaufania ;)

Oczywiście nie biorę odpowiedzialności za złe działanie skryptu (za dobre zresztą też nie), etc etc. Używasz go na własną odpowiedzialność :)

Jeśli gdzieś ktoś dojrzy na diary jakieś problemy z pl-znaczkami, to proszę o info.


Tak, właśnie takie coś sobie wymyśliłem jak siedziałem wczoraj w sądzie więzieniu. Do dyspozycji miałem:

  • tradycyjny interfejs proceduralny mysql_*
  • nowy w php5 interfejs mysqli_ (proceduralny)
  • j.w. mysqli, ale obiektowo (OOP)
  • uniwersalny interfejs (w wersjach PHP < 5.1.0 dostępny poprzez PECL) PDO

Niestety, o ile w wersji Windows-owej w pracy miałem wersję PHP 5.1.0beta3 (z wbudowanym PDO), o tyle w domu i na serwerze na którym stoi urzenia jest starsze, stabilne PHP 5.0.5, na którym wersja PECL-owa PDO nie chce mi działać. Ale też jakoś specjalnie nie walczyłem, żeby zadziałało. Nie chce mi się :)

Wyniki, wraz z testami online, można obejrzeć pod urzenia.net/wp-content/mysql_test/, a żródła plików: urzenia.net/wp-content/mysql_test/sources/.

Dostępne tam są, na dole, 3 linki do wyników jakie uzyskałem na 3 kompach, na których chciało mi się bawić w testy. Najbardziej mnie zszokowało porównanie z P4 2.4 GHZ i AMD64… heheh. Nie ma to jak 64 bity :) Do każdego z linków jest którki opis, na jakim sprzęcie były wykonywane testy, jaki soft etc.

Moje podsumowanie: nie ma znaczenia, którego z interfejsów się użyje. Różnice w wydajności między nimi są tak niewielkie, że imo pomijalne. Dla mnie najwygodniejszy chwilowo się wydaje MySQLi, choć zdecydowanie PDO zasługuje na uwagę. Niestety, na tą chwilę PHP5 (nie mówiąc o wszechdostępności PDO, związanej z nieistnieniem wersji stabilnej/końcowej PHP5.1 i nie działaniem – u mnie – wersji PECL-owej) nie jest jeszcze tak rozpowszechnione jak bym chciał, ze względu na niekompatybilność części softu, dostosowanej do możliwości i błędów ;) starszej wersji, tj. PHP4. Choć w wolnych chwilach prawdopodobnie zacznę przerabiać Core CMS na ‘międzymordzie’ (interfejs) MySQLi… :)

Niedługo też zostaną wznowione prace nad telefonami, które też może doczekają się przejścia na MySQLi, jako że następny hosting będzie u providera, który oferuje PHP5 :) Które to PHP coraz bardziej podbija moje serce (w stosunku do PHP4, nie w ogólności, gdzie python króluje… :) ).

Wszelkie uwagi i ew. zgłoszenia błędów procedury testowej proszę zostawiać w komentarzach – postaram się nimi zająć tak szybko jak się da :)


dlaczego nie warto uzywac foreach ?

testcase wyglada tak:
jest sobie tablica:

  • 10224 elementow
  • 10 znaków każdy element
  • 356954 znakow to dlugosc powstalego po zlaczeniu stringa

funkcja mierzaca czas:


function t(){
list($usec, $sec) = explode(" ",microtime());
return ((float)$usec + (float)$sec);
}

test1 (while):

$t1 = t();
$r = '';
while ( list($k, $v) = each($test) )
{
$r .= sprintf('key: %s | value: %s
', $k, $v);
}
$t2 = t();

test2 (foreach):

$r = '';
foreach ($test as $k => $v)
{
$r .= sprintf('key: %s | value: %s
', $k, $v);
}
$t3 = t();

rezultat

rezultat jest generowany przy kazdym wejsciu na strone.

juz wszyscy wiedza, czemu nie powinno sie uzywac foreach() ? ;)

update:
testy byly wykonywane na sofcie:

php jako cgi, poprzez suphp

a tutaj linki do zrodel wykorzystanego przeze mnie testu:
foreach:while1.php (807 bajtow)
foreach:while_array.php (141 kilobajtow)

i nie smiac sie z pieknej tablicy :P do celow testowych byla super ;)

update2:
no to dalem dupy. na calej linii. gdyby nie piecu, to bym nawet o tym nie wiedzial… ;) chujnia, chyba bede musial przestac uzywac mojej ulubionej konstrukcji :P a mialo byc tak milo… :P

tylko czemu mi az tak glupio ? ;)


Strona 4 z 4