Tvorba webových aplikací Jakub Vrána
Stavební kameny HTML struktura stránky (1-2. hodina) CSS formátování obsahu (3+vyhledávače) JavaScript interakce v prohlížeči (4) PHP programování na serveru (5-6) SQL databáze (7) HTTP protokol pro přenos Certifikáty zabezpečení
Situace na serveru Windows Linux... IIS Apache... ASP PHP... ODBC MySQL...
Komunikace se serverem Klient položí serveru protokolem HTTP dotaz na dokument Server vrátí HTML dokument, který může obsahovat objekty jako jsou obrázky, styl a JavaScript Každý z těchto objektů si klient opět musí vyžádat od serveru
Značky HTML Jakub Vrána
<html> <head> HTML tvorné značky {hypertext markup language} záhlaví dokumentu <title> název dokumentu <body> tělo dokumentu <meta/> vložení metainformací
Základní tvar dokumentu <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"> <html> <head> <title>název dokumentu</title> </head> <body> Tělo dokumentu. </body> </html>
<meta/> Metainformace http-equiv informace v hlavičce name jméno content obsah vkládá se do části <head> doplnění <meta http-equiv="content-type" content="text/html; charset=iso-8859-2"> <meta name="description" content="...">
Tělo dokumentu <body> background obrázek na pozadí! bgcolor barva pozadí! text barva obyčejného textu! link barva odkazu! vlink barva prohlédnutého odkazu! alink barva aktivního odkazu! [#rrggbb jméno]
HTML entity < > & < (menší než) > (větší než) & (ampersand) (pevná mezera) <!--... --> komentáře
Stránkotvorné značky <p> {paragraph} odstavec <br/> {line break} <hr/> {horizontal rule} <h1> - <h6> nadpis zlom řádku vodorovná čára {heading} <a> {anchor} odkaz
Formát odstavce <p align=> zarovnání! [right center justify] <br clear=> vyčištění okolí! [all left right] <center> vycentrování! <pre> <div> <span> naformátovaný text kontejner na objekty kontejner na text <blockquote>citace
Vodorovná čára <hr/> size tloušťka! width šířka na obrazovce! align zarovnání! noshade potlačení stínování! [noshade]
<a> Odkaz href odkaz na dokumenty name vytvoření částí dokumentu title nápovědný text accesskey přístupová klávesa [x] <a href="#kapitola1">odkaz</a> <a name="kapitola1"></a>kapitola 1
Formátování Fyzické Logické <font> přímá úprava písma! size velikost písma [ 1 7] color barva [#rrggbb jméno] face řez písma <basefont/> základní nastavení písma!
Fyzické formátování <b> {bold} tučné písmo <i> {italic} kurzíva <u> {underline} podtržení! <sup> {superscript} <sub> {subscript} horní index dolní index <tt> {teletype} pevná šířka znaku
<em> Logické formátování {emphasized} zvýraznění <strong> silné zvýraznění <code> <kbd> ukázka kódu vstup z klávesnice
Seznamy <ul> {unordered list} <ol> {ordered list} <li> {list item} <dl> {definition list} <dt> {definition term} <dd> {def. description} nesetříděný seznam setříděný seznam položka seznamu seznam definic pojem vysvětlující text
<ul> <li>první položka</li> </ul> Příklad seznamu <li>druhá položka První položka <ol> Druhá položka <li>první vnořená položka</li> 1. První vnořená položka <li>druhá vnořená položka</li> 2. Druhá vnořená </ol> položka </li>
Atributy seznamů <ul> type podoba značky! [circle, disc, square] <ol> type podoba značky! [1 i I a A] start číslování od! <li> value číslování od této značky dále!
<img/> src alt Obrázky URL obrázku width, height informace pro textové klienty rozměry v pixelech vspace, hspace mezera okolo obrázku! align zarovnání! [left right middle...] border rámeček obrázku s odkazem!
Obrázky s klikou <img usemap=> indikace obrázku s klikou <map name=> <area/> shape coords href nohref alt deklarace oblastí definice oblasti tvar [rect circle polygon] souřadnice odkaz oblast je bez odkazu [nohref] pomocný text
Příklad obrázku s klikou <img src="obrazek.gif" usemap="#mapa" width="35" height="30"> <map name="mapa"> <area shape="circle" coords="10,10,5" href="elipsa.html"> <area shape="rect" coords="20,15,30,25" href="obdelnik.html"> </map>
<table> Tabulky tabulka <tr> {table row} řádka <th> {table heading} políčko nadpisu <td> {table data} datové políčko
Příklad tabulky <table border="1"> <tr> <td>1. řádek, 1. sloupec</td> <td>1. řádek, 2. sloupec</td> </tr> <tr> <td>2. řádek, 1. sloupec</td> <td>2. řádek, 2. sloupec</td> </tr> </table> 1. řádek, 1. sloupec 1. řádek, 2. sloupec 2. řádek, 1. sloupec 2. řádek, 2. sloupec
<table> border Formát tabulky okraj cellspacing velikost mezer mezi buňkami cellpadding vzdálenost dat od okraje width šířka align zarovnání! [center right] bgcolor barva pozadí!
Atributy tabulky <tr>, <td>, <th> align vodorovné zarovnání [center right] valign svislé zarovnání [top bottom middle] bgcolor barva pozadí! <td>, <th> colspan spojení více sloupců rowspan spojení více řádek nowrap nezalamovat obsah buněk! [nowrap]
<frameset> rámů Rámy deklarace rows rozdělení okna na řádky a sloupce cols [* 200 20% 3*] <frame> src name <noframes> nepodporující rámy definice rámů zdrojový dokument rámu jméno rámu klienti
Příklad dokumentu s rámy <html><head><title>dokument s rámy</title></head> <frameset cols="20%,*"> <frameset rows="*,120"> <frame name="obsah" src="obsah.html"> <frame name="logo" src="logo.html"> </frameset> <frame name="hlavni" src="titulni.html"> <noframes><body> Dokument pro klienty nepodporující rámy. <a href="obsah.html">obsah</a> </body></noframes> </frameset> </html>
Úpravy rámů <frame> frameborder rámeček [yes no 0] scrolling přikáže, zakáže posouvání [yes no auto] noresize znemožní změnu velikosti [noresize] marginheight šířka okraje marginwidth výška okraje
<a target=> [jméno Odkazy na rámy cílový rám _blank _self _parent _top] <base/> základ pro odkaz target základní rám pro odkaz href základ pro odkaz na dokument
<form> <input/> Formuláře formulář vstupní pole <textarea>vstupní textová oblast <select> menu
<form> Formulář action co se s daty formuláře provede method jak se to provede [get post] enctype jakého jsou data druhu, při posílání souborů: [multipart/form-data] target cílové okno
Příklad formuláře <form action="mailto.php" method="post"> Jméno: <input type="text" name="jmeno"> E-mail: <input type="text" name="email"> Zpráva: <textarea name="zprava"></textarea> Stránky se mi: <input type="radio" name="libi" value="ano"> Líbí <input type="radio" name="libi" value="ne"> Nelíbí <input type="submit" value="odeslat"> </form>
<input type=> Typy vstupů text, passwordjednoduchý, skrytý text checkbox radio hidden file submit reset zaškrtávací políčko přepínač skrytý prvek odeslání celého souboru tlačítko pro odeslání tlačítko pro vynulování
<input/> name value size Vstupy formulářů identifikátor hodnota velikost vstupního pole maxlength maximální délka vstupu checked disabled readonly indikátor výběru [checked] prvek nelze vybrat [disabled] prvek nelze změnit [readonly]
<textarea> Vstupní textová oblast name identifikátor rows, cols počet řádků, sloupců wrap zalamování na konci řádku!! [off soft hard] <textarea> Text, který se na začátku zobrazí ve vstupním poli. </textarea>
<select> name size Výběrový seznam identifikátor položky velikost menu multiple lze vybrat více položek [multiple] <option> value položka nabídky text odeslaný formulářem selected vybraná položka [selected]
XHTML Rozdíly XHTML 1.0 proti HTML 4.01: Značky a atributy jsou psány malými písmeny Nepárové značky musí být ukončeny: <br /> Hodnoty atributů jsou vždy obaleny uvozovkami Přepínače musí mít stejnojmennou hodnotu <area nohref="nohref"> Dokument musí být uvozen <?xml version="1.0" charset="..."?> a správným <!DOCTYPE>
Závěr Literatura World wide web consortium (www.w3.org) HTML Reference Library (HomeSite) Jiří Kosek: HTML tvorba dokonalých WWW stránek Stránky v HTML na WWW Další studium dynamické prvky (JavaScript, PHP, databáze) moderní rysy (styly, XHTML)
Webové aplikace CSS Jakub Vrána
Vkládání do HTML <link rel="stylesheet" type="text/css" href="styl.css"> <style type="text/css"> @import url(styl.css); P { margin-bottom: 0; } </style> <div id="citat-1" class="citat"> <p style="text-indent: 10px;">
Zápis stylu selektor { vlastnost: hodnota;... } Typy selektorů: značka, #id,.třída, :pseudotřída Kaskáda se vyznačuje mezerou, např.: #menu A odkazy v <div id="menu"> Více selektorů pro stejný styl lze oddělit čárkou
Hodnoty vlastností Délka: 3px (pt, cm, mm, ex, em,...) Procenta: 80% Barvy: pojmenované (blue,...), #rrggbb URL: url(pozadi.jpg) Řetězce: "text" nebo 'text', \ escapuje
Formátování vzhledu color, background-color, background-image background-repeat: repeat-y no-repeat background-position: top left center right font-family: Arial, sans-serif monospace font-size, font-weight: bold, font-style: italic text-decoration: none underline text-align: left right justify center vertical-align: baseline top middle
Příklad formátování P { text-align: justify; } A { text-decoration: none; } A:hover { color: Red; }.perex,.diskuse { font-size: 10pt; font-family: Verdana, sans-serif; font-style: italic; }.male TD { font-size: 80%; }
Okraje margin, padding, border Lze určit buď jednotlivě pomocí -left, -right, -top, -bottom nebo najednou jako 1 až 4 hodnoty oddělené mezerou v pořadí top, right, bottom, left (kromě border) border-width, border-color border-style: solid dotted margin: 0 auto margin border padding text text
width, height Pozicování display: block inline none float: left right clear: left right both position: relative absolute fixed top, right, bottom, left z-index
Příklad pozicování #navigace { width: 200px; float: left; } #telo { margin-left: 210px; } #paticka { clear: both; } Odpovídající HTML kód: <div id="navigace">...</div> <div id="telo">...</div> <div id="paticka">...</div>
Další vlastnosti list-style-type: disc lower-alpha none list-style-image overflow: visible hidden scroll auto white-space: normal pre nowrap cursor: default pointer help
značka, třída, id Priorita podrobnější má přednost při stejné prioritě má přednost pozdější!important zvýší prioritu vlastnosti
:first-line, :first-letter Další obraty A:link, A:visited, :hover /*... */ komentáře @media print { } #telo { width: 100%; } #navigace { display: none; }
Reference Norma: http://www.w3.org/tr/css21/ Dílna CSS: http://www.wellstyled.com/
Vytváření stránek, které naleznou vyhledávače Jakub Vrána
Přístupné stránky K JavaScriptu vždy vytvořit alternativu, vyhnout se navigaci pouze v JavaScriptu K prezentaci ve Flashi vytvořit HTML verzi ocení i někteří uživatelé Rámy nejsou v principu špatné, ale při nalezení konkrétní stránky chybí navigace Styly jsou výhodou zpřehledňují kód a uživatelům zrychlují načítání
Určení relevance stránky Není znám přesný výpočet relevance, ale používá se např. následující: Slova v nadpisech <h1> až <h6> mají větší váhu Slova v <title> mají větší váhu titulek by měl být pro každou stránku jiný Slova v doméně a v URL obecně mají větší váhu; Google ignoruje?search=
Podpoření relevance stránky Relevance se určuje i podle toho, co obsahují odkazy vedoucí na stránku vyhnout se odkazům typu klikněte zde Obrázky nesoucí textovou informaci by měly mít alt popisek, uvádění rozměrů obrázků zabrání poskakování stránky Zpětné odkazy relevanci zvyšuje i odkaz na jiné relevantní stránce
Vyhledávače Registrace ve vyhledávačích čitelný popis obsahující klíčová slova, DMOZ.org používá řada vyhledávačů včetně Google Řada vyhledávačů hledá i v dokumentech DOC, PDF apod. Je proto užitečné poskytnout i nekomprimovanou verzi Stránky vytvářet s diakritikou zahraniční vyhledávače ji neumí odstraňovat
Čemu se vyhnout Neduplikovat stránky na více adresách tříští to pozornost vyhledávačů a cachí a může být vyhodnoceno i jako podvod použít hlavičku Location Nepoužívat špinavé triky (např. skryté texty a spamování diskusních fór) může vést k vyřazení z výsledků vyhledávání (podvodné stránky lze udat)
Webové aplikace JavaScript Jakub Vrána
Vkládání do HTML <script src="scripts.js" type="text/javascript"></script> <script type="text/javascript"><!-- document.write(document.lastmodified); // --></script> <noscript>nepodporuje skripty.</noscript> <select onchange="this.form.submit();"> <a href="javascript:window.print();">tisk</a>
Vychází z jazyka C Základy Jedná se o objektový jazyk, ke všem objektům na stránce se dá přistoupit Beztypový jazyk Řetězce: 'text' nebo "text" operátor zřetězení je plus Přístup k vlastnostem objektu: objekt.vlastnost nebo objekt['vlastnost']
Základní objekty prohlížeče window document location navigator history
alert('výzva') b = confirm('výzva') window s = prompt('výzva', 'výchozí') open('url', 'název okna', 'parametry') close(), print() parent, opener, status timeout = settimeout('funkce', ms) cleartimeout(), setinterval(), clearinterval()
document document.getelementbyid('id') document.write('řetězec') document.forms['name'] document.lastmodified
location, history, navigator location.href location.reload() history.length history.back(), history.go(ofset) navigator.appname, navigator.appversion navigator.cookieenabled
Další objekty Array Date Math RegExp String
'řetězec'.length String, RegExp i = s.indexof('hledat') s = s.substr(začátek, délka) re = new RegExp('pattern', 'přepínače') re = /pattern/přepínače ar = re.exec('řetězec') b = re.test('řetězec')
Array, Math, Date ar = Array(prvky), ar = Array(počet) ar[0], ar.sort() for (klíč in obj) { alert(obj[klíč]); } Math.round(číslo), Math.max(x, y) d = new Date([rok, měsíc, den]) d.getdate(), d.getmonth(), d.getyear()
Další obraty encodeuri('řetězec'), eval('výraz') většina HTML atributů má protějšek v JS style kopíruje vlastnosti CSS, pomlčku nahrazuje velké písmeno this odkaz na aktuální objekt, např. <form onsubmit="return kontrola(this);">
Funkce a objekty function nazev_funkce(parametry) { /* tělo funkce */ return true; } obj = new nazev_funkce(); vlastnosti a metody se definují pomocí this zkrácený zápis: { vlastnost: hodnota,... }
Obsluha událostí onblur při ztrátě focusu onclick, onchange při kliknutí, při změně onmouseover, onmouseout najetí myši form.onsubmit před odesláním formuláře body.onload po nahrání stránky return zda má pokračovat obsluha události
Reference Netscape: http://devedge.netscape.com/central/javascript/ Microsoft: http://msdn.microsoft.com/workshop/ author/dhtml/reference/dhtml_reference_entry.asp Příklady: http://www.vrana.cz/javascript/
Webové aplikace PHP Jakub Vrána
PHP PHP = PHP: Hypertext Preprocessor (dříve: Professional Home Pages) Alternativy: ASP, JSP Domácí stránka: http://www.php.net Verze: používá se hlavně verze 4 a 5, kde je především přepracovaná práce s objekty
Základní syntaxe Vychází z jazyka C (řídící struktury, operátory,...), částečně z Unix shellu Lze kombinovat s textovým výstupem Příkazy jsou ukončeny středníkem Proměnné jsou uvozeny dolarem Záleží na velikosti písmen (u funkcí ale ne)
HTML <?php // PHP kód?> HTML Vkládání do HTML Existuje i zkrácená a prodloužená forma
Komentáře /* libovolný komentář */ (nelze vnořovat do sebe) // jednořádkový komentář # jednořádkový komentář (nedoporučuje se)
Operátory! negace, && logický AND, OR = přiřazení == rovnost,!= nerovnost === identita,!== neidentita ++ inkrementace, -- dekrementace $a +=... zkratka pro $a = $a +...?: ternární operátor (a == 1? 'kus' : 'kusy')
Proměnné Uvozeny dolarem nekolidují s jinými názvy, lze přímo použít v řetězcích Funkce nevidí globální proměnné (lze ale použít global nebo $GLOBALS), soubory si proměnné vzájemně vidí Pro hodnoty zvenku (např. z formulářů) jsou vytvořeny speciální pole automaticky viditelné i ve funkcích
Typy Typy se převádějí podle potřeby Není třeba deklarovat proměnné Základní typy (pro představu): pravdivostní (true, false) čísla (celá, desetinná) řetězce (libovolně dlouhé) pole (s libovolnými indexy) objekty zdroje (používají různé funkce)
Řetězce Tři způsoby zadávání: 'jednoduchý řetězec' "převod proměnných ($var) a speciálních znaků (\n\t)" <<<EOT řetězec na místě EOT Zřetězení: operátor tečka
Pole Způsoby zadávání: $a = array(3, 5, 7); $a[0] = 3; $a[] = 9; $a = array("id" => 7, "nazev" => "Propiska", "cena" => 24); $a["nazev"] = "Propiska"; Přístup k prvkům: $a[klíč] Pole v řetězcích: "Název: $a[nazev]"
Funkce Uživatelsky definované: function mocnina($a) { return $a * $a; } parametry mohou mít výchozí hodnotu $a=3 parametry mohou být předané referencí &$a Vestavěné základní nebo z modulů Speciální jazykové konstrukce
Speciální funkce echo, print tisk řetězců exit, die ukončení běhu skriptu include, require, include_once, require_once vložení souborů isset, empty, unset práce s proměnnými list($a, $b) = array(3, 5); return návrat z funkcí nebo souborů
Speciální proměnné zvenku $_GET["a"] = "3" soubor.php?a=3 $_POST["a"] <form method="post"> <input name="a"></form> $_COOKIE["a"] = "3" setcookie("a", 3) $_REQUEST = $_GET + $_POST + $_COOKIE $_FILES["a"] = array("tmp_name" => "", "name" => "", "type" => "",...) <input type="file" name="a">
Speciální proměnné serverové $_ENV proměnné prostředí, např. PATH $_SERVER proměnné web. serveru a PHP $_SESSION session_start() $GLOBALS globální proměnné
Řídící struktury: if, switch if (!$prihlasen) { echo "Nejste přihlášen."; } else { mysql_query("update..."); } switch ($hodnota) { case 0:...; break; case 1:...; break; default:...; break; }
Řídící struktury: while, do $result = mysql_query("select * FROM..."); while ($row = mysql_fetch_assoc($result)) { echo $row["nazev"]. "<br>\n"; } do { // alespoň jeden průchod echo ($i++). ". průchod\n"; } while ($i < 5); lze přerušit pomocí break a continue
Řídící struktury: for, foreach for ($i = 1; $i <= 7; $i++) { echo "<font size=\"$i\">". "Velikost $i</font>"; } foreach ($row as $key => $val) { echo "$key: $val\n"; } lze přerušit pomocí break a continue
Třídy a objekty class Archive_Tar extends PEAR { var $_tarname = ''; function Archive_Tar($tarname) { //... } } $tar = new Archive_Tar('tmp.tar'); $tar->add('file.html'); parent::, $this->, :: sleep, wakeup
Třídy v PHP 5 construct, destruct, self:: public, protected, private static, const abstract, final interface, implements, Iterator call, get, set, tostring throw, try, catch clone, clone
Řetězce Pole Čísla, datum Soubory Nastavení Komunikace Regulární výrazy MySQL Základní funkce
Řetězce addslashes($str) stripslashes($str) htmlspecialchars($str) urlencode($str) trim($str, $charlist) nl2br($str) md5($str) sha1($str)
strlen($str) Práce s řetězci strpos($str, $needle) stripos($str, $needle) strrchr($str, $needle) substr($str, $start, $len) str_replace($search, $repl, $str)
count($ar) Pole in_array($needle, $ar) isset($ar[$index]) implode($glue, $ar) explode($glue, $str) asort($ar) krsort($ar)
rand($min, $max) Čísla, datum round($num), ceil($num), floor($num) number_format($num, $decimals) date('j.n.y H:i:s', $timestamp) time() aktuální timestamp mktime($h, $m, $s, $M, $D, $Y)
Soubory fopen($filename, $mode) fclose($fp) fread($fp, $length) fgets($fp) načtení celého řádku fwrite($fp, $str) file($filename) řádky do pole file_get_contents($filename) jako název souboru lze použít i http://...
Nastavení phpinfo(), ini_set($name, $value) set_time_limit($sec) flush(), ob_flush() define($constant, $value) Některé konfigurační direktivy: magic_quotes_gpc, register_globals, safe_mode, open_basedir, error_reporting, session.save_path, short_open_tag
Komunikace header($str) HTTP hlavička, např. header('location: http://...') setcookie($name, $value, $expire) mail($to, $subj, $msg, $headers) fsockopen($target, $port) např. fsockopen('www...', 80)
Regulární výrazy $patt = '~<a href="([^"]*)~i'; preg_match($patt, $str, $matches) preg_replace($patt, $repl, $str) preg_match_all($patt, $str, $matches) preg_quote($str, $delim)
MySQL mysql_connect($server, $login, $pwd) mysql_select_db($dbname) mysql_query($query) mysql_num_rows($result) mysql_affected_rows() mysql_fetch_assoc($result) mysql_insert_id() mysql_error()
Vlastnosti dobré webové aplikace Ošetřovat nedůvěryhodná data (escapování) Nespoléhat se na nečitelnost zdrojáků a dat (hashovat hesla, inicializovat proměnné) Nespoléhat se na to, že na stránku nevede odkaz (zabezpečit heslem) Ošetřovat kritické chyby (připojení k databázi, odeslání e-mailu) Všechen kód mít na jednom místě (použít funkce nebo třídy a vkládat soubory)
Reference http://www.php.net/manual/en/ Jiří Bráza: PHP 5 začínáme programovat Welling, Thomsonová: PHP a MySQL PHP triky: http://php.vrana.cz Šablonovací systémy: http://smarty.php.net, http://htmltmpl.sf.net
Webové aplikace databáze Jakub Vrána
SQL Structured Query Language (dříve: SEQueL English) Využívají různé databáze: MySQL, PostgreSQL, Oracle, MS SQL, DB2,... Obvykle architektura klient/server
Struktura dat v databázi Databázový server Databáze Tabulky Sloupce a řádky
int real decimal(m, d) date time datetime varchar(m) text Základní datové typy
Základní SQL příkazy CREATE TABLE vytvoření tabulky ALTER TABLE změna tabulky DROP TABLE odstranění tabulky SELECT získání dat INSERT vložení dat UPDATE úprava dat DELETE smazání dat
Vytvoření tabulky CREATE TABLE nazev (sloupec typ,..., klíč,...) Příklad: CREATE TABLE tabulka ( id int NOT NULL AUTO_INCREMENT, nazev varchar(50), cena decimal(9, 2), PRIMARY KEY (id) )
Změna a smazání tabulky Příklad změny: ALTER TABLE tabulka ADD popis text AFTER cena, CHANGE cena cena decimal(12, 2) Smazání tabulky: DROP TABLE tabulka
Získání dat SELECT sloupec, sloupec,... FROM tabulka, tabulka,... WHERE podmínka ORDER BY sloupec LIMIT počet OFFSET od Příklad: SELECT * FROM vyrobky WHERE stav = 'aktivní' ORDER BY cena
Spojování tabulek, indexy INNER JOIN tabulka ON podmínka LEFT JOIN tabulka ON podmínka Indexy jsou vhodné u sloupců dle kterých se spojují tabulky vyhledává třídí Složené indexy: INDEX (skupina, poradi) Unikátní indexy: UNIQUE (sloupce)
Agregace Agregační funkce: COUNT, COUNT(DISTINCT), SUM, AVG GROUP BY sloupec,... HAVING podmínka
Vložení dat INSERT INTO tabulka (sloupec, sloupec,...) VALUES ('hodnota', 'hodnota',...) Příklad: INSERT INTO vyrobky (nazev, cena) VALUES ('Propiska', '27')
Úprava dat UPDATE tabulka SET sloupec = 'hodnota',... WHERE podmínka Příklad: UPDATE vyrobky SET cena = '24' WHERE id = '137'
Smazání dat DELETE FROM tabulka WHERE podmínka Příklad: DELETE FROM vyrobky WHERE cena <= '15'