Třída String v PHP

Začalo mi vadit, že jsem si musel pamatovat všechny ty speciální funkce pro práci s řetězci a zároveň, že nepodporují kódování UTF-8. Co si budeme povídat, člověk občas zapomene použít mb_ variantu. Proto jsem se nechal inspirovat třídou String v Javě a pokusil se implementovat něco podobného v PHP. Chtěl jsem vytvořit něco, co se bude používat jako standartní řetězce v PHP s přidanou objektovou hodnotou.

Druhá moje myšlenka byla, aby se třída dala instancovat, ale zároveň šla používat i staticky. Tady jsem trochu narazil a byl jsem nakonec nucen udělat třídy dvě. Pokud zavolám nestatickou metodu staticky, vyhodí PHP (alespoň verze 5.3) strict vyjímku. Statickou funkci sice lze z instancované třídy zavolat, ale docela logicky se jí nepředá kontext třídy. Vše jsem chtěl vyřešit pomocí magických funkcí __call a __callStatic, ale nakonec jsem od toho upustil. Chtěl jsem, aby mi IDE napovídalo všechny použitelné metody a takhle bych o tuto vlastnost přišel. Takže nakonec vznikla třída StringInstance a statická třída String. Přitom String není pouhou kopií StringInstance, ale jsou v ní pouze staticky využitelné funkce. Nakonec jsem využil magických funkcí __call a __callStatic. U tohoto řešení mi nejvíc vadilo, že by mi IDE nenapovídalo při psaní kódu, ale využil jsem phpdoc anotaci @method. Bohužel zde nelze rozlišit statické volání metody od volání metody na instanci třídy. Prozatím nevím jak to vyřešit a tak si musím pamatovat, že statické metody vždy jako svůj první parametr potřebují řetězec, se kterým se bude pracovat a jako volitelný parametr většina z nich přijímá na posledním místě kódování, které je defaultně UTF-8.

Podívejme se teď na využití třídy String. Když chceme vytvořit nový řetězec, použijeme:


$string = new String("Testovací řetězec");

nebo jednodušší:


$string = string("Testovací řetězec");

Konstruktor třídy String má dva parametry. První povinný je samotný řetězec a druhý nepovinný je kódování. Zadat ho musíte pouze pokud je jiné než UTF-8.

Od teď už s proměnou $string pracujeme jako s obyčejným řetězcem. Můžeme ho vypisovat, porovnávat (z pochopitelných důvodů pouze pomocí == a ne pomocí ===) a vůbec s ním dělat vše, co s normálním řetězcem.

Teď se ovšem podívejme na onu přidanou hodnotu, kterou jsem zmiňoval na začátku. Většina funkcí je převzata z Javové třídy String a i použití je obdobné. Podívejme se na příkad:


echo $string->length(); // Vypíše délku řetězce

echo $string->toUpperCase()->substring(2, 4); // Vypíše ST

if($string->startsWith('Test')) {

  echo "Řetězec začíná na Test...";

}

Nebudu zde vypisovat všechny možné funkce, které můžete použít, najdete je popsané přímo ve třídě. Vypíchnu ještě dvě vlastnosti. Třída implementuje rozhraní Iterator a ArrayAccess, proto můžete používat i následující konstrukce:


// Procházení řetězce pomocí foreach

foreach($string as $position => $char) {

  echo $char . " at " . $position . "\n";

}

// Práce s řetězcem jako s polem

echo $string[5]; // Vypíše v

$string[5] = 'X'; // Změní pátý znak na X

unset($string[5]); // Vypustí pátý znak z řetězce

Poslední funkce, na kterou bych rád upozornil je encode. Pokud ji zavoláte bez parametrů, vrátí použité kódování. Pokud jí předáte nové kódování, vrátí String v novém kódování.

Statická třída String, funguje na podobném principu, akorát jako první parametr přebírá vždy řetězec, na který se má funkce aplikovat a jako poslední většinou použité kódování, které je opět potřeba zadat pouze pokud se liší od UTF-8.


echo String::length("Test..."); // Vypíše délku řetězce

echo String::toUpperCase("tohle bude velké");

if(String::startsWith("Testovací string...", 'Test')) {

  echo "Řetězec začíná na Test...";

}

Třída implementuje fluent interface. Takže je možné používat i následující kontrukce:


echo $string->substring(2)->toLowerCase();

echo String::substring("jejda, tohle bude velké", 7)->toLowerCase();

Aktuální verzi můžete stahovat z frameworku phpMiniVC zde.

Napsat komentář

Vaše emailová adresa nebude zveřejněna.