Webprogramozás
Horváth Győző
Egyetemi docens
1117 Budapest, Pázmány Péter sétány 1/c., 2.408-as szoba
Tel: (1) 372-2500/8469
horvath.gyozo@inf.elte.hu
Dinamikus szerveroldali webprogramozás: program (PHP) állítja elő a tartalmat (HTML)
$_GET
, $_POST
$_POST
, $_GET
)$_POST
, $_GET
, HTML)Közös adat mint erőforrás megosztása
if (isset($szamlalo)) {
$szamlalo += 1;
} else {
$szamlalo = 0;
}
var_dump($szamlalo);
$f = fopen($fájlnév, $mód)
feof($f)
fclose($f)
// $mód
r (csak olvasás)
r+ (olvasás, írás)
w (csak írás, üres fájl)
w+ (olvasás, írás, üres fájl)
a (hozzáfűzés)
a+ (hozzáfűzés, olvasás)
x (csak írás, üres fájl, ha létezik a fájl, akkor hiba)
x+ (olvasás, írás, üres fájl, ha létezik, akkor hiba)
c (csak írás, ha létezik, akkor elejére áll)
c+ (írás, olvasás, ha létezik, elejére áll)
fread($f, $hossz)
$hossz
byte beolvasásafscanf($f, $formátum)
fgets($f[, $hossz])
fgetcsv($f, $hossz[, $elv])
fwrite($f, $s)
$s
kiírásafputs($f, $s)
fwrite()
fprintf($f, $formátum, $változók)
fputcsv($f, $tömb[, $elv])
$tömb = file($fájlnév[, módosítók])
$s = file_get_contents($fájlnév)
readfile($fájlnév)
fpassthru($f)
file_put_contents($fájlnév, $s)
mkdir($útvonal)
rmdir($könyvtárnév)
copy($forrás, $cél)
rename($mit, $mire)
unlink($fájlnév)
is_dir($fájlnév)
is_file($fájlnév)
is_readable($fájlnév)
is_writable($fájlnév)
is_link($fájlnév)
is_executable($fájlnév)
basename($útvonal)
chown($fájl, $user)
chmod($fájl, $mód)
chgrp($fájl, $group)
stat($fájl)
fseek($f, $offset)
@
operátor: hibaüzenet kiírásának elnyomása$f = @fopen('nem_letezik.txt', 'r');
if ($f) {
/* ... */
fclose($f);
}
Adott filmcímek listája egy fájlban, soronként egy filmmel. Olvassuk ezt be egy tömbbe!
$filmek = file('lista.txt',
FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
/*
Array
(
[0] => A hobbit
[1] => A Gyűrűk Ura
[2] => Út a vadonba
[3] => Passió
)
*/
A hobbit
A Gyűrűk Ura
Út a vadonba
Passió
// Required
$filmek = @file('lista_.txt',
FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES)
or die('Nincs meg a fájl');
vagy
// Default data
$filmek = @file('lista_.txt',
FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
if (!$filmek) {
$filmek = [];
}
Egy filmcímeket tartalmazó tömb fájlba mentése (egy cím egy sor)
// A tömb filmcímekkel
$filmek = [
'Vuk',
'Lolka és Bolka',
'Macskafogó',
'Kisvakond és barátai',
];
// Kiírás alacsony szintű műveletekkel
define('SORVEG', "\n");
$f = @fopen('mesek.txt', 'w')
or die('Hiba!');
if ($f) {
foreach ($filmek as $film) {
fputs($f, $film . SORVEG);
}
fclose($f);
}
// VAGY
define('SORVEG', "\n");
// Elemek összefűzése
$s = implode(SORVEG, $filmek)
. SORVEG;
// Kiírás magas szintű művelettel
$siker = @file_put_contents(
'mesek.txt', $s);
Adott egy rekordokból álló tömb. Végezzük el a kiírását úgy, hogy egy sorban egy rekordnyi információ legyen, az egyes értékeket soron belül tabulátorral válasszuk el!
$filmek = [
[
'cim' => 'Passió',
'rendezo' => 'Mel Gibson',
'ev' => '2004',
],
[
'cim' => 'Pio atya - A csodák embere',
'rendezo' => 'Carlo Carlei',
'ev' => '2000',
],
];
define('SORVEG', "\n");
$f = @fopen('filmek.txt', 'w')
or die('Hiba!');
if ($f) {
foreach ($filmek as $film) {
fputcsv($f, $film, "\t");
}
fclose($f);
}
$filmek = [
[
'cim' => 'Passió',
'rendezo' => 'Mel Gibson',
'ev' => '2004',
],
[
'cim' => 'Pio atya - A csodák embere',
'rendezo' => 'Carlo Carlei',
'ev' => '2000',
],
];
Passió Mel Gibson 2004
Pio atya - A csodák embere Carlo Carlei 2000
Az előző példában kapott fájlt olvassuk be rekordok tömbjeként!
Passió Mel Gibson 2004
Pio atya - A csodák embere Carlo Carlei 2000
//Beolvasás a file paranccsal, és az utólagos soronkénti bontás
$filmek = file('filmek.txt',
FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
foreach($filmek as &$film) {
list($c, $r, $e) = explode("\t", $film);
$film = [
'cim' => $c,
'rendezo' => $r,
'ev' => $e,
];
}
Az előző példában kapott fájlt olvassuk be rekordok tömbjeként!
Passió Mel Gibson 2004
Pio atya - A csodák embere Carlo Carlei 2000
//Beolvasás soronként az fgetcsv-vel
$filmek = [];
$f = @fopen('filmek.txt', 'r');
if ($f) {
while ($sor = fgetcsv($f, 0, "\t")) {
$filmek[] = [
'cim' => $sor[0],
'rendezo' => $sor[1],
'ev' => $sor[2],
];
}
fclose($f);
}
//Mentés fájlba
define('SORVEG', "\n");
$f = @fopen('filmek_tobbsor.txt', 'w')
or die('Hiba!');
if ($f) {
foreach ($filmek as $film) {
fputs($f, $film['cim'] . SORVEG);
fputs($f, $film['rendezo'] . SORVEG);
fputs($f, $film['ev'] . SORVEG);
fputs($f, SORVEG);
}
fclose($f);
}
$filmek = [
[
'cim' => 'Passió',
'rendezo' => 'Mel Gibson',
'ev' => '2004',
],
// ...
];
Passió
Mel Gibson
2004
Pio atya - A csodák embere
Carlo Carlei
2000
Passió
Mel Gibson
2004
Pio atya - A csodák embere
Carlo Carlei
2000
//Beolvasás fájlból
$filmek = [];
$f = @fopen('filmek_tobbsor.txt', 'r');
if ($f) {
while (!feof($f)) {
$cim = trim(fgets($f));
$rendezo = trim(fgets($f));
$ev = trim(fgets($f));
$ures = fgets($f);
if ($cim != '') {
$filmek[] = [
'cim' => $cim,
'rendezo' => $rendezo,
'ev' => $ev,
];
}
}
fclose($f);
}
flock($f, $op)
LOCK_SH
(olvasáshoz)LOCK_EX
(íráshoz)LOCK_UN
(kioldáshoz)fflush($f)
define('SORVEG', "\n");
$f = @fopen('mesek.txt', 'w')
or die('Hiba!');
if ($f) {
if (flock($f, LOCK_EX)) {
foreach ($filmek as $film) {
fputs($f, $film . SORVEG);
}
flock($f, LOCK_UN);
}
fclose($f);
}
$filmek = [];
$f = @fopen('lista.txt', 'r');
if ($f) {
if (flock($f, LOCK_SH)) {
while (!feof($f)) {
$sor = trim(fgets($f));
if ($sor != '') {
$filmek[] = $sor;
}
}
flock($f, LOCK_UN);
}
fclose($f);
}
serialize($érték)
→ szövegunserialize($szöveg)
→ értékjson_encode($érték)
→ szövegjson_decode($szöveg)
→ érték$filmek = [
[
'cim' => 'Passió',
'rendezo' => 'Mel Gibson',
'ev' => '2004',
'szereplok'=> [
'Jim Caviezel',
'Maia Morgenstern',
'Christo Jivkov',
],
],
[
'cim' => 'Feltámadás',
'rendezo' => 'Kevin Reynolds',
'ev' => '2016',
'szereplok'=> [
'Joseph Fiennes',
'Tom Felton',
'Cliff Curtis',
],
],
];
$s = serialize($filmek);
//a:2:{i:0;a:4:{s:3:"cim";s:7:"Passió";s:7:"rendezo";s:10:"Mel Gibson";s:2:"ev";s:4:"2004";s:9:"szereplok";a:3:{i:0;s:12:"Jim Caviezel";i:1;s:16:"Maia Morgenstern";i:2;s:14:"Christo Jivkov";}}i:1;a:4:{s:3:"cim";s:12:"Feltámadás";s:7:"rendezo";s:14:"Kevin Reynolds";s:2:"ev";s:4:"2016";s:9:"szereplok";a:3:{i:0;s:14:"Joseph Fiennes";i:1;s:10:"Tom Felton";i:2;s:12:"Cliff Curtis";}}}
$filmek2 = unserialize($s);
/*
Array
(
[0] => Array
(
[cim] => Passió
[rendezo] => Mel Gibson
[ev] => 2004
[szereplok] => Array
(
[0] => Jim Caviezel
[1] => Maia Morgenstern
[2] => Christo Jivkov
)
)
[1] => Array
(
[cim] => Feltámadás
[rendezo] => Kevin Reynolds
[ev] => 2016
[szereplok] => Array
(
[0] => Joseph Fiennes
[1] => Tom Felton
[2] => Cliff Curtis
)
)
)*/
$s = json_encode($filmek);
//[{"cim":"Passi\u00f3","rendezo":"Mel Gibson","ev":"2004","szereplok":["Jim Caviezel","Maia Morgenstern","Christo Jivkov"]},{"cim":"Felt\u00e1mad\u00e1s","rendezo":"Kevin Reynolds","ev":"2016","szereplok":["Joseph Fiennes","Tom Felton","Cliff Curtis"]}]
[
{
"cim": "Passi\u00f3",
"rendezo": "Mel Gibson",
"ev": "2004",
"szereplok": [
"Jim Caviezel",
"Maia Morgenstern",
"Christo Jivkov"
]
},
{
"cim": "Felt\u00e1mad\u00e1s",
"rendezo": "Kevin Reynolds",
"ev": "2016",
"szereplok": [
"Joseph Fiennes",
"Tom Felton",
"Cliff Curtis"
]
}
]
$filmek3 = json_decode($s, true);
/*
Array
(
[0] => Array
(
[cim] => Passió
[rendezo] => Mel Gibson
[ev] => 2004
[szereplok] => Array
(
[0] => Jim Caviezel
[1] => Maia Morgenstern
[2] => Christo Jivkov
)
)
[1] => Array
(
[cim] => Feltámadás
[rendezo] => Kevin Reynolds
[ev] => 2016
[szereplok] => Array
(
[0] => Joseph Fiennes
[1] => Tom Felton
[2] => Cliff Curtis
)
)
)*/
$filmek3 = json_decode($s, false);
/*
Array
(
[0] => stdClass Object
(
[cim] => Passió
[rendezo] => Mel Gibson
[ev] => 2004
[szereplok] => Array
(
[0] => Jim Caviezel
[1] => Maia Morgenstern
[2] => Christo Jivkov
)
)
[1] => stdClass Object
(
[cim] => Feltámadás
[rendezo] => Kevin Reynolds
[ev] => 2016
[szereplok] => Array
(
[0] => Joseph Fiennes
[1] => Tom Felton
[2] => Cliff Curtis
)
)
)*/
function load_from_file(string $filename, bool $array_result = false, $default_data = []) {
$s = @file_get_contents($filename);
return ($s === false
? $default_data
: json_decode($s, $array_result));
}
function save_to_file(string $filename, $data) {
$s = json_encode($data);
return file_put_contents($filename, $s, LOCK_EX);
}
Akármilyen adatszerkezetre működik
$filmek = load_from_file('filmek.json');
$filmek[0]['szereplok'][] = 'Monica Bellucci';
save_to_file('filmek.json', $filmek);
[
{"cim":"Passi\u00f3","rendezo":"Mel Gibson","ev":"2004",
"szereplok":["Jim Caviezel","Maia Morgenstern","Christo Jivkov","Monica Bellucci"]},
{"cim":"Pio atya - A csod\u00e1k embere","rendezo":"Carlo Carlei","ev":"2000",
"szereplok":["Sergio Castellitto","Sergio Albelli"]}
]
array_map(callable $fn, array $x)
: másolásarray_filter(array $x, callable $fn)
: kiválogatásarray_reduce(array $x, callable $fn, $initial)
: általános összegzésarray_sum(array $x)
: összegzésarray_walk(array $x, callable $fn)
: iteráció$numbers = [1, 2, 3, 4, 5];
$evens = array_filter($numbers, function ($e) {
return $e % 2 === 0;
});
in_array($mit, $tömb)
: eldöntés (logikai)array_search($mit, $tömb)
: lineáris keresés (kulcs)sort($tömb)
: rendezés (többféle van)shuffle($tömb)
: keverésarray_keys($tömb)
: $tömb
kulcsai tömbkéntarray_values($tömb)
: $tömb
értékeit tömbkéntarray_key_exists($kulcs, $tömb)
: $kulcs
szerepel-e a $tömb
tömb kulcsai között.Jelenítsük meg a filmeket felsorolásban! A lista fölött szűrőmező.
<?php
// Data
function getMoviesByYear(int $year = NULL): array {
// ...
}
// Main
$year = (int)$_GET["year_filter"] ?? NULL;
$movies = getMoviesByYear($year);
?>
<h1>Movies</h1>
<form action="">
<input name="year_filter">
<button>Filter</button>
</form>
<ul>
<?php foreach ($movies as $movie) : ?>
<li>
<?= $movie["title"] ?>
(<?= $movie["year"] ?>)
</li>
<?php endforeach ?>
</ul>
movies.json
{
"1": {
"title": "The Passion of the Christ",
"year": 2004,
"director": "Mel Gibson"
},
"2": {
"title": "Risen",
"year": 2016,
"director": "Kevin Reynolds"
}
}
function getMoviesByYear(int $year = NULL): array {
$all = load_from_file('movies.json', true);
return array_filter($all, function ($movie) use ($year) {
return $movie['year'] === $year;
});
}
$movies = getMoviesByYear(2004);
interface FileIO {
public function save_to_file(string $filename, $data);
public function load_from_file(string $filename, bool $array_result = false, $default_data = []);
};
class JsonIO implements FileIO {
public function save_to_file(string $filename, $data) {
$s = json_encode($data);
return file_put_contents($filename, $s, LOCK_EX);
}
public function load_from_file(string $filename, bool $array_result = false, $default_data = []) {
$s = @file_get_contents($filename);
return ($s === false
? $default_data
: json_decode($s, $array_result));
}
}
class JsonStorage {
private $io;
private $filename;
public function __construct(string $filename) {
$this->io = new JsonIO();
$this->filename = $filename;
}
public function all() {
return $this->io->load_from_file($this->filename, true);
}
public function filter(callable $fn) {
$all = $this->all();
return array_filter($all, $fn);
}
public function insert(array $item): string {
$all = $this->all();
$id = uniqid('', true);
$item['_id'] = $id;
$all[$id] = $item;
$this->io->save_to_file($this->filename, $all);
return $id;
}
public function update(callable $filter, callable $updater) {
$all = $this->all();
array_walk($all, function (&$item) use ($filter, $updater) {
if ($filter($item)) {
$updater($item);
}
});
$this->io->save_to_file($this->filename, $all);
}
public function delete(callable $filter) {
$remaining = $this->filter(function ($elem) use ($filter) {
return !$filter($elem);
});
$this->io->save_to_file($this->filename, $remaining);
}
}
function getMoviesByYear(int $year = NULL): array {
$movieRepository = new JsonStorage('movies.json');
return $movieRepository->filter(function ($movie) use ($year) {
return $movie['year'] === $year;
});
}
function changeDirectorName(string $old, string $new) {
$movieRepository = new JsonStorage('movies.json');
$movieRepository->update(
function ($movie) use ($old) {
return $movie['director'] === $old;
},
function (&$movie) use ($new) {
$movie['director'] = $new;
}
);
}
function getMoviesByYear(int $year = NULL): array {
$movieRepository = new JsonStorage('movies.json');
return $movieRepository->filter(function ($movie) use ($year) {
return $movie->year === $year;
});
}
class JsonStorage {
// ...
public function all() {
return (array)$this->io->load_from_file($this->filename, false);
}
public function insert(object $item): string {
$all = $this->all();
$id = uniqid('', true);
$item->_id = $id;
$all[$id] = $item;
$this->io->save_to_file($this->filename, $all);
return $id;
}
// ...
}
function getMoviesByYear(int $year = NULL): array {
$movieRepository = new MovieRepository();
return $movieRepository->filter(function ($movie) use ($year) {
return $movie->year === $year;
});
}
// OR
$movies = $movieRepository->getMoviesByYear(2016);
class MovieRepository extends JsonStorage {
public function __construct() {
parent::__construct('movies.json');
}
public function getMoviesByYear(int $year = NULL): array {
return $this->filter(function ($movie) use ($year) {
return $movie->year === $year;
});
}
}
$movieRepository = new MovieRepository();
$movieRepository->add(new Movie("God's Not Dead", 2014, 'Harold Cronk'));
$movies = $movieRepository->getMoviesByYear(2016);
$movieRepository->changeDirectorName('Mel Gibson', 'Gibson, Mel');
class Movie {
public $_id = NULL;
public $title;
public $year;
public $director;
public function __construct($title = NULL, $year = NULL, $director = NULL) {
$this->title = $title;
$this->year = $year;
$this->director = $director;
}
public static function from_array(array $arr): Movie {
$instance = new Movie();
$instance->_id = $arr['_id'] ?? NULL;
$instance->title = $arr['title'] ?? NULL;
$instance->year = $arr['year'] ?? NULL;
$instance->director = $arr['director'] ?? NULL;
return $instance;
}
public static function from_object(object $obj): Movie {
return self::from_array((array)$obj);
}
}
class MovieRepository {
private $storage;
public function __construct() {
$this->storage = new JsonStorage('movies.json');
}
private function convert(array $arr): array {
return array_map([Movie::class, 'from_object'], $arr);
}
public function all() {
return $this->convert($this->storage->all());
}
public function add(Movie $movie): string {
return $this->storage->insert($movie);
}
public function getMoviesByYear(int $year = NULL): array {
return $this->convert($this->storage->filter(function ($movie) use ($year) {
return $movie->year === $year;
}));
}
public function changeDirectorName(string $old, string $new) {
$this->storage->update(
function ($movie) use ($old) {
return $movie->director === $old;
},
function (&$movie) use ($new) {
return $movie->director = $new;
}
);
}
}