Egyszerű dinamikus oldal elrendezés PHP-vel

Előképzettség (amiről itt nem lesz szó vagy csak a szükséges mértékben): programozási alapismeretek, PHP nyelvi elemek (változók, elágazás, ciklusok, tömbök). A PHP egy ún. C-like (C-szerű) nyelv, ami azt jelenti, hogy szintaktikailag sokban hasonlít a C nyelvre (például kapcsos zárójelek alkalmazás utasításblokkhoz). Tehát aki tanult már valamilyen C-szerű nyelvet (pl. C#), annak ezek nem jelenthetnek gondot.

Az egyik előző postban szereplő Layout-2-t fogjuk úgy átalakítani, hogy a menüpontok működjenek. Mindezt dinamikusan, PHP-vel.

Miért van szükség PHP-re?

Egy weblapnak általában vannak statikus, nem változó (header, footer) és dinamikus változó (content) részei. Ha csak HTML segítségével akarunk megvalósítani egy ilyen oldalt, akkor hivatkozásaink mindig egy másik .html állományra mutatnak, melyekben a statikus részeket ugyanúgy meg kell ismételnünk, mint a változó tartalmat. Ez nagyon megnehezítené a statikus részek módosítását, hiszen ahány oldal, annyiszor kellene elvégezni. Itt jön a képbe a PHP, segítségével a statikus és dinamikus részeket szét tudjuk választani, ezáltal mindegyik csak egyszer lesz tárolva.

A statikus részeket az index.php-ben hagyjuk, a változó részeket pedig külön állományokba tesszük. A változó részek helyére az index.php-ben PHP kódot helyezünk, ami lefutva elvégzi majd a változó részek betöltését.

Ahhoz, hogy a PHP kódok lefussanak, megfelelő PHP-s fejlesztő környezetet kell kialakítani és a .html kiterjesztést át kell nevezni .php-re!!!

Másik fájl tartalmának beillesztése

A PHP leggyakrabban használt függvényei azok, amelyekkel másik állományok tartalma illeszthető be abba az állományba, amelyből a függvényt hívtuk. Ezek:

  • include() : beilleszti a paraméterben megadott fájl tartalmát, hiba esetén FALSE  értéket és egy figyelmeztetést (warning) ad vissza.
  • include_once() : hasonló az include() -hoz, azzal a különbséggel, hogy csak egyszer illeszt be egy fájlt, elkerülve a a többszörös beillesztéssel járó problémákat
  • require() : hasonló az include() -hoz, azzal a különbséggel, hogy hiba esetén fordítási hibát (E_COMPILE_ERROR hibakód) ad vissza és megáll a script futása
  • require_once() : ugyanaz, mint a require() , de csak egyszer végzi el a beillesztést

A beillesztendő (include) fájlok létrehozása

Először nevezzük át az index.html-t index.php-re, majd hozzunk létre egy inc nevű mappát. Ebben létrehozunk az egyes menüpontoknak megfelelő .php állományokat:

  • about.php
  • contact.php
  • home.php
  • products.php
  • services.php

Az index.php-ből másoljuk ki a content  azonosítójú div  tartalmát a home.php -be, a többi állományba tegyünk tetszőleges tartalmat, amit a hozzá tartozó menüpont esetén akarunk megjeleníteni a div id=”content”  szakaszban.

A home.php  tartalma:

<h1>Simple Gray Layout...</h1>
<p>Lorem ipsum dolor sit amet, et nemore deleniti sea, sale propriae eum ne, vim at detracto pericula. Et fuisset theophrastus usu, summo mnesarchum at mei. Est in iudico bonorum convenire. Te mea ipsum exerci vituperata, sit et hinc facer assentior. Vix id laudem regione urbanitas, falli suavitate vel et, wisi mazim dolorem id per. Te vel noster blandit.</p>
<h2>Lorem ipsum dolor sit amet...</h2>
<p>Iisque eloquentiam concludaturque nec cu, menandri
...

content  azonosítójú div -be tegyük a következő kódot:

<?php
    include_once("inc/" . $page . ".php");
?>

A PHP-ben . -al lehet stringeket összefűzni. A $page  változóban fog szerepelni annak a menünek a neve, amit be akarunk tölteni.

A menü módosítása

Az eddig nem működő menünkben minden hivatkozás a #  címkére mutatott, ami az oldal tetejére ugrott vissza. Módosítsuk a menüt a nav  azonosítójú szakaszban:

<div id="nav">
  <ul>
    <li><a href="index.php?page=home">Home</a></li>
    <li><a href="index.php?page=products">Products</a></li>
    <li><a href="index.php?page=services">Services</a></li>
    <li><a href="index.php?page=about">About Us</a></li>
    <li><a href="index.php?page=contact">Contact</a></li>
  </ul>
</div>

image_2016-05-04_10-31-12

A $page változó, Query string és a menük hivatkozásai

Hogyan kerül a $page  változóba a hivatkozott menüpont neve? Természetesen az adott menüpont hivatkozásából: index.php?page=home , de ehhez nem árt ismerni az URL (Uniform Resource Locator) részeit.

Általános alakja:

scheme:[//host[:port]][/]path[?query][#fragment]

ahol:

  • scheme: rendszer v. protokoll (pl. http:)
  • //
  • host az elérni kívánt gép neve vagy IP címe
  • :port
  • /path elérési út
  • ?query a lekéréshez fűzőtt attribútumok és értékek
  • #fragment egy oldalon belül adott ponthoz görgeti a böngésző ablakot

A szokásos jelölés szerint a szögletes zárójelben levő részek nem kötelezőek, vagyis elhagyhatóak. Az egyetlen kötelező elem a path, ami az erőforrás (jellemzően fájl) helyét határozza meg a szerveren.

A query string általános alakja: ?key1=value1&key2=value2&…

Példa egy teljes hivatkozásra: http://www.domain.com/Layout-3/index.php?page=services

Relatív hivatkozás a host és a path egy részének elhagyásával: indpex.php?page=services

A Query stringben szereplő kulcs-érték párokat (key1=value1) a PHP kódból a $_GET  asszociatív tömbön keresztül lehet elérni: <?php $page = $_GET[‘page’]; ?> . Tegyük ezt a kódot, valahova az oldal elejére, lényeg, hogy előtt legyen mielőtt a $page  változót használjuk, mivel ezzel adunk a változónak értéket.

Ezzel lényegében kész is az oldal:

<?php $page = $_GET['page']; ?>
<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>Title...</title>
	<link rel="stylesheet" type="text/css" href="styles.css">
</head>
<body>
	<div id="wrapper">
		<div id="header">
		   #header
			<h1>Az oldal címe</h1>
		</div>
		<div id="nav">
			<ul>
				<li><a href="index.php?page=home">Home</a></li>
				<li><a href="index.php?page=products">Products</a></li>
				<li><a href="index.php?page=services">Services</a></li>
				<li><a href="index.php?page=about">About Us</a></li>
				<li><a href="index.php?page=contact">Contact</a></li>
			</ul>
		</div>
		<div id="content">
			<?php include_once("inc/" . $page . ".php"); ?>
		</div>
		<div id="sidebar">
		   #sidebar 
		</div>
		<div class="clear"></div>
		<div id="footer">
			#footer
		</div>
	</div>
</body>
</html>

Hibák

Az előzőekben láthattuk hogyan lehet megfelelő hivatkozásokkal és a PHP beillesztési függvényeivel nagyon egyszerű módon dinamikussá tenni az oldalt. Néhány dolog azonban kimaradt, amit javítani kell.

  • hiányos / hibás  URL-ek kezelése
  • hiányzik az aktív menüpont kiemelése

Hiányos / hibás URL-ek kezelése

Az oldal csak akkor működik megfelelően, ha az URL-ben van query string, amiből a $page változó értéke kiolvasható. A felhasználó általában nem azt írja a böngészőbe, hogy akarmi.hu/index.php?page=home, hanem csak annyit, hogy akarmi.hu. Ilyen esetben nem működik az oldal, mivel a query string hiányában a $page változó nem fog értéket kapni, és amikor az include_once()  fv. paraméterében hivatkozunk rá, akkor olyan fájlt szeretnénk megnyitni ami nem létezik (inc/.php):

image_2016-05-03_15-52-46

Ezt úgy lehet javítani, hogy ha hiányzik az URL-ből a query string, akkor alapértelmezetten a kezdőoldalt (Home) töltjük be. Vizsgáljuk meg tehát, hogy van-e a query stringben page változó, ha van akkor ennek értéke kerüljön a $page változóba, különben pedig a ‘home’. Cseréljük le a

<?php $page = $_GET['page']; ?>

részt a következőre:

<?php 
  if (isset($_GET['page'])) 
    $page = $_GET['page']; 
  else 
    $page = "home"; 
?>

Szintén hibaüzenetet kapunk, ha valaki véletlenül vagy szándékosan hibás értéket ad meg a page változónak az URL-ben. Pl. a böngésző címsorába begépelve az akarmi.hu/index.php?page=ooopps címet, szintén hibát kapunk, mert az ooopps.php fájl nem létezik. Ilyenkor is tehetnénk azt, hogy a kezdőlapot töltjük be, de mivel itt valami tévedésről van szó, ezért célszerűbb valami kulturáltabb tájékoztatást adni, hogy a keresett oldal nem létezik.

Hozzunk létre az inc mappában egy 404.php fájlt, és tegyünk bele valamilyen tesztőleges HTML tartalmat, ami nem létező fájl hibájára figyelmeztet.

Módosítani kell a content  div-et is, hogy megvizsgáljuk, hogy létezik-e a $page  változóban megadott nevű fájl. Ha létezik akkor azt töltjük be, ha nem akkor 404.php-t:

<?php
	if(file_exists("inc/" . $page . ".php")) {
		include_once("inc/" . $page . ".php");
	} else {
		include_once("inc/404.php");
	}
?>

Az isset() PHP függvény logikai igaz (true) értéket ad vissza, ha a paraméterként átadott változó létezik és értéke nem NULL.

A file_exists() PHP függvény logikai igaz értéket ad vissza, ha a paraméterként átadott fájl vagy könyvtár létezik, különben hamisat.

Az aktív menüpont kiemelése

Ahhoz, hogy az aktív menüpont kiemelése működjön, mindig az aktuális menüpontra kell tenni aktív osztályt (class=”active” ). Mivel így a menünk HTML kódja is dinamikusan fog változni, ezt is csak a PHP-vel tudjuk megoldani. Szintén jó lenne, ha menüpontokat bármikor könnyedén tudnánk módosítani, és gyorsan hozzáférhető lenne. Adódik hát a következtetés, hogy tegyük menüpontok egy külön állományba, és tároljuk őket egy tömbben, mégpedig a már említett asszociatív fajtában. Hozzunk létre az inc mappában egy menu.php fájlt a következő tartalommal:

<?php
  $pages = array(
    'home' => 'Home',
    'products' => 'Products',
    'services' => 'Services',
    'about' => 'About Us',
    'contact' => 'Contact'
  );
?>

Az index.php-ben úgy fogjuk módosítani a nav  elemet, hogy először beillesztjük a menu.php-t, majd a menüt alkotó listát egy for  ciklussal fogjuk legenerálni, miközben megvizsgáljuk, hogy melyik az aktív elem, és arra rátesszük az active  osztályt:

<div id="nav">
    <?php include_once("inc/_menu.php"); ?>
    <ul>
      <?php
        foreach($pages as $page_id => $page_title) {
          if ($page == $page_id) {
            echo '<li><a class="active" href="index.php?page=' . $page_id . '">' . $page_title . '</a></li>';
          } else {
            echo '<li><a href="index.php?page=' . $page_id . '">' . $page_title . '</a></li>';
          }
        }
      ?>
    </ul>
</div>

Rövidítések és ugra-bugra

A fenti példa jól működik, de az echo  utasítás (amit arra használhatunk, hogy a PHP kódból HTML kódot írjunk ki) elég nehezen áttekinthető. Ennek az az oka, hogy a echo -val kiírandó HTML kódot aposztrófok között, string paraméterként adjuk át. Ily módon minden szintaxis kiemeléssel rendelkező szövegszerkesztő egy színnel fogja jelölni:

echo '<li><a class="active" href="index.php?page=';

HTML kódként:

<li><a class="active" href="index.php?page=

Megoldást az jelentheti, hogy ahol HTML kódot akarunk kiírni, ott egyszerűen kilépünk (kiugrunk) a PHP módból, megírjuk a HTML részt, majd vissza a PHP-be, mindezt akár egy PHP utasítás közben is megtehetjük:

<div id="nav">
    <?php include_once("inc/_menu.php"); ?>
    <ul>
        <?php foreach($pages as $page_id => $page_title) { ?>
        <li><a <?=($page == $page_id) ? 'class="active"' : '' ?> 
                href="index.php?page=<?=$page_id ?>"><?=$page_title?></a></li>
        <?php } ?>
    </ul>
</div>

További egyszerűsítésre ad lehetőséget, hogy ott ahol mindenképpen echo -val kell kiírni valamit (pl. egy változó értékét: <?php echo $page_title; ?> ) ott használjuk a echo  rövid alakját: <?=$page_title?> . Lényeges, hogy azáltal, hogy a PHP és a HTML mód között ki-be lépkedünk, a végeredmény nem fog változni.

Ez csak egy példa volt a menü dinamikussá tételére, számtalan más megoldás is megvalósítható.

Shortings

open_short_tag

A PHP alapértelmezett nyitó tag-je a <?php . Ugyanakkor létezik egy rövid nyitó tag is <? … ?>  alakban, aminek használata nem javasolt, mert XML kódok (<?xml )használata esetén gondot okozhat. Használatához a php.ini konfigurációs állományban az open_short_tag  beállítást On -ra kell állatani (open_short_tag = On ).

short echo

Létezik a echo függvénynek is egy rövid alakja: <?=  formában. Ennek használatához PHP 5.4 verzió előtt szükség van open_short_tag  bekapcsolására, PHP 5.4-nél újabb verziók esetén viszont mindig elérhető. Ha nem működik a <?=  alak, akkor <?php echo  -t kell írni helyette.

short if

( feltétel ) ? igaz-ág : hamis-ág;

short echo és short if kombinálva

<?=($page == $page_id) ? 'class="active"' : '' ?>

A végeredmény megtekinthető itt.

Leave a Reply

Your email address will not be published. Required fields are marked *