Jak psát kód: Nepoužívejte copy/paste

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

Tento blog je sice určen pro mírně pokročilé, ale můžou na něj zabrousit i naprostí začátečníci nezkušení nejen v PHP, ale v programování vůbec. Postupně proto zveřejním několik velmi jednoduchých tipů, které můžou začátečníkům pomoci. Ale upřímně řečeno, některé z nich by si měli vzít k srdci i ostřílení mazáci. Některé z těchto rad naleznete v trochu jiném podání i v mé knize, stejně jako spoustu dalších.

Nepište kód metodou copy/paste

Máte kousek kódu, který dělá skoro přesně to, co potřebujete, tak ho zkopírujete jinam, trochu upravíte a je hotovo. Podle mě to je jedna z největších chyb, kterou můžete udělat. Pro údržbu a rozšiřování kódu je to hotová katastrofa – když později chcete něco opravit nebo vylepšit, tak to musíte udělat na mnoha místech. Obvykle nemůžete použít ani náhradu textu, protože kód je na různých místech různě upraven. Zkopírovaný kód je také velmi náchylný k chybám – řekněme, že chcete použít přesně ten stejný kód, jenom potřebujete vyměnit název proměnné. Uděláte to na dvou místech, ale třetího si nevšimnete. Tuhle chybu je obvykle těžké odhalit, obzvlášť pokud zkopírovaný kód použijete ve stejné funkci, kde původní proměnná pořád existuje.

Správné řešení je obvykle kód zobecnit, vyčlenit ho do funkce nebo metody a tu zavolat ze všech míst, kde je potřeba. Často je také vhodné použít jinou abstrakci. Např. místo takovéhoto kódu:

<?php
$result = $db->query($query);
if ($result === false) {
    trigger_error($db->error, E_USER_ERROR);
    return false;
}
foreach ($result as $row) {
    // zpracování řádek
}
?>

… je lepší chyby vyházet jako výjimky rovnou v metodě query() a dál si jich nevšímat:

<?php
foreach ($db->query($query) as $row) {
    // zpracování řádek
}
?>

Pro základní obraty je také vhodné používat makra v editoru. Já mám nadefinovaných kolem 300 maker, z nichž některé používám neustále a některá jsem si nadefinoval třeba jenom dočasně. Např. mám jednoduché makro, které před označený text vloží if () {, označený text odsadí, za něj vloží } a kurzor umístí do (). Nebo mám trochu složitější, které vloží tento kód:

<?php
foreach (glob("*") as $filename) {
    $file = file_get_contents($filename);
    
}
?>

Používám to často v jednoúčelových skriptech, kde žádnou abstrakci nemám k dispozici a nevyplatí se ji dělat. Nebo mám makro, které vloží tohle (value přijímá jako parametr):

<?php
private $value;

public function setValue($value) {
    $this->value = $value;
    return $this;
}

protected function getValue() {
    return $this->value;
}
?>

Kurzor se umístí za setValue(, takže nezapomenu doplnit typehint (ten by makro mohlo přijímat v druhém parametru, když bych ho chtěl dát třeba i do dokumentačního komentáře). Možná změním viditelnost metod, možná některou z nich smažu nebo ze setteru udělám konstruktor. Pointa je v tom, že je rychlejší a bezpečnější smazat vygenerovaný kód, než ho kopírovat odjinud a upravovat. V některých projektech samozřejmě opět můžete použít jinou abstrakci, takže dané metody vůbec nebudete potřebovat.

Zkopírování jedné řádky může být v pořádku, třeba pokud vytváříte prvky pole ve formátu self::TYPE_ => '',. Ale často i zkopírování jediné hodnoty může způsobit velký problém. Vezměme si tenhle kód:

<?php
$offset = 0;
$limit = 1000;
do {
    $results = getData($limit, $offset);
    // zpracování výsledků
    $offset += 1000;
} while (count($results) == $limit);
?>

Co se stane, když se časem rozhodneme limit zvýšit, abychom skript zrychlili, nebo naopak snížit, abychom ušetřili paměť? Pokud zároveň nezměníme i $offset += 1000, tak v prvním případě některé záznamy přeskočíme a v druhém případě je zpracujeme víckrát. Opět si toho vůbec nemusíme všimnout. Správné řešení je kód změnit na $offset += $limit nebo $offset += count($results), čímž si tyto problémy v budoucnu ušetříme.

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

Diskuse

P.:

Co doporučejete za editor pro PHP? Zkoušel jsem i různá placená řešení a skoro vždy skončím zase u PSPadu...

Medvídek:

Nedoporučuji ani tak editor, jako spíše vývojové prostředí (IDE). Sám používám NetBeans a jsem spokojen :)

Roman Antl:

No já používám PHPStorm a nemohu si stěžovat. Netbeansy jsem měl hrozně rád, ale díky tomu, jak žerou paměť a procesor tak jsem od nich odešel. PHPStorm je sice placený, ale můžeš si jej vyzkoušet na 30 dní zdarma.

Medvídek:

V dnešní době i7 a 16GB RAM to už ani nepociťuji. Ale je pravda, že jsou trošku žrouti :)

Dero:

Pokud chcete opravdu jenom editor a nikoli IDE, pak doporučuju Sublime Text. Přecházel jsem na něj právě z PSPadu, na který jsem jinak nedal dopustit.

Patrik Šíma:

Vše co běží na Javě patří do koše. Doporučuji Sublime 3.

ikona Jakub Vrána OpenID:

Já používám SciTE: http://php.vrana.cz/editor-scite.php. Je to jen jednoduchý editor, nemá ani debugger, ale jeho naprostá přizpůsobitelnost zatím zvítězila nad vším ostatním.

jozi:

Ahoj Jakub, som velmi rad, ze znova pises. Ako vidis buducnost notorm?
Uz som sa odhodlal ho zacat pouzivat, no neviem, ci sa tomu niekto este venuje. Je velka skoda, ze sa to zatial viac nerozsirilo... Dakujem

Juraj:

Scite a PHPStorm

Nik:

Osobně momentálně používám Netbeans v7.2.1, oproti 6.5 je o dost rychlejší. Mnoho lidí berou alternativu Eclipse.

Jako zálohu používám SciTE, nebo Vim. Ono, pokud člověk upravuje kód skrze SSH na virtuálním stroji, tak ani v době i7 a 16GB RAM není zrovna paráda otvírat Netbeans na vzdálené ploše, možná ještě tak na lokální síti.

Ještě jsem používal Komodo, ale pro častý pocit, že mě zdržuje při našeptávání jsem přešel právě na SciTE.

Jediná věc, co mě vadí u SciTE, je trošku zdlouhavá konfigurace.

Obecně je to vše nejspíš o ,,zvyknout si" a kompromisu :-)

ikona Ondrej:

Rozhodne SciTe

ikona Jakub Vrána OpenID:

NotORM bohužel doplácí na to, že ho poslední dobou nepoužívám. Mám jeden plán, jak dále podstatně vylepšit výkonnost, ale realizuji ho asi jen jako proof of concept (v branchi). NotORM bylo forknuto do Nette Database, které je udržované, takže bych asi doporučil použít spíš to, i když mně víc vyhovovalo NotORM.

kamil:

Aj ja mam ovela radsej NotORM. V podstate mi ani nevadi, ze sa nevyvija, lebo je super ako je. Zaujimalo by ma ci si nevedies nejaku statistiku stiahnuti, pripadne ci sa stretavas s tym, ze by sa pouzivalo v nejakych velkych projektoch (Nette je jasne) sudiac z odozvy, ktoru isto dostavas. Vdaka.

ikona Jakub Vrána OpenID:

O NotORM mám asi 100 nevyřízených mailů. Statistiku stáhnutí nevedu. Hlavní myšlenka NotORM (stahování souvisejících záznamů pro celý výsledek najednou místo jednotlivě) se dostala kromě Nette ještě do Phabricatoru. O jiných velkých užitích nevím. Mám za to, že většina přešla na Nette Database.

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: Reakce na: Jakub Vrána

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.