Na potrzeby pewnego projektu o pewnej nazwie, o której niebawem się przekonacie, powstał nowy plugin. Generuje on sitemapa przyjaznego dla Google. Po co to wszystko… Rejestrując się w google mamy możliwość skorzystać z wielu narzędzi webmastera. Jednym z nich jest “pomaganie” robotowi w indeksowaniu naszej strony, poprzez podanie mu sitemapu po którym powinien się poruszać. Po zweryfikowaniu naszej strony w systemie google, proszeni jesteśmy o podanie sitemapu (więcej o weryfikacji).
W tym miejscu z pomocą przychodzi nam WordPress ContexlinkSitemap Plugin. Plugin przede wszystkim:
Instalacja pluginu:
Dodanie mapy witryny do google:
Dodatkowa konfiguracja:
W celu szczegółowej konfiguracji pluginu, możesz:
PHP 4 end of life announcement
Takim nagłówkiem dnia 13 lipca (tj. piątek) 2007 roku na oficjalnej stronie PHP ujawnił się news dotyczący oficjalnego zamknięcia projektu PHP 4.
Today it is exactly three years ago since PHP 5 has been released. In those three years it has seen many improvements over PHP 4. PHP 5 is fast, stable & production-ready and as PHP 6 is on the way, PHP 4 will be discontinued.
The PHP development team hereby announces that support for PHP 4 will continue until the end of this year only. After 2007-12-31 there will be no more releases of PHP 4.4. We will continue to make critical security fixes available on a case-by-case basis until 2008-08-08. Please use the rest of this year to make your application suitable to run on PHP 5.
For documentation on migration for PHP 4 to PHP 5, we would like to point you to our migration guide. There is additional information available in the PHP 5.0 to PHP 5.1 and PHP 5.1 to PHP 5.2 migration guides as well.
Tłumaczenie by Paweł ‘hwao’ Halicki:
Dziś (tj. 13 lipca 2007) mijają dokładnie trzy lata od daty wydania w pełni stabilnego PHP5. Przez ten okres czasu ciężko pracowaliśmy nad PHP4 czego owocem były liczne poprawki. Lecz teraz, kiedy PHP5 stało się szybkie, stabilne i w pełni dojrzałe, a prace nad PHP6 są w toku, możemy oznajmić iż projekt PHP4 zostanie zamknięty.
Deweloperzy pracujący nad PHP oświadczają, że wsparcie dla PHP4 będzie kontynuowane jedynie do końca tego roku. Po 31 grudnia 2007 nie będą ukazywać się już kolejne wersje PHP z linii 4.4. Wszystkie krytyczne błędy będą poprawiane będą jedynie do 8 sierpnia 2008 roku. Prosimy aby wszyscy programiści, wykorzystali czas pozostały do końca roku, aby ich aplikacje były kompatybilne z PHP5.
Wszelkie niezbędne wskazówki pomocne w migracji z PHP4 do PHP5 możecie znaleźć w pod linkiem migration guide. Są też dostępne wskazówki jak migrować z PHP5.0 do PHP5.1 a także PHP5.1 do PHP5.2.
O autoloadzie klas było już głośno, rozpatrywaliśmy wszelkie za i przeciw w wielu miejscach choćby tu, tu i tu.
Mechanizm automatycznego ładowania potrzebnych nam klas jest bardzo dobrym sposobem na zrelaksowanie się poprzez brak przymusu ręcznego ładowania plików potrzebnych do działania aplikacji. Znajdźmy receptę na owe pytanie przedstawiając dwa najpopularniejsze sposoby trzymania klas w np. frameworkach.
Zend Framework i Rapide mają dość sztywną, lecz nie wymagającą specjalnego kombinowania technikę umieszczania plików w core. Sposób nazewnictwa jest bardzo prosty: Folder_Subfolder_Klasa – owy zapis odnosi się do ./Folder/Subfolder/Klasa.Class.php.
W moim frameworku Vframe zastosowałem technikę, w której pliki leżą sobie „wolność w core, nazewnictwo klas nie tyczy się ich ścieżki, np. NazwaKlasy może odnieść się do ./NazwaKlasy.Class.php lub ./Folder/Subfolder/ NazwaKlasy.Class.php.
Spróbuję opisać drugi – mój – sposób na ładowanie plików z core aplikacji. Potrzebna nam będzie klasa, która jest w stanie przeskanować całe core i zapisać je do tablicy. Aby było łatwiej, skan zostanie zaserializowany do pliku jako mapa folderu. Co jeżeli plik nie będzie istniał w core? Wówczas mapa zostanie stworzona od nowa, jeżeli to nie pomoże – wyrzucimy wyjątek.
Projektujemy naszą klasę, nazwiemy ją przykładowo Autoload, metody:
Load($sLibrary, $bRemapped = false) – metoda która będzie odpowiedzialna za załadowanie pliku oraz (jeżeli nie będzie istniała) stworzenie tablicy plików. W wypadku braku pliku zostanie ponownione wywołanie metody tworzenia mapy plików z przymusowym przeskanowaniem folderu klas oraz tym samym odpalenie metody samej siebie z przyjęciem drugiego jej parametru na true – brak ponownego skanowania folderu i wyrzut wyjątku.
Map($bUseTemp = true) – metoda odpowiedzialna za stworzenie tablicy z plikami na podstawie pliku mapy poprzez odserializowanie danych w nim zapisanych. Jeżeli parametr otrzyma wartość false lub plik mapy nie będzie możliwy do odczytu, wówczas tworzona zostanie mapa, zapisana do pliku mapy oraz do tablicy klasy.
FormatName($sLibrary) – metoda formatująca nazwę klasy: Klasa.Class.php
Wykorzystamy trzy stałe:
const _LibDir – określa ścieżkę folderu z klasami
const _LibSurfix – surfixy plików (.Class.php)
const _LibMap – ścieżka i nazwa pliku mapy
Potrzebna będzie nam jeden statyczny, prywatny parametr klasy, który jest sam w sobie jej singletonem, więc każda instancja klasy będzie z niego korzystała:
private static $_aCoreMap = array();
Ok, teraz wystarczy użyć funkcji __autoload() i wykorzystać naszą klasę:
[php]function __autoload($sLibrary)
{
try
{
Autoload::Load($sLibrary);
}
catch(AutoloadException $oException)
{
// some message to display
die(‘Autoload failed: ‘ . $oException->getMessage());
}
}[/php]
Tworzymy osobisty wyjątek dla autoloadera:
[php]class AutoloadException extends Exception
{
}[/php]
oraz samą klasę:
[php] class Autoload
{
const _LibDir = ‘Core/’;
const _LibSurfix = ‘.Class.php’;
const _LibMap = ‘Map.tmp’;
private static $_aCoreMap = array();
public static function Load($sLibrary, $bRemapped = false)
{
if(!count(self::$_aCoreMap))
self::Map();
$sLibraryFile = self::FormatName($sLibrary);
if(!isset(self::$_aCoreMap[$sLibraryFile]))
{
if($bRemapped)
// if we remapped core and library dosen’t exists – throw an exception
throw new AutoloadException(‘Library “‘ . $sLibrary . ‘” has not been found in directory map!’);
else
{
// ok, let’s go map core again without using map from file
self::Map(false);
// try load class from core directory again…
self::Load($sLibrary, true);
}
}
require_once(self::$_aCoreMap[$sLibraryFile]);
}
public static function Map($bUseTemp = true)
{
// if map is ok and we counld use it, get the map from file…
if($bUseTemp && is_readable(self::_LibMap))
self::$_aCoreMap = unserialize(file_get_contents(self::_LibMap));
// …unless we have to scan core and make map
else
{
// clear array and remamp directory
self::$_aCoreMap = array();
foreach(new RecursiveIteratorIterator(new RecursiveDirectoryIterator(self::_LibDir)) as $oFile)
{
$sFile = $oFile->getFilename();
if(isset(self::$_aCoreMap[$sFile]))
throw new AutoloadException(‘Core duplication “‘.$sFile.’” found!’);
else
self::$_aCoreMap[$sFile] = $oFile->getPathname();
}
// ok, save map to file
if(!file_put_contents(self::_LibMap, serialize(self::$_aCoreMap)))
throw new VframeException(‘Cannot create core map!’);
}
}
private static function FormatName($sLibrary)
{
return $sLibrary . self::_LibSurfix;
}
}
?>[/php]
Całą paczkę klasy i zastosowań możecie pobrać tutaj.
Kiedyś napisałem klasę ModRewriteString, którą opublikowałem na łamach forum.php.pl, która ma sprowadzić polskie, niemieckie i czeskie znaki do zwykłych liter, na przykład ą do a, ż i ź do z, itd. Na potrzeby jednego z moich projektów (portalu) została ona użyta na kodowaniu UTF-8. Okazało się, że klasa akceptuje tylko kodowania WINDOWS-1250 i ISO 8859-2. Ze znaków zakodowanych przez UTF robił się znak nieodczytywalny, potocznie zwany “krzak”. Problem został oznaczony jako bug najwyższego stopnia, klasa trafiła natychmiastowo do analizy. Z pomocą przyszła dokumentacja na temat Multibyte String Functions (rozdział LXXXV) dostępna w podstawowych rozdziałach oficjalnej dokumentacji języka PHP:
http://pl2.php.net/manual/pl/ref.mbstring.php
Ponadto cały dokument z klasą był zakodowany w formie ASCII, co jest niedorzeczne w tego typu działaniach. Plik zawierający klasę został ujęty w formie UTF-8 – uniwersalnego kodowania, które można bez problemu odkowodać.
Zmiany objęły tylko metodę Rewrite(), przyjmuje ona dodatkowy, nieobowiązkowy drugi parametr, który ustawia tryb pracy klasy na podane kodowanie. Gdy parametru nie podamy, lub otrzyma wartość null, wówczas kodowanie zostanie ustawione automatycznię poprzez analizę podanego ciągu znaków przez funkcję mb_detect_encoding(). Kodowanie jest o tyle ważnym elementem, gdyż zostaje podane wewnątrz klasy w funkcjach mb_strtolower() oraz mb_strlen(), odpowiedzialnych za poprawne wykonanie zadania metody.
Dodana została linijka odpowiedzialna za przerwania działania klasy juz na samym początku. Sprawdzane zostaje załadowane rozszerzenie “mbstring”, odpowiedzalne za Multibyte String Functions. Gdy rozszerzenie nie zostanie załadowane, konstruktor wyrzuca wyjątek pierwotnej klasy Exception:
[php]if(!extension_loaded(“mbstring”))
throw new Exception(‘MbString has not been enabled yet!’);[/php]
Wersja klasy została oficjalnie uznana za stabilną, nadany jest jej numerek 0.0.5.
Zastosowanie klasy:
[php]echo ModRewriteString::Rewrite(‘żółw, ktróy przez zboże się ślimaczy’);[/php]

Odnośnie samych kanałów RSS, w wigilijną noc zacząłem kodzić, gdyż będą stanowić część mojego frameworka. Stworzyłem trzy klasy, odpowiedzalne kolejno za kanały: RSS, Atom i XML. Powstała nowa notka na forum php.pl:
http://forum.php.pl/klasy-php5-Generator-kanalow-informacyjnych-Feeds-t59071.html
Może dział nie jest trafny co do mojego celu zamieszczenia tych klas, ale po części chodzi mi o ocenę. Ostatnio dużo myślałem nad obsługą kanałów informacyjnych w moim fameworku (ang. Feeds). Sprawa wygląda bardzo kontrowersyjnie, bowiem RSS nie cieszy się już taką dobrą opinią, jednak większość użytkowników używa właśnie tej wersji kanałów informacyjnych. Według ekspertów jego miejsce ma zastąpić kanał Atom, który stał się trendem i już rok temu liczba jego użytkowników znacznie wzrosła. Pomyślałem również o udostępnianiu naszych informacji w formie czystego arkusza XML.
Powstały kolejne klasy:
Feed.Class.php – klasa abstrakcyjna, a zarazem rodzic wszystkich innych klas kanałów informacyjnych.
FeedRSS.Class.php – kanał informacyjny w formie RSS
FeedAtom.Class.php – kanał informacyjny w formie Atom
FeedXML.Class.php – czysty arkusz Tagów XML, nie przedstawiany jako kanał, ale jako dostępne źródło informacji, zaliczyłem go jako kanał, gdyż można z niego pobierać informacje poprzez różne dostępne metody takie jak SimpleXML, czy SAX.W paczce został załączony jeszcze interfejs oraz przykładowe pliki użycia klas. Dokumentacji niestety nie ma, bowiem jest to jeden z komponentów mojego frameworka, szczegółowa dokumentacja wraz z przykładami pojawi się przy wydaniu stabilnej wersji Feeds. Proszę o ocenę, ale nie na tym mi zależy. Jakbyście mogli protestować wszystkie możliwości klasy, zadawać mi jak najwięcej pytań, aby wykryć tyle błędów, ile się tylko da.
Klasy zostały napisane w niecałą godzinę, dlatego wszystko jest możliwe. W razie wystąpienia jakichkolwiek błędów, będę zamieszczał kolejne wersje z poprawkami.
Już mogę powiedzieć, że opublikowana wersja klasy dla kanału Atom nie jest finalna, bowiem zapoznałem się dziś ze szczegółową budową kanału Atom. Brakuje mi parametrów dla tagów wewnątrz klauzuli < entry > takiego jak na przykład < link > dla pliku video.
Ostatnio dużo myślałem nad tym, co jeszcze można dodać do mojego frameworka, bo jest bardzo duży, a do publikacji (03.01.2007) już niedługo. Przez moją myśl przeszło ściąganie plików… no tak. Teraz gdzie to ująć :) . Mam klasę odpowiedzialną za przechwycenie uploadowanych plików, zbieranie informacji o nich, kopiowanie. Może tam? Owszem.
Kwestia ściągnięcia plików jest bardzo prosta: do przeglądarki wysyłamy odpowiednie nagłówki oraz wczytujemy treść, która zostanie pobrana. Możemy podjąć dowolną nazwę pliku, chociaż oryginalny ma nazwę stałą. Zacząłem szukać źródeł, w których zastosowane jest pobieranie plików.
Szczególnie pomocnym skryptem okazał się FileSupply mojego kolegi Korneliusza Jarzębskiego (bardziej znany pod nickiem Bastion, autor słynnych klas takich jak Babel, Chameleon, ScoutGeo, FileMagic). Dlaczego ten skrypt? Przykładem jest funkcja ekspozycji pliku, na samej górze jest link, za pomocą którego bez problemu możemy pobrać plik. Zacząłem szperać w kodzie :)
Po zapoznaniu się ze sposobem pobierania (nagłówki umiałem wysłać już wcześniej), który opierał się na pobraniu zawartości plików „w kawałkach‿ postanowiłem zastosować to w nowej metodzie mojej klasy. Co oznacza tzw. Pobieranie „w kawałkach‿? Często serwer mówi , że odczytywana treść wielkiego pliku przekroczyła dozwolony limit bajtów, haczykiem podsuniętym mi przez Bastion’a jest to, że pobieramy go w partiach: 64 * 1024 bajtów (64 kilo), po czym przerywamy odczyt i pętla działa dalej, od momentu w którym przerwaliśmy. Zapobiegnie to wyświetleniu błędów o dużym pliku :).
Ok, czas na kod całej klasy, dodana została metoda download, która jest statyczna, można ją wykorzystywać bez uprzedniego wywoływania instancji klasy. W pierwszym parametrze podajemy ścieżkę do pliku, a w drugim (nieobowiązkowo) nazwa pliku, pod którą ma być on pobrany. Gdy drugi argument pozostanie pusty, nazwa pliku który zostanie wysłany jako nagłówek do ściągnięcia pozostanie taka sama jak oryginalny plik. Przed wywołaniem metody wysłania pliku, nie mogą zostać przesłane żadne nagłówki, po metodzie nie mogą być wykonywane żadne działania przez skrypt php.
Pełny kod obsługi plików w moim frameworku (omawiana została metoda Vfile::download() ): http://phpfi.com/187275