Předávání pravdivostních parametrů

Školení, která pořádám

Někdy je funkci potřeba předat pravdivostní parametr, třeba jestli má v průběhu své činnosti něco tisknout nebo ne:

<?php
function process($print = false) {
    if ($print) {
        echo "průběžné informace\n";
    }
    // ...
}
?>

Pokud tuto funkci zavoláme jako process(true), je to značně nečitelný zápis, protože není na první pohled patrné, co to true znamená. Já jsem si proto zvyknul používat zápis process("print"). Jiná možnost je definovat si konstanty a pak volat process(PRINT), s tím je ale samozřejmě trochu práce navíc.

Jakub Vrána, Dobře míněné rady, 25.7.2005, diskuse: 22 (nové: 0)

Diskuse

Michal:

Programuju v PHP už 5 let, ale nějak jsem nepochopil, co tímto chtěl autor říct?

houba:

Pravděpodobně chtěl autor říct, že lepší než nazvat funkci pořádně, aby každý pochopil co dělá nebo může dělat, tak si raději odvyknu používat proměnné typu Boolean (jejichž zpracování je velmi rychlé) a vše budu smolit pomocí řetězců...

ikona Jakub Vrána OpenID:

O pojmenování funkce tady vůbec nejde. Jde o to, že když funkce dostává volitelné parametry, které mohou nabývat hodnot true/false, je čitelnější volání:

process($normalni_parametr, "no_print", "debug");

než

process($normalni_parametr, false, true);

Ve spoustě případů zcela nepodstatné snížení výkonnosti nehraje žádnou roli. Pokud roli hraje, je zmíněna možnost definice konstant.

ikona dgx:

jenže

process($normalni_parametr, "no_print", "debug");

znamená

process($normalni_parametr, true, true);

ikona Jakub Vrána OpenID:

Trochu představivosti... V prvním případě může být funkce deklarovaná jako <?php process($x, $no_print = false, $debug = false) ?>, v druhém jako <?php process($x, $print = true, $debug = false) ?>.

Případně lze mít funkci deklarovanou takto:

<?php
function process($x, $print = null, $debug = null)
{
    if (!isset($print)) $print = false;
    if (!isset($debug)) $debug = false;
}
?>

To se hodí v případě, kdy jedna funkce s volitelnými parametry volá druhou, tedy např.:

<?php
function process2($x, $print = null, $debug = null)
{
    return process(2*$x, $print, $debug);
}
?>

Výchozí hodnoty volitelných parametrů je potom možné mít pouze na jednom místě.

Mimochodem, ta vlna nesouhlasných reakcí se zvedla proto, že jsem to napsal nepochopitelně nebo to považujete za naprostou blbost? Jak to řešíte vy?

ikona dgx:

spíš jde o to, že pravdivostní hodnota řetětce je až na dvě výjimky vždycky true, tedy můžu napsat process("print", "debug"), ale process("no_print", "debug") bude totéž. Tedy musím psát process(false, "debug") a jaksi efekt je fuč, dokonce v tom vzniká jistý zmatek.

Tuhle myšlenku nezatracuju a pokud Ti vyhovuje, je to jen dobře. Osobně to používat nebudu, vidím v tom krok zpátky.

ikona Jakub Vrána OpenID:

Krok zpátky oproti čemu? Co třeba pole s parametry, jako jsem viděl myslím v JpGraph?

<?php
function process($x, $params = array()) {
    if (!isset($params["debug"])) $params["debug"] = false;
}

process($x, array("debug" => true));
?>

ikona dgx:

taky je možné, že jsem to zcela správně nepochopil...

ikona dgx:

Jakube, v čem jsi programoval před PHP?

Jakub Podhorský:

no tak tohle se mi nezdá jako nejlepší řešení...

buď si nazvu funkci pořádně abych na první pohled věděl co dělá

a nebo používám editor který podporuje PHPDoc a přidává ho při doplňování funkcí jako nápovědu...tuším že tohle umí phpEd a myslím že i Zend Studio

halogan:

Je to dobra idea, sam jsem driv delal metody ve tridach, ktere se volaly treba takto:
$t->input("Jmeno", 20, true, false, false, true);

Ted si to zpetne uvedomuji.

Jakub Podhorsky: Ano, ZDE to umi.

Tomáš (ATom):

Ano, čitelné je to lépe, ale kdo si bude pamatovat, co tam mám psát. Když nad tu funkci najedu v ZendStudiu, tak se zobrazí bublina s definici jednotlivých parametrů a jásně vidím, co kam mám dát, kdybych tam dával řetězece, tak to musím složitěji popisovat, co který řětězec znamená a hlavně ten řětězec musím psát, což může vést k překplepům. To už jsou lepší ty konstanty, nebo ještě lépe statické proměnné třídy.

Ale něčemu jako
$t->input("Jmeno", 20, true, false, false, true);
je fakt lepší se vyhnout
Od toho je to přece OOP, aby šlo:
$t->setMaxLenght(20);
$t->activateCheck(true);
$t->input("Jmeno");

halogan:

Jiste, to je dobre, ale pak formular s dvaceti inputy bude bordel...

ikona llook:

Zajímavý nápad, ale připadá mi, že to je vlastně jen zvláštní poznámka. Asi jako /* print = */ true. Já bych to psal spíš takhle:
<?php
process
(true); // print=true
?>

Třeba v Pythonu to řeší tzv. keyword argumenty. Když má funkce pět volitelných argumentů a já chci explicitně určit jen ten poslední, uvedu jeho název, např.:

frame = wx.Frame(title = "Hello world");

ia:

imho je najlepsie pouzit konstanty, ked nam ti TRUE/FALSE tak vadi, je to ovela efektnejsie a efektivnejsie...
tie konstanty mozme definovat akurat nad tou ktorou funkciou napriklad...

ikona Jakub Vrána OpenID:

Nevím co máš na mysli "konstantami definovanými nad tou kterou funkcí". Mohl bys to nějak vysvětlit?

ia:

define ('DEBUG', TRUE);
define ('NO_DEBUG', FALSE); <- toto som myslel tym 'dan funkciou' :) proste ze su napisane pri funkcii.

function blabla ($debug)
{
if ( $debug )
{
  // nieco zrob
}
}

Ale jak na to pozeram, tiez to nieje bohvieaka vyhra...

Jakub Podhorský:

já si myslím že se takhle akorát zbytečně vytvářejí konstanty a zbytečně tak zaberou místo v paměti

ikona Jakub Vrána OpenID:

Kolik bys řekl, že zabírá paměti konstantní řetězec?  Bez detailních znalostí toho, jak PHP vevnitř funguje není vhodné takové soudy vynášet.

Vozka:

Ahoj, trochu to na me pusobi jako proc delat veci jednoduse kdyz to jde slozite. Zcela bez pochyby se nejedna o nic sloziteho, ale zanasi to do kodu dalsi logiku nad kterou bude muset nekdo (nebo i ty sam) pozdeji premyslet. Proc proste nepouzit komentar a nenapsat si ze predni parametr je print a druhy debug, pokud to chci mit prehledne...
Nasledne kdokoliv prijde tak vidi jednoduchou funkci bez balastu a nastavovani konstant a ucel to splnilo take?
Nebo uz dneska neni v mode psat komentare?
V

ikona Jakub Vrána OpenID:

Nejspíš jsi článek nepochopil. Parametry zůstávají stejné, pouze při volání se použije process("print") místo process(true). Vnitřek funkce se nijak nemění.

msx:

A prečo nevyužiť JavaDoc, či  ako sa to volá? Ja by som radšej, pri volaní funkcie použil $print = true. Síce  sa zbytočne Inicializuje premená, ale bude to prehľadnejsie.

Vložit komentář

Používejte diakritiku. Vstup se chápe jako čistý text, ale URL budou převedeny na odkazy a PHP kód uzavřený do <?php ?> bude zvýrazněn. Pokud máte dotaz, který nesouvisí s článkem, zkuste raději diskusi o PHP, zde se odpovědi pravděpodobně nedočkáte.

Jméno: URL:

avatar © 2005-2018 Jakub Vrána. Publikované texty můžete přetiskovat pouze se svolením autora. Ukázky kódu smíte používat s uvedením autora a URL tohoto webu bez dalších omezení Creative Commons. Můžeme si tykat. Skripty předpokládají nastavení: magic_quotes_gpc=Off, magic_quotes_runtime=Off, error_reporting=E_ALL & ~E_NOTICE a očekávají předchozí zavolání mysql_set_charset. Skripty by měly být funkční v PHP >= 4.3 a PHP >= 5.0.