poglavlje 1 znakovni nizovi - mikro knjigamikroknjiga.rs/knjige/phpk/01_phpk.pdf · 2008. 2....

35
1 Poglavlje 1Poglavàe 1 POGLAVLJE 1 Znakovni nizovi 1.0 Uvod U PHP-u, znakovni nizovi (engl. strings) jesu nizovi bajtova – na primer, “Oåe naã” ili “Æivàaãe jednom u nekoj zemài” ili åak “111211211”. Podaci koje åitate iz datote- ke ili ãaàete åitaåu Weba predstavàeni su u obliku znakovnih nizova. PHP-ovi znakovni nizovi su binarno bezbedni (tj. mogu da sadræe null bajtove) i ãire se i skupàaju po potrebi. Njihova veliåina je ograniåena samo koliåinom memorije koja je PHP-u stavàena na raspolagaçe. PHP-ovi znakovni nizovi najåeãñe su ASCII znakovni nizovi. Ne-ASCII znak- ovne nizove, recimo one kodirane po UTF-8 ili drugim viãebajtnim ãemama za kodiraçe, morate drugaåije da tretirate; videti poglavàe 19. PHP-ovi znakovni nizovi su po obliku i ponaãaçu sliåni onima u Perlu i Unixovim komandnim okruæeçima. Moæete ih inicijalizovati na tri naåina: tako ãto ñete ih sta- viti u polunavodnike, navodnike, ili upotrebiti heredoc sintaksu. U znakovnim nizo- vima zatvorenim u polunavodnike, jedini posebni znakovi koje morate da pretvorite u izlazne sekvence (engl. escape sequences) jesu obrnuta kosa crta i sam polunavod- nik. U primeru 1-1 prikazana su åetiri znakovna niza navedena u polunavodnicima. Primer 1-1. Znakovni nizovi u polunavodnicima print 'I have gone to the store.'; print 'I\'ve gone to the store.'; print 'Would you pay $1.75 for 8 ounces of tap water?'; print 'In double-quoted strings, newline is represented by \n'; Kada se izvrãi kôd iz primera 1-1, odãtampañe se sledeñe: I have gone to the store. I've gone to the store. Would you pay $1.75 for 8 ounces of tap water? In double-quoted strings, newline is represented by \n

Upload: others

Post on 27-Jan-2021

4 views

Category:

Documents


0 download

TRANSCRIPT

  • 1

    Poglavlje 1Poglavàe 1

    POGLAVLJE 1

    Znakovni nizovi

    1.0 Uvod

    U PHP-u, znakovni nizovi (engl.

    strings

    ) jesu nizovi bajtova – na primer, “Oåe naã”ili “Æivàaãe jednom u nekoj zemài” ili åak “111211211”. Podaci koje åitate iz datote-ke ili ãaàete åitaåu Weba predstavàeni su u obliku znakovnih nizova.

    PHP-ovi znakovni nizovi su binarno bezbedni (tj. mogu da sadræe null bajtove) i ãirese i skupàaju po potrebi. Njihova veliåina je ograniåena samo koliåinom memorijekoja je PHP-u stavàena na raspolagaçe.

    PHP-ovi znakovni nizovi najåeãñe su ASCII znakovni nizovi. Ne-ASCII znak-ovne nizove, recimo one kodirane po UTF-8 ili drugim viãebajtnim ãemamaza kodiraçe, morate drugaåije da tretirate; videti poglavàe 19.

    PHP-ovi znakovni nizovi su po obliku i ponaãaçu sliåni onima u Perlu i Unixovimkomandnim okruæeçima. Moæete ih inicijalizovati na tri naåina: tako ãto ñete ih sta-viti u polunavodnike, navodnike, ili upotrebiti

    heredoc

    sintaksu. U znakovnim nizo-vima zatvorenim u polunavodnike, jedini posebni znakovi koje morate da pretvoriteu izlazne sekvence (engl.

    escape sequences

    ) jesu obrnuta kosa crta i sam polunavod-nik. U primeru 1-1 prikazana su åetiri znakovna niza navedena u polunavodnicima.

    Primer 1-1

    .

    Znakovni nizovi u polunavodnicima

    print 'I have gone to the store.';print 'I\'ve gone to the store.';print 'Would you pay $1.75 for 8 ounces of tap water?';print 'In double-quoted strings, newline is represented by \n';

    Kada se izvrãi kôd iz primera 1-1, odãtampañe se sledeñe:

    I have gone to the store.I've gone to the store.Would you pay $1.75 for 8 ounces of tap water?In double-quoted strings, newline is represented by \n

  • 2 | Poglavlje 1: Znakovni nizovi

    Poãto PHP ne proverava postoje li u znakovnim nizovima navedenim u polunavod-nicima interpolirane promenàive i izlazne sekvence (osim nekih), znakovni nizovi sena taj naåin definiãu jednostavno i brzo.

    U znakovnim nizovima datim izmeœu navodnika ne prepoznaju se polunavodnicipretvoreni u izlazne sekvence, ali se prepoznaju interpolirane promenàive i izlaznesekvence navedene u tabeli 1-1.

    U primeru 1-2 prikazano je nekoliko znakovnih nizova definisanih stavljanjem iz-meœu navodnika.

    Primer 1-2. Znakovni nizovi izmeœu navodnika

    print "I've gone to the store.";print "The sauce cost \$10.25.";$cost = '$10.25';print "The sauce cost $cost.";print "The sauce cost \$\061\060.\x32\x35.";

    Kada se izvrãi kôd iz primera 1-2, odãtampañe se sledeñe:

    I've gone to the store.The sauce cost $10.25.The sauce cost $10.25.The sauce cost $10.25.

    Posledçi red primera 1-2 ispravno ãtampa cenu umaka (engl.

    sauce cost

    ) zato ãto je uASCII tabeli kôd znaka 1 decimalno 49 odnosno oktalno 061. Kôd znaka 0 u ASCIItabeli je decimalno 48 odnosno oktalno 060; kôd znaka 2 u ASCII tabeli je decimal-no 50 odnosno heksadecimalno 32; kôd znaka 5 u ASCII tabeli je decimalno 53 od-nosno heksadecimalno 35.

    Dokumenti definisani pomoñu

    heredoc

    sintakse prepoznaju sve interpolacije i izlaznesekvence znakovnih nizova zatvorenih u navodnike (tabela 1-1), ali nije potrebno dase sami navodnici pretvore u izlazne sekvence. Dokumenti definisani pomoñu

    heredoc

    sintakse poåiçu simbolom

  • 1.0 Uvod | 3

    Primer 1-3. Definisaçe dokumenta pomoñu heredoc sintakse

    print

  • 4 | Poglavlje 1: Znakovni nizovi

    U primeru 1-5, znak taåka i zarez (;) iza zavrãne oznake (HTML) kazuje PHP-u da jedoãao do kraja naredbe. Meœutim, u nekim sluåajevima znak taåka i zarez ne trebapisati. Jedan od tih sluåajeva prikazan je u primeru 1-6, gde se u dokumentu defi-nisanom pomoñu

    heredoc

    sintakse upotrebàava operator nadovezivaça znakovnihnizova (engl.

    concatenation operator

    ).

    Primer 1-6. Nadovezivaçe znakovnih nizova u dokumentu definisanom pomoñu heredoc sintakse

    $html =

  • 1.2 Izdvajaçe podnizova | 5

    1.1 Pristupaçe podnizovima

    Problem

    Æelite da utvrdite da li znakovni niz sadræi odreœeni podniz. Primera radi, æelite dautvrdite da li adresa e-poãte sadræi znak

    @

    .

    Reãeçe

    Upotrebite funkciju

    strpos()

    , kao u primeru 1-8.

    Primer 1-8. Pronalaæeçe podniza funkcijom strpos()

    Objaãnjenje

    Povratna vrednost funkcije

    strpos()

    jeste indeks prve pojave podniza (“igle”) u nizu(“plastu sena”). Ukoliko

    strpos()

    uopãte ne naœe iglu u plastu sena, vratiñe

    false

    .Ako je igla na poåetku plasta sena,

    strpos()

    ñe vratiti 0, poãto indeks 0 predstavàapoåetak (prvi znak) znakovnog niza. Da biste razlikovali povratne vrednosti 0 i

    false

    ,morate upotrebiti operator identiteta

    (===)

    ili neidentiteta

    (!==)

    umesto obiånogoperatora jednakosti

    (==)

    ili nejednakosti

    (!=)

    . U primeru 1-8, operatorom

    ===

    utvr-diñemo da li funkcija

    strpos()

    vraña vrednost

    false

    . Ta provera ñe uspeti samo akostrpos vrati

    false

    , a ne ako vrati 0 ili bilo koji drugi broj.

    Videti i

    Dokumentaciju funkcije

    strpos()

    na adresi

    http://www.php.net/strpos

    .

    1.2 Izdvajaçe podnizova

    Problem

    Iz znakovnog niza hoñete da izdvojite jedan çegov deo, poåev od odreœenog mesta unizu. Na primer, izdvojili biste prvih osam znakova korisniåkog imena upisanog uobrazac.

    Reãeçe

    Za izdvajanje podniza upotrebite funkciju

    substr()

    , kao u primeru 1-9.

  • 6 | Poglavlje 1: Znakovni nizovi

    Primer 1-9. Izdvajaçe podniza funkcijom substr()

    Objaãnjenje

    Ako su vrednosti parametara

    $start

    i

    $length

    pozitivne,

    substr()

    ñe iz znakovnogniza izvaditi

    $length

    znakova, poåev od znaka åiji je indeks

    $start

    . Prvi znak znakov-nog niza ima indeks 0. U primeru 1-10, parametri

    $start

    i

    $length

    su pozitivni.

    Primer 1-10. Upotreba funkcije substr() s pozitivnim parametrima $start i $length

    print substr('watch out for that tree',6,5);

    Primer 1-10 ñe ispisati:

    out f

    Ako izostavite parametar $length, substr() ñe kao rezultat vratiti podniz od indeksa$start do kraja prvobitnog znakovnog niza, kao u primeru 1-11.

    Primer 1-11. Upotreba funkcije substr() s pozitivnim parametrom $start i bez parametra $lengthprint substr('watch out for that tree',17);

    Primer 1-11 ñe ispisati:

    t tree

    Ukoliko je vrednost parametra $start veña od duæine znakovnog niza, substr()vraña false.

    Ako zbir vrednosti parametara $start i $length premaãuje duæinu znakovnog niza,funkcija substr() vraña ceo podniz od indeksa $start do kraja niza, kao u primeru1-12.

    Primer 1-12. Upotreba funkcije substr() kada duæina podniza premaãuje kraj znakovnog nizaprint substr('watch out for that tree',20,5);

    Primer 1-12 ñe ispisati:

    ree

    Ukoliko je parametar $start negativan, substr() broji unazad od kraja znakovnogniza i tako utvrœuje poåetak podniza koji treba izdvojiti, kao u primeru 1-13.

    Primer 1-13. Upotreba funkcije substr() uz negativnu vrednost parametra $startprint substr('watch out for that tree',-6);print substr('watch out for that tree',-17,5);

  • 1.3 Zamena podnizova | 7

    Rezultat izvrãavanja primera 1-13 biñe

    t tree out f

    Ukoliko negativna vrednost parametra $start premaãuje poåetak znakovnog niza(recimo, kada $start iznosi -27, a duæina znakovnog niza je 20), substr() se ponaãakao da je $start jednak 0.

    U sluåaju da je vrednost parametra $length negativna, substr() broji unazad od kra-ja znakovnog niza i tako utvrœuje znak kojim se zavrãava podniz koji treba izvaditi,kao u primeru 1-14.

    Primer 1-14. Upotreba funkcije substr() uz negativnu vrednost parametra $lengthprint substr('watch out for that tree',15,-2);print substr('watch out for that tree',-4,-1);

    Primer 1-14 ñe ispisati:

    hat tr tre

    Videti iDokumentaciju funkcije substr() na adresi http://www.php.net/substr.

    1.3 Zamena podnizova

    ProblemJedan podniz æelite da zamenite drugim. Primera radi, pre ãtampaça hoñete da sa-krijete sve cifre broja kreditne kartice sem posledçe åetiri.

    ReãeçeUpotrebite funkciju substr_replace( ), kao u primeru 1-15.

    Primer 1-15. Zamena podniza pomoñu funkcije substr_replace()// Sve od indeksa $start do kraja znakovnog niza $old_string// postaje $new_substring$new_string = substr_replace($old_string,$new_substring,$start);

    // $length znakova, poåev od indeksa $start, postaje znakovni niz $new_substring$new_string = substr_replace($old_string,$new_substring,$start,$length);

    ObjaãnjenjeKada ne dobije argument $length, funkcija substr_replace() zameçuje sve, poåevod indeksa $start do kraja znakovnog niza. Kada je parametar $length specificiran,zameçuje se samo zadati broj znakova:

  • 8 | Poglavlje 1: Znakovni nizovi

    print substr_replace('My pet is a blue dog.','fish.',12);print substr_replace('My pet is a blue dog.','green',12,4);$credit_card = '4111 1111 1111 1111';print substr_replace($credit_card,'xxxx ',0,strlen($credit_card)-4);

    My pet is a fish.My pet is a green dog.xxxx 1111

    Ako je vrednost parametra $start negativna, novi podniz biñe smeãten $start zna-kova od kraja znakovnog niza $old_string, a ne od çegovog poåetka:

    print substr_replace('My pet is a blue dog.','fish.',-9);print substr_replace('My pet is a blue dog.','green',-9,4);

    My pet is a fish.My pet is a green dog.

    Ako su $start i $length jednaki 0, novi podniz biñe umetnut na poåetak znakovnogniza $old_string:

    print substr_replace('My pet is a blue dog.','Title: ',0,0);

    Title: My pet is a blue dog.

    Funkcija substr_replace() podesna je kada je tekst predug da bi se sav prikazao od-jednom, pa æelite da prikaæete samo deo teksta i vezu ka ostatku. Primer 1-16 prika-zuje prvih 25 znakova poruke i tri taåke, kao vezu ka stranici koja prikazuje ostatakteksta.

    Primer 1-16. Prikazivaçe dugaåkog teksta pomoñu znaka tri taåke$r = mysql_query("SELECT id,message FROM messages WHERE id = $id") or die();$ob = mysql_fetch_object($r);printf('%s', $ob->id, substr_replace($ob->message,' ...',25));

    U primeru 1-16 referencirana je stranica more-text.php, koja preuzima i prikazuje celuporuku åiji je ID (identifikator) prosleœen u znakovnom nizu upita (engl. query).

    Videti iDokumentaciju funkcije substr_replace() na adresi http://www.php.net/substr--replace.

    1.4 Pojedinaåna obrada svakog znaka (bajta) znakovnog niza

    ProblemSvaki bajt (znak) znakovnog niza morate da obradite pojedinaåno.

  • 1.4 Pojedinaåna obrada svakog znaka (bajta) znakovnog niza | 9

    ReãeçePetàom for pojedinaåno izdvojte svaki znak (bajt) znakovnog niza. U primeru 1-17prebrojañemo samoglasnike znakovnog niza funkcijom strstr().

    Primer 1-17. Obrada svakog bajta znakovnog niza pojedinaåno

  • 10 | Poglavlje 1: Znakovni nizovi

    Primer 1-18 ñe ispisati:

    1112112111112213122111311222111132132113113121113122113211311123113112211

    Takva sekvenca se naziva “Pregledaj i saopãti” poãto svaki çen element dobijatepregledom prethodnog elementa i imenovaçem çegovog sadræaja. Na primer, prvielement je 1, ãto åitamo kao “jedna jedinica”. Zato je drugi element “11”. To su dvejedinice, pa je treñi element “21”. Sliåno kao pre, to su jedna dvojka i jedna jedinica,pa je åetvrti element jednak “1211” itd.

    Videti iDokumentaciju petàe for na adresi http://www.php.net/for; viãe informacija o sek-vencama “Pregledaj i saopãti” na adresi http://mathworld.wolfram.com/LookandSay-Sequence.html.

    1.5 Obrtaçe znakovnog niza reå po reå ili znak po znak (bajt po bajt)

    ProblemÆelite da obrnete redosled reåi ili znakova (bajtova) znakovnog niza.

    ReãeçeZa obrtaçe redosleda bajtova znakovnog niza upotrebite funkciju strrev(), kao uprimeru 1-19.

    Primer 1-19. Obrtaçe redosleda bajtova znakovnog niza

    Primer 1-19 ñe ispisati:

    .emordnilap a ton si sihT

    Da biste obrnuli redosled reåi znakovnog niza, razdelite znakovni niz funkcijomexplode() po granicama reåi, obrnite redosled tih reåi funkcijom array_reverse() izatim ih spojite u nov znakovni niz, kao u primeru 1-20.

  • 1.6 Poveñavaçe i smaçivaçe ãirine tabulatora (kolona) | 11

    Primer 1-20. Obrtaçe redosleda reåi znakovnog niza

    Primer 1-20 ñe ispisati:

    turtle. a was there time a upon Once

    ObjaãnjenjeZa obrtaçe redosleda reåi znakovnog niza funkcijom implode() dovoàan je jedanred koda, kao u primeru 1-21.

    Primer 1-21. Saæeto obrtaçe redosleda reåi znakovnog niza

    Videti iRecept 23.7, gde se razmatraju implikacije koriãñeça neke druge granice reåi umestorazmaka; dokumentaciju funkcije strrev() na adresi http://www.php.net/strrev, afunkcije array_reverse() na adresi http://www.php.net/array-reverse.

    1.6 Poveñavaçe i smaçivaçe ãirine tabulatora (kolona)

    ProblemU znakovnom nizu, æelite da zamenite razmake tabulatorima (ili tabulatore razmaci-ma), a da tekst ostane poravnat u kolone. Na primer, formatiran tekst treba da pri-kaæete korisnicima na standardizovan naåin.

    ReãeçeZa zamenu razmaka tabulatorima ili tabulatora razmacima upotrebite funkciju str_replace(), kao u primeru 1-22.

  • 12 | Poglavlje 1: Znakovni nizovi

    Primer 1-22. Uzajamna zamena tabulatora i razmaka

    Meœutim, pri konverziji razmaka u tabulatore pomoñu funkcije str_replace() neuzima se u obzir ãirina kolona. Ukoliko æelite da kolone poåiçu na svakih osam zna-kova, a da red poåiçe reåju od pet slova i tabulatorom, taj tabulator treba zamenititrima razmacima, a ne jednim. Da biste tabulatore pretvorili u razmake uz oåuvaçeãirine kolona, upotrebite funkciju pc_tab_expand(), kao u primeru 1-23.

    Primer 1-23. Funkcija pc_tab_expand()

    Za pretvaraçe razmaka u tabulatore (uz oåuvaçe ãirine kolona) upotrebite funkcijupc_tab_unexpand(), kao u primeru 1-24.

    Primer 1-24. Funkcija pc_tab_unexpand()

  • 1.6 Poveñavaçe i smaçivaçe ãirine tabulatora (kolona) | 13

    // Pregledaj sve sem posledçeg paråeta for ($j = 0; $j < $chunkCount - 1; $j++) { $chunks[$j] = preg_replace('/ {2,}$/',"\t",$chunks[$j]); } // Ako posledçe paråe ima razmake za jednu kolonu, // pretvori ga u tabulator; u protivnom, ostavi ga onakvo kakvo je. if ($chunks[$chunkCount-1] == str_repeat(' ', $tab_stop)) { $chunks[$chunkCount-1] = "\t"; } // Ponovo spoji paråiñe u red: $lines[$i] = implode('',$chunks); } // Ponovo spoji redove u znakovni niz: return implode("\n",$lines);}

    $tabbed = pc_tab_unexpand($ob->message);?>

    Obe funkcije primaju znakovni niz kao argument i vrañaju znakovni niz modifiko-van na odgovarajuñi naåin.

    ObjaãnjenjeU svim funkcijama se pretpostavàa da je svaka kolona (znak tabulatora) ãiroka kaoosam razmaka, ali to se moæe promeniti tako ãto se zada druga vrednost za pro-menàivu $tab_stop.

    Regularan izraz u funkciji pc_tab_expand() odgovara i grupi tabulatora i celomtekstu tog reda pre te grupe tabulatora. Tekst pre tabulatora mora da se uzme u obzirzato ãto od çegove duæine zavisi broj razmaka kojima treba zameniti te tabulatore,da bi dalji tekst bio poravnat sa sledeñom kolonom (znakom tabulatora). Funkcija sene ograniåava samo na to da svaki tabulator zameni sa osam razmaka, veñ tekst na-kon znaka tabulatora poravnava u kolone.

    Sliåno tome, ni funkcija pc_tab_unexpand() ne ograniåava se samo na to da traæiosam uzastopnih razmaka i da ih zameni jednim znakom tabulatora, veñ svaki reddeli na paråad od po osam znakova i zatim zavrãnu belinu svakog paråeta (od naj-maçe dva razmaka) zameçuje tabulatorom. Time ne samo da se zadræava porav-naçe teksta u kolone, nego se i ãtedi prostor u znakovnom nizu.

    Videti iDokumentaciju funkcije str_replace() na adresi http://www.php.net/str-replace,funkcije preg_replace_callback() na adresi http://www.php.net/preg_replace_call-back, i funkcije str_split() na adresi http://www.php.net/str_split. O funkciji preg_replace_callback() govoriñemo i u receptu 22.10.

  • 14 | Poglavlje 1: Znakovni nizovi

    1.7 Pretvaraçe velikih slova u mala i obrnuto

    ProblemÆelite da pretvorite mala slova u velika, velika u mala ili da na neki drugi naåin mo-difikujete veliåinu slova znakovnog niza. Na primer, poåetna slova imena hoñete dapretvorite u velika, a ostala slova u mala.

    ReãeçeZa pretvaraçe prvog slova jedne, odnosno viãe reåi u veliko slovo, upotrebite funk-ciju ucfirst() odnosno funkciju ucwords(), kao u primeru 1-25.

    Primer 1-25. Pretvaraçe malih slova u velika

    Primer 1-25 ñe ispisati:

    How do you do today?The Prince Of Wales

    Za pretvaraçe velikih slova u mala (ili obrnuto) u celom znakovnom nizu, upotrebi-te funkcije strtolower() odnosno strtoupper(), kao u primeru 1-26.

    Primer 1-26. Pretvaraçe velikih slova u mala (i obrnuto) u celom znakovnom nizuprint strtoupper("i'm not yelling!");// Sadræaj oznaka mora biti ispisan malim slovima da bi bio kompatibilan sa XHTML-omprint strtolower('one');

    Primer 1-26 ñe ispisati:

    I'M NOT YELLING!one

    ObjaãnjenjeZa pretvaraçe prvog slova reåi u veliko slovo upotrebite funkciju ucfirst():

    Time ñe se ispisati:

    Monkey face1 monkey fac

    Obratite paæçu na to da druga reåenica ne glasi “1 Monkey face”.

  • 1.7 Pretvaraçe velikih slova u mala i obrnuto | 15

    Funkciju ucwords() upotrebite za pretvaraçe prvog slova svake reåi znakovnog nizau veliko slovo:

  • 16 | Poglavlje 1: Znakovni nizovi

    Videti iViãe informacija o parametrima koji opisuju regionalne specifiånosti potraæite upoglavàu 19; dokumentaciju o funkciji ucfirst() na adresi http://www.php.net/uc-first, o funkciji ucwords() na adresi http://www.php.net/ucwords, o funkciji strtolo-wer() na adresi http://www.php.net/strtolower, i o funkciji strtoupper() na adresihttp://www.php.net/strtoupper.

    1.8 Interpoliraçe rezultata funkcija i izraza unutar znakovnih nizova

    ProblemRezultate izvrãavaça funkcije ili izraåunavaça izraza æelite da ubacite u znakovni niz.

    ReãeçeAko odreœenu vrednost ne moæete da ubacite u znakovni niz, upotrebite operator (.)za nadovezivaçe znakovnih nizova, kao u primeru 1-27.

    Primer 1-27. Nadovezivaçe znakovnih nizova

    ObjaãnjenjePromenàive, svojstva objekata i elemente nizova (åiji indeksi nisu unutar navodnika)moæete da navedete neposredno u znakovnom nizu zatvorenom u navodnike:

  • 1.9 Uklaçaçe belina s poåetka i kraja znakovnih nizova | 17

    Direktna interpolacija i nadovezivaçe znakovnih nizova moguñi su i u dokumenti-ma definisanim pomoñu heredoc sintakse. Interpolacija uz nadovezivaçe znakovnihnizova u dokumentima definisanim pomoñu heredoc sintakse ume åudno da izgleda,zato ãto zavrãna oznaka dokumenta definisanog pomoñu heredoc sintakse i operatornadovezivaça znakovnih nizova moraju biti u zasebnim redovima:

    Sem toga, ako interpolirate u dokumentu definisanom pomoñu heredoc sintakse, po-vedite raåuna o razmacima potrebnim da bi ceo znakovni niz izgledao kako treba. Uprethodnom primeru, Right now the time mora se zavrãiti jednim razmakom, a deobut tomorrow it will be mora imati po jedan razmak na poåetku i na kraju.

    Videti iZa sintaksu interpoliraça vrednosti promenàivih (kao ãto je ${"amount_$i"}), pogle-dajte recept 5.4; dokumentaciju operatora nadovezivaça znakovnih nizova potraæi-te na adresi http://www.php.net/language.operators.string.

    1.9 Uklaçaçe belina s poåetka i kraja znakovnih nizova

    ProblemÆelite da uklonite beline s poåetka ili kraja znakovnog niza, recimo zato da biste oåi-stili korisniåki unos pre nego ãto ga podvrgnete validaciji.

    ReãeçeUpotrebite funkcije ltrim(), rtrim() ili trim(). Funkcija ltrim() uklaça belinu spoåetka znakovnog niza, rtrim() s kraja znakovnog niza, a trim() i s poåetka i s kra-ja znakovnog niza:

  • 18 | Poglavlje 1: Znakovni nizovi

    ObjaãnjenjeZa te funkcije, beline su sledeñi znakovi: novi red (engl. newline), poåetak reda (engl.carriage return), razmak, horizontalni i vertikalni tabulator, i znak null.

    Uklaçaçem belina ispred i iza znakovnih nizova ãtedi se memorijski prostor, aomoguñava se i preciznije prikazivaçe formatiranih podataka i teksta unutar, reci-mo, oznaka . Ukoliko korisniåki unos uporeœujete s neåim, najpre uklonitebeline ispred i iza çega, kako onaj ko greãkom unese “98052” kao svoj poãtanskibroj ne bi morao da sve piãe iz poåetka. Uklaçaçem belina pre poreœeça s taånimtekstom obezbeœuje se i da se, na primer, “salami\n” podudari sa “salami”. Takoœe,znakovni niz treba da normalizujete tako ãto ñete ukloniti beline pre nego ãto gasmestite u bazu podataka.

    Funkcije trim() mogu da uklaçaju iz znakovnih nizova i znakove koje zada kori-snik. Znakove koje treba ukloniti zadajte kao drugi argument. Ukoliko treba uklo-niti ceo opseg znakova [od ..do], zadajte ga pomoñu dve taåke izmeœu prvog iposledçeg znaka opsega:

    Ispisañe se:

    PRINT A$SELECT * FROM turtles

    PHP ima i funkciju chop(), ãto je samo drugo ime za rtrim(). Meœutim, boàe je daupotrebàavate rtrim() umesto PHP-ove funkcije chop(), zato ãto se ona ponaãadrukåije od Perlove funkcije chop() (kojoj bi u Perlu ionako trebalo pretpostavitifunkciju chomp), a mogla bi da zbuni ostale kada budu åitali vaã kôd.

    Videti iDokumentaciju funkcije trim() na adresi http://www.php.net/trim, funkcije ltrim()na adresi http://www.php.net/ltrim i funkcije rtrim() na adresi http://www.php.net/rtrim.

    1.10 Generisaçe podataka razdvojenih zarezima

    ProblemÆelite da formatirate podatke kao vrednosti razdvojene zarezima (engl. comma-sepa-rated values, CSV), da biste ih mogli uvesti u tabelarni proraåun ili bazu podataka.

  • 1.10 Generisaçe podataka razdvojenih zarezima | 19

    ReãeçeZa generisaçe reda vrednosti razdvojenih zarezima od niza (engl. array) podatakaupotrebite funkciju fputcsv(). U primeru 1-28, podaci iz niza $sales upisuju se u da-toteku.

    Primer 1-28. Generisaçe podataka razdvojenih zarezima

  • 20 | Poglavlje 1: Znakovni nizovi

    Primer 1-30. Upisivaçe podataka razdvojenih zarezima u znakovni niz

  • 1.12 Generisaçe zapisa s poàima fiksne ãirine | 21

    }print '\n';fclose($fp) or die("can't close file");?>

    ObjaãnjenjeU PHP-u 4, kao drugi argument funkcije fgetcsv() morate da zadate vrednost veñuod maksimalne duæine reda CSV datoteke. (Ne zaboravite da uraåunate beline nakraju redova.) U PHP-u 5, duæina reda je opcioni argument. Ako ga ne zadate,fgetcsv() ñe uåitati ceo red podataka. (U PHP-u 5.0.4 i kasnijim verzijama, isto ñetepostiñi ako prosledite vrednost 0 kao duæinu reda.) U sluåaju da je proseåna duæinareda veña od 8192 bajta, program ñe se izvrãavati bræe ukoliko duæinu reda zadateeksplicitno, umesto da pustite PHP da je pogaœa.

    Funkciji fgetcsv() moæete proslediti i opcioni treñi argument, graniånik koji umestozareza razdvaja podatke. Meœutim, upotrebom drugaåijeg graniånika donekle segubi smisao koriãñeça CSV datoteka kao jednostavnog sredstva za razmenu tabelar-nih podataka.

    Ne padajte u iskuãeçe da zaobiœete fgetcsv() tako ãto ñete uåitati podatke i na svezareze primeniti funkciju explode(). CSV je previãe komplikovan za takav pristup,zato ãto çegova poàa mogu sadræati, na primer, prave, doslovne zareze koje ne trebatretirati kao graniånike poàa. Funkcija fgetcsv() ãtiti vas i vaã kôd od takvih “sitnih”greãaka.

    Videti iDokumentaciju funkcije fgetcsv() na adresi http://www.php.net/fgetcsv.

    1.12 Generisaçe zapisa s poàima fiksne ãirine

    ProblemÆelite da formatirate zapise podataka tako da svako poàe zauzme dati broj znakova.

    ReãeçeUpotrebite funkciju pack() sa znakovnim nizom za formatiraçe (engl. format string)koji specificira sekvencu znakovnih nizova nadopuçenih razmacima. U primeru 1-32,pretvoriñemo niz podataka u zapise fiksne ãirine.

    Primer 1-32.Generisaçe zapisa s poàima fiksne ãirine

  • 22 | Poglavlje 1: Znakovni nizovi

    foreach ($books as $book) { print pack('A25A15A4', $book[0], $book[1], $book[2]) . "\n";}

    ?>

    ObjaãnjenjeZnakovni niz za formatiraçe, A25A14A4, kazuje funkciji pack() da argumente koji sle-de pretvori u: znakovni niz od 25 znakova nadopuçen razmacima, znakovni niz od14 znakova nadopuçen razmacima i znakovni niz od 4 znaka nadopuçen razmaci-ma. Funkcija pack() daje koncizno reãeçe za poàa nadopuçena razmacima u zapisi-ma fiksne ãirine.

    Ukoliko poàa æelite da nadopunite nekim drugim znakom, a ne razmacima, upotre-bite funkciju substr() koja obezbeœuje da vrednosti u poàima ne budu predugaåke,odnosno funkciju str_pad() koja obezbeœuje da vrednosti u poàima ne budu pre-kratke. U primeru 1-33, pretvoriñemo niz zapisa u zapise fiksne ãirine, åija ñe poàado pune ãirine biti nadopuçena znakom taåka.

    Primer 1-33. Generisaçe zapisa s poàima fiksne ãirine, bez funkcije pack()

    Videti iDokumentaciju funkcije pack() na adresi http://www.php.net/pack i funkcije str_pad()na adresi http://www.php.net/str_pad. Znakovni nizovi funkcije pack() za formatiraçe,detaànije su razmotreni u receptu 1.16.

    1.13 Raãålaçivaçe zapisa s poàima fiksne ãirine

    ProblemZapise fiksne ãirine hoñete da raãålanite u znakovne nizove.

  • 1.13 Raãålaçivaçe zapisa s poàima fiksne ãirine | 23

    ReãeçeUpotrebite funkciju substr(), kao u primeru 1-34.

    Primer 1-34. Raãålaçivaçe zapisa fiksne ãirine funkcijom substr()

  • 24 | Poglavlje 1: Znakovni nizovi

    for($i = 0, $j = count($books); $i < $j; $i++) { $book_array[$i]['title'] = substr($books[$i],0,25); $book_array[$i]['author'] = substr($books[$i],25,14); $book_array[$i]['publication_year'] = substr($books[$i],39,4);}?>

    Nakon podele dokumenta $booklist u niz redova, istu petàu moæemo upotrebiti i zajedan znakovni niz i za viãe redova uåitanih iz datoteke.

    Petàa ñe biti prilagodàivija ukoliko imena i ãirine poàa zadamo u zasebnom nizu kojise funkciji za raãålaçivaçe moæe proslediti, kao u funkciji pc_fixed_width_substr()u primeru 1-36.

    Primer 1-36. Funkcija pc_fixed_width_substr()

    Promenàiva $line_pos prati poåetak svakog poàa. Dok petàa prolazi kroza svaki red,ta promenàiva se poveñava za ãirinu prethodnog poàa. Za uklaçaçe beline iza sva-kog poàa upotrebite funkciju rtrim().

    Kao zamenu za substr(), za izdvajaçe poàa moæete upotrebiti funkciju unpack().Umesto da specificirate imena i ãirine poàa u obliku asocijativnog niza, za unpack()treba da napravite znakovni niz za formatiraçe. U primeru 1-37 imate funkciju pc_fixed_width_unpack(), koja pomoñu funkcije unpack() izdvaja poàa fiksne ãirine.

    Primer 1-37. Funkcija pc_fixed_width_unpack()

  • 1.13 Raãålaçivaçe zapisa s poàima fiksne ãirine | 25

    return $r;}

    $book_array = pc_fixed_width_unpack('A25title/A14author/A4publication_year', $books);

    ?>

    Poãto funkcija unpack() shvata format A kao “znakovni niz nadopuçen razmaci-ma”, nema potrebe da uklaçate zavrãne razmake funkcijom rtrim().

    Nakon ãto bilo koja od prethodnih funkcija izdvoji poàa u niz $book_array, podacise mogu ispisati, na primer, u obliku HTML tabele:

    Zadavaçem argumenata funkciji join() koja elemente niza (engl. array)nadovezuje u jedan znakovni niz (engl. string) povezujuñi ih prvim argumentom (uovom sluåaju znakovima ), dobijamo red HTML tabele bez prve oznake i posledçe oznake . Upotpuniñemo red tabele tako ãto ñemo ispisati ozna-ke pre tako povezanih podataka, odnosno iza tako povezanihpodataka.

    Funkcije substr() i unpack() imaju jednake moguñnosti kada su u poàima znakovninizovi, ali je unpack() boàe reãeçe kada elementi poàa nisu samo znakovni nizovi.

    U sluåaju da su sva poàa iste ãirine, funkcija str_split() sluæi za lako cepanje ulaz-nih podataka. Taj novitet PHP-a 5 vraña izlazni niz sastavàen od delova ulaznog zna-kovnog niza. U primeru 1-38, funkcijom str_split() delimo znakovni niz na deloveãirine 32 bajta.

    Primer 1-38. Podela znakovnog niza na delove jednake ãirine funkcijom str_split( )

  • 26 | Poglavlje 1: Znakovni nizovi

    Videti iViãe informacija o funkciji unpack() potraæite u receptu 1.16 i na adresi http://www.php.net/unpack; dokumentaciju funkcije str_split() na adresi http://www.php.net/str_split; funkcija join() razmotrena je u receptu 4.8.

    1.14 Podela znakovnog niza na delove

    ProblemTreba da podelite znakovni niz na delove. Na primer, hoñete da pristupite svakomredu teksta koji je korisnik upisao u polje na obrascu.

    ReãeçeAko su delovi razgraniåeni istim nizom znakova kao graniånikom, upotrebite funk-ciju explode():

    U sluåaju da graniånik morate opisati regularnim izrazom kompatibilnim s POSIX-omili Perlom, upotrebite funkciju split() ili preg_split():

    Funkciju spliti(), odnosno funkciju preg_split() sa indikatorom /i upotrebite iukoliko æelite da se, prilikom ispitivaça podudaraça znakova s graniånikom, razli-ka izmeœu velikih i malih slova ne uzima u obzir:

    ObjaãnjenjeNajjednostavnije reãeçe od svih daje funkcija explode(). Prosledite joj niz znakovakoji definiãe graniånik, znakovni niz koji teba izdeliti i, opciono, broj elemenata kojetreba da vrati kao svoj rezultat:

  • 1.14 Podela znakovnog niza na delove | 27

    Time bismo dobili $dwarf_array kao niz od sedam elemenata, pa bi naredba print_r($dwarf_array) ispisala:

    Array( [0] => dopey [1] => sleepy [2] => happy [3] => grumpy [4] => sneezy [5] => bashful [6] => doc)

    Ako se specificira broj elemenata rezultata maçi od broja moguñih delova, posledçideo ñe obuhvatiti ostatak znakovnog niza:

    Rezultat bi bio:

    Array( [0] => dopey [1] => sleepy [2] => happy [3] => grumpy [4] => sneezy,bashful,doc)

    Funkcija explode() doslovno shvata zadati graniånik. Ako kao graniånik zadate za-rez i razmak, ona ñe znakovni niz podeliti samo tamo gde naœe i zarez i razmak, a netamo gde naœe samo zarez ili samo razmak.

    Funkcija split() je prilagodàivija. Umesto da graniånik zadajete doslovno, çojzadajete POSIX regularan izraz:

    Ovaj regularan izraz cepa ulazni znakovni niz tamo gde naœe zarez i opciono razmakiza çega, åime se svi novi elementi (niz $more_dwarves) tretiraju ispravno. Neñe bitipocepan element koji u imenu sadræi razmak, ali ñe ulazni znakovni niz biti pocepanna svim mestima gde stoji "," ili ", ". Naredba print_r($more_dwarf_array() ispisañe:

    Array( [0] => cheeky [1] => fatso

  • 28 | Poglavlje 1: Znakovni nizovi

    [2] => wonder boy [3] => chunky [4] => growly [5] => groggy [6] => winky)

    Sliåna funkciji split() jeste funkcija preg_split(), ali se çoj zadaje regularan izrazkompatibilan s Perlom, a ne POSIX-ov. Uz preg_split() moæete da koristite raznaproãireça Perlovih regularnih izraza, i trikove kao ãto je ukàuåivaçe teksta graniåni-ka u rezultujuñi niz znakovnih nizova:

    Ispisañe se:

    Array( [0] => 3 [1] => + [2] => 2 [3] => / [4] => 7 [5] => - [6] => 9)

    Regularan izraz graniånika podudara se sa åetiri matematiåka operatora (+, -, /, *), is-pred i iza kojih su opcioni razmaci. Indikator PREG_SPLIT_DELIM_CAPTURE kazuje funk-ciji preg_split() da u rezultujuñi niz znakovnih nizova ukàuåi i znakove koji sepodudaraju s regularnim izrazom graniånika navedenim u malim zagradama. Poãto suu çima samo znakovi matematiåkih operatora, u vrañenom nizu neñe biti razmaka.

    Videti iRegularni izrazi su detaànije razmotreni u poglavàu 22; dokumentaciju funkcijeexplode() potraæite na adresi http://www.php.net/explode, funkcije split() na adresihttp://www.php.net/split, i funkcije preg_split() na adresi http://www.php.net/preg-split.

    1.15 Prelamaçe teksta na redove odreœene duæine

    ProblemHoñete da prelomite znakovni niz u viãe redova. Primera radi, tekst æelite da prikaæe-te izmeœu oznaka /, ali tako da ostane unutar prozora åitaåa Weba uobi-åajene veliåine.

  • 1.15 Prelamaçe teksta na redove odreœene duæine | 29

    ReãeçeUpotrebite funkciju wordwrap():

    Time ñe se ispisati:

    Four score and seven years ago our fathers brought forth on this continenta new nation, conceived in liberty and dedicated to the proposition thatall men are created equal.

    ObjaãnjenjeFunkcija wordwrap() podrazumevano prelama tekst u redove duæine 75 znakova.Opcionim drugim argumentom drugu duæinu reda:

    Ispisañe se:

    Four score and seven years ago our fathers broughtforth on this continent a new nation, conceived inliberty and dedicated to the proposition that allmen are created equal.

    Za prelazak u novi red mogu se upotrebiti i drugi znakovi, ne samo \n. Kada æelitedvostruki prored, zadajte "\n\n":

    Ispisañe se:

    Four score and seven years ago our fathers brought

    forth on this continent a new nation, conceived in

    liberty and dedicated to the proposition that all

    men are created equal.

  • 30 | Poglavlje 1: Znakovni nizovi

    Opcioni åetvrti argument funkcije wordwrap() odreœuje tretman reåi duæih od speci-ficirane duæine reda. Ukoliko je taj argument 1, te reåi ñe biti prelomàene. U protiv-nom, biñe ispisane neprekinute, iako se time premaãuje zadata duæina reda:

    Ispisañe se:

    jabberwocky

    jabberwocky

    Videti iDokumentaciju funkcije wordwrap() na adresi http://www.php.net/wordwrap.

    1.16 Smeãtaçe binarnih podataka u znakovne nizove

    ProblemÆelite da raãålanite znakovni niz koji sadræi vrednosti kodirane u obliku binarnestrukture ili da upiãete kodirane vrednosti u znakovni niz. Na primer, hoñete da us-kladiãtite brojeve predstavàene binarno, a ne kao sekvence ASCII znakova.

    ReãeçeZa upisivaçe binarnih podataka u znakovni niz, upotrebite funkciju pack():

    Za izdvajanje binarnih podataka iz znakovnog niza, upotrebite funkciju unpack():

    ObjaãnjenjePrvi argument funkcije pack() je oznaka formata koja opisuje naåin kodiraça poda-taka prosleœenih u ostalim argumentima. Oznaka formata S4 kazuje funkciji pack()da od ulaznih podataka napravi åetiri 16-bitna broja tipa short, bez predznaka, poredosledu bajtova vaæeñem na raåunaru na kojem se program izvrãava. Ako su kaoulazni podaci dati brojevi 1974, 106, 28225 i 32725, a na raåunaru se najpre piãe

  • 1.16 Smeãtaçe binarnih podataka u znakovne nizove | 31

    maçe znaåajan (engl. little-endian) bajt broja, funkcija ñe kao rezultat dati osam baj-tova: 182, 7, 106, 0, 65, 110, 213 i 127. Svaki par bajtova odgovara jednom od ulaz-nih brojeva: 7 * 256 + 182 daje 1974; 0 * 256 + 106 daje 106; 110 * 256 + 65 = 28225;127 * 256 + 213 = 32725.

    I prvi argument funkcije unpack() je oznaka formata, a drugi argument su podacikoje treba dekodirati. Kada joj kao oznaku formata prosledimo S4, osmobajtna sek-venca koju je dala funkcija pack() dañe niz od åetiri elementa s prvobitnim brojevi-ma. Naredba print_r($nums) ispisala bi:

    Array( [1] => 1974 [2] => 106 [3] => 28225 [4] => 32725)

    U funkciji unpack(), iza oznake formata i broja elemenata moæete navesti znakovniniz od kojeg treba napraviti kàuå niza. Na primer:

    Ispisañe se:

    Array( [num1] => 1974 [num2] => 106 [num3] => 28225 [num4] => 32725)

    U funkciji unpack(), viãe oznaka formata mora biti razdvojeno kosom crtom /:

    Ispisañe se:

    Array( [a] => 1974 [b] => 106 [c] => 28225 [d] => 32725)

  • 32 | Poglavlje 1: Znakovni nizovi

    U tabeli 1-2 navedene su oznake formata koje se mogu upotrebàavati u funkcijamapack() i unpack().

    U formatima a, A, h i H, broj iza oznake formata pokazuje duæinu znakovnog niza. Pri-mera radi, A25 oznaåava razmacima nadopuçen znakovni niz duæine 25 znakova. Uostalim oznakama formata, broj iza oznake formata pokazuje koliko je takvih tipovauzastopno u znakovnom nizu. Za ostatak dostupnih podataka upotrebite oznaku * .

    Funkcija unpack() sluæi i za konverziju tipova podataka. U narednom primeru, niz$ascii popuniñemo ASCII kodom svakog znaka u $s:

    Ispisañe se:

    Array( [1] => 112 [2] => 108

    Tabela 1-2. Oznake formata za funkcije pack() i unpack()

    Oznaka formata Tip podataka

    a Znakovni niz dopunjen vrednostima NULL

    A Znakovni niz dopunjen razmacima

    h Heksadecimalni znakovni niz, prvo niæi nibl (polubajt)

    H Heksadecimalni znakovni niz, prvo viãi nibl (polubajt)

    c signed char (oznaåen znakovni tip)

    C unsigned char (neoznaåen znakovni tip)

    s signed short (16 bitova, redosled bajtova zavisi od maãine)

    S unsigned short (16 bitova, redosled bajtova zavisi od maãine)

    n unsigned short (16 bitova, redosled bajtova big endian)

    v unsigned short (16 bitova, redosled bajtova little endian)

    i signed int (veliåina i redosled bajtova zavise od maãine)

    I unsigned int (veliåina i redosled bajtova zavise od maãine)

    l signed long (32 bita, redosled bajtova zavisi od maãine)

    L unsigned long (32 bita, redosled bajtova zavisi od maãine)

    N unsigned long (32 bita, redosled bajtova big endian)

    V unsigned long (32 bita, redosled bajtova little endian)

    f float (veliåina i naåin predstavljanja zavise od maãine)

    d double (veliåina i naåin predstavljanja zavise od maãine)

    x Bajt vrednosti nula

    X Arhiviraçe/dearhiviraçe jednog bajta

    @ Popuçavaçe vrednoãñu NUL do apsolutno zadate pozicije

  • 1.17 Program: CSV datoteka za preuzimaçe | 33

    [3] => 97 [4] => 116 [5] => 121 [6] => 112 [7] => 117 [8] => 115)

    Videti iDokumentaciju funkcije pack() na adresi http://www.php.net/pack i funkcijeunpack() na adresi http://www.php.net/unpack.

    1.17 Program: CSV datoteka za preuzimaçeKombinacija funkcije header() za meçaçe tipa sadræaja izlaza PHP programa i funk-cije fputcsv() za formatiraçe podataka, omoguñava slaçe CSV datoteka åitaåimaWeba, koji ih automatski predaju programu za obradu tabelarnih proraåuna (odno-sno aplikaciji koja je u konkretnom klijentskom sistemu zaduæena za rad sa CSV da-totekama). U primeru 1-39, formatirañemo rezultate SQL upita SELECT kao CSVdatoteku i dati joj odgovarajuña zaglavàa tako da je åitaå moæe ispravno obraditi.

    Primer 1-39. CSV datoteka za preuzimaçe

  • 34 | Poglavlje 1: Znakovni nizovi

    Program u primeru 1-39 ãaàe dva zaglavàa kako bi se obezbedilo da åitaå ispravnoobradi CSV izlaz. Prvo zaglavàe, Content-Type, kazuje åitaåu da tip izlaza nije HTMLnego CSV. Drugo zaglavàe, Content-Disposition, kazuje åitaåu da izlaz ne prikazujesam, veñ da pokuãa da uåita spoàni program koji ñe to uraditi. Atribut filename ovogzaglavàa daje åitaåu podrazumevano ime koje moæe upotrebiti za preuzetu datoteku.

    Ukoliko iste podatke æelite da prikaæete na razliåite naåine, moæete da kombinujetekôd za formatiraçe na jednoj stranici i da promenàivom upita (engl. query string va-riable) odredite koju vrstu formatiraça treba obaviti. U primeru 1-40, promenàivaupita nazvana format odreœuje da li ñe se rezultati SQL upita SELECT vratiti u oblikuHTML tabele ili CSV datoteke.

    Primer 1-40. Dinamiåka odluka: CSV ili HTML

  • 1.17 Program: CSV datoteka za preuzimaçe | 35

    fputcsv($output,$total_line); fclose($output) or die("Can't close php://output"); } else { echo '' . implode('', $total_line) . ''; echo ''; }?>

    Ako u primeru 1-40 pristupite programu uz format=csv u upitu, on ñe kao svoj izlazvratiti CSV datoteku. Za sve druge vrednosti promenàive format u upitu, vratiñeHTML izlaz. Istom logikom koja promenàivoj $format zadaje vrednosti CSV ili HT-ML, mogli biste zadati i druge izlazne formate, recimo XML. Ukoliko iste podatkeæelite da ponudite na preuzimaçe na viãe mesta i u viãe formata, upakujte kôd iz pri-mera 1-40 u funkciju koja prihvata niz podataka i specifikator formata, i zatim prika-zuje odgovarajuñe rezultate.