Metoda pro generování náhodného řetězce

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
Jan Mikeš
Člen | 771
+
0
-

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
+
+1
-

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
+
0
-

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
+
0
-

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
+
0
-

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
+
0
-

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
+
0
-

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)

Jan Mikeš
Člen | 771
+
0
-

Diky vsem za nazory a za peknou ukazku od uestla, rozsirila mi obzory.

ViPEr*CZ*
Člen | 814
+
0
-

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.

Jan Mikeš
Člen | 771
+
0
-

A v 2.0.4 by se to resilo jak?
Pres konstruktor?

private $randomizer;

function __construct(StringRandomizer $randomizer)
{
    $this->randomizer= $randomizer;
}

Toto by fungovalo? Ciste teoreticky, v tuhle chvili to nevyuziju, ale do budoucnosti bych rad vedel.

Filip Procházka
Moderator | 4668
+
0
-

Ano, ale musel bys ještě zavolat parent::__construct(); vždycky volej parent!

Jan Mikeš
Člen | 771
+
0
-

Samozrejme, toto bylo psano z hlavy jen jako ukazka. Diky.

castamir
Člen | 629
+
0
-

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
+
0
-

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)

castamir
Člen | 629
+
0
-

autowiring by nejspíš byl právě na stringRandomizer nikoliv přece na Randomizer.

Jan Mikeš
Člen | 771
+
0
-

Ano to jsem napsal :)

castamir
Člen | 629
+
0
-

no asi jsem se vyjádřil blbě – předpokládám, že to má být

function injectStringRandomizer(StringRandomizer $randomizer) {
    $this->randomizer= $randomizer;
}

nikoliv

function injectRandomizer(StringRandomizer $randomizer) {
    $this->randomizer= $randomizer;
}
Jan Mikeš
Člen | 771
+
0
-

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
+
0
-
  1. inject metody mohou mít jakýkoliv název (akorát musí být prefixované tím inject)
  2. autowiring se neřídí podle názvu metody, ale podle typehintu
  3. 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)
vvoody
Člen | 910
+
0
-

@castamir: myslím že podstatné je len to že funkcia začína na inject a aký je uvedený type hint. Tu sa prehľadávajú metódy presenteru a vôbec sa neberie ohľad na to čo je za inject.

edit: zasa neskoro :D

Editoval vvoody (31. 8. 2012 23:10)

Jan Mikeš
Člen | 771
+
0
-

Takze jsem to pochopil spravne, to me tesi :)