miffmedia.com

The PHP Manifesto

minimal

I am a PHP developer

  • I am not a Zend Framework or Symfony or CakePHP developer
  • I think PHP is complicated enough

I like building small things

  • I like building small things with simple purposes
  • I like to make things that solve problems
  • I like building small things that work together to solve larger problems

I want less code, not more

  • I want to write less code, not more
  • I want to manage less code, not more
  • I want to support less code, not more
  • I need to justify every piece of code I add to a project

I like simple, readable code

  • I want code that is easily verifiable
  • I want to write code that is easily understood

 

Prekopirao sam odavde http://funkatron.com/posts/the-microphp-manifesto.html. Rečeno je i opisano sve kako valja, nema se šta dodati više. :)

PHP i RegEx (regularni izrazi)

Šta su i kako glasi definicija regularnih izraza najbolje je da potražite ovde (recimo).

Pokušaću da u što manje "tupljenja" objasnim kako je najbolje naučiti i koristiti regularne izraze u PHP-u.

RegEx u PHP-u
slika je sa: http://shirtoid.com/17208/regular-expressions/

Primena

Primena je skoro u svakom projektu, dobar primer su forme tj unos podataka i provera istih. Lepo je to što može Javascript-om da se proveri unos, ispravi i opomene korisnik ali čarobno Disable JavaScript i podaci iz forme odoše takvi kavi (zlonamerni recimo...), i onda tu nastupa (server-side) kontrola.

$s = 'lisica';
echo preg_match("/ic/", $s); //echo: 1
echo preg_match("/IC/", $s); //echo: 0

U Na ovom primeru se se da zaključiti da: veličina jeste bitna (velika i mala slova prave razliku), string lisica ima u sebi ic ali nema IC, i da koristim PHP funkciju preg_match.

Meta-characters

Snaga regularnih izraza je u meta karakterima, meta karakteri su inače skup znakova sa specijalnim značenjem i to ne literalnim. Zvuči pomalo uf.. ali je ustvari baš prava definicija, cela zamisao oko izkaza je da se pomoću obrazca (pattern) pronađu podudaranja u određenom stringu. Upravo taj obrzac formiramo pomoću meta karaktera.

Caret (stepen) ^

Početak stringa

$s = 'lisica';
echo preg_match("/^li/", $s); //echo: 1
echo preg_match("/^is/", $s); //echo: 0

Inče caret ima još jednu primenu

Dollar (dolar, string) $

Kraj stringa

$s = 'lisica';
echo preg_match("/ica$/", $s); //echo: 1
echo preg_match("/isi$/", $s); //echo: 0

Character class (uglaste zagrade) []

U izrazima uglasta zagrada predstavlja klasu karaktera što bi značilo da je u pitanju set karaktera slično kao niz

$s = 'liga';
echo preg_match("/[aeiou]/", $s); //echo: 1
$s1 = 'laig';
echo preg_match("/[aoiu]/", $s1); //echo: 1
$s2 = 'lag';
echo preg_match("/l[aoiu]g/", $s2); //echo: 1
$s3 = 'leg';
echo preg_match("/l[aoiu]g/", $s3); //echo: 0
$s4 = 'laog';
echo preg_match("/l[aoiu]g/", $s4); //echo: 0

^ Caret znak se koristi za početak stringa ali ako se koristi u uglastim zagradama onda znaci NOT.

$s = 'lisica';
if(preg_match("/[^o]/",$s)) echo 'Nema znaka o.';

Da spomenem znak $ u uglastim zagradama nema nikakvog značaja, samo običan dolar znak.

U klasi karakteraa korisna stvar je range (raspon) i znak je - (minus), tako da [a-e] znači da se traže poklapanja po [abcde]

$s = 'lisica';
echo preg_match("/[a-z]/", $s); //echo: 1
$s1 = 'BraonLisicaSkace';
echo preg_match("/[a-z]/", $s1); //echo: 1
$s2 = 'LISICA';
echo preg_match("/[a-z]/", $s2); //echo: 0
$s3 = '12345';
echo preg_match("/[a-zA-Z]/", $s3); //echo: 0
$s4 = '12345';
echo preg_match("/[^0-9]/", $s4); //echo: 0

Dot (tačka) .

Jako prosto, označava sve karaktere izuzev nove linije.

$s = 'lisica';
echo preg_match("/./", $s); //echo: 1
$s1 = 'lisica';
echo preg_match("/[.]/", $s1); //echo: 0
$s2 = 'lis';
echo preg_match("/l.s/", $s2); //echo: 1
$s3 = 'lig';
echo preg_match("/l.e/", $s3); //echo: 0
$s4 = 'liis';
echo preg_match("/l.s/", $s4); //echo: 0
$s5 = "l\re";
echo preg_match("/l.e/", $s5); //echo: 1
$s6 = "l\ne";
echo preg_match("/l.e/", $s6); //echo: 0

Asterix (zvezdica) *

a* označava 0 ili više karaktera a, da bih pokazao korišćenje * napisaću malo komplikovaniji izraz:


$s = "<html>";
echo preg_match("/<[A-Za-z][A-Za-z0-9]*>/", $s); //echo: 1
$s1 = "<b>";
echo preg_match("/<[A-Za-z][A-Za-z0-9]*>/", $s1); //echo: 1
$s2 = "<h2>";
echo preg_match("/<[A-Za-z][A-Za-z0-9]*>/", $s2); //echo: 1
$s3 = "<2>";
echo preg_match("/<[A-Za-z][A-Za-z0-9]*>/", $s3); //echo: 0

Plus +

a+ označava jedno ili više karaktera a.

$s = "php";
echo preg_match("/ph+p/", $s); //echo: 1
$s1 = "phhp";
echo preg_match("/ph+p/", $s1); //echo: 1
$s2 = "pp";
echo preg_match("/ph+p/", $s2); //echo: 0
$s3 = "12345";
echo preg_match("/[a-z]+/", $s3); //echo: 0

Question mark (znak pitanja) ?

a? predstavlja 0 ili jedano poklapanje karaktera a.

$s = "123456";
echo preg_match("/123-?456/", $s); //echo: 1
$s1 = "123-456";
echo preg_match("/123-?456/", $s1); //echo: 1
$s2 = "123--456";
echo preg_match("/123-?456/", $s2); //echo: 0

Curly braces (velike zagrade) {}

a{2} tačno 2 karaktera a
a{2,} 2 ili više a
a{,2} do 2 karaktera a
a{2,5} od 2 do 5 karaktera a

$s = "google";
echo preg_match("/go{2}gle/", $s); //echo: 1
$s1 = "gooogle";
echo preg_match("/go{2}gle/", $s1); //echo: 0
$s2 = "gooogle";
echo preg_match("/go{2,}gle/", $s2); //echo: 1
$s3 = "google";
echo preg_match("/go{,2}gle/", $s3); //echo: 0
$s4 = "google";
echo preg_match("/go{2,3}gle/", $s4); //echo: 1

Subpattern (pod obrazac, zagrade) ()

$s = "Braon lisica skace.";
echo preg_match("/^(Braon)/", $s); //echo: 1
$s1 = "Crvena lisica skace.";
echo preg_match("/^(Braon)/", $s1); //echo: 0
$s2 = "Braon lisica skace.";
echo preg_match("/^([0-9])/", $s2); //echo: 0
$s3 = "13 je srecan broj.";
echo preg_match("/^([0-9])/", $s3); //echo: 1

Logical Or (pipe, uspravna crta) |

$s = "Braon lisica skace.";
echo preg_match("/^(Braon|Crvena)/", $s); //echo: 1
$s1 = "Crvena lisica skace.";
echo preg_match("/^(Braon|Crvena)/", $s1); //echo: 1

Backslash (naopaka kosa crta) \

Naopaka kosa crta se koristi u slučaju da ovih 11 meta karaktera želite da proverite kao string, moraćete da ih escape-ujete (izbegnete) sa znakom backslash.

$s = 'miffmedia.com';
if(preg_match("/\./",$s)) echo 'Postoji znak .';
$s1 = 'miffmedia+com';
if(preg_match("/\+/",$s1)) echo 'Postoji znak + .';

Upotreba

Ovo je sasvim dovoljno predznanje da napravite svoj PHP email validator koji ima iskaz:

^[a-zA-Z0-9._%-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$

Gde svaka email adresa ima odrđeni format korisničko_ime @ domen . ekstenzija, tako da imamo izraze za korisničko ime: ^[a-zA-Z0-9._%-]+; domen: [a-zA-Z0-9.-]+ i za ekstenziju: [a-zA-Z]{2,4}.

Ovaj post sam najviše napisao zbog sebe samog, a vi koji ste zalutali možda i naučite nešto ili se podsetite... ;)

Reference:
http://www.regular-expressions.info/
http://php.net

Reflection API

Reflection API in PHP | miff blog

Brian Cantwell Smith je 1980 godine u svojoj doktorskoj disertaciji osmislio termin refleksije u kompijuterskom programiranju, te svaki programer koji radi OOP a drzi do sebe mora da zna šta je i kako se primenjuje Reflection u programskim jezicima.

Reflection je jako opširna tema, tako da primere za većinu možete videti na wiki stranici o refleksiji, ja ću pisati o voljenom PHP-u ;). Inače refleksija u ovom "našem" smislu i okruženju znači da program moze da nadgleda(sebe) i modifikuje sopstvenu strukturu i to u trenutku kada se izvršava(runtime).

Reflection API je sastvni deo PHP(core) i ne zahteva nikakve dodatne module za instalirati i/ili konfigurisati. Dakle od 5. verzije ali se slabo upotrebljava a i mnogi ne znaju da PHP to može ;).

Slučaji najčešćeg korišćenja:

  • Provera da li su odredjene metode dostupne
  • Pozivanje klase sa više kontrole
  • Izmene stanje promenljivih i metoda
  • Izvlačenje vrednosti promenljivih koje su inače nedostupne

Navode se još neka kao dobijanje meta informacije iz komentara ali iskreno nisam probao, dosada nisam imao potrebe za tako nečim, u svakom slučaju celokupnu dokumentaciju možete pročitati na php manual stranicama.

Ako pogledate kod, videćete kako je moguće modifikovati nedostupnu promenljivu:

  class prvaKlasa {
        protected $prva = 1;
        public function izvPrvu() {
            return $this->prva;
        }
    }
    class drugaKlasa extends prvaKlasa {
        protected $druga = 2;
        public function izvDrugu() {
            return $this->druga;
        }
    }
    class trecaKlasa extends drugaKlasa {
        protected $treca = 3;
        public function izvTrecu() {
            return $this->treca;
        }
    }

 

 

Ako instanciramo klasu trcaKlasa i pozovemo metodu izvDrugu(); ispis će biti 2

    // bez refleksije
    $obj = new trecaKlasa();
    echo 'Bez Refleksije: '.$obj->izvDrugu();

 

 

Morate da primetite da ne postoji direktan, posredan način da se promenljiva $druga modifikuje, ali uz pomoć Reflection API-ja može:

    // refleksija
    $rf = new ReflectionClass('trecaKlasa');
    $ref = $rf->getProperty('druga');
    $ref->setAccessible(true);
    $ref->setValue($obj, 64);
    echo 'Sa Refleksijom: '.$obj->izvDrugu();

 

 

Ispisaće 64, moćno zar ne?

 

Ako kod nije bas najjasnije prikazan, primer ovog fajla je ovde.

Twitpic photo stream

Ne znam koliko vas koristi twitpic.com ali je jako dobra stvar. Deljenje slike preko tvitera (da, mora tviter nalog). Pa ako koristite pomenute servise i zelite stream slika sa twitpic-a evo, uz minimalno PHP kodiranje :)

HTML blok

Pre svega HTML, prvi deo je poprilicno klasican, "uvlacenje" jQuery fajlova, prvij je jQ, ostala tri linka je ustvari plugin pisan od strane Mike Alsup, i na kraju malo CSS

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.5/jquery.min.js"></script>
<script type="text/javascript" src="http://malsup.github.com/chili-1.7.pack.js"></script>
<script type="text/javascript" src="http://malsup.github.com/jquery.cycle.all.js"></script>
<script type="text/javascript" src="http://malsup.github.com/jquery.easing.1.3.js"></script>
<style type="text/css">
	#slideshow { height: 182px; width: 182px;}
	#slideshow img { padding: 15px; border: 1px solid #ccc; background-color: #eee; cursor: pointer;}
	.nav {width: 182px;}
	.status {width: 140px; float: left;}
	#prev {width: 20px; float: left;}
	#next {width: 20px; float: right;}
</style>

Sledeci deo nema puno za objasnjavati, dva DIV-a, prvi #slideshow koji "drzi" slike, i drugi #nav koji sadrzi dve slike koje sluze za kontrolu prikaza, tu je i PHP foreach koja "izvrti" xml objekat koji je ranije pre svega pozvan.

<div id="slideshow" class="pics">
	<?php foreach($xml->channel->item as $path) { ?>
		<a title="<?php echo str_replace('miff78: ', '',$path->title);?>" href="<?php echo $path->link;?>">
			<img src="<?php echo findThumb($path->link);?>" alt="" width="150" height="150"/>
		</a>
	<?php } ?>
</div>
<div class="nav">
	<div id="prev"><img src="twp/prev1.png"/></div>
	<div class="status"></div>
	<div id="next"><img src="twp/next1.png"/></div>
</div>

JS blok

Ispod svega jQuery tj JS blok, ready funkcija koja poziva plugin cycle i pomocna funkcija onAfter ako zelite da se nesto dogadja posle prelistane slike :)

<script type="text/javascript">
    $(document).ready(function () {
		$('#slideshow').cycle({
			fx:     'scrollHorz', 
			prev:   '#prev', 
			next:   '#next', 
			timeout: 0
			//after: onAfter 
		});
		function onAfter() {
			$('.status').html(this.title);
		}
    });
</script>

PHP blok

PHP blok ima dve funkcije, prilicno jednostavno. Prva, ucita xml fajl za datog korisnika u jedan veliki niz, dok druga dodje kao pomagac i bavi se str_replace operacijom.

<?php
function getPic($uid){
		$url = 'http://twitpic.com/photos/'. $uid . '/feed.rss';
		$xml = simplexml_load_file($url) or die('Nisam uspeo da se ucitam fajl!');
		return($xml);
	}
	function findThumb($s) {
		$thumb = str_replace('http://twitpic.com', 'http://twitpic.com/show/thumb', $s);
		return($thumb);
	}
?>

Zadnju liniju koda koju ce te dodati je:

<?php $xml = getPic('miff78');?>

i ona ide u sam vrh dokumenta.

Source je ovde.

Ne zaboravite da mora SimpleXML, svuda gde pise miff78 zameniti sa zeljenim korisnickim imenom, takodje  na pojedinim hostovima mora da se doda php.ini u direktorijumu gde je skripta, ovaj red allow_url_fopen = on. 

Twitter status PHP verzija

Sa ukusom PHP-a :)

Ako vam ikada zatreba TL sa tvitera u PHP verziji, tu je. Potrebno je samo da je SimpleXML instaliran na serveru.

<?php
	// Init (Pozivanje $param1 = username sa twittera, $param2 = koliko statusa)
	getTwitterStatus('miff78',20);
	/*
	 * $uid = Twitter username // string
	 * $l	= Limit, koliko statusa da se prikazu // int
	 * return: Statuse
	 * */
	function getTwitterStatus($uid,$l){
		$url = "http://twitter.com/statuses/user_timeline/$uid.xml?count=$l";
		$xml = simplexml_load_file($url) or die('Nisam uspeo da se ucitam fajl!');
		echo '<ul>';
		foreach($xml->status as $status){
			$text = findTw($status->text);
			echo '<li>'.utf8_decode($text).'</li>';
		}
		echo '</ul>';
	}
	/*
	 * $s = Teks iz kojeg treba da se zamene @User i #Hashtag sa aktuelnim linkovima // string
	 * return: obradjeni tekst
	 * */
	function findTw($s) {
		$s = preg_replace("#(^|[\n ])([\w]+?://[\w]+[^ \"\n\r\t< ]*)#", "\\1<a href=\"\\2\" >\\2</a>", $s);
		$s = preg_replace("#(^|[\n ])((www|ftp)\.[^ \"\t\n\r< ]*)#", "\\1<a href=\"http://\\2\" >\\2</a>", $s);
		$s = preg_replace("/@(\w+)/", "<a href=\"http://www.twitter.com/\\1\" >@\\1</a>", $s);
		$s = preg_replace("/#(\w+)/", "<a href=\"http://search.twitter.com/search?q=\\1\" >#\\1</a>", $s);
		return($s);
	}
?>

 

 

Dok ne sredim ovaj prikaz coda, evo zip fajla.

 

PS. RegEX je mozda mogao bolje, zato nemoj odma neko da me napljuje nego neka napise u komentar :)