Wczoraj odbyła się druga konferencja z serii 4Developers. I ja tam byłem, Allegro i herbatę piłem, ciastek się najadłem i w ogóle ;)

Sama konferencja była podzielona na 4 ścieżki: Zarządzanie projektami IT, Java, .Net & C# oraz PHP. Ja wybrałem sobie kilka wykładów z Zarządzania projektami IT (w sumie większość) i zahaczyłem także o wykłady nt. PHP.

Pierwszy wykład na którym byłem, była to zrealizowana w formacie Pecha Kucha (coś na kształt Lightning Talk) seria 3 prezentacji na tematy dotyczące, a jakże, zarządzania ;) Podobało mi się, 3 panów z organizacji PMI Poznań fajnie poopowiadało o tematach takich jak “Produktywne lenistwo”, “Przyczyny porażek startupów” i “Projekt w opałach”. Wykłady dużo nowego mi nie powiedziały, ale kilka rzeczy nazwały po imieniu w miejscach gdzie się czegoś domyślałem, albo zwróciły mi na coś uwagę. Ogólnie zdecydowanie za.

Kolejny wykład który mnie interesował, odbył się w tej samej sali, też z Zarządzania projektem IT. Tym razem Monika Konieczny opowiadała o tym, jak można pogodzić/ułatwić współpracę testerów z programistami. Trzeba przyznać, że Monika miała świetny pomysł z ciastem ;) Oprócz tego, że wykład dał mi sporo tematów do przemyśleń i podsunął trochę pomysłów, to z przyjemnością patrzyło się na kogoś kto z łatwością i zaangażowaniem prowadził zajęcia. Widać było, że Monika raz, wiedziała o czym mówi, dwa, ma sporo swoich przemyśleń na ten temat, trzy, była doskonale przygotowana. Myślę że dla mnie to najlepszy wykład na całej konferencji. A Monice tylko pogratulować :)

Na następny wykład miałem dylemat: pójść na PHP: “Aplikacje internetowe wydajne od początku”, czy zostać na Zarządzaniu projektami IT: “Zarządzanie rozwojem oprogramowania – nieco bardziej ‘funky’”. W końcu stwierdziłem że trochę technikaliów mi nie zaszkodzi, poszedłem sobie na PHP. Jeszcze wtedy nie wiedziałem co czynię… Panowie niestety nie dość że byli słabo przygotowani do wykładu (więcej czytali ze slajdów niż byli w stanie powiedzieć, patrzyli co chwila na siebie, który ma właśnie mówić etc), to nie do końca mieli pojęcie o czym mówią. Niestety. Być może później wyprostowali trochę swój wizerunek, ale tego już nie wiem, bo wyszedłem po 15 minutach. Po tym jak kilkukrotnie potraktowali wymiennie bufor z cache (używali tych słów jak synonimów), a wcześniej puścili kilka innych bezsensownych stwierdzeń. Najgorszy z możliwych wykładów IMHO.

Po tym jak uciekłem z “Aplikacji internetowych wydajnych od początku”, poszedłem na wspomniane “Zarządzanie rozwojem oprogramowania – nieco bardziej ‘funky’”. Peter Horsten poopowiadał nieco o rzeczach które znałem już doskonale, więc sam temat mnie nie do końca zainteresował (myślałem że będzie to nieco głębsze wejście w temat, tutaj było tylko pobieżnie), ale sam sposób prowadzenia wykładu to bajka. Najlepiej poprowadzony wykład na całym 4Developers, z tych na których byłem. Peter z lekkością i wprawą poopowiadał o wszystkim, z humorem, etc. Z przyjemnością go słuchałem :)

Po lunchu znów poszedłem na wykład PHP: “PHP wysokiej wydajności”. Tutaj było zdecydowanie lepsze przygotowanie techniczne Mariusza Gila niż kolegów od wydajności z poprzedniego wykładu. Nie było już wrażenia że nie wie o czym mówi, wręcz przeciwnie, większość tego o czym wspominał znam z własnych testów, choć nigdy nie miałem tak porywającego serwisu napisanego w PHP żebym musiał to stosować w praktyce :) Ogólnie sam wykład mnie nie szczególnie zainteresował, bo bardzo niewiele nowego miałem okazję się dowiedzieć (zapisałem sobie chyba tylko kilka nazw narzędzi z którymi warto żebym się zapoznał), ale oceniam go znacznie wyżej niż poprzedników ;)

Później już nie wychodziłem ze ścieżki “Zarządzania projektami IT”. Najpierw Jakub Dąbkowski w fajny sposób, z humorem, poopowiadał o jednym z aspektów metodyki Scrum, czyli o pytaniach jakie są ważne podczas “scrum meeting”. Wykład oceniam wysoko, Jakub zwrócił uwagę na powody dla których te pytania są ważne dla członków zespołu.

Następnie byłem na “Praktyce zarządzania portfelem projektów IT”. Okazało się jednak, że temat nie zainteresował mnie tak bardzo jak na to liczyłem. Wygląda na to, że te 40 minut jakie miał Szymon Włochowicz to zdecydowanie za mało na omówienie choćby częściowo tego tematu, usłyszeliśmy ledwie zajawkę, więc na sali było sporo osób które, jak mi się wydaje, podobnie jak ja nie zostali przekonani do takiego podejścia.

Ostatnim wykładem był “Łączenie ognia i wody – proces projektowy w Gratka Technologie”, ale tutaj było za mało interesujących tematów, ot, prelegent poopowiadał o swoich doświadczeniach, niestety myślę że zrobił to nieco za wcześnie, gdyż jeszcze miał ich nieco za mało. Mam mocno mieszane uczucia odnośnie tej prezentacji.

Ogólnie jestem bardzo zadowolony z całości. Ciekawe wykłady, rewelacyjne hostessy ;) darmowy wyjazd (sponsorowany przez firmę ;) ), i nie za daleko od domu (w sensie: mało czasu straconego w ciapągu) – zdecydowanie było warto :) Do tego stopnia, że jak tylko będę miał możliwość, to w przyszłym roku na pewno się wybiorę na kolejną edycję – nawet pomimo tego że konkurs komiksowy wygrał rysunek uzupełniony z oryginalnego Garfielda, a nie nasz :)


Dawno tu nie pisałem… No cóż, (bardzo) dużo pracy, życie osobiste i takie tam – to odstrasza od blogowania ;) Jeśli już, to od czasu do czasu coś publikuję jeśli chodzi o zdjęcia, a sprawy “kodowe” to raczej “robię” niż o nich piszę :)

Jako że od kilka dni jestem na L4, to się ostro opierdzielam, ale dopiero dziś jestem w stanie podjąć jakikolwiek intelektualny wysiłek… No to popatrzyłem sobie m.in. na GoldenLine. Dziś na forum PHPowym ktoś poruszył dość banalny problem, ktoś inny podrzucił rozwiązanie (preg_replace_callback (), a ja zacząłem się zastanawiać czemu wszyscy w PHP tak napierają na regexpy (rozumiem w Perlu, ale PHP?). Jak zacząłem się zastanawiać jak to zrobić bez regexpów, to zacząłem się bawić w zakodowanie tego ;)

Najpierw zrobiłem dość banalną wersję, przy użyciu strlen (), strpos () i substr (), i chciałem ją podać jako wersję hardcore ;) Wtedy pomyślałem sobie, że prawdziwa wersja hardcore, to byłaby bez użycia tychże funkcji… najprostsza postać tego to zastąpienie tychże funkcji swoimi ;) I o ile substr () i strpos () są dość banalne, o tyle dla mnie prawdziwym hardcorem jest strlen () ;)

Oczywiście nie są to najbardziej optymalne wydajne rozwiązania (a jeśli są to tylko przypadkiem), bo jeśli chodzi o optymalizację, to trzeba by używać wersji natywnych to trzeba by się najpierw zastanowić i sprawdzić czy jest co optymalizować… :) A całość warto potraktować stricte jako zabawę, którą dla mnie było pisanie tego :)

W całym “problemie” chodziło o zastąpienie w tekście wystąpień “[userId]ID[/userId]” tym, co zostanie wyplute przez dodatkową funkcję której podajemy zawartość tego co jest między znacznikami. Użycie preg_replace_callback () jest chyba najbardziej intuicyjnym rozwiązaniem, ale nie jedynym… :) Poniżej obydwie wersje: hardcore i bardziej hardcore – enjoy ;)

hardcore

function replace_user_id ($str, $fn) {
    $tags = array ('start' => '[userId]', 'end' => '[/userId]');
    $tag_len = array (
        'start' => strlen ($tags['start']),
        'end'   => strlen ($tags['end'])
    );
    $offset = $pos_end = 0;
    $ret    = '';
    $strlen = strlen ($str);

    while ($pos_end < $strlen) {
        if (
            ($pos_start = strpos ($str, $tags['start'], $pos_end)) !== false &&
            ($pos_end   = strpos ($str, $tags['end'], $pos_start)) !== false
        ) {
            $ret .= substr ($str, $offset, $pos_start - $offset);
            $pos_start += $tag_len['start'];

            $ret .= $fn (substr ($str, $pos_start, $pos_end - $pos_start));

            $pos_end += $tag_len['end'];
            $offset = $pos_end;
        }
        else {
            break;
        }
    }

    return $ret;
}

bardziej hardcore

class __mstrlen__ErrH {
    private static $error = false;
    private function __construct () {}
    static public function errh ($errno, $errstr, $errfile = '', $errline = 0, $errctx = array ()) {
        if ($errno != E_NOTICE) {
            return false;
        }

        $expected = 'Uninitialized string offset';
        for ($i=0; $i<26; ++$i) {
            if ($expected[$i] != $errstr[$i]) {
                return false;
            }
        }

        self::$error = true;
    }
    public static function isError () {
        return self::$error;
    }
    public static function zero () {
        self::$error = false;
    }
}

function mstrlen ($str) {
    $str = (string) $str;

    $len = -1;
    __mstrlen__ErrH::zero ();
    set_error_handler (array ('__mstrlen__ErrH', 'errh'), E_NOTICE);
    while (__mstrlen__ErrH::isError () === false) {
        ++$len;
        $q = $str[$len];
    }

    restore_error_handler ();
    return $len < 0 ? 0 : $len;
}

function mstrpos ($str, $seek, $offset=0) {
    if (!is_int ($offset) || $offset < 0) {
        $offset = 0;
    }

    $str_len = mstrlen ($str);
    if ($offset > $str_len) {
        return false;
    }

    $seek_len = mstrlen ($seek);
    for ($i=$offset; $i < $str_len; ++$i) {
        for ($j=0; $j < $seek_len; ++$j) {
            if ($str[$i + $j] != $seek[$j]) {
                break;
            }
        }

        if ($j == $seek_len) {
            return $i;
        }
    }
    return false;
}

function msubstr ($str, $start, $length = null) {
    $str_len = mstrlen ($str);
    if (!is_int ($start)) {
        trigger_error ('Incorrect offset');
    }
    else if ($start >= $str_len) {
        return false;
    }
    else if ($start < 0) {
        $start = $str_len + $start;
    }

    if (!is_int ($length)) {
        $length = $str_len - $start;
    }
    else if ($length < 0) {
        $length = $str_len + $length - $start;
    }
    else if ($length + $start > $str_len) {
        $length = $str_len - $start;
    }

    $ret = '';
    for ($i=0; $i < $length; ++$i) {
        $ret .= $str[$i + $start];
    }

    return $ret;
}

function replace_user_id2 ($str, $fn) {
    $tags = array ('start' => '[userId]', 'end' => '[/userId]');
    $tag_len = array (
        'start' => mstrlen ($tags['start']),
        'end'   => mstrlen ($tags['end'])
    );
    $offset = $pos_end = 0;
    $ret    = '';
    $strlen = mstrlen ($str);

    while ($pos_end < $strlen) {
        if (
            ($pos_start = mstrpos ($str, $tags['start'], $pos_end)) !== false &&
            ($pos_end   = mstrpos ($str, $tags['end'], $pos_start)) !== false
        ) {
            $ret .= msubstr ($str, $offset, $pos_start - $offset);
            $pos_start += $tag_len['start'];

            $ret .= $fn (msubstr ($str, $pos_start, $pos_end - $pos_start));

            $pos_end += $tag_len['end'];
            $offset = $pos_end;
        }
        else {
            break;
        }
    }

    return $ret;
}

wwwshell.php to skrypt napisany w php, pozwalający obejść część ograniczeń związanych z brakiem shella na hostingu. Jako że w home.pl takowego nie ma, musiałem jakiś czas temu ratować się takim wynalazkiem ;)

Założeniem które przyświecało od początku jego istnienia była kompaktowość (wszystko w jednym pliku), używalność, wygoda. Wydaje mi się że jak na razie spełnia wszystkie wymienione ;) Ograniczeniami są PHP >= 4.3.0 i nie zablokowane wykonywanie funkcji proc_open () i proc_close ().

Zalety (z mojego punku widzenia ;) ):

  • wszystko w jednym pliku (biblioteki jQuery pobierane są bezpośrednio z serwera jQuery.com
  • obsługa aliasów
  • prostota użytkowania
  • historia poleceń

Wady:

  • no cóż, to jednak nie prawdziwy shell…
  • brak uzupełniania
  • uprzyjemniacze typu historia wymagają połączenia z netem lub modyfikacji skryptu i używania lokalnych kopii bibioteki jQuery

Znane błędy:

  • nie zapamiętuje ustawionego rozmiaru czcionki w okienku wyjścia
  • czasem z jakiegoś powodu historia nie działa, trzeba np. otworzyć okienko konsoli w ff i je zamknąć, wtedy jest ok :/

Nie sprawdzałem też (ani nawet nie zamierzam jak na razie) sprawdzać jak wygląda i działa pod IE. Może się coś sypać :)

Jeśli ktoś jest zainteresowany tą zabawką, to zapraszam do pobierania na GoogleCode, i komentowania/krytykowania pod tą notką ;)


Mały bugfix release (zgłoszony przez WPNinja): W przypadku gdy nie można zapisać pliku z cache do katalogu ustawionego jako zmienna $wp_blip_cacheroot, próbuje zapisać do systemowego katalogu tymczasowego (o ile się uda takowy znaleźć). Gdy także i ta operacja się nie powiedzie, zostanie rzucony E_USER_NOTICE z informacją o problemie, a wtyczka po prostu nie będzie korzystała z funkcji cacheowania wpisów.

Do pobrania z GoogleCode. Jak zawsze proszę o informacje i uwagi nt działania wtyczki, a także ucieszyłbym się z informacji że ktoś gdzieś moich wypocin używa :)


Kolejna odsłona WP-Blip!a :) Tym razem jeden bugfix (no, powiedzmy że fix), i jedna zmiana:

  • możliwość formatowania daty dodania statusu (via komentarz Julka)
  • naprawione linkowanie tagów i userów – teraz łapie poprawnie polskie znaczki. Może nie do końca poprawnie działać jeśli kodowanie znaków jest inne niż UTF-8, proszę wtedy dać znać, mam wrażenie że coś źle przemyślałem ;)

Standardowo proszę o komentarze pod tym wpisem, lub na email :) A nowa wersja pluginu jest do pobrania na Google Code.

UPDATE:

Już nowa wersja – 0.3.1 ;)

  • fix: pliterki w tagach teraz działają lepiej
  • fix: myślnik w tagach też działa lepiej
  • add: linki we wpisach są obejmowana tagiem <a />

Do pobrania tradycyjnie na GoogleCode.


Nowa wersja plugina do WordPressa pokazującego statusy z Blip!a. Zmiany:

  • update BlipApi.php do nowej wersji
  • linkowanie tagów i użytkowników
  • dodanie pliku README z podstawową dokumentacją

Zainteresowanych zapraszam ściągania i aktualizowania :)


Kilka dni temu Tomasz Tybulewicz (http://tybulewicz.com/) podesłał mi wersję BlipApi.php z dodaną obsługą operacji na obrazkach, jakie zaczęło oferować Blip!owe API :) Tomek równocześnie dołączył do “zespołu” tworzącego i rozwijającego BlipApi, które obecnie jest tylko w wersji PHP, a docelowo, o ile czas pozwoli, pojawi się w jeszcze kilku językach. Nie będę na razie mówił w jakich, bo to dość niepewna przyszłość ;)

Nową wersję można pobrać ze specjalnie utworzonego w tym celu projektu na Google Code: blipapi.googlecode.com (jeśli ktoś kojarzy projekt blipapi-php na Google Code, to niech wymaże go ze swoich bookmarków, został usunięty).


Dokopałem się właśnie do pewnego wpisu na PeHaPowym Wiki omawiającego status i różne ciekawostki dotyczące PHP6. Można się dowiedzieć fajnych rzeczy… Ale po kolei.

Przejdź do reszty tego wpisu »


Strona 1 z 4