WEBES ALKALMAZÁSFEJLESZTÉS 1. Horváth Győző Egyetemi adjunktus 1117 Budapest, Pázmány Péter sétány 1/C, 2.420 Tel: (1) 372-2500/1816
Tartalom 2
PHP nyelvi elemei PHP a webszerveren Webes alkalmazások és adatbázis PHP és adatbázis Kódszervezés
3
PHP ismétlés – nyelvi alapok
PHP 4
PHP Personal
Home Page PHP: Hypertext Preprocesszor
Jellemzői nyílt
forráskódú általános célú szkriptnyelv HTML-be ágyazható
PHP a webprogramozásban 5
.php kiterjesztésű állomány kérése esetén webszerver kikeresi az állományt Átadja a PHP értelmezőnek A program kimenetét a böngésző a kliens felé továbbítja Szerver
Kliens
PHP
PHP mint programozási nyelv 6
Értelmezett szkriptnyelv Gyengén típusos Változó
típusa a tárolt értéktől függ Automatikus konverziókra figyelni kell!
Sok minden igaz, amit JavaScriptnél tanultunk Nincs use strict, helyette error_reporting(E_ALL); PSR (PHP Standards Recommendation) http://www.php-fig.org/
Típusok 7
Négy elemi típus
Két összetett típus
logikai
tömb
egész
objektum
lebegőpontos szöveg
Két speciális típus erőforrás NULL
Literálok 8
//Logikai true false TRUE FALSE //Egész 12 //decimális -34 0123 //oktális 0x0F //hexadecimális 0b0101 //bináris //Lebegőpontos 3.1415 5.6e12 -7E-2
//Például $l = true; $i = -23; $d = 23.65;
Szövegliterál 9
aposztróf macskaköröm heredoc nowdoc Változók behelyettesítése
$a = 12; $s1 = 'alma\t{$a} alma'; $s1 = 'Több sor is lehet benne';
//alma\t{$a} alma
$s2 = "alma\t{$a} alma"; $s2 = "Ez egy több soros szöveg";
//alma
12 alma
$s3 = <<<EOT Több soros {$a} szöveg EOT;
//behelyettesít
$s4 = <<<'EOT' Ez is lehet {$a} több soros. EOT;
//nem helyettesít be
Tömbök 10
Gyűjtemények általános objektuma Összetett
adatszerkezet megvalósítása
rekord
indexelt
tömb asszociatív tömb többdimenziós tömb fa, sor, verem, stb.
Asszociatív tömb: kulcs-érték párokból áll kulcs:
integer vagy string érték: bármilyen típusú lehet
Tömb 11
//Üres tömb $uresTomb = array(); //Indexelt tömb $indTomb = array('alma', 'korte', 'szilva'); echo $indTomb[0]; //'alma' print_r($indTomb); /* Array ( [0] => alma [1] => korte [2] => szilva ) */
//Indexelt tömb vegyes értékekkel $indTombVegyes = array('alma', 12, true, -23.34); print_r($indTombVegyes); /* Array ( [0] => alma [1] => 12 [2] => 1 [3] => -23.34 ) */
Tömb 12
//Indexelt tömb egyesével hozzáadva $indTombKezi = array(); $indTombKezi[0] = 'alma'; $indTombKezi[1] = 'korte'; $indTombKezi[2] = 'szilva'; print_r($indTombKezi); /* Array ( [0] => alma [1] => korte [2] => szilva ) */
//Indexelt tömb egyesével hozzáadva $indTombKezi2 = array(); $indTombKezi2[] = 'alma'; $indTombKezi2[] = 'korte'; $indTombKezi2[] = 'szilva'; print_r($indTombKezi2); /* Array ( [0] => alma [1] => korte [2] => szilva ) */
Asszociatív tömb 13
//Asszociatív tömb $asszTomb = array( 'alma' => 'piros', 'korte' => 'sarga', 'szilva' => 'kek', ); echo $asszTomb['alma']; //piros print_r($asszTomb); /* Array ( [alma] => piros [korte] => sarga [szilva] => kek ) */
//Asszociatív tömb kézzel $asszTombKezi = array(); $asszTombKezi['alma'] = 'piros'; $asszTombKezi['korte'] = 'sarga'; $asszTombKezi['szilva'] = 'kek'; print_r($asszTombKezi); /* Array ( [alma] => piros [korte] => sarga [szilva] => kek ) */
Mátrix 14
Tömbök tömbje Lehet vegyesen használni indexeltben
indexelt indexeltben asszociatív //Mátrix $matrix = array( array(1, 2, 3), array(4, 5, 6), array(7, 8, 9), );
Tömbök bejárása 15
foreach reset(), next(), prev(), current(), key(), each()
foreach ($t as $key => $value) { echo $key.$value; } foreach ($t as $value) { echo $value; } $fruit = array('a' => 'apple', 'b' => 'banana', 'c' => 'cranberry'); reset($fruit); while (list($key, $val) = each($fruit)) { echo "$key => $val\n"; }
Osztályok és láthatóság 16
PHP5-ben teljesen újraírták PHP5 objektumorientált class A { public $publikus = 'alapérték'; protected $proti = 'alapproti'; private $privat = 'alapprivi'; public function kiir() { echo $this->publikus; echo $this->proti; echo $this->privat; } } $a = new A(); echo $a->publikus; echo $a->kiir();
Konstruktorok és öröklés 17
class A { function __construct() { echo "A konstruktora"; } } class B extends A { function __construct() { parent::__construct(); print "B konstruktora"; } }
$a = new A(); $b = new B();
Osztályok automatikus betöltése 18
Általában az osztályok külön állományban Egyesével include-olni hibához
vezethet
__autoload function __autoload($class) { echo $class; include $class . '.php'; } $a = new A(); $b = new B();
Egyéb osztálytulajdonságok 19
absztrakt osztályok és metódusok interface-ek statikus osztályok és adattagok mágikus metódusok __call(),
__get(), __set(), __toString(), __clone()
Névterek 20
Definiálás namespace
my\namaspace;
Használat my\namespace\func()
PHP Standards Recommendation 21
PSR http://www.php-fig.org/psr/
Standard PHP Library (SPL) 22
http://php.net/manual/en/book.spl.php Adatstruktúrák Iterátorok Interface-ek
23
PHP a webszerveren PHP és HTML, PHP és űrlapok
Kliens-szerver architektúra 24
Adatbázis-szerver
Webszerver
PHP modul
Internet
Kliens (böngésző)
Logikai architektúra
Middleware
Backend
25
Adatbázis-szerver
Kapcsolati réteg (adatbázis-absztrakciós réteg) Üzleti logikai réteg Prezentációs réteg
Frontend
Internet
Kliens (böngésző)
PHP és HTML (kimenet) 26
HTML és PHP kód váltogathatja egymást Lényeg: a PHP eredménye általában HTML kód Mindig
nézzük meg a generált forrást HTML elvárásunkat fogalmazzuk meg először
HTML kód HTML kód HTML kód HTML kód
PHP és HTML (bemenet) 27
GET: urlben query string http://pelda.hu?alma=piros&korte=kukacos
POST: standard inputon a query string A query stringet űrlapküldésnél a böngésző állítja elő (name attribútum szükséges!) PHP $_GET,
$_POST, $_COOKIE, $_FILES, $_SESSION, stb.
Űrlapfeldolgozás 28
Első megtekintés: űrlap megjelenítése Űrlap elküldése ugyanannak a szkriptnek Űrlapadatok ellenőrzése Ha hiba volt, akkor hibák megjelenítése, űrlap megjelenítése állapotát megőrizve Ha nem volt hiba, akkor adatok feldolgozása, és megjelenítése vagy más oldal megjelenítése
Űrlapfeldolgozás 29
30
Webes alkalmazások és adatbázis
Web és adatbázis 31
Adatintenzív, adatközpontú webes alkalmazások Adatvezérelt alkalmazások: alkalmazás felépítése, logikája, megjelenése függ a háttérben tárolt adatok szerkezetétől, jellegétől Adatok tárolása adatbázis-kezelő rendszerben történik a leggyakrabban
Kapcsolat az adatbázissal 32
Szerveroldali technológiától független Adott nyelvben függvények, osztályok az egyes adatbázis-kezelő rendszerekhez Adatbázis-művelet előtt kapcsolódás az adatbázishoz SQL utasítások kiadása a nyelv adatbázisfüggvényeinek segítségével DDL,
DML (eredményhalmaz feldolgozása), DCL, TCL
Kapcsolat bontása
Általános fogalmak 33
Állandó kapcsolatok átmeneti
Előkészített utasítások ld.
tároló
adatkötés
Pufferelt lekérdezések
34
PHP és adatbázis
PHP és adatbázisok 35
Különböző függvénykönyvtárak a különböző adatbázis-kezelő rendszerekhez IBM
DB2 — IBM DB2 Mssql — Microsoft SQL Server MySQL Mysqli — MySQL Improved Extension OCI8 — Oracle OCI8 PostgreSQL
PHP és MySQL 36
Kétféle interfész MySQL régebbi mind
a mai napig gyakran használják
Mysqli újabb
MySQL verziók funkcióinak kihasználása biztonságosabb kapcsolódás és használat OOP-s interfész manapság ez ajánlott PDO
(ld. később)
MySQL függvénykönyvtárak 37
libmysql régebbi kliens
megléte szükséges
mysqlnd korszerűbb
Legkorszerűbb mysqli
+ mysqlnd pdo + mysqlnd
Tipikus lépések 38
Kapcsolat létesítése az adatbázis-szerverrel Adatbázis kiválasztása Összeállított SQL utasítás futtatása Opcionálisan a visszakapott eredmények feldolgozása
Fontosabb parancsok 39
MySQL
mysql_connect() mysql_select_db() mysql_query() mysql_fetch_*() mysql_free_result() mysql_close()
Mysqli
$mysqli = new myslqi() $r = $mysqli->query() $r->fetch-*() $r->free() $mysqli->close() $s=$mysqli->prepare() $s->bind_param() $s->bind_result()
Tipikus utasítások 40
mysqli bővítmény, pufferelt lekérdezés new
mysqli::mysqli() mysqli::real_query() mysqli::store_result() mysqli_result::fetch_assoc() mysqli_result::free() mysqli::close()
Tipikus utasítások 41
mysqli bővítmény, nem pufferelt lekérdezés new
mysqli::mysqli() mysqli::real_query() mysqli::use_result() mysqli_result::fetch_assoc() mysqli_result::free() mysqli::close()
Tipikus utasítások 42
mysqli bővítmény, nem pufferelt lekérdezés, előkészített utasítás new
mysqli::mysqli() mysqli::prepare() mysqli_stmt::bind_param() mysqli_stmt::execute() mysqli_stmt::bind_result() mysqli_stmt::fetch() mysqli_stmt::free_result() mysqli::close()
Tipikus utasítások 43
mysqli bővítmény, pufferelt lekérdezés, előkészített utasítás new mysqli::mysqli() mysqli::prepare() mysqli_stmt::bind_param() mysqli_stmt::execute() mysqli_stmt::store_result() mysqli_stmt::bind_result() mysqli_stmt::fetch() mysqli_stmt::free_result() mysqli::close()
Tipikus utasítások 44
nem pufferelt lekérdezés, előkészített utasítás new
PDO() PDO::prepare() PDOStatement::bindParam() PDOStatement::execute() PDOStatement::fetch()
Tipikus utasítások 45
pufferelt lekérdezés, előkészített utasítás new
PDO() PDO::prepare() PDOStatement::bindParam() PDOStatement::execute() PDOStatement::fetchAll()
Adatbázis biztonság 46
Mysqli interfész a preferált (Mysql-lel szemben) Szövegösszefűzés mysql_real_escape_string() sprintf()
Adatkötés előkészített
kifejezések
prepare bind_param()
bind_result()
Példa 47
Lekérdezés egy táblából Lépésekre bontva Tábla: CREATE TABLE `albums` ( `id` int(10) unsigned `nev` varchar(45) NOT `leiras` varchar(200) PRIMARY KEY (`id`), ) ENGINE=InnoDB DEFAULT
NOT NULL auto_increment, NULL, NOT NULL,
CHARSET=utf8;
HTML előkészítése 48
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
Albumok Albumok listázása
Azonosító | Név | Leírás |
1 | Album1 | Album1 leírása |
Mysqli használata 49
$mysqli = new mysqli('servername', 'username', 'password', 'database'); if ($mysqli->connect_error) { die('Kapcsolodasi hiba' . $mysqli->connect_errno . $mysqli->connect_error); } $mysqli->query('set names utf8'); $q = 'select * from photo_albums'; $result = $mysqli->query( $q ); if ($result) { while ($sor = $result->fetch_assoc()) { echo <<<EOT
{$sor['id']} | {$sor['nev']} | {$sor['leiras']} |
EOT; } $result->free(); } $mysqli->close();
Paraméterek összefűzéssel 50
$nev = ''; $leiras = ''; echo $q = sprintf( "select * from photo_albums where nev like '%%%s%%' and leiras like '%%%s%%'", mysql_real_escape_string($nev), mysql_real_escape_string($leiras) ); $result = $mysqli->query( $q );
Paraméterek adatkötéssel 51
$nev = ''; $leiras = ''; $stmt = $mysqli->prepare( "select id, nev, leiras from photo_albums where nev like ? and leiras like ?"); $stmt->bind_param('ss', $nev, $leiras); $nev = "%{$nev}%"; $leiras = "%{$leiras}%"; $stmt->execute(); $stmt->bind_result($r_id, $r_nev, $r_leiras); while ($stmt->fetch()) { echo <<<EOT
{$r_id} | {$r_nev} | {$r_leiras} |
EOT; }
Paraméterek adatkötéssel 52
Általánosabb eredménykötés
$stmt->execute(); $meta = $stmt->result_metadata(); $sor = array(); foreach ($meta->fetch_fields() as $field) { $params[] = &$sor[$field->name]; } call_user_func_array(array($stmt, 'bind_result'), $params); while ($stmt->fetch()) { echo <<<EOT
{$sor['id']} | {$sor['nev']} | {$sor['leiras']} |
EOT; }
53
Kód újrarendezése Útban az MVC felé
Kritika 54
HTML és PHP keveredik egymással Különböző funkciójú kódrészletek keverednek egymással vezérlés,
adatelérés, megjelenítés, feldolgozás, alkalmazáslogika
Konfiguráció kódba épített Több belépési pontja lehet az alkalmazásnak Csoportmunka nem lehetséges Karbantartása nehézkes
Logika és megjelenés szétválasztása 55
Válasszuk szét a logikát a megjelenéstől Határozott
vonal húzható a PHP és HTML között Akár külön file-ba kerülhet a megjelenés
A HTML-ben lesznek PHP kódrészletek, de ezek már csak a megjelenést szolgálják: sablonnyelv PHP
alternatív szintaxis Háromféle utasítás szerepelhet echo,
HTML
if, foreach
nem generálható (echo) Logikában nincs HTML kód
HTML HTML HTML
Nézet (view) 56
A logika és megjelenés szétválasztásából születik meg a nézet (view) Előnye Egy
logikához többféle nézet is rendelhető
HTML,
Külön
szöveg, PDF, XML
szakember foglalkozhat a kétféle résszel
Példa: index2.php és list.php
Adatmanipuláció elkülönítése (modell) 57
Adatokkal kapcsolatos rész elkülönítése Előnyei Több
helyen felhasználható Módosítások egy helyre összpontosulnak (pl. tábla átnevezés, adatbázis-váltás)
Az adatok feldolgozását végző kódrész a modell Ld. albums_model.php
Vezérlő (controller) 58
A maradék kód a folyamat irányításáért felel: vezérlő Inputadatok
begyűjtése, adatok átadása, elkérése a modelltől, az eredményt a nézetnek átadni Kérés feldolgozása Munkamenet-kezelés Authentikáció, authorizáció
Könnyen áttekinthetővé vált Ld. index3.php
Vezérlő (controller) 59
$nev = ''; $leiras = ''; if (isset($_POST['nev'])) { $nev = $_POST['nev']; } if (isset($_POST['leiras'])) { $leiras = $_POST['leiras']; } $albums = get_albums($nev, $leiras); include('list.php');
//view
//modell
Modell (model) 60
connect_error) { die('Kapcsolodasi hiba' . $mysqli->connect_errno . $mysqli->connect_error); } $mysqli->query('set names utf8'); $stmt = $mysqli->prepare( "select * from photo_albums where nev like ? and leiras like ?"); $stmt->bind_param('ss', $nev, $leiras); $nev = "%{$nev}%"; $leiras = "%{$leiras}%"; $stmt->execute();
Modell (model) 61
$meta = $stmt->result_metadata(); $sor = array(); foreach ($meta->fetch_fields() as $field) { $params[] = &$sor[$field->name]; } call_user_func_array(array($stmt, 'bind_result'), $params); $albums = array(); while ($stmt->fetch()) { $albums[] = array( 'id' 'nev' 'leiras' ); } $stmt->free_result(); $mysqli->close();
return $albums; }
=> $sor['id'], => $sor['nev'], => $sor['leiras'],
Nézet (view) 62
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
Albumok listazasa
Nézet (view) 63
Új album...