Metoda pro generování náhodného řetězce
- Jan Mikeš
- Člen | 771
Jsem pouze pokrocily zacatecnik a tak vas prosim o radu :).
Mam tuto metodu v jednom z presenteru.
protected function randString($length = 0, $charset = null)
{
$length = ($length)? $length : $this->context->parameters["codeLength"];
$charset = ($charset)? $charset : $this->context->parameters["codeCharset"];
$str = '';
$count = strlen($charset);
while ($length--) {
$str .= $charset[mt_rand(0, $count-1)];
}
return $str;
}
A v configu
parameters:
codeCharset: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz123456789'
codeLength: 15
Vse funguje tak jak ma a je v poradku, co se mi ale nezda a s cim bych rad poradil, je jak to vyresit s temi parametry z kontejneru? Myslim si, ze neni uplne koser si sahat az primo v metode pro ne.
Je to otazka spise typu BEST PRACTISE, protoze vse funguje tak jak ma, jde mi jen o cistotu kodu a take o to abych se priucil neco dalsiho.
Tedy, je to takhle v poradku nebo to lze nejak lepe prepsat?
- Filip Procházka
- Moderator | 4668
Ano, jde to lépe. Všechno tohle co jsi napsal smažeš a použiješ následující řádek.
$code = Nette\Utils\Strings::random(15);
- vvoody
- Člen | 910
Tú metódu máš zrejme v presenteri. Presenteru vieme momentálne predať len službu ale parameter nie (tento problém má v pláne David poriešiť) preto by som si tú metódu randString vložil do služby ktorej už bez problému v configu nastavíš nejaký parameter do konstruktoru.
A keď potrebuješ random string tak pozri dokumentáciu.
- ViPEr*CZ*
- Člen | 814
I kdyby nešlo toto
$code = Nette\Utils\Strings::random(15);
, tak není dobré to cpát do určitého presenteru. Je to velice obecná věc, takovej helper pro práci s řetězcem. Buď (opět kdyby to nešlo) by jsis rozšířil tu třídu z Nette přes dědičnost a pak by jsi všude používal ji nebo si to dát do nějaké svojí. Furt to bude vně presenteru a kdykoliv k použití.
- Jan Mikeš
- Člen | 771
Mate pravdu, random() plne splni me pozadavky, diky moc.
Ohledne toho ze nelze presenteru momentalne predat parametr jak to myslis?
echo $this->context->parameters["codeCharset"]; // vypise ABCDEFGHIJKLM...
Myslis to tak, ze si pro nej musim sahat rucne a ne ho nejak predat jako parametr funkce? Pokud ano tak to chapu a zajima me, jestli je to takto jedine a tedy i spravne reseni, nebo to je fuj a jak jsi napsal radeji si vytvorit nejakou pomocnou sluzbu.
- uestla
- Backer | 796
S předřečníky souhlasím, přidám přetavený příklad…
config/config.neon
parameters:
randomizer:
codeCharset: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz123456789'
codeLength: 15
services:
stringRandomizer: StringRandomizer( %randomizer.codeCharset%, %randomizer.codeLength% )
presenters/helpers/StringRandomizer.php
class StringRandomizer extends Nette\Object
{
/** @var string */
protected $chars;
/** @var int */
protected $length;
function __construct($chars, $length)
{
$this->chars = $chars;
$this->length = $length;
}
function generate()
{
// ...
}
}
presenter/HomepagePresenter.php
class HomepagePresenter extends BasePresenter
{
/** @var StringRandomizer */
protected $randomizer;
function injectRandomizer(StringRandomizer $randomizer)
{
$this->randomizer = $randomizer;
}
function renderDefault()
{
$this->template->randomString = $this->randomizer->generate();
}
}
Editoval uestla (31. 8. 2012 19:33)
- vvoody
- Člen | 910
Lexi napsal(a):
Ohledne toho ze nelze presenteru momentalne predat parametr jak to myslis?
echo $this->context->parameters["codeCharset"]; // vypise ABCDEFGHIJKLM...
Myslis to tak, ze si pro nej musim sahat rucne a ne ho nejak predat jako parametr funkce? Pokud ano tak to chapu a zajima me, jestli je to takto jedine a tedy i spravne reseni, nebo to je fuj a jak jsi napsal radeji si vytvorit nejakou pomocnou sluzbu.
Myslel som to bez použitia contextu, ťahanie čohokoľvek z neho ide proti DI. Vybodnúť sa na DI môžeš, čo este fuj fuj nieje, ale ako už bolo spomenuté tak tá funkcia logicky vôbec nepatrí do presenteru. Mať ju tam už fuj fuj je :D
Editoval vvoody (31. 8. 2012 19:43)
- ViPEr*CZ*
- Člen | 814
Jenom upozorním,
class HomepagePresenter extends BasePresenter
{
/** @var StringRandomizer */
protected $randomizer;
function injectRandomizer(StringRandomizer $randomizer)
{
$this->randomizer = $randomizer;
}
function renderDefault()
{
$this->template->randomString = $this->randomizer->generate();
}
}
Tohle půjde až od 2.0.5. verze.
- Filip Procházka
- Moderator | 4668
Ano, ale musel bys ještě zavolat parent::__construct();
vždycky volej parent
!
- castamir
- Člen | 629
Můžu poprosit malé o vysvětlení?
class HomepagePresenter extends BasePresenter {
/** @var StringRandomizer */
protected $randomizer;
function __construct(StringRandomizer $randomizer) {
parent::__construct();
$this->randomizer= $randomizer;
}
}
Toto chápu, ikdyž bych měl určité nutkání to řešit přes metodu startup() místo konstruktoru, ale to je jedno. Co jsem naopak nepobral je ta následující prý ekvivalentní metoda injectRandomizer():
class HomepagePresenter extends BasePresenter {
/** @var StringRandomizer */
protected $randomizer;
function injectRandomizer(StringRandomizer $randomizer) {
$this->randomizer= $randomizer;
}
}
Randomizer z názvu této metody souvisí s privátní proměnnou $randomize, parametrem randomize v config.neon nebo třídou StringRandomize?
Edit: Ať je to kterákoliv z těchto možností, tak mi to přijde docela divné řešení. Stačí pomyslet třeba na víc takto přidaných parametrů (člověk si zahltí zdroják spoustou jednořádkových metod, když to může mít pěkně přehledně u sebe na jednom místě)…
Editoval castamir (31. 8. 2012 22:04)
- Jan Mikeš
- Člen | 771
Tusim ze se zde vyuzije autowiring, diky tomu ze trida StringRandomizer (service) je unikatni v cele aplikaci tak presenter vi odkud ji vzit (alespon takto si mysli mze to funguje, ale ruku do ohne bych za to vazne nedal), tudiz odpoved na tvou otazku je ze souvisi s nazvem tridy StringRandomizer.
A pouziti __construct:: asi bych ho pouzil proto, ze se vola drive nez startup, kdybych nahodou chtel objekt pouzivat uz tam.
Edit: me se zase zamlouva vice injection reseni, nez mit nafouknuty
konstruktor
Edit2: pokud to chapu spatne nekdo me opravte prosim
Editoval Lexi (31. 8. 2012 22:10)
- Jan Mikeš
- Člen | 771
Podle toho co jsem se nekde docetl tak se v presenter factory provadi vsechny injectXXX metody a parametr si to dohleda podle nazvu tridy uvedenem tam, takze asi je uplne jedno jak se metoda jmenuje (dulezity je jen jeji parametr), ale o teto problematice toho moc nevim, takze jenom tlumocim co jsem se docetl nekde jinde a jak jsem to pochopil.
Editoval Lexi (31. 8. 2012 22:55)
- Vojtěch Dobeš
- Gold Partner | 1316
inject
metody mohou mít jakýkoliv název (akorát musí být prefixované tíminject
)- autowiring se neřídí podle názvu metody, ale podle typehintu
startup
a__construct
nejsou podobné metody. Konstruktor je specifická metoda volaná při vytváření instance třídy.startup
je specifikum životního cyklu Nette presenterů. Takže snažit se předat něco do presenteru pomocístartup
je nesmysl (protože tu metodu volá sám presenter, nemůže si sám předat závislosti)