FK~

Moje odkazy

Ostatní odkazy

Close Windows
Nenajdete mě na Facebooku ani Twitteru
Rozpad EU
Jsem členem FSF
There Is No Cloud …just other people's computers.
Sane software manifesto / Manifest příčetného softwaru

Java na serveru: porovnání Javy a PHP

vydáno: 9. 3. 2010 15:29, aktualizováno: 18. 7. 2020 13:10

Dnes na chvíli vybočíme z praktické linie tohoto seriálu a budeme se místo další práce na naší aplikaci věnovat obecnějšímu srovnání Javy a PHP na webu. Podíváme se na ně jak z hlediska jazykového, tak i z pohledu nasazení na server a hostingu.

Logo OpenJDK (průhledné 1)

Historie PHP sahá do roku 1994, kdy Rasmus Lerdorf vytvořil sadu skriptů v Perlu a vydal ji jako balíček „Personal Home Page“, což byl původní význam PHP. Od této sady skriptů po aktuální verzi 5.3 udělalo PHP velký pokrok (místy bouřlivější, než si jeho uživatelé přáli). Dnešní název jazyka se vykládá jako rekuzrivní zkratka „PHP: Hypertext Preprocessor“.

Na jazyce Java se začalo pracovat už v roce 1991 a první veřejná verze byla uvolněna roku 1995. Jejím autorem je James Gosling. Ke svému názvu Java údajně přišla podle slangového označení pro kávu, kterou programátoři rádi pijí. I tento jazyk se průběžně vyvíjí a dnes je ve verzi 6. Za vývojem Javy stojí firma Sun Microsystems (dnes součást Oracle Corporation).

Programovací jazyk

Programovací jazyky dělíme do skupin podle různých kritérií. Např. kompilované vs. interpretované, silně vs. slabě typované, staticky vs. dynamicky typované, objektové vs. procedurální. Podívejme se, jak se v těchto ohledech liší Java a PHP.

Kompilované vs. interpretované

PHP je skriptovací interpretovaný jazyk tzn. jeho skripty nasazujeme na server tak, jak je programátor napsal a zde se interpretují. (což ne všem vyhovuje – např. se bojí, že někdo jejich úžasný program ukradne – a tak se uchylují k různým obfuskacím, které znesnadňují čtení takových skriptů).

S Javou je to trochu složitější. Zdrojový kód napsaný programátorem není možné interpretovat – je třeba ho nejdříve zkompilovat do tzv. bajtkódu (mezikód) a až ten se interpretuje pomocí JRE. Java se tedy zároveň kompiluje i interpretuje – oficiálně se pokládá za interpretovaný jazyk, protože její „zkompilované“ třídy nejsou ve strojovém kódu a neběží přímo na procesoru – je nutné je interpretovat. Formálně tak oba jazyky spadají do stejné kategorie.

Za zmínku stojí nástroj HipHop, který slouží k překladu PHP do jazyka C++. Tudíž i PHP může být za určitých okolností kompilované.

Statické vs. dynamické typování

Statické typování znamená, že datový typ proměnné (např. Integer nebo String) uvádíme už při její deklaraci. Tudíž typy jednotlivých proměnných známe už v době kompilace a díky tomu odhalíme řadu chyb dříve než v provozu – kompilátor takový program odmítne přeložit. U dynamicky typovaných jazyků dochází ke kontrole až při běhu aplikace. Díky tomu lze psát pružnější (ovšem často taky méně přehledný) kód, ve kterém jedna proměnná nabývá hodnot různých datových typů.

Java je staticky typovaný jazyk – všechny proměnné musíme deklarovat včetně jejich typu, nedeklarované proměnné nemůžeme používat. Zatímco PHP je jazyk dynamicky typovaný.

V PHP tak klidně můžeme napsat následující kód:

if ($a) {
	$b = 1;
} else {
	$b = "ahoj";
}

echo("b = $b");

Až v době běhu, v závislosti na hodnotě $a, je možné rozhodnout, zda $b je číslo nebo text. Kdežto v Javě si musíme předem rozmyslet, jaký datový typ bude proměnná b mít a deklarovat ho.

Silné vs. slabé typování

Toto kritérium se s tím předchozím někdy nesprávně zaměňuje. Silné typování není totéž, co statické, a slabé totéž, co dynamické. Silné typování znamená, že jazyk kontroluje typy proměnných za běhu a odhaluje jejich chybné použití. Java je silně typovaný jazyk. PHP slabě typovaný.

Možná si teď říkáte, že to ani jinak být nemůže – když je Java staticky typovaná, musí být i silně. Není to však pravidlem. Příkladem staticky ale slabě typovaného jazyka je C:

#include <stdio.h>
int main () {
	int a = 123;
	const char* b = "ahoj";
	printf("%d\n", a + b);
	return 0;
}

Můžeme „sčítat“ čísla a znaky, ale výsledek asi není to, co bychom očekávali.

Jednotlivé druhy typování nelze obecně považovat za výhodu nebo nevýhodu, každý z přístupů má své zastánce. Já osobně dávám přenost silnému statickému typování. Jednak část chyb odhalíte už při kompilaci a jednak pomáhá psát přehlednější a spolehlivější aplikace. Např. v naší aplikaci máme třídu Podnik, která má proměnnou cisloPopisne. Tato proměnná je typu int a kdekoli v programu se můžeme spolehnout, že v ní bude pouze číslo. Kdyby do ní uživatel zkoušel dostat pomocí HTTP POST parametru např. řetězec, došlo by k chybě (na rozhraní JSP a Javy).

Další vlastnosti

Oba jazyky jsou objektově orientované (Java od samého začátku, PHP až postupem času, ve verzi 5 byla objektová funkcionalita zásadně přepsána). Dodnes je Java „objektovější“ jazyk – např. ani při psaní „Hello World“ programu se zde nevyhnete práci s třídami.

Oba jazyky jsou otevřené a volně dostupné komukoli (i pro komerční použití). V tomto ohledu má náskok PHP, které je svobodný software od počátku – zatímco k otevření zdrojového kódu a osvobození Javy došlo až v roce 2006 (licence GPL).

Čím se Java a PHP liší zásadněji je standardizovanost a styl vývoje. Java se rozvíjí v rámci tzv. Java Community Process, ve kterém vzniká specifikace tohoto jazyka/platformy. Tato specifikace se následně implementuje – nejznámější je implementace od Sunu, ale svoji implementaci má i IBM (a vedle nich existuje i řada necertifikovaných implementací). Oproti tomu vývoj PHP je poněkud živelnější. Formální specifikace neexistuje a jako „standard“ je třeba brát hlavní implementaci, která stojí na jádru Zend. Existují i další implementace jako např. výše zmíněný překladač HipHop nebo třeba Quercus.

Životní cyklus aplikace

Aplikace v PHP je tvořena sadou skriptů a její nasazení na server spočívá v jejich nakopírování do příslušného adresáře. Celou dobu se nic neděje a až ve chvíli, kdy přijde HTTP požadavek od klienta, aplikace „ožívá“ – PHP volané webovým serverem interpretuje příslušný skript. Po dokončení HTTP požadavku a odpovědi skončí i běh skriptu a aplikace kromě místa na disku nezabírá žádné další zdroje. Aplikace se tedy načítá s každým HTTP požadavkem znovu.

Webová aplikace v Javě se skládá ze sady JSP stránek, zkompilovaných Javových tříd a případných dalších knihoven. Aplikace se obvykle nasazuje v podobě .war souboru (v podstatě přejmenovaný ZIP archiv). Při nasazení (deploy) aplikace na server dojde k rozbalení tohoto archivu a ke kompilaci JSP stránek. Z nich se nejprve vygenerují javovské třídy (.java) a následně se zkompilují na bajtkód (.class). Aplikace je inicializována a běží po celou dobu, dokud ji ze serveru neodstraníme (undeploy) nebo alespoň nedeaktivujeme (pokud to server umožňuje).

Z těchto odlišných způsobů vyplývají i možnosti sdílení dat. V Javovské aplikaci v JSP můžeme definovat JavaBeanu pomocí značky jsp:useBean:

<jsp:useBean
	id="registraceUzivatele"
	class="cz.frantovo.nekurak.web.RegistraceUzivatele"
	scope="session"/>

Tím jsme vytvořili instanci třídy RegistraceUzivatele a nastavili jsme ji jako hodnotu proměnné registraceUzivatele. Tato proměnná je platná pro danné sezení uživatele (scope="session"). Rozsah platnosti můžeme omezit jen na daný HTTP požadavek (scope="request"). Nebo naopak rozšířit na celou aplikaci (scope="application"), potom je daný objekt sdílený mezi požadavky všech uživatelů.

V PHP si musíme vystačit s proměnnými sezení $_SESSION a další stavy aplikace je potřeba ukládat v databázi nebo souborech. Aplikace ve smyslu nějaké ucelené entity tu vlastně neexistuje, protože se jedná o sadu více či méně provázaných skriptů.

Pokud vás nenapadá, k čemu je to dobré, podívejme se na malou ukázku. Nedávno jsem např. psal jednoduchý chat, resp. webové rozhraní k Jabberu. Tento problém lze elegantně vyřešit pomocí EJB, což jsou komponenty běžící v aplikačním serveru a pro nás je zajímavé, že jsou schopné „dlouhodobějšího života“ podobně jako webové aplikace v Javě. Kostra takového EJB vypadá následovně:

@Singleton
@Startup
public class Jabber1 implements Jabber1Remote {
	
	@Override
	public void posliZpravu(String mistnost, String prezdivka, String zprava)
			throws Jabber1Vyjimka {
		
	}

	@Override
	public Collection<Zprava> getZpravy(String mistnost, int poradoveCislo)
			throws Jabber1Vyjimka {
		
	}


	@PreDestroy
	public void odpoj() {
		for (Spojeni s : spojeni) {
			s.odpoj();
		}
	}

	@PostConstruct
	public void inicializuj()
			throws JabberotovaVyjimka, JMSException, NamingException {
		pripojXMPP();
	}
}

Využili jsme tu nové vlastnosti EJB 3.1 a jedná se o trochu specifický případ – klasické EJB 3 nemusí být Singleton a nemusí se vytvářet jeho instance hned po nasazení aplikace (může se vytvořit ad-hoc, až když si ji někdo vyžádá).

Po nasazení komponenty Jabber1 na aplikační server se vytvoří právě jedna instance této třídy (díky anotacím @Singleton@Startup) a díky anotaci @PostConstruct se spustí metoda inicializuj(), která naváže spojení s XMPP serverem (Jabber). Toto spojení si držíme po celou dobu života komponenty - tzn. do doby než ji vypneme nebo ukončíme aplikační server. Není tedy vázané na nějaký HTTP požadavek. Ostatně EJB komponenta může na serveru existovat i bez jakékoli webové aplikace.

Webová aplikace si potom tuto EJB komponentu najde pomocí jejího JNDI jména (stejně jako v naší aplikaci přistupujeme ke komponentám PodnikEJB nebo UzivatelEJB) a volá její metody pro odeslání zprávy do chatovací místnosti nebo pro vyzvednutí historie zpráv.

Příjemnou vlastností, kterou nám tato architektura přináší je abstrakce. Pouhou zmenou konfigurace můžeme aplikaci rozdělit na dvě části – webovou část provozovat na jednom serveru a EJB komponentu na druhém. Nemusíme si vymýšlet žádný vlastní komunikační protokol – o komunikaci se postará aplikační server (Glassfish např. použije protokol CORBA/IIOP), a z pohledu naší aplikace je vše transparentní – s EJB komponentami pracujeme stejně, ať už se nacházejí na lokálním serveru nebo nějakém jiném.

Hosting

Zprovoznit si lokálně LAMP nebo třeba aplikační server či pouhý webový kontejner a vedle toho databázi vyjde přibližně nastejno. Ovšem už v době návrhu a analýzy bychom měli myslet na to, kde naše aplikace poběží. V tomto směru má velkou výhodu PHP – je prakticky všude. Najít hosting pro Javu je trochu složitější, ale ne nemožné. V ČR seženete nejlevnější za cca sto korun mesíčně. Jedná se ale o sdílený hosting (společný Tomcat). Můžete si ale pořídit i VPS (virtuální server) za cca 300 Kč, ve kterém lze pohodlně provozovat aplikační server (nebo webový kontejner) podle svého výběru a s vlastní konfigurací. Vedle toho nejlevnější hosting pro PHP stojí pár desetikorun. Zajímavým řešením pro Javu může být služba Google Application Engine, která byla spuštěna minulý rok. Nevyužijete zde zdaleka všechny možnosti JEE platfomy a bude třeba psát javovou aplikaci psát poněkud střídměji, ale na druhou stranu ale Google nabízí poměrně zajímavé ceny, účtované podle intenzity využití (jak už to u cloudových služeb bývá). Pro malé aplikace může být zajímavé, že Google poskytuje „kolem 5 milionů zobrazení stránky měsíčně“ zdarma.

Závěr

Dnes jsme si stručně porovnali PHP a Javu z hlediska programovacího jazyka. Vysvětlili jsme si rozdíl v životním cyklu PHP a Java aplikace. A na příkladu webového chatu jsme si ukázali výhody EJB komponent. Příště se zase vrátíme k naší aplikaci a budeme pokračovat ve vývoji.

Odkazy a zdroje:

Témata: [Java] [www]

Komentáře čtenářů

Tento článek zatím nikdo nekomentoval

Přidat komentář

reagujete na jiný komentář (zrušit)
jméno nebo přezdívka
název příspěvku
webová stránka, blog
e-mailová adresa
nápověda: možnosti formátování
ochrana proti spamu a špatným trollům

Náhled komentáře