05 - Osnove PHP-a

Šta je PHP?

  • PHP = PHP Hypertext Preprocessor
  • PHP je skript jezik koji se izvršava na serveru, rezultat izvršavanja se kao čist HTML šalje pregledaču

Šta je PHP datoteka?

  • PHP datoteka sadrži tekst, HTML, CSS, JavaScript i PHP kod
  • Ekstenzija je php

Šta PHP može da radi?

  • Generiše dinamički sadržaj stranice
  • Kreira, otvara, čita, piše, briše i zatvara datoteke na serveru
  • Prikuplja podatke sa formi
  • Šalje i prima kolačiće
  • Dodaje, briše i menja podatke u bazi podataka
  • Kontroliše prava pristupa određenim stranicama na sajtu
  • Šifrira podatke

Sintaksa

  • PHP skript može da se smesti bilo gde u dokumentu
  • PHP skript počinje sa <?php i završava se sa ?>
    • <!DOCTYPE html>
      <html>
          <body>
              <h1>My first PHP page</h1>
              <?php
                  echo "Hello World!";
              ?>
          </body>
      </html>
  • PHP naredbe se završavaju sa ;

Komentari

  • Komentar u jednom redu počinje sa // ili sa #
  • Komentar u više redova počinje sa /* i završava se sa */

Mala i velika slova

  • Sve korisnički definisane funkcije, klase i PHP ključne reči ne razlikuju mala i velika slova
  • Sve promenljive razlikuju mala i velika slova

Promenljive

  • Imenovanje
    • Promenljiva počinje znakom $ i zatim sledi ime promenljive
    • Ime promenljive mora početi slovom ili podvlakom
    • Ime promenljive ne može početi cifrom
    • Ime promenljive jedimo može sadržati slova (A-Z,a-z), cifre (0-9) i podvlaku
  • Deklaracija promenljivih
    • U PHP ne postoji naredba za deklaraciju promenljivih i definišu im se tipovi
    • Promenljiva se deklariše u trenutku kada joj se prvi put dodeli vrednost
  • Oblast važenja promenljivih
    • Lokalne i globalne promenljive
      • Promenljive deklarisane van funkcija su globalne promenljive i može im se pristupiti samo van funkcija
      • Promenljive deklarisane unutar funkcije su lokalne promenljive i može im se pristupiti samo unutar funkcije
      • Ako se unutar funkcije želi pristup globalnim promenljivama mora se prvo upotrebiti naredba global ili se koristi niz $GLOBALS[index] gde je index ime globalne promenljive
        • global $x,$y;
        • $GLOBALS['y']=$GLOBALS['x']+$GLOBALS['y'];
    • Statičke promenljive
      • Kada funkcija završi rad sve njene lokalne promenljive se brišu
      • Ako je potrebno da se lokalne promenljive i njihove vrednosti sačuvaju za sledeći poziv funkcije koristi se ključna reč static prilikom deklaracije tih promenljivih
        • static $x=0;

Naredbe echo i print

  • echo
    • Može da prikaže jedan ili više stringova
    • Koristi se bez ili sa zagradama - echo ili echo()
    • <?php
          $txt1="Learn PHP";
          $txt2="W3Schools.com";
          $cars=array("Volvo","BMW","Toyota");
          echo $txt1;
          echo "<br>";
          echo "Study PHP at $txt2";
          echo "My car is a {$cars[0]}";
      ?>
  • print 
    • Može da prikaže samo jedan string i uvek vraća 1
    • Koristi se bez ili sa zagradama - print ili print()
    • <?php
          $txt1="Learn PHP";
          $txt2="W3Schools.com";
          $cars=array("Volvo","BMW","Toyota");
          print $txt1;
          print "<br>";
          print "Study PHP at $txt2";
          print "My car is a {$cars[0]}";
      ?>

Tipovi podataka

  • String
    • String je niz znakova
    • Bilo koji tekst unutar navodnika ili apostrofa
    • Numerisanje pozicija znakova unutar stringa počinje od nule
  • Integer (celi brojevi)
    • Integer je broj bez decimala
    • Mora da ima bar jednu cifru (0-9)
    • Ne može da sadrži zarez ili razmak
    • Ne sme da ima decimalnu tačku
    • Može biti pozitivan ili negativan
    • Koriste se tri formata - decimalni, heksadecimalni (sa prefiksom 0x) i oktalni (sa prefiksom 0)
    • 5985, -345, 0x8C, 047
  • Floating point numbers (brojevi u pokretnom zarezu)
    • To su brojevi sa decimalnom tačkom i u eksponencijalnom zapisu
    • 10.365, 2.4e3, 8E-5
  • Boolean (logičke vrednosti)
    • true
    • false
  • Array (niz)
    • Služe za čuvanje više vrednosti u jednoj promenljivoj
    • $cars=array("Volvo","BMW","Toyota");
  • Object
    • Tip podataka koji čuva podatke i informacije kako se ti podaci obrađuju
    • Objekti moraju da se eksplicitno deklarišu
    • Prvo se deklariše klasa objekta korišćenjem ključne reči class
    • Klasa je struktura koja sadrži svojstva i metode
  • NULL
    • NULL je posebna vrednost koja označava da promenljiva nema vrednost, tj. da je prazna
    • Promenljive mogu da se isprazne postavljanjem vrednosti na NULL
  • Funkcija var_dump() vraća tip i vrednost promenljive

String funkcije

  • strlen() - Dužina stringa, tj. broj znakova
  • strpos() - Traži zadati znak ili string u stringu, braća poziciju prvog pojavljivanja ili false ako ga nema, razlikuje mala i velika slova
  • stripos() - Traži zadati znak ili string u stringu, braća poziciju prvog pojavljivanja ili false ako ga nema, ne razlikuje mala i velika slova
  • chr() - Vraća znak za navedenu ASCII vrednost
  • ord() - Vraća ASCII kod prvog znaka u stringu
  • explode() - Pretvara string u niz podstringova, a na mestima zadatog separatora i moguće je da se zada broj podstringova
  • implode(), join() - Vraća string napravljen od elemenata niza uz korišćenje opcionog separatora
  • str_replace() - Zamena podstringa drugim stringom uz mogućnost brojanja zamena
  • str_split() - Pretvara string u niz podstringova zadate dužine
  • strtolower() - Pretvara string u mala slova
  • strtoupper() - Pretvara string u velika slova
  • trim() - Uklanja beline sa obe strane stringa

Konstante

  • Konstante su slične promenljivama, samo što vrednost ne može da im se menja u toku izvršavanja skripta
  • Ime konstante počinje slovom ili podvlakom
  • Konstante su globalne, tj. vidljive u celom skriptu
  • Najčešće se ime konstante piše sa svim velikim slovima
  • Za definisanje konstante koristi se funkcija define() sa tri parametra:
    • Ime konstante
    • Vrednost konstante
    • Da li je konstanta neosetljiva na mala/velika slova, opciono, podrazumevano je false
    • define("GREETING", "Welcome to W3Schools.com!", true);

Operatori

  • Aritmetički
    • + - Sabiranje
    • - - Oduzimanje
    • * - Množenje
    • / - Deljenje
    • % - Ostatak pri deljenju, moduo
  • Dodele
    • = - Dodela vrednosti
    • += - Sabiranje i dodela vrednosti
    • -= - Oduzimanje i dodela vrednosti
    • *= - Množenje i dodela vrednosti
    • /= - Deljenje i dodela vrednosti
    • %= - Ostatak pri deljenju i dodela vrednosti
  • String
    • . - Konkatenacija
    • .= - Konkatenacija i dodela vrednosti
  • Inkrement/dekrement
    • ++$x - Pre-inkrement
    • $x++ - Post-inkrement
    • --$x - Pre-dekrement
    • $x-- - Post-dekrement
  • Poređenja
    • == - Jednako
    • === - Identično, jednako i istog tipa
    • != - Nije jednako
    • <> - Nije jednako
    • !== - Nije identično
    • > - Veće od
    • < - Manje od
    • >= - Veće od ili jednako
    • <= - Manje od ili jednako
  • Logički
    • and - Logičko i
    • or - Logičko ili
    • xor - Logičko isključivo ili
    • && - Logičko i
    • || - Logičko ili
    • ! - Negacija
  • Nizovni
    • + - Unija
    • == - Jednako
    • === - Identično
    • != - Nije jednako
    • <> - Nije jednako
    • !== - Nije identično

Uslovni izrazi

  • if
    • if (uslov) {
          kod koji se izvrsava ako je uslov true;
      }
  • if...else
    • if (uslov) {
          kod koji se izvrsava ako je uslov true;
      } else {
          kod koji se izvrsava ako je uslov false;
      }
  • if...elseif....else
    • if (uslov) {
          kod koji se izvrsava ako je uslov true;
      } elseif (uslov) {
          kod koji se izvrsava ako je uslov true;
      } else {
          kod koji se izvrsava ako je uslov false;
      }
  • switch
    • switch (n) {
          case label1:
              kod koji se izvrsava ako je n=label1;
              break;
          case label2:
              kod koji se izvrsava ako je n=label2;
              break;
          case label3:
              kod koji se izvrsava ako je n=label3;
              break;
      ...
          default:
              kod koji se izvrsava ako je n razlocito od svega;
      }

While petlje

  • Izvršavaju se dok je navedini uslov ispunjen
  • while
    • while (uslov is true) {
          kod koji se izvrsava;
      }
  • do...while
    • do {
          kod koji se izvrsava;
      } while (uslov is true);

For petlje

  • Izvršavaju se određen broj puta
  • for
    • for (init counter; test counter; increment counter) {
          kod koji se izvrsava;
      }
  • foreach
    • foreach ($array as $value) {
          kod koji se izvrsava;
      }

Funkcije

  • Postoji više od 1000 ugrađenih funkcija, a pored toga i korisnik može da kreira svoje funkcije
  • Funkcija se ne izvrša odmah sa učitavanjem stranice, već po pozivu
  • Kreiranje funkcije
    • function imeFunkcije() {
          kod koji se izvrsava;
      }
  • Parametri/argumenti funkcije
    • Informacije se prenose funkcijama kroz argumente
    • Argumenti su promenljive koje se navode u zagradi iza imena funkcije i kojima se može zadati podrazumevana vrednost
    • function familyName($fname, $year) {
          echo "$fname Refsnes. Born in $year <br>";
      }
    • function setHeight($minheight=50) {
          echo "The height is : $minheight <br>";
      }
  • Ukoliko funkcija treba da vrati vrednost koristi se naredba return
    • function sum($x,$y) {
          $z=$x+$y;
          return $z;
      }

Nizovi

  • Nizovi su specijalne promenljive koje mogu istovremeno da čuvaju više od jedne vrednosti
  • Za kreiranje nizova koristi se funkcija array()
  • Indexed arrays - Nizovi sa numeričkim indeksima
    • $cars=array("Volvo","BMW","Toyota");
    • Ili dodelom vrednosti pojedinačnim elementima - $cars[0]="Volvo";
    • Prolazak kroz niz:
      • for($x=0;$x<count($cars);$x++) {
            echo $cars[$x];
            echo "<br>";
        }
  • Associative arrays - Nizovi sa imenovanim ključevima
    • Ovi nizovi sadrže parove ključ/vrednost
    • $age=array("Peter"=>"35","Ben"=>"37","Joe"=>"43");
    • Ili dodelom vrednosti pojedinačnim elementima - $age['Peter']="35";
    • Prolazak kroz niz:
      • foreach($age as $x=>$x_value) {
            echo "Key=" . $x . ", Value=" . $x_value;
            echo "<br>";
        }
  • Multidimensional arrays - Nizovi koji sadrže više nizova
  • Sortiranje nizova
    • Nizovi se mogu sortirati u alfabetskom ili numeričkom redosledu, rastuće ili opadajuće
    • sort() - Rastući redosled
    • rsort() - Opadajući redosled
    • asort() - Asocijativni niz, u rastućem redosledu prema vrednostima
    • ksort() - Asocijativni niz, u rastućem redosledu prema ključevima
    • arsort() - Asocijativni niz, u opadajućem redosledu prema vrednostima
    • krsort() - Asocijativni niz, u opadajućem redosledu prema ključevima

Superglobalne promenljive

  • To su promenljive koje su uvek dostupne u svakom delu skripta, tj. u svakoj funkciji, klasi i datoteci i može im se pristupiti bez potrebe da se pre toga uradi bilo šta posebno
  • $GLOBALS
    • Čuva niz globalnih promenljivih
  • $_SERVER
    • Čuva informacije o zaglavljima, putanjama i lokacijama za skriptove
  • $_REQUEST
    • Koristi se za pristup podacima koji poslati korišćenjem forme
  • $_POST
    • Koristi se za pristup podacima koji poslati korišćenjem forme uz method="post", kao i za prenošenje promenljivih
  • $_GET
    • Koristi se za pristup podacima koji poslati korišćenjem forme uz method="get"
  • $_FILES
    • Prosleđene datoteke
  • $_ENV
    • Promenljive prosleđene trenutnom skriptu kroz metod environment
  • $_COOKIE
    • Kolačići
  • $_SESSION
    • Promenljive za trenutnu sesiju

Forme

  • Prosta forma
    • <form action="obrada_post.php" method="post">
    • obrada_post.php
      • <html>
            <body>
                Zdravo <?php echo $_POST["name"]; ?><br>
                Vas e-mail je: <?php echo $_POST["email"]; ?>
             </body>
        </html>
    • <form action="obrada_get.php" method="get">
    • obrada_get.php
      • <html>
            <body>
                Zdravo <?php echo $_GET["name"]; ?><br>
                Vas e-mail je: <?php echo $_GET["email"]; ?>
             </body>
        </html>
  • _GET - niz promenljivih prosleđenih tekućem skriptu pomoću URL parametara
    • Nije bezbedno jer se podaci vide u URL-u
    • Moguće je zapamtiti takav poziv
    • Ograničena količina podataka na oko 2000 znakova
  • _POST - niz promenljivih prosleđenih tekućem skriptu pomoću HTTP POST methoda
    • Bezbedno
    • Nema ograničenja u količini prosleđenih podataka
    • Nije moguće zapamtiti takav poziv
  • Tekstualna polja na formi za primer
    • Name: <input type="text" name="name">
    • E-mail: <input type="text" name="email">
    • Website: <input type="text" name="website">
    • Comment: <textarea name="comment" rows="5" cols="40"></textarea>
  • Radio dugmad na formi za primer
    • <input type="radio" name="gender" value="female">Female
    • <input type="radio" name="gender" value="male">Male
  • Elemet form na formi za primer
    • <form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">
    • $_SERVER["PHP_SELF"] je superglobalna promenljiva koja čuva ime datoteke trenutnog skripta
    • Funkcija htmlspecialchars() pretvara specijalne znakove u HTML entitete
  • Validacija podataka sa forme
    • Validacija podataka sa forme je važna radi zaštite od hakera i spamera
    • Prenos svih podataka sa forme kroz funkciju htmlspecialchars()
    • Odsecanje nepotrebnih znakova korišćenjem funkcije trim()
    • Uklanjanje znakova \ korišćenjem funkcije stripslashes()
    • Kreiranje funkcije koja će odrađivati potrebne provere - test_input()
      • <?php
            $name = $email = $gender = $comment = $website = "";
            if ($_SERVER["REQUEST_METHOD"] == "POST") {
                $name = test_input($_POST["name"]);
                $email = test_input($_POST["email"]);
                $website = test_input($_POST["website"]);
                $comment = test_input($_POST["comment"]);
                $gender = test_input($_POST["gender"]);
            }
            function test_input($data) {
                $data = trim($data);
                $data = stripslashes($data);
                $data = htmlspecialchars($data);
                return $data;
            }
        ?>
    • Sledi provera obaveznih polja
      • <?php
            $nameErr = $emailErr = $genderErr = $websiteErr = "";
            $name = $email = $gender = $comment = $website = "";
            if ($_SERVER["REQUEST_METHOD"] == "POST") {
                if (empty($_POST["name"])) {
                    $nameErr = "Name is required";
                } else {
                    $name = test_input($_POST["name"]);
                }
                if (empty($_POST["email"])) {
                    $emailErr = "Email is required";
                } else {
                    $email = test_input($_POST["email"]);
                }
                if (empty($_POST["website"])) {
                    $website = "";
                } else {
                    $website = test_input($_POST["website"]);
                }
                if (empty($_POST["comment"])) {
                    $comment = "";
                } else {
                    $comment = test_input($_POST["comment"]);
                }
                if (empty($_POST["gender"])) {
                    $genderErr = "Gender is required";
                } else {
                    $gender = test_input($_POST["gender"]);
                }
            }
        ?>
    • Kreiranje poruka o greškama ukoliko je potrebno
      • <form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">
            Name: <input type="text" name="name">
            <span class="error">* <?php echo $nameErr;?></span>
            <br><br>
            E-mail: <input type="text" name="email">
            <span class="error">* <?php echo $emailErr;?></span>
            <br><br>
            Website: <input type="text" name="website">
            <span class="error"><?php echo $websiteErr;?></span>
            <br><br>
            <label>Comment: <textarea name="comment" rows="5" cols="40"></textarea>
            <br><br>
            Gender:
            <input type="radio" name="gender" value="female">Female
            <input type="radio" name="gender" value="male">Male
            <span class="error">* <?php echo $genderErr;?></span>
            <br><br>
            <input type="submit" name="submit" value="Submit"> 
        </form>
    • Validacija samog sadržaja podataka
      • Provera da li su tu samo slova i razmaci
        • $name = test_input($_POST["name"]);
          if (!preg_match("/^[a-zA-Z ]*$/",$name)) {
              $nameErr = "Only letters and white space allowed"; 
          }
      • Provera da li e-mail adresa ima smislen format
        • $email = test_input($_POST["email"]);
          if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
              $emailErr = "Invalid email format"; 
          }
      • Provera URL adrese
        • $website = test_input($_POST["website"]);
          if (!preg_match("/\b(?:(?:https?|ftp):\/\/|www\.)[-a-z0-9+&@#\/%?=~_|!:,.;]*[-a-z0-9+&@#\/%=~_|]/i",$website)) {
              $websiteErr = "Invalid URL"; 
          }
      • <?php
            $nameErr = $emailErr = $genderErr = $websiteErr = "";
            $name = $email = $gender = $comment = $website = "";
            if ($_SERVER["REQUEST_METHOD"] == "POST") {
                if (empty($_POST["name"])) {
                    $nameErr = "Name is required";
                } else {
                    $name = test_input($_POST["name"]);
                    if (!preg_match("/^[a-zA-Z ]*$/",$name)) {
                        $nameErr = "Only letters and white space allowed"; 
                    }
                }
                if (empty($_POST["email"])) {
                    $emailErr = "Email is required";
                } else {
                    $email = test_input($_POST["email"]);
                    if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
                        $emailErr = "Invalid email format"; 
                    }
                }
                if (empty($_POST["website"])) {
                    $website = "";
                } else {
                    $website = test_input($_POST["website"]);
                    if (!preg_match("/\b(?:(?:https?|ftp):\/\/|www\.)[-a-z0-9+&@#\/%?=~_|!:,.;]*[-a-z0-9+&@#\/%=~_|]/i",$website)) {
                    $websiteErr = "Invalid URL"; 
                    }
                }
                if (empty($_POST["comment"])) {
                    $comment = "";
                } else {
                    $comment = test_input($_POST["comment"]);
                }
                if (empty($_POST["gender"])) {
                    $genderErr = "Gender is required";
                } else {
                    $gender = test_input($_POST["gender"]);
                }
            }
        ?>
    • Čuvanje podataka u poljima da ne bi moralo da se ponovo unose ukoliko postoji neka greška
      • Name: <input type="text" name="name" value="<?php echo $name;?>">
        E-mail: <input type="text" name="email" value="<?php echo $email;?>">
        Website: <input type="text" name="website" value="<?php echo $website;?>">
        Comment: <textarea name="comment" rows="5" cols="40"><?php echo $comment;?></textarea>
        Gender: <input type="radio" name="gender"<?php if (isset($gender) && $gender=="female") echo "checked";?> value="female">Female
        <input type="radio" name="gender"<?php if (isset($gender) && $gender=="male") echo "checked";?> value="male">Male

Višedimenzioni nizovi

  • Višedimenzioni niz sadrži jedan ili više nizova
  • $cars = array (
        array("Volvo",22,18),
        array("BMW",15,13),
        array("Saab",5,2),
        array("Land Rover",17,15)
    );
  • echo $cars[2][0];

Datum i vreme

  • date(format,timestamp) - Datum/vreme servera
    • format - Format vremenskog trenutka
      • d - Dan u mesecu (01 do 31)
      • m - Mesec (01 do 12)
      • Y - Četvorocifrena godina
      • l - Dan u nedelji
      • h - 12-očasovno vreme sa vodećom nulom (01 do 12)
      • i - Minuti sa vodećim nulama (00 do 59)
      • s - Sekunde sa vodećim nulama (00 do 59)
      • a - Malim slovima am ili pm
    • timestamp - Definiše trenutak, podrazumevani je tekući, opcioni parametar
  • mktime(hour,minute,second,month,day,year) - Kreiranje vremenskog trenutka
  • strtotime(time,now) - Pretvara slobodni string sa vremenom u vremenski trenutak
    • time - Vreme ("10:30pm April 15 2014", "tomorrow", "next Saturday", "+3 Months")
    • now - Opcioni vremenski trenutak od koga se računa

Umeranje datoteka - Include/require

  • Kad dođe do greške pri umetanju datoteke require prijavi grešku E_COMPILE_ERROR i zaustavi skript
    • require 'filename';
  • Kada dođe do greške pri umetanju datoteke include prijavi upozorenje E_WARNING i nastavi sa izvršavanjem skripta
    • include 'filename';

Rad sa datotekama

  • readfile('filename') - Čita datoteku i ispisuje je na izlazu, vraća broj pročitanih bajtova
  • fopen('filename', "r") - Otvara/Kreira datoteku u određenom modu (r, w, a, x, r+, w+, a+, x+)
  • fread($myfile,filesize('filename')) - Čita iz otvorene datoteke zadati broj bajtova
  • fclose($myfile) - Zatvara otvorenu datoteku
  • fgets($myfile) - Čita jedan red iz datoteke
  • feof($myfile) - Proverava da li je dostignut EOF (end-of-file)
  • fgetc($myfile) - Čita jedan znak iz datoteke
  • fwrite($myfile, $txt) - Upisuje string u datoteku
  • Otpremanje datoteka
    • <body>
          <form action="upload_file.php" method="post" enctype="multipart/form-data">
              <label for="file">Filename:</label>
              <input type="file" name="file" id="file"><br>
              <input type="submit" name="submit" value="Submit">
          </form>
      </body>
    • <?php
          $allowedExts = array("gif", "jpeg", "jpg", "png");
          $temp = explode(".", $_FILES["file"]["name"]);
          $extension = end($temp);
          if ((($_FILES["file"]["type"] == "image/gif")
              || ($_FILES["file"]["type"] == "image/jpeg")
              || ($_FILES["file"]["type"] == "image/jpg")
              || ($_FILES["file"]["type"] == "image/pjpeg")
              || ($_FILES["file"]["type"] == "image/x-png")
              || ($_FILES["file"]["type"] == "image/png"))
              && ($_FILES["file"]["size"] < 20000)
              && in_array($extension, $allowedExts)) {
                  if ($_FILES["file"]["error"] > 0) {
                      echo "Return Code: " . $_FILES["file"]["error"] . "<br>";
                  } else {
                      echo "Upload: " . $_FILES["file"]["name"] . "<br>";
                      echo "Type: " . $_FILES["file"]["type"] . "<br>";
                      echo "Size: " . ($_FILES["file"]["size"] / 1024) . " kB<br>";
                      echo "Temp file: " . $_FILES["file"]["tmp_name"] . "<br>";
                      if (file_exists("upload/" . $_FILES["file"]["name"])) {
                          echo $_FILES["file"]["name"] . " already exists. ";
                      } else {
                          move_uploaded_file($_FILES["file"]["tmp_name"], "upload/" . $_FILES["file"]["name"]);
                          echo "Stored in: " . "upload/" . $_FILES["file"]["name"];
                      }
              }
          } else {
              echo "Invalid file";
          }
      ?>

Kolačići

  • Kolač (Cookie) je mala datoteka koju server smešta na korisničkom računaru radi identifikacije korisnika.
  • Postavljanje kolačića
    • setcookie(name, value, expire, path, domain);
    • setcookie("user", "Alex Porter", time()+3600);
    • setrawcookie() - Da se izbegne automatsko URLencode-ovanje vrednosti kolačića
  • Čitanje kolačića
    • $_COOKIE["user"]
    • if (isset($_COOKIE["user"]))
          echo "Welcome " . $_COOKIE["user"] . "!<br>";
      else
          echo "Welcome guest!<br>";
  • Brisanje kolačića
    • Postavi mu se vreme isteka na trenutak u prošlosti
    • setcookie("user", "", time()-3600);

Sesije

  • Promenljiva sesije se koristi za čuvanje podataka o jednom korisniku i dostupna je svim stranicama u aplikaciji, tj. na sajtu
  • Radi tako što se kreira jedinstveni ID (UID - unique ID) za svakog korisnika i on se čuva u kolačiću ili se prenosi pomoću URL-a
  • Pokretanje sesije
    • <?php session_start(); ?>
      <html>
          <body>
              . . .
          </body>
      </html>
  • Čuvanje promenljive sesije
    • <?php
          session_start();
          $_SESSION['views']=1;
      ?>
    • <?php
          session_start();
          if(isset($_SESSION['views']))
              $_SESSION['views']=$_SESSION['views']+1;
          else
              $_SESSION['views']=1;
          echo "Views=". $_SESSION['views'];
      ?>
  • Oslobađanje određene promenljive sesije
    • <?php
        session_start();
        if(isset($_SESSION['views']))
          unset($_SESSION['views']);
      ?>
  • Uništavanje sesije
    • <?php
          session_destroy();
      ?>

E-mail

  • mail(to,subject,message,headers,parameters)
    • to - Mejl adrese primaoca
    • subject - Predmet poruke, ne sme sadržati prelom reda (\n)
    • message - Telo poruke, može sadržati i prelome redova (\n), a redovi ne smeju biti duži od 70 znakova
    • headers - Dodatna zaglavlja ("From", "Cc", "Bcc"), razdvajaju se sa CRLF (\r\n), opciono
    • parameters - Dodatni opcioni parametri
  • Nebezbedno slanje mejla
    • <h2>Feedback Form</h2>
      <?php
          if (!isset($_POST["submit"])) {
      ?>
      <form method="post" action="<?php echo $_SERVER["PHP_SELF"];?>">
          From: <input type="text" name="from"><br>
          Subject: <input type="text" name="subject"><br>
          Message: <textarea rows="10" cols="40" name="message"></textarea><br>
          <input type="submit" name="submit" value="Submit Feedback">
      </form>
      <?php 
          } else {
              if (isset($_POST["from"])) {
                  $from = $_POST["from"];
                  $subject = $_POST["subject"];
                  $message = $_POST["message"];
                  $message = wordwrap($message, 70);
                  mail("Ova adresa el. pošte je zaštićena od spambotova. Omogućite JavaScript da biste je videli.",$subject,$message,"From: $from\n");
                  echo "Thank you for sending us feedback";
              }
          }
      ?>
  • Bezbedno slanje mejla
    • <html>
          <body>
              <?php
                  function spamcheck($field) {
                      $field=filter_var($field, FILTER_SANITIZE_EMAIL);
                      if(filter_var($field, FILTER_VALIDATE_EMAIL)) {
                          return TRUE;
                      } else {
                          return FALSE;
                      }
                  }
              ?>
              <h2>Feedback Form</h2>
              <?php
                  if (!isset($_POST["submit"])) {
              ?>
              <form method="post" action="<?php echo $_SERVER["PHP_SELF"];?>">
                  From: <input type="text" name="from"><br>
                  Subject: <input type="text" name="subject"><br>
                  Message: <textarea rows="10" cols="40" name="message"></textarea><br>
                  <input type="submit" name="submit" value="Submit Feedback">
              </form>
              <?php 
                  } else {
                      if (isset($_POST["from"])) {
                          $mailcheck = spamcheck($_POST["from"]);
                          if ($mailcheck==FALSE) {
                              echo "Invalid input";
                          } else {
                              $from = $_POST["from"];
                              $subject = $_POST["subject"];
                              $message = $_POST["message"];
                              $message = wordwrap($message, 70);
                              mail("Ova adresa el. pošte je zaštićena od spambotova. Omogućite JavaScript da biste je videli.",$subject,$message,"From: $from\n");
                              echo "Thank you for sending us feedback";
                          }
                      }
                  }
              ?>
          </body>
      </html>
    • FILTER_SANITIZE_EMAIL uklanja sve znakove iz stringa koji nisu dozvoljeni da se pojave u mejlu
    • FILTER_VALIDATE_EMAIL proverava vrednost kao mejl adresu

Obrada grešaka

  • Jednostavna die() naredba
    • <?php
          if(!file_exists("welcome.txt")) {
              die("File not found");
          } else {
              $file=fopen("welcome.txt","r");
          }
      ?>
  • Kreiranje funkcije za obradu greške je prilično jednostavno
    • error_function(error_level, error_message, error_file, error_line, error_context)
      • error_level - Nivo greške za korisnički definisanu grešku
        • 2 - E_WARNING - Samo upozorenje o grešci koja nije fatalna, skript nastavlja rad
        • 8 - E_NOTICE - Run-time obaveštenje, skript je pronašao nešto što može biti greška, ali ne mora
        • 256 - E_USER_ERROR - Korisnički generisana fatalna greška, nešto kao E_ERROR postavljena od strane korisnika korišćenjem funkcije trigger_error()
        • 512 - E_USER_WARNING - Korisnički generisana greška koja nije fatalna, nešto kao E_WARNING postavljena od strane korisnika korišćenjem funkcije trigger_error()
        • 1024 - E_USER_NOTICE - Korisnički generisano obaveštenje, nešto kao E_NOTICE postavljena od strane korisnika korišćenjem funkcije trigger_error()
        • 4096 - E_RECOVERABLE_ERROR - Uhvatljiva fatalna greška, nešto kao E_ERROR ali koja se može uhvatiti korisnički definisanim hendlerom
        • 8191 - E_ALL - Sve greške i upoozorenja
      • error_message - Poruka o grešci
      • error_file - Ime datoteke gde se desila greška, opciono
      • error_line - Broj reda u kodu gde se desila greška, opciono
      • error_context - Niz koji sadrži sve promenljive i njihove vrednosti koje su postojale u trenutku kada se desila greška, opciono
    • function customError($errno, $errstr) {
          echo "<b>Error:</b> [$errno] $errstr<br>";
          echo "Ending Script";
          die();
      }
  • Podešavanje hendlera za greške
    • Postoji podrazumevani hendler za greške u PHP-u, ali moguće je napraviti i funkciju koja ima prednost nad njim u toku izvršavanja skripta
    • Moguće je napraviti hendler koji se odnosi samo na određenu vrstu grešaka ili na sve
    • set_error_handler("customError", nivo);
      • nivo - Nivo greške, opciono
    • <?php
          function customError($errno, $errstr) {
              echo "<b>Error:</b> [$errno] $errstr";
          }
          set_error_handler("customError");
          . . .
      ?>
  • Okidanje greške
    • trigger_error("customError", nivo);
    • <?php
          $test=2;
          if ($test>1) {
              trigger_error("Value must be 1 or below");
          }
      ?>
    • <?php
          function customError($errno, $errstr) {
              echo "<b>Error:</b> [$errno] $errstr<br>";
              echo "Ending Script";
              die();
          }
          set_error_handler("customError",E_USER_WARNING);
          $test=2;
          if ($test>1) {
              trigger_error("Value must be 1 or below",E_USER_WARNING);
          }
      ?>
  • Beleženje grešaka
    • Funkcija error_log() može da beleži greške u posebnu datoteku ili na udaljenu lokaciju, takođe je moguće poslati informaciju mejlom
    • <?php
          function customError($errno, $errstr) {
              echo "<b>Error:</b> [$errno] $errstr<br>";
              echo "Webmaster has been notified";
              error_log("Error: [$errno] $errstr",1,"Ova adresa el. pošte je zaštićena od spambotova. Omogućite JavaScript da biste je videli.","From:Ova adresa el. pošte je zaštićena od spambotova. Omogućite JavaScript da biste je videli.");
          }
          set_error_handler("customError",E_USER_WARNING);
          $test=2;
          if ($test>1) {
              trigger_error("Value must be 1 or below",E_USER_WARNING);
          }
      ?>

Obrada izuzetaka

  • Izuzeci se koriste za promenu toka izvršavanja skripta u slučaju da se desi određena greška
  • Tok događaja:
    • Sačuva se trenutno stanje
    • Izvršavanje se predaje predefinisanoj (korisničkoj) funkciji za obradu grešaka
    • U zavisnosti od situacije, ta funkcija može da nastavi izvršavanje od sačuvanog stanja, prekine izvršavanje skripta ili da nastavi izvršavanje od nekog drugog mesta u kodu
  • Osnovno korišćenje izuzetaka
    • Da se ne bi desilo da kad se baci izuzetak, a nema koda koji ga hvata i dolazi do fatalne greške i poruke "Uncaught Exception" treba napisati odgovarajući kod:
      • Try - Funkcija koja koristi izuzetak treba da bude u try bloku, pa ako nema izuzetka skript nastavi normalno izvršavanje, a u suprotnom baci se izuzetak
      • Throw - Tako se okida izuzetak, svaki throw mora da ima bar jedan catch
      • Catch - Catch blok preuzima izuzetak i kreira objekat koji sadrži informacije o izuzetku
    • <?php
          function checkNum($number) {
              if($number>1) {
                  throw new Exception("Value must be 1 or below");
             }
              return true;
          }
          try {
              checkNum(2);
              echo 'If you see this, the number is 1 or below';
          }
          catch(Exception $e) {
              echo 'Message: ' .$e->getMessage();
          }
      ?>
  • Kreiranje namenske klase izuzetka
    • Kreiranje namenskog obrađivača greški je jednostavno i svede se na kreiranje specijalne klase sa funkcijama koje se pozivaju u slučaju da se deši izuzetak
    • Ova klasa mora da nasledi klasu Exception
    • <?php
          class customException extends Exception {
              public function errorMessage() {
                  $errorMsg = 'Error on line '.$this->getLine().' in '.$this->getFile().': <b>'.$this->getMessage().'</b> is not a valid E-Mail address';
                  return $errorMsg;
             }
          }
          $email = "Ova adresa el. pošte je zaštićena od spambotova. Omogućite JavaScript da biste je videli.";
          try {
              if(filter_var($email, FILTER_VALIDATE_EMAIL) === FALSE) {
                  throw new customException($email);
              }
          }
          catch (customException $e) {
              echo $e->errorMessage();
          }
      ?>
  • Višestruki izuzeci
    • Moguće je da skript koristi višestruke izuzetke za proveru više uslova
    • Može se koristiti nekoliko if..else blokova, switch ili ugnježdeni višestruki izuzeci koji koriste različite klase izuzetaka i vraćaju različite poruke o greškama
    • <?php
          class customException extends Exception {
              public function errorMessage() {
                  $errorMsg = 'Error on line '.$this->getLine().' in '.$this->getFile().': <b>'.$this->getMessage().'</b> is not a valid E-Mail address';
                  return $errorMsg;
             }
          }
         $email = "Ova adresa el. pošte je zaštićena od spambotova. Omogućite JavaScript da biste je videli.";
         try {
              if(filter_var($email, FILTER_VALIDATE_EMAIL) === FALSE) {
                  throw new customException($email);
             }
              if(strpos($email, "example") !== FALSE) {
                  throw new Exception("$email is an example e-mail");
             }
          }
          catch (customException $e) {
              echo $e->errorMessage();
          }
          catch(Exception $e) {
              echo $e->getMessage();
          }
      ?>
  • Bonovno bacanje izuzetka
    • Moguće je da se ponovo baci greška unutar catch bloka
    • Ovo se koristi npr. kada se želi da se od korisnika sakriju neke sistemske greške i da se prikaže neka drugačija poruka o grešci
    • <?php
          class customException extends Exception {
              public function errorMessage() {
                  $errorMsg = $this->getMessage().' is not a valid E-Mail address.';
                  return $errorMsg;
              }
          }
          $email = "Ova adresa el. pošte je zaštićena od spambotova. Omogućite JavaScript da biste je videli.";
          try {
              try {
                  if(strpos($email, "example") !== FALSE) {
                      throw new Exception($email);
                  }
              }
              catch(Exception $e) {
                  throw new customException($email);
              }
          }
          catch (customException $e) {
              echo $e->errorMessage();
          }
      ?>
  • Podešavanje obrađivača izuzetaka najvišeg nivoa
    • Funkcija set_exception_handler() postavlja korisnički definisanu funkciju za obrađivača svih neuhvaćenih izuzetaka
    • <?php
          function myException($exception) {
              echo "<b>Exception:</b> " . $exception->getMessage();
          }
          set_exception_handler('myException');
          throw new Exception('Uncaught Exception occurred');
      ?>
    • Ovde nema catch bloka već se okida obrađivač izuzetaka najvišeg nivoa
  • Ukratko, ako baciš nešto, treba to i da uhvatiš :)

Filter

  • Filteri se koriste za proveru i filtriranje podataka koji dolaze iz nepouzdanih izvora kao što je korisnički ulaz
  • Svi eksterni podaci treba da budu filtrirani!
  • Šta su eksterni podaci:
    • Podaci uneti u formu
    • Kolačići
    • Podaci web servisa
    • Serverske promenljive
    • Rezultati upita nad bazom podataka
  • Funkcije i filteri
    • filter_var() - Filtrira jednu promenljivu određenim filterom
    • filter_var_array() - Filtrira nekoliko promenljivih istim ili različitim filterima
    • filter_input - Čita jednu ulaznu promenljivu i filtrira je
    • filter_input_array - Čita nekoliko ulaznih promenljivih i filtrira ih istim ili različitim filterima
    • <?php
          $int = 123;
          if(!filter_var($int, FILTER_VALIDATE_INT)) {
              echo("Integer is not valid");
          } else {
              echo("Integer is valid");
          }
      ?>
  • Provera i saniranje
    • Filteri za proveru
      • Koriste se proveru korisnički unetih podataka
      • Striktna formalna pravila (kao provera URL-a ili validiranje mejl adrese)
      • Vraćaju očekivani tip ako je uspešno ili false ako nije uspešno
    • Filteri za saniranje
      • Koriste se da dozvole ili ne dozvole određene znakove u stringu
      • Nemaju pravila o formatu podataka
      • Uvek vraćaju string
  • Opcije i zastavice
    • Koriste se za dodavanje dodatne opcije filtriranja određenim filterima
    • Različiti filteri imaju različite opcije i zastavice
    • Opcije moraju biti smeštene u asocijativni niz sa imenom options
    • Zastavica ne mora biti u nizu
    • <?php
          $var=300;
          $int_options = array(
              "options"=>array(
                  "min_range"=>0,
                  "max_range"=>256
              )
          );
          if(!filter_var($var, FILTER_VALIDATE_INT, $int_options)) {
              echo("Integer is not valid");
          } else {
              echo("Integer is valid");
          }
      ?>
  • Provera unosa
    • Prvo se proveri postoje li uneti podaci u nekom polju na formi
    • Zatim se filtrira uneti podatak korišćenjem funkcije filter_input()
    • <?php
          if(!filter_has_var(INPUT_GET, "email")) {
              echo("Input type does not exist");
          } else {
              if (!filter_input(INPUT_GET, "email", FILTER_VALIDATE_EMAIL)) {
                  echo "E-Mail is not valid";
              } else {
                  echo "E-Mail is valid";
              }
          }
      ?>
  • Saniranje unosa
    • Prvo se proveri postoje li uneti podaci u nekom polju na formi
    • Zatim se sanira uneti podatak korišćenjem funkcije filter_input()
    • <?php
          if(!filter_has_var(INPUT_POST, "url")) {
              echo("Input type does not exist");
          } else {
              $url = filter_input(INPUT_POST, "url", FILTER_SANITIZE_URL);
          }
      ?>
  • Filtriranje više unosa
    • Forma najčešće ima više polja pa da bi se izbeglo višestruko pozivanje funkcija filter_var ili filter_input moguće je korišćenje funkcija filter_var_array ili the filter_input_array
    • <?php
          $filters = array (
              "name" => array (
              "filter"=>FILTER_SANITIZE_STRING
              ),
              "age" => array (
                  "filter"=>FILTER_VALIDATE_INT,
                  "options"=>array (
                      "min_range"=>1,
                      "max_range"=>120
                  )
              ),
              "email"=> FILTER_VALIDATE_EMAIL
          );
          $result = filter_input_array(INPUT_GET, $filters);
          if (!$result["age"]) {
              echo("Age must be a number between 1 and 120.<br>");
          } elseif(!$result["email"]) {
              echo("E-Mail is not valid.<br>");
          } else {
              echo("User input is valid");
          }
      ?>
  • Korišćenje Filter Callback
    • Moguće je da se pozove korisnički definisana funkcija i da se ona iskoristi kao filter korišćenjem filtera FILTER_CALLBACK
    • Moguće je kreirati svoju funkciju ili koristiti neku od postojećih PHP funkcija
    • Ovakva funkcija se definiše na isti način kao i opcije - u asocijativnom nizu sa imenom options
    • <?php
          function convertSpace($string) {
              return str_replace("_", " ", $string);
          }
          $string = "Peter_is_a_great_guy!";
          echo filter_var($string, FILTER_CALLBACK, array("options"=>"convertSpace"));
      ?>

MySQL

  • Konekcija ka MySQL serveru
    • mysqli_connect(host,username,password,dbname) - Otvaranje konekcije
      • host - Ime hosta ili IP adresa, opcioni parametar
      • username - Korisničko ime za MySQL, opcioni parametar
      • password - Šifra za MySQL, opcioni parametar
      • dbname - Podrazumevana baza koja se koristi za upite, opcioni parametar
      • <?php
            $con=mysqli_connect("example.com","peter","abc123","my_db");
            if (mysqli_connect_errno()) {
                echo "Failed to connect to MySQL: " . mysqli_connect_error();
            }
        ?>
    • mysqli_close() - Zatvaranje konekcije, inače može i automatski kad se završava skript
  • CREATE DATABASE - Kreiranje baze podataka i tabela
    • <?php
          $con=mysqli_connect("example.com","peter","abc123");
          if (mysqli_connect_errno()) {
              echo "Failed to connect to MySQL: " . mysqli_connect_error();
          }
          $sql="CREATE DATABASE my_db";
          if (mysqli_query($con,$sql)) {
              echo "Database my_db created successfully";
          } else {
              echo "Error creating database: " . mysqli_error($con);
          }
      ?>
  • CREATE TABLE - Koristi se za kreiranje tabele
    • <?php
          $con=mysqli_connect("example.com","peter","abc123","my_db");
          if (mysqli_connect_errno()) {
              echo "Failed to connect to MySQL: " . mysqli_connect_error();
          }
          $sql="CREATE TABLE Persons(FirstName CHAR(30),LastName CHAR(30),Age INT)";
          if (mysqli_query($con,$sql)) {
              echo "Table persons created successfully";
          } else {
              echo "Error creating table: " . mysqli_error($con);
          }
      ?>
      • Svaka tabela treba da ima definisan primarni ključ
      • AUTO_INCREMENT - Podešava da se vrednost polja automatski poveća za 1 svaki put kada se doda novi zapis
      • NOT NULL - Označava polje koje ne može da ima null vrednost
      • $sql = "CREATE TABLE Persons (
            PID INT NOT NULL AUTO_INCREMENT, 
            PRIMARY KEY(PID),
            FirstName CHAR(15),
            LastName CHAR(15),
            Age INT
        )";
  • INSERT INTO - Umetanje zapisa u tabelu
    • Ima dva oblika:
      • INSERT INTO table_name
        VALUES (value1, value2, value3,...)
      • INSERT INTO table_name (column1, column2, column3,...)
        VALUES (value1, value2, value3,...)
    • Za izvršavanje upita koristi se funkcija mysqli_query()
    • <?php
          $con=mysqli_connect("example.com","peter","abc123","my_db");
          if (mysqli_connect_errno()) {
              echo "Failed to connect to MySQL: " . mysqli_connect_error();
          }
           mysqli_query($con,"INSERT INTO Persons (FirstName, LastName, Age) VALUES ('Peter', 'Griffin',35)");
           mysqli_query($con,"INSERT INTO Persons (FirstName, LastName, Age) VALUES ('Glenn', 'Quagmire',33)");
           mysqli_close($con);
      ?>
    • Umetanje podataka sa forme u bazu podataka
      • <?php
            $con=mysqli_connect("example.com","peter","abc123","my_db");
            if (mysqli_connect_errno()) {
                echo "Failed to connect to MySQL: " . mysqli_connect_error();
            }
            $firstname = mysqli_real_escape_string($con, $_POST['firstname']);
            $lastname = mysqli_real_escape_string($con, $_POST['lastname']);
            $age = mysqli_real_escape_string($con, $_POST['age']);
            $sql="INSERT INTO Persons (FirstName, LastName, Age) VALUES ('$firstname', '$lastname', '$age')";
            if (!mysqli_query($con,$sql)) {
                die('Error: ' . mysqli_error($con));
            }
            echo "1 record added";
            mysqli_close($con);
        ?>
  • SELECT - Selekcija podataka iz tabele
    • SELECT column_name(s)
      FROM table_name
    • Za izvršavanje upita koristi se funkcija mysqli_query()
    • <?php
          $con=mysqli_connect("example.com","peter","abc123","my_db");
          if (mysqli_connect_errno()) {
              echo "Failed to connect to MySQL: " . mysqli_connect_error();
          }
          $result = mysqli_query($con,"SELECT * FROM Persons");
          echo "<table border='1'>
                      <
      tr>
                          <th>Firstname</th>
                          <th>Lastname</th>
                      </tr>";
          while($row = mysqli_fetch_array($result)) {
              echo "<tr>";
              echo "<td>" . $row['FirstName'] . "</td>";
              echo "<td>" . $row['LastName'] . "</td>";
              echo "</tr>";
          }
          echo "</table>";
          mysqli_close($con);
      ?>
  • WHERE - Koristi se za odabir samo onih zapisa koji zadovoljavaju određeni kriterijum
    • SELECT column_name(s)
      FROM table_name
      WHERE column_name operator value
  • ORDER BY - Koristi se za sortiranje selektovanih podataka
    • Po drazumevani redosled je rastući (ASC), a može se navesti i opadajući (DESC)
    • SELECT column_name(s)
      FROM table_name
      ORDER BY column_name(s) ASC|DESC
  • UPDATE - Ažuriranje podataka u tabeli
    • UPDATE table_name
      SET column1=value, column2=value2,...
      WHERE some_column=some_value
    • Za izvršavanje upita koristi se funkcija mysqli_query()
    • <?php
          $con=mysqli_connect("example.com","peter","abc123","my_db");
          if (mysqli_connect_errno()) {
              echo "Failed to connect to MySQL: " . mysqli_connect_error();
          }
          mysqli_query($con,"UPDATE Persons SET Age=36 WHERE FirstName='Peter' AND LastName='Griffin'");
          mysqli_close($con);
      ?>
  • DELETE FROM - Brisanje podataka iz tabele
    • DELETE FROM table_name
      WHERE some_column = some_value
    • Za izvršavanje upita koristi se funkcija mysqli_query()
    • <?php
          $con=mysqli_connect("example.com","peter","abc123","my_db");
          if (mysqli_connect_errno()) {
              echo "Failed to connect to MySQL: " . mysqli_connect_error();
          }
          mysqli_query($con,"DELETE FROM Persons WHERE LastName='Griffin'");
          mysqli_close($con);
      ?>
  • Korišćenje ODBC baze podataka (MS Access)
    • odbc_connect(host,username,password) - Konektovanje nna ODBC izvor podataka
    • odbc_exec() - Izvršavanje SQL naredbe
    • odbc_fetch_row() - Vraća jedan zapis iz grupe selektovanih zapisa
    • odbc_result() - Vraća vrednost određenog polja iz zapisa i to po rednom broju ili imenu polja
    • odbc_close() - Zatvara ODBC konekciju
    • <html>
          <body>
              <?php
                  $conn=odbc_connect('northwind','','');
                  if (!$conn) {
                      exit("Connection Failed: " . $conn);
                  }
                  $sql="SELECT * FROM customers";
                  $rs=odbc_exec($conn,$sql);
                  if (!$rs) {
                      exit("Error in SQL");
                  }
                  echo "<table><tr>";
                  echo "<th>Companyname</th>";
                  echo "<th>Contactname</th></tr>";
                  while (odbc_fetch_row($rs)) {
                      $compname=odbc_result($rs,"CompanyName");
                      $conname=odbc_result($rs,"ContactName");
                      echo "<tr><td>$compname</td>";
                      echo "<td>$conname</td></tr>";
                  }
                  odbc_close($conn);
                  echo "</table>";
              ?>
          </body>
      </html>

XML Expat parser

  • Expat je XML parser ugrađen u PHP i koristi se za kreiranje, čitanje i menjanje XML dokumenta
  • Pošto je deo osnovne PHP konfiguracije nije potrebna nikakva prethodna instalacija da bi se koristio
  • XML se koristi za opis podataka i nema predefinisane tagove, već korisnik definiše svoje
  • Primer XML dokumenta:
    • <?xml version="1.0" encoding="UTF-8"?>
      <note>
          <to>Tove</to>
          <from>Jani</from>
          <heading>Reminder</heading>
          <body>Don't forget me this weekend!</body>
      </note>
  • <?php
        //Inicijalizacija XML parsera
        $parser=xml_parser_create();
         //Funkcija koja se koristi na početku elementa
        function start($parser,$element_name,$element_attrs) {
            switch($element_name) {
                case "NOTE":
                    echo "-- Note --<br>";
                    break;
                case "TO":
                    echo "To: ";
                    break;
                case "FROM":
                    echo "From: ";
                    break;
                case "HEADING":
                    echo "Heading: ";
                    break;
                case "BODY":
                    echo "Message: ";
            }
        }
        //Funkcija koja se koristi na kraju elementa
        function stop($parser,$element_name) {
            echo "<br>";
        }
        //Funkcija koja se korkisti kada se pronađe podatak
        function char($parser,$data) {
            echo $data;
        }
        //Specifikacija obradjivaca elementa
        xml_set_element_handler($parser,"start","stop");
        //Specifikacija obradjivaca podataka
        xml_set_character_data_handler($parser,"char");
        //Otvaranje XML dokumenta
        $fp=fopen("test.xml","r");
        //Citanje podataka
        while ($data=fread($fp,4096)) {
            xml_parse($parser,$data,feof($fp)) or
            die (sprintf("XML Error: %s at line %d", 
            xml_error_string(xml_get_error_code($parser)),
            xml_get_current_line_number($parser)));
        }
        //Oslobadjanje XML parsera
        xml_parser_free($parser);
    ?>

XML DOM parser

  • Pošto je deo osnovne PHP konfiguracije nije potrebna nikakva prethodna instalacija da bi se koristio
  • Učitavanje i ispis XML dokumenta
    • <?php
          $xmlDoc = new DOMDocument();
          $xmlDoc->load("note.xml");
          print $xmlDoc->saveXML();
      ?>
    • Funkcija saveXML() pretvara interni XML dokument u string tako da se može prikazati
  • Prolazak kroz XML dokument
    • <?php
          $xmlDoc = new DOMDocument();
          $xmlDoc->load("note.xml");
          $x = $xmlDoc->documentElement;
          foreach ($x->childNodes AS $item) {
              print $item->nodeName . " = " . $item->nodeValue . "<br>";
          }
      ?>
    • Ovde se često dešava da se prilikom kreiranja XML dokumenta ubacuju prazni elementi što pri ovakvom prolasku treba imati u vidu

SimpleXML

  • Pošto je deo osnovne PHP konfiguracije nije potrebna nikakva prethodna instalacija da bi se koristio
  • Jednostavniji je za korišćenje od Expat i DOM parsera, ali nije za naprednije XML strukture
  • Ispis XML dokumenta
    • <?php
          $xml=simplexml_load_file("note.xml");
          print_r($xml);
      ?>
    • <?php
          $xml=simplexml_load_file("note.xml");
          echo $xml->to . "<br>";
          echo $xml->from . "<br>";
          echo $xml->heading . "<br>";
          echo $xml->body;
      ?>
    • <?php
          $xml=simplexml_load_file("note.xml");
          echo $xml->getName() . "<br>";
          foreach($xml->children() as $child) {
              echo $child->getName() . ": " . $child . "<br>";
          }
      ?>

AJAX

  • AJAX = Asynchronous JavaScript and XML
  • AJAX omogućava da se osveži deo web stranice tako što stranica u pozadini sa serverom razmeni malu količinu podataka
  • Kako AJAX radi?

AJAX

  • AJAX koristi kombinaciju sledećih standarda:
    • Objekt XMLHttpRequest za asinhronu razmenu podataka sa serverom
    • JavaScript/DOM za prikazivanje/interakciju sa podacima
    • CSS za oblikovanje podataka
    • XML se često koristi za format podataka koji se prenose
  • AJAX i PHP - primer
    • HTML dokument za primer
      • <html>
            <head>
                <script>
                    function showHint(str) {
                        if (str.length==0) { 
                            document.getElementById("txtHint").innerHTML="";
                            return;
                        }
                        var xmlhttp=new XMLHttpRequest();
                        xmlhttp.onreadystatechange=function() {
                            if (xmlhttp.readyState==4 && xmlhttp.status==200) {
                                document.getElementById("txtHint").innerHTML=xmlhttp.responseText;
                            }
                        }
                        xmlhttp.open("GET","gethint.php?q="+str,true);
                        xmlhttp.send();
                    }
                </script>
            </head>
            <body>
                <p><b>Start typing a name in the input field below:</b></p>
                <form> 
                    First name: <input type="text" onkeyup="showHint(this.value)">
                </form>
                <p>Suggestions: <span id="txtHint"></span></p>
            </body>
        </html>
      • Ako je input polje prazno (str.length==0) showHint() funkcija briše sadržaj txtHint elementa i završava rad
      • Ako input polje nije prazno showHint() radi sledeće:
        • Kreira XMLHttpRequest objekat
        • Kreira funkciju koja će se izvršiti kad odgovor servera bude spreman
        • šalje zahtev dokumentu na serveru
        • Parametar q je dodat URL-u zajedno sa sadržajem input polja
    • PHP dokument za primer
      • <?php
            $a[]="Natasa";
            $a[]="Sofija";
            $a[]="Sladjana";
            $a[]="Maja";
            $a[]="Miljana";
            $a[]="Jovana";
            $a[]="Aleksandra";
            $a[]="Olivera";
            $a[]="Valentina";
            $a[]="Luka";
            $a[]="Zeljko";
            $a[]="Mirko";
            $a[]="Nikola";
            $a[]="Nenad";
            $a[]="Svetislav";
            $a[]="Nemanja";
            $a[]="Stefan";
            $a[]="Sasa";
            $a[]="Mihajlo";
            $a[]="Filip";
            $a[]="Miladin";
            $q=$_REQUEST["q"]; $hint="";
            if ($q !== "") {
                $q=strtolower($q); $len=strlen($q);
                foreach($a as $name) {
                    if (stristr($q, substr($name,0,$len))) {
                        if ($hint==="") {
                            $hint=$name;
                        } else {
                            $hint .= ", $name";
                        }
                    }
                }
            }
            echo $hint==="" ? "no suggestion" : $hint;
        ?>
  • AJAX i MySQL baza podataka - primer
    • HTML dokument za primer
      • <html>
            <head>
                <script>
                    function showUser(str) {
                        if (str=="") {
                            document.getElementById("txtHint").innerHTML="";
                            return;
                        }
                        if (window.XMLHttpRequest) {
                            xmlhttp=new XMLHttpRequest();
                        } else {
                            xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
                        }
                        xmlhttp.onreadystatechange=function() {
                            if (xmlhttp.readyState==4 && xmlhttp.status==200) {
                                document.getElementById("txtHint").innerHTML=xmlhttp.responseText;
                            }
                        }
                        xmlhttp.open("GET","getuser.php?q="+str,true);
                        xmlhttp.send();
                    }
                </script>
            </head>
            <body>
                <form>
                    <select name="users" onchange="showUser(this.value)">
                        <option value="">Select a person:</option>
                        <option value="1">Peter Griffin</option>
                        <option value="2">Lois Griffin</option>
                        <option value="3">Joseph Swanson</option>
                        <option value="4">Glenn Quagmire</option>
                    </select>
                </form>
                <br>
                <div id="txtHint"><b>Person info will be listed here.</b></div>
            </body>
        </html>
      • Funkcija showUser() radi sledeće:
        • Proverava da li je odabrana osoba
        • Kreira XMLHttpRequest objekat
        • Kreira funkciju koja će se izvršiti kad bude spreman odgovor od servera
        • Šalje zahtev datoteci na serveru
        • Parametar q je dodat URL-u zajedno sa sadržajem padajuće liste
    • PHP dokument za primer
      • <?php
            $q = intval($_GET['q']);
            $con = mysqli_connect('localhost','peter','abc123','my_db');
            if (!$con) {
                die('Could not connect: ' . mysqli_error($con));
            }
            mysqli_select_db($con,"ajax_demo");
            $sql="SELECT * FROM user WHERE id = '".$q."'";
            $result = mysqli_query($con,$sql);
            echo "<table border='1'>
                <tr>
                    <th>Firstname</th>
                    <th>Lastname</th>
                    <th>Age</th>
                    <th>Hometown</th>
                    <th>Job</th>
                </tr>";
            while($row = mysqli_fetch_array($result)) {
                echo "<tr>";
                echo "<td>" . $row['FirstName'] . "</td>";
                echo "<td>" . $row['LastName'] . "</td>";
                echo "<td>" . $row['Age'] . "</td>";
                echo "<td>" . $row['Hometown'] . "</td>";
                echo "<td>" . $row['Job'] . "</td>";
                echo "</tr>";
            }
            echo "</table>";
            mysqli_close($con);
        ?>
      • Kada se pošalje upit iz JavaScript-a PHP datoteci desi se sledeće:
        • PHP otvori konekciju ka MySQL serveru
        • Tražena osoba se pronađe
        • Kreira se HTML tabela, popuni se podacima i pošalje nazad u txtHint element
  • AJAX i XML - primer
    • HTML dokument za primer
      • <html>
            <head>
                <script>
                    function showCD(str) {
                        if (str=="") {
                            document.getElementById("txtHint").innerHTML="";
                            return;
                        }
                        if (window.XMLHttpRequest) {
                            xmlhttp=new XMLHttpRequest();
                        } else {
                            xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
                        }
                        xmlhttp.onreadystatechange=function() {
                            if (xmlhttp.readyState==4 && xmlhttp.status==200) {
                                document.getElementById("txtHint").innerHTML=xmlhttp.responseText;
                            }
                        }
                        xmlhttp.open("GET","getcd.php?q="+str,true);
                        xmlhttp.send();
                    }
                </script>
            </head>
            <body>
                <form>
                    Select a CD:
                        <select name="cds" onchange="showCD(this.value)">
                            <option value="">Select a CD:</option>
                            <option value="Bob Dylan">Bob Dylan</option>
                            <option value="Bonnie Tyler">Bonnie Tyler</option>
                            <option value="Dolly Parton">Dolly Parton</option>
                        </select>
                </form>
                <div id="txtHint"><b>CD info will be listed here...</b></div>
            </body>
        </html>
      • Funkcija showCD() radi sledeće:
        • Proveri da li je odabran CD
        • Kreira XMLHttpRequest objekat
        • Kreira funkciju koja će se izvršiti kad bude spreman odgovor od servera
        • Šalje zahtev datoteci na serveru
        • Parametar q je dodat URL-u zajedno sa sadržajem padajuće liste
    • PHP dokument za primer
      • <?php
        $q=$_GET["q"];

        $xmlDoc = new DOMDocument();
        $xmlDoc->load("cd_catalog.xml");

        $x=$xmlDoc->getElementsByTagName('ARTIST');

        for ($i=0; $i<=$x->length-1; $i++) {
          //Process only element nodes
          if ($x->item($i)->nodeType==1) {
            if ($x->item($i)->childNodes->item(0)->nodeValue == $q) {
              $y=($x->item($i)->parentNode);
            }
          }
        }

        $cd=($y->childNodes);

        for ($i=0;$i<$cd->length;$i++) { 
          //Process only element nodes
          if ($cd->item($i)->nodeType==1) {
            echo("<b>" . $cd->item($i)->nodeName . ":</b> ");
            echo($cd->item($i)->childNodes->item(0)->nodeValue);
            echo("<br>");
          }
        }
        ?>
      • Kada se pošalje CD upit iz JavaScript-a PHP datoteci desi se sledeće:
        • PHP kreira XML DOM objekat
        • Pronađu se svi <artist> elementi koji imaju ime poslato iz JavaScript-a
        • Prikažu se informacije o albumu tako što se smeste u txtHint element
  • AJAX živa pretraga - primer
    • HTML dokument za primer
      • <html>
            <head>
                <script>
                    function showResult(str) {
                        if (str.length==0) { 
                            document.getElementById("livesearch").innerHTML="";
                            document.getElementById("livesearch").style.border="0px";
                            return;
                        }
                        if (window.XMLHttpRequest) {
                            xmlhttp=new XMLHttpRequest();
                        } else {
                            xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
                        }
                        xmlhttp.onreadystatechange=function() {
                            if (xmlhttp.readyState==4 && xmlhttp.status==200) {
                                document.getElementById("livesearch").innerHTML=xmlhttp.responseText;
                                document.getElementById("livesearch").style.border="1px solid #A5ACB2";
                            }
                        }
                        xmlhttp.open("GET","livesearch.php?q="+str,true);
                        xmlhttp.send();
                    }
                </script>
            </head>
            <body>
                <form>
                    <input type="text" size="30" onkeyup="showResult(this.value)">
                    <div id="livesearch"></div>
                </form>
            </body>
        </html>
      • Ako je input polje prazno (str.length==0) showHint() funkcija briše sadržaj livesearch elementa i završava rad
      • Ako input polje nije prazno showHint() radi sledeće:
        • Kreira XMLHttpRequest objekat
        • Kreira funkciju koja će se izvršiti kad odgovor servera bude spreman
        • šalje zahtev dokumentu na serveru
        • Parametar q je dodat URL-u zajedno sa sadržajem input polja
    • PHP dokument za primer
      • <?php
            $xmlDoc=new DOMDocument();
            $xmlDoc->load("links.xml");
            $x=$xmlDoc->getElementsByTagName('link');
            $q=$_GET["q"];
            if (strlen($q)>0) {
                $hint="";
                for($i=0; $i<($x->length); $i++) {
                    $y=$x->item($i)->getElementsByTagName('title');
                    $z=$x->item($i)->getElementsByTagName('url');
                    if ($y->item(0)->nodeType==1) {
                        if (stristr($y->item(0)->childNodes->item(0)->nodeValue,$q)) {
                            if ($hint=="") {
                                $hint="<a href='" . 
                                $z->item(0)->childNodes->item(0)->nodeValue . "' target='_blank'>" . 
                                $y->item(0)->childNodes->item(0)->nodeValue . "</a>";
                            } else {
                                $hint=$hint . "<br /><a href='" . 
                                $z->item(0)->childNodes->item(0)->nodeValue .  "' target='_blank'>" . $y->item(0)->childNodes->item(0)->nodeValue . "</a>";
                            }
                        }
                    }
                }
            }
            if ($hint=="") {
                $response="no suggestion";
            } else {
                $response=$hint;
            }
            echo $response;
        ?>
      • Ukoliko postoji tekst koji je poslat iz JavaScript-a (strlen($q) > 0) dešava se sledeće:
        • Učitava se XML datoteka u novi XML DOM objekat
        • Prolazi se kroz sve <title> elemente da bi se pronašli pogoci prema tekstu poslatom iz JavaScript-a
        • Postavlja se ispravan url i title promenljivoj $response, ako je pronađeno više od jednog pogotka svi se dodaju promenljivoj
        • Ako nema pogodaka, promenljiva $response se postavlja na "no suggestion"
  • AJAX RSS čitač - primer
    • HTML dokument za primer
      • <html>
            <head>
                <script>
                    function showRSS(str) {
                        if (str.length==0) { 
                            document.getElementById("rssOutput").innerHTML="";
                            return;
                        }
                        if (window.XMLHttpRequest) {
                            xmlhttp=new XMLHttpRequest();
                        } else {
                            xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
                        }
                        xmlhttp.onreadystatechange=function() {
                            if (xmlhttp.readyState==4 && xmlhttp.status==200) {
                                document.getElementById("rssOutput").innerHTML=xmlhttp.responseText;
                            }
                        }
                        xmlhttp.open("GET","getrss.php?q="+str,true);
                        xmlhttp.send();
                    }
                </script>
            </head>
            <body>
                <form>
                    <select onchange="showRSS(this.value)">
                        <option value="">Select an RSS-feed:</option>
                        <option value="Google">Google News</option>
                        <option value="NBC">NBC News</option>
                    </select>
                </form>
                <br>
                <div id="rssOutput">RSS-feed will be listed here...</div>
            </body>
        </html>
      • Funkcija showCD() radi sledeće:
        • Proveri da li je odabran CD
        • Kreira XMLHttpRequest objekat
        • Kreira funkciju koja će se izvršiti kad bude spreman odgovor od servera
        • Šalje zahtev datoteci na serveru
        • Parametar q je dodat URL-u zajedno sa sadržajem padajuće liste
    • PHP dokument za primer
      • <?php
            $q=$_GET["q"];
            if($q=="Google") {
                $xml=("http://news.google.com/news?ned=us&topic=h&output=rss");
            } elseif($q=="NBC") {
                $xml=("http://rss.msnbc.msn.com/id/3032091/device/rss/rss.xml");
            }
            $xmlDoc = new DOMDocument();
            $xmlDoc->load($xml);
            $channel=$xmlDoc->getElementsByTagName('channel')->item(0);
            $channel_title = $channel->getElementsByTagName('title')->item(0)->childNodes->item(0)->nodeValue;
            $channel_link = $channel->getElementsByTagName('link')->item(0)->childNodes->item(0)->nodeValue;
            $channel_desc = $channel->getElementsByTagName('description')->item(0)->childNodes->item(0)->nodeValue;     echo("<p><a href='" . $channel_link  . "'>" . $channel_title . "</a>");
            echo("<br>");
            echo($channel_desc . "</p>");
            $x=$xmlDoc->getElementsByTagName('item');
            for ($i=0; $i<=2; $i++) {
                $item_title=$x->item($i)->getElementsByTagName('title')->item(0)->childNodes->item(0)->nodeValue;
                $item_link=$x->item($i)->getElementsByTagName('link')->item(0)->childNodes->item(0)->nodeValue;
                $item_desc=$x->item($i)->getElementsByTagName('description')->item(0)->childNodes->item(0)->nodeValue;
                echo ("<p><a href='" . $item_link . "'>" . $item_title . "</a>");
                echo ("<br>");
                echo ($item_desc . "</p>");
            }
        ?>
      • Kada se pošalje zahtev za RSS feed iz JavaScript-a dešava se sledeće:
        • Proveri se koji feed je selektovan
        • Kreira se novi XML DOM objekat
        • Učita se RSS dokument u xml promenljivu
        • Izvade se i prikažu elementi liste kanala
        • Izvade se i prikažu elementi liste stavki
  • AJAX anketa
    • HTML dokument za primer
      • <html>
            <head>
                <script>
                    function getVote(int) {
                        if (window.XMLHttpRequest) {
                            xmlhttp=new XMLHttpRequest();
                        } else {
                            xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
                        }
                        xmlhttp.onreadystatechange=function() {
                            if (xmlhttp.readyState==4 && xmlhttp.status==200) {
                                document.getElementById("poll").innerHTML=xmlhttp.responseText;
                            }
                        }
                        xmlhttp.open("GET","poll_vote.php?vote="+int,true);
                        xmlhttp.send();
                    }
                </script>
            </head>
            <body>
                <div id="poll">
                    <h3>Do you like PHP and AJAX so far?</h3>
                    <form>
                        Yes:
                        <input type="radio" name="vote" value="0" onclick="getVote(this.value)">
                        <br>No:
                        <input type="radio" name="vote" value="1" onclick="getVote(this.value)">
                    </form>
                </div>
             </body>
        </html>
      • Funkcija getVote() radi sledeće:
        • Kreira XMLHttpRequest objekat
        • Kreira funkciju koja će se izvršiti kad bude spreman odgovor od servera
        • Šalje zahtev datoteci na serveru
        • Parametar vote je dodat URL-u zajedno sa vrednošću opcije yes ili opcije no
    • PHP dokument za primer
      • <?php
            $vote = $_REQUEST['vote'];
            $filename = "poll_result.txt";
            $content = file($filename);
            $array = explode("||", $content[0]);
            $yes = $array[0];
            $no = $array[1];
            if ($vote == 0) {
                $yes = $yes + 1;
            }
            if ($vote == 1) {
                $no = $no + 1;
            }
            $insertvote = $yes."||".$no;
            $fp = fopen($filename,"w");
            fputs($fp,$insertvote);
            fclose($fp);
        ?>
        <h2>Result:</h2>
        <table>
            <tr>
                <td>Yes:</td>
                <td>
                    <img src="/poll.gif" width='<?php echo(100*round($yes/($no+$yes),2)); ?>'
        height='20'> <?php echo(100*round($yes/($no+$yes),2)); ?>%
                </td>
            </tr>
            <tr>
                <td>No:</td>
                <td>
                    <img src="/poll.gif" width='<?php echo(100*round($no/($no+$yes),2)); ?>' height='20'> <?php echo(100*round($no/($no+$yes),2)); ?>%
                </td>
            </tr>
        </table>
      • Kada se pošalje vrednost iz JavaScript-a dešava se sledeće:
        • Pokupi se sadržaj datoteke poll_result.txt
        • Sadržaj datoteke se smesti u promenljivu i doda se jedan odabranoj promenljivoj
        • Upiše se rezultat u datoteku poll_result.txt
        • Ispiše se grafički prikaz rezultata ankete
      • Tekstualna datoteka poll_result.txt izgleda ovako - 0||0 gde je prvi broj broj Yes glasova, a drugi No glasova

 

Vi ste ovde: Home Predavanja Četvrta godina Informatički smer - Web dizajn 05 - Osnove PHP-a