Co takhle datový typ String (a hezky s Fluent interface)?
- knyttl
- Člen | 196
Určitě jste již někdy dospěli do stavu, kdy jste psali něco podobného:
<?php
return str_replace(array('<', '>'), array('<', '>'),
preg_replace('#\n{3,}#', "\n\n",
preg_replace('#[ ]*[\n][ ]*#', "\n",
preg_replace('#<.*?>#', "\n",
preg_replace('#<script.*?</script>#sm', '',
preg_replace('#<a.*?href=\"(.*?)\".*? >#', "\n\n$1\n\n",
(string) $str
))))));
?>
Fuj! Chci-li pak třeba zakomentovat jeden řádek, tak musím na konci odmazávat koncové závorky a vůbec je to celé ošklivé.
Všimněte si prosím také tohoto příkladu:
<?php
function foo(string $string) {
return $string;
}
foo('Ahoj světe!');
?>
PHP bude celé nešťastné, že $string není třídy ‚string‘, ale že je pouze ‚string‘.
Co si tedy takhle implementovat Fluent třídu String, která podobné problémy řeší?
https://gist.github.com/1613895
Wow! Nyní tedy můžeme psát:
<?php
return String::from($str)
->pregReplace('#<a.*?href=\"(.*?)\".*? >#', "\n\n$1\n\n")
->pregReplace('#<script.*?</script>#sm', '')
->pregReplace('#<.*?>#', "\n")
->pregReplace("/[ ]*[\n][ ]*/", "\n")
->pregReplace("/\n{3,}/", "\n\n")
->replace(array('<' => '<', '>' => '>'));
?>
Volání funkcí:
<?php
function foo(String $string) {
return $string->replace('mastná', 'nemastná');
}
$foo = foo(String::from('Vlhká, mastná.'));
?>
Což kompilátoru už nevadí!
Všimněte si proměnné $classInjection, kterou je možné do třídy předat třídu, která bude magicky volána v případě, že methoda není implementována. Tedy například:
<?php
$string = ' Tahle vyvinutá Britka patří mezi oblíbenkyně Hugha Hefnera. Podívejte se na její perfektní tělíčko ';
$string = String::from($string)
->replace(array('patří' => 'nepatří', 'Podívejte' => 'Nedívejte'))
->pregReplace('#B.*?tka#', 'Američanka')
->trim()
->toAscii();
echo $string;
?>
Trim a toAscii jsou methody implementované v Nette\Utils\Strings a tímto způsobem je možné se jich velice snadným způsobem domoci!
Není problém doimplementovat jakoukoliv metodu, zatím na zkoušku jsem střelil pouze replace, pregReplace a iconv. Asi to chce ještě trochu učesat a ohlídat, ale jinak pěkné, že?
Editoval knyttl (15. 1. 2012 3:21)
- llook
- Člen | 407
Já bych především ten první příklad nepsal tímhle LISPovským stylem, kdo se má pak v těch závorkách vyznat:
$out = preg_replace('#<a.*?href=\"(.*?)\".*? >#', "\n\n$1\n\n", (string) $str);
$out = preg_replace('#<script.*?</script>#sm', '', $out);
$out = preg_replace('#<.*?>#', "\n", $out);
// atd.
return $out;
Jinak budeš muset dávat pozor, jestli na daném místě používáš string
nebo String, mimo jiné kvůli knihovnám třetích stran. Zaneseš si kód
spoustou (string)
a String::from
, což na
přehlednosti nepřidá. Jedinou výhodu vidím v tom type hintingu, ale typ se
nakonec vždycky dá zkontrolovat uvnitř funkce, pokud je ta potřeba.
- Patrik Votoček
- Člen | 2221
knyttl napsal(a):
Určitě jste již někdy dospěli do stavu, kdy jste psali něco podobného
Nedospěl… A i kdyby tak nebudu prasátko a budu to psát tak jak píše llook.
Co se týká typehintu v metodách tak bych tě rád odkázal do příslušného vlákna v PHP internals. Kde se řešilo proč to v PHP není a nebude. Ale nemůžu ho najít :-(
a jinak tě odkážu sem https://forum.nette.org/…g-byla-trida