Zdar priatelia. Ako začiatočník mám vcelku jednoduchú otázku. Čo sa v PHP používa viac? Alebo dá sa povedať že jeden prístup je správny a druhý nie? prípadne aké sú výhody a nevýhody medzi OOP a funkcionalnim programovanim v PHPcku? Diky
Fórum › PHP
OOP vs Funkionalni programovani
#1 Koder
V PHP se dá používat obojí plus pár dalších paradigmat. Nedá se říct, že by jeden byl horší než druhý a dají se skvěle kombinovat. Obtížné je pouze udržet v kódu jistý řád, aby se v něm dalo vyznat i po delší době.
Nejpoužívanější paradigma v PHP je asi strukturované, případně špagetové :)
#3 MilanL
OOP je naopak šetrnější k serveru, protože logicky se 50řádkový skript natahuje rychleji než 500řádkový, i když jich je 10× tolik. Do paměti se totiž natahují jen třídy, které jsou aktuálně potřebné.
Koder - Bych si tipl, ze Kit pracuje nekde ve firme a nespis se podili mozna i nejak na tomhle forku.
Osobne pouzivam, jak funkce, tak objekty. Objekty mam radeji, protoze vytvari jakousi ucelenou strukturu funkci. Jakoze si udelas treba objekt pro praci s db nebo pro praci se soubory, odesilani mailu a tak. A pak, kdyz chces odeslat mail i jinde v programu, opet pouzijes objekt. Pridas tam treba funkce pro escapovani a tak. Dalsi objekt si treba udelas pro vypis html. Resi renderovani tagu, selecty / checkbox listy z pole a tak. V jinem programu, kdyz to chces pak pouzit, tak presne vis co, pretahnes cely class.
Funkce pouzivam vyjimecne, pro nejake kratke veci nebo zjednoduseni. Treba prave pro escapovani.
function escapeHtml($str) {return htmlspecialchars($str);}
function escapeUrl($str) {return urlencode($str);}
function unescapeUrl($str) {return urldecode($str);}
function escapeJs($str)
{
$str = preg_replace('~[\']~' ,'\\$1',$str);
$str = preg_replace('~[\\n]~','\\$1',$str);
return $str;
}
function escapeCsvValue ...
function escapeSqlKey ...
function escapeSqlValue ...
Vim, ze se ta funkce jmenuje escape a nemusim se rozpominat, jak to ma php pojmenovane a pod cim to mam hledat :) A hlavne ji pouzivam ve vice class, takze bych to musel mit vsude definovane nebo nejakou globalni class jenom pro ecapovani.
#7 peter
Máš pravdu v tom, že dělám vývojáře ve firmě, ale sem chodím jako řadový člen pro inspiraci. Také se tím snažím vrátit komunitě to, co mi dala.
BTW: Ten seznam funkcí je hezký. Ty funkce jsou bezstavové a proto by bylo zbytečné je dávat do tříd.
#1 Koder
Funkcionální programování je v PHP velice podivné. Sice má nějakou podporu, ale co jsem se naposledy díval, nebylo to nic, co bych komukoliv doporučil.
Ve skutečnosti ses chtěl zeptat na rozdíl mezi procedurálním a OOP programováním. A na to ti Kit odpověděl.
Alespoň bych si to tak tipl na základě toho, že mluví o "delším skriptu".
Funkcionální programování je obecně stručnější než OOP. Ale PHP a FP mají k sobě obecně velmi daleko.
#9 hanpari
Poměrně často používám styl FP například pro spojování stringů v seznamu s nějakou spojkou. Na to má PHP i své zkratky, například implode(). Spolu s funkcí array_map() se dobře slepují SQL dotazy s proměnným počtem podmínek ve WHERE apod. Je to i přehledné. Ostatní to běžně dělávají v cyklu, ale musí nějak ošetřit, že před prvním a za posledním prvkem spojka být nesmí.
PHP a FP sice k sobě mají daleko, ale stále je to blíž, než jak to má třeba Java (před verzí 8). Lambdy, uzávěry a l-výrazy v PHP docela ujdou.
#10 Kit
To by mohl být námět na zajímavou debatu nebo flameware. Mají prvky z FP něco společného se samotným funkcionálním programováním? Stejný rozdíl může být mezi OOP a programování s objekty.
Vzhledem k tomu, jaké zmatení tady panuje, nebudu raději takové drobnosti řešit. Pokud ale budeme za základ FP považovat silný typový systém, neměnnost (immutability) a ryzí (pure) funkce, tak celá filosofie PHP jde proti tomu.
Doufám, že nebudu PHP křivdit, když ho označím za slabě typovaný jazyk s řadou globálních proměnných.
Pokoušet se v PHP o FP je IMHO marné. Ono to není snadné ani v jazycích, které jsou jako funkcionální navrženy, nebo jsou jimi hodně ovlivněné. Například Clojure je sám o sobě úplně jiný svět, protože pokud vím vychází z LISPu. ML rodina (OCaml, Fsharp, Haskell) opět jiný svět.
Nejsrandovněji z toho pak vyjde Javascript, který prý původně měl být LISPem s Céčkovou syntaxí, ale protože se jmenuje JAVAscript klame už svým názvem, i když s Javou rozhodně nemá nic společného.
To ostatně demostruje tady:
https://github.com/hemanth/functional-programming-jargon
Omlouvám se, že jsem z PHP přeskočil na Javascript, ale o FP se nemá v PHP smysl moc bavit. Na druhou stranu v Javascriptu to snad smysl má:
http://www.apress.com/la/book/9781484226551
Mimochodem, doporučuji :)
#14 hanpari
Souhlasím, že PHP je slabě typované a že FP se v něm dá provozovat jen omezeně. Ta trocha mi však stačí a používám ji spíš jen jako koření do převažujícího paradigmatu OOP. Na bezstavové záležitosti však OOP nedává příliš smysl.
#14 hanpari
V JS pouzivam ted objekty taky. Obvykle potrebuji jen jeden, tak se nepyplam s this-y. Obvykle to vypada takto:
function objGet(id) {return document.getElementById(id);}
var ENG = {};
ENG.obj = {};
ENG.data = {};
ENG.func = {};
ENG.plug.R = {}; // nebo bez toho plug
ENG.plug.R.obj = {};
ENG.plug.R.data = {};
ENG.plug.R.func = {};
ENG.func.init = function(pref)
{
ENG.obj.all = objGet(pref+'neco_all');
ENG.obj.pole1 = objGet(pref+'neco_pole1');
ENG.obj.pole2 = objGet(pref+'neco_pole2');
ENG.data.left = 123;
ENG.data.top = 123;
ENG.data.timer = null;
ENG.data.timer_interval = 3000;
ENG.plug.R.func.init(pref);
}
pref = 'eng_';
ENG.func.init(pref);
OBJ2.func.init(pref);
Treba mam objekt HTML (nebo jinak pojmenovane kvuli kolizim), ktery se mi stare jen o prepisovani objektu {} na select, ktere pak pres innerHTML nekam vypisu.
#17 peter
Zkus to dělat tak, abys měl na každé straně výrazu jen jednu tečku. Dvě tečky už moc objektové nejsou. Uvedený příklad sice pracuje s objekty, ale k OOP má dost daleko.
#17 peter
Nejsem sice velký odborník na JS, ale ale takhle bych to nedělal. :)
Některé věci mi tam nedávají smysl.
Například:
pref = 'cz_';
ENG.func.init(pref);
Funkce objGet ti zamořuje jmenný prostor, čemuž ses asi chtěl vyhnout tím, že jsi udělal objekt Eng.
Jenomže co když si někde přepíšeš:
objGet = UplneJinaFunkce
Pokud si dobře vzpomínám, tak moderní Javascript má const právě pro takové případy.
Jinak je to celé špatně. Pokud tomu dobře rozumím, tak jak jsi to napsal, pak:
ENG.func.init("eng_);
ENG.func.init("cz_);
ti vesele přepíše celý tvůj objekt. Pokud se ten objekt jmenuje ENG, pak asi nemá smysl, abys tak nastavoval češtinu, že ano. Zřejmě mělo jít o nějaké globální nastavení. Ostatně to byl můj první příklad, který mne zarazil. Jak to máš napsané, je to takové malé minové pole. Pokud uděláš překlep, nebo si něco přepíšeš, tak se s tím nedomluvíš.
Přijde mi, že trochu zneužíváš dynamickou stránku JS. Nic ve zlém :)
#21 hanpari
V poradku, pochopil jsi, jak to funguje. Psal jsem, ze je to delane pro jeden objekt. Nebudu vytvaret vic nez 1 a init spoustet vic nez 1x. Spravne se samozrejme objekty pisi v js jinak. Mozna, ze moderne to jde resit i pres class, ale stare se to pise:
var ENG = {};
ENG.obj = {};
ENG.data = {};
ENG.func = {};
ENG.func.init = function(pref){...};
--
function classENG()
{
this.obj = {};
this.data = {};
this.func = {};
this.func.init = function(pref){...};
}
var ENG = new classENG;
ENG.init('cz_');
--
function classENG(pref)
{
...
this.func.init = function(pref){...};
ENG.init(pref);
}
var ENG = new classENG('cz_');
Ale to je prave fura neprehledneho kodu a this a ted, kdyz chces pouzit casovace, tak musis pres.
function classENG()
{
var root = this;
setTimeout(root.func.timerStart,1000);
}
V tom prvnim kodu to zas vypada
setTimeout(ENG.func.timerStart,1000);
Tady jasne vis, co je hlavni uzel a nemusis dohledavat, k cemu byla ta promenna prirazena.
#23 peter
Proč do těch atributů dáváš prázdné objekty? Proč funkci init dáváš do atributu func? Proč se v Javascriptu snažíš implementovat class? Proč to píšeš do sekce o PHP?
#24 Kit
' Proč funkci init dáváš do atributu func?'
Init je funkce, funkce chci mit pohromade. Klidne pouzij construct jako u php. To mi treba u navodu a classu v php vadi, ze michaji jmena funkci s daty a pak to vypada takto:
mujclass->neco;
mujclass->neco();
Kdyz chces pak nekde vytahnout jen seznam funkci nebo jen vsechna data, tak je problem. Aspon v js je to problem. Musis pres typeof zjistovat, zda je to function. A function navic muze byt jen class pro objekt.
ENG.neco = function () {this.i=0;}
x = new ENG.neco(); // nebo
ENG.neco();
Proste, ta podobnost mi vadi v prehlednosti kodu.
#26 peter
Pokud máš v objektu 3 atributy a 5 metod, tak mi to nepřipadá zrovna nepřehledné. Atributy nahoře, metody pod ně. Spíš je podle mne nepřehledné používání typeof, které se do OOP moc nehodí. Mělo by se používat jen v krajních případech, kdy tu reflexi skutečně potřebuješ - tedy při práci s daty.
Přidej příspěvek
Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku
×Vložení zdrojáku
×Vložení obrázku
×Vložení videa
Uživatelé prohlížející si toto vlákno
Moderátoři diskuze