Twitter API aplikācija ar cache funkcionalitāti
Izveidoju nelielu pamācību, kā ar Twitter API palīdzību savākt datus no sava twitter konta. Twitter API piedāvā dažādus veidus kādā formātā iegūt datus, tai skaitā xml, json, atom un rss. Es šoreiz izmantošu json, php un curl lai nolasītu un attēlotu tvītus no lietotājiem, kuriem es sekoju un attēlotu tos lietotājam saprotamā formātā.
Kādam varbūt radīsies jautājums kāpēc ir nepieciešams kešot tvītus? Atbilde ir pavisam vienkārša: Twitter no viena lietotāja konta ļauj veikt ne vairāk kā 150 pieprasījumus stundā! Ja šis limits tiek pārsniegts, tad vairs nav iespējams neko nolasīt. Un ja lapā būs 300 refreshi stundā, tad pusi no laika, aplikācija vienkārši nestrādās.
<?php
function saveCache($data){
$cache = "coderportfolio.json";
$fp = @fopen($cache,"w");
if(!$fp){
return false;
}
fwrite($fp,$data);
fclose($fp);
}
function readCache(){
$cache = "coderportfolio.json";
if(!file_exists($cache)){
return false;
}
$fp = @fopen($cache,"r");
$buffer = "";
if(!$fp) {
return false;
}else {
while(!feof($fp)) {
$buffer .= fgets($fp,4096);
}
}
fclose($fp);
return $buffer;
}
function LastModified(){
$cache = "coderportfolio.json";
return @filemtime($cache);
}
$login = "lietotājvārds:parole";
$tweeters = array();
$tweeter = array();
$prev = LastModified();
$now = time();
if(!$prev || (( $now - $prev ) > 60)){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://twitter.com/statuses/friends_timeline.json?count=10");
curl_setopt($ch, CURLOPT_USERPWD, $login);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$tweeters = curl_exec($ch);
saveCache($tweeters);
$tweeters = json_decode($tweeters, true);
}else{
$tweeters = json_decode(readCache(), true);
}
if(is_array($tweeters)) foreach($tweeters as $tweets){
$tweets['text'] = preg_replace("#(^|[\n ])@([^ \"\t\n\r<]*)#ise", "'\\1<a href=\"http://www.twitter.com/\\2\" >@\\2</a>'", $tweets['text']);
$tweets['text'] = preg_replace("#(^|[\n ])([\w]+?://[\w]+[^ \"\n\r\t<]*)#ise", "'\\1<a href=\"\\2\" >\\2</a>'", $tweets['text']);
$tweets['text'] = preg_replace("#(^|[\n ])((www|ftp)\.[^ \"\t\n\r<]*)#ise", "'\\1<a href=\"http://\\2\" >\\2</a>'", $tweets['text']);
?><div ><?
echo '<img src="'.$tweets["user"]["profile_image_url"].'" /><h3>'.$tweets['user']['name'].'</h3>';
echo '<p>'.$tweets['text'].'</p>';
echo '<p>From: '.$tweets['source'].'</p>';
?></div><?
}
?>
Pirmais, kas jāizdara pieslēdzoties Twitter API ir jānosūta logins un parole kontam no kura ir nepieciešams iegūt datus. Nākamais solis ir norādīt kādus datus vēlies saņemt. Šajā gadījumā es izvēlējos http://twitter.com/statuses/friends_timeline.json. Bet kā jau minēju datus ir iespējams iegūt dažādos formātos, tos norādot .json vietā, piemēram, .xml!
Tālāk ar curl autentificējoties jau tiek iegūti dati un vienkārši apstrādāti ar php. saveCache(), readCache() un LastModified() atbild par kešosanas funkcionalitāti. 41. rindā tiek pārbaudīts vai kešotā versija jau nav vecāka par vienu minūti, ja ir tad tiek vilkta svaiga informācija no twittera.
Kā tas darbojas dzīvē ir iespējams apskatīt labajā pusē.
Ar pilnu Twitter API dokumentāciju var iepazīties šeit.
Kāpēc vienmēr unserialize() funkcija atgriež bool(false)?
Nesen strādājot pie jauna projekta saskāros ar problēmu, ka unserialize() man visu laiku atgriež false. Sākumā nesapratu, kas par problēmu, līdz pamanīju php.net komentāros, ka to var novērst datus palaižot caur base64_encode.
<?php $safe_string_to_store = base64_encode(serialize($multidimensional_array)); $array_restored_from_db = unserialize(base64_decode($encoded_serialized_string)); ?>
Protams šis nebūs labākais risinājums, kā cīnīties ar šo problēmu, jo base64_encode() datu apjomu palielina par apmēram 33% no sakotnējā datu garuma, bet iemesls tam ir pavisam vienkāršs: serialize() nepatīk slīpsvītras.
To var apiet arī pirms serializēšanas palaižot datus caur stripslashes() funkciju, kas izravētu slīpsvītras.
Kā ar PHP pārbaudīt vai eksistē domēns?
checkdnsrr() funkcija pārbauda vai padotais parametrs eksistē DNS ierakstos.
Piemērs:
<?php
$recordexists = checkdnsrr("coderportfolio.com", "ANY");
if ($recordexists) echo "Domēna vārds jau ir aizņemts!";
else echo "Domēna vārds ir brīvs!";
?>
Atgriezīs: Domēna vārds jau ir aizņemts!
Ja ieraksts eksistēs checkdnsrr() atgriezīs TRUE, pretējā gadījumā FALSE.
checkdnsrr() var izmantot arī lai pārbaudītu vai ievadītās e-pasta adreses domēns eksistē, tādā veidā atsijājot asdfghj@gnlreiu.lv tipa adreses...
<?php
$email = "example@coderportfolio.com";
$domain = explode("@",$email);
$valid = checkdnsrr($domain[1], "ANY");
if($valid) echo "E-pasta adreses domēns eksistē";
else echo "$domain[1] neeksistē!";
?>
Bet jāpiezīmē, ka šādā veidā nevar pārbaudīt vai eksistē pati e-pasta adrese.
Apollo.lv jauna seja!
Apollo ir palaidusi testa versiju, testēšanai un viedokļu izpaušanai. Apollo ir viens no diviem ziņu portālie kuru es apmeklēju ikdienā. Zinu par pārmaiņām pameta Coolynx, kas izrādās ir apollo attīstības nodaļas vadītājs.
Tagad par pašām pārmaiņām.
Pirmais kas iekrita acīs bija nenormālais lapas garums. Apskatoties kaut vai CNN lapu nebūs grūti pamanīt, ka viņiem pirmajā lapā koncentrējas svarīgākais, bet apollo šoreiz manuprāt ir aizšāvuši garām. Iespējams, ka iemesls ir vēlme informēt pēc iespējas lielāku mērķa auditoriju jau ienākot pirmajā lapā. Bet es tiešām apšaubu, ka kāds izvēlētos skrulēt lapu uz 3 metrus attālo apakšējo daļu lai izlasītu ievadtekstus 3 rakstiem par tēmu "IT&T. Zinātne", nevis nospiestu lapas augšējā daļā uz attiecīgas kategorijas kur varētu atrast simtiem rakstu par attiecīgo tēmu.
Otrais kas iekrita acīs bija informācijas dublēšanās. Es nesaprotu kādēļ ir nepieciešams divās un vairāk vietās norādīt uz horoskopiem, vārdadienu svinētājiem un laika ziņām? Manuprāt arī šāda liekas informācijas izņemšana palīdzētu lapas saspiešanai.
Ok ejam tālāk.. Bildes.. Manuprāt tur to ir stipri par daudz. Vai tiešām pie katra raksta vajag ievietot mazu bildīti? Tas manuprāt ir lieki un jau atkal aizņem nevajadzīgu vietu + palielina lapas ielādes laiku. Atgriežoties pie CNN lapas, manuprāt viņiem ir lielisks risinājums jaunāko ziņu sadalīšanai pa kategorijām.

Nav nekādu milzīgu bilžu, ir tikai svarīgākie jaunumi. Šādi izkārtot ziņas nav nekāds jaunums, tikai nav skaidrs kāpēc apollo neņem, piemēru, no ārzemju kolēģiem.
Variants ko es ieteiktu apollo.lv ir dot lasītājam iespēju pašam sakārtot portāla sākumlapu pēc saviem ieskatiem. Atslēgt un ieslēgt konkrētus blokus. Nav pat svarīgi ļaut kārtot un mainīt bloku atrašanās vietas.. Galvenais ļaut atslēgt informācijas blokus kas lasītājam ir vienaldzīgi, tādā veidā padarot lapu personiskāku. Jāpiebilst gan, ka Latvijā šādu praksi neesmu novērojis.
Tikko pamanīju, ka neesmu pateicis nevienu atzīnīgu vārdu :). Katrā gadījumā žetons apollo par vēlmi kaut ko mainīt un kā vēsta veca paruna - pastāvēs kas pārvērtīsies.
PHP ietvari (Frameworks)! Kāpēc? Kad?
Šī ieraksta sakarā palūgšu ievērot to, ka katra brīva izvēle ir izvēlēties vai neizvēlēties izmantot ietvaru un ja izmantot tad kādu. Bet tagad ķeramies pie lietas..
Galvenā piekšrocība ietvaros manuprāt slēpjas tajā, ka tā palīdz samazināt web aplikāciju izstrādes laiku, sniedzot pamata struktūru uz kuras balstīt savu aplikāciju, kā arī MVC (Model View Controller).
Kā jau varētu noprast ietvari satur ļoti daudz visādu noderīgu bibliotēku. Piemēram, ja tev ir nepieciešamība novalidēt formas datus tev vairs nebūs kā ierasts jāraksta visas validācijas no nulles, pietiks ar pāris rindiņām, kas ielādēs bibliotēku un novalidēs datus.
MVC priekšrocība ir tāda, ka tiek izolēta lietotāja daļa no aplikācijas daļas, līdzīgi kā tas ir ar XHTML un CSS. Bet jāpiebilst, ka ne visi PHP ietvari seko MVC noteikumiem.
Lai labāk izprastu MVC zemāk ir, piemērs, ar mašīnu:
A car is a good real-world example of MVC. With a car you have two views: the interior and the exterior. Both take input from the controller: the driver. The brakes, steering wheel and other controls represent the model: they take input from the controller (driver) and hand them off to the views (interior/exterior) for presentation.
Šobrīd jau liekas, ka lielākā daļa ir sākuši strādāt ar ietvariem, vai tas būtu JavaScriptā, Rubijā vai PHP. Bet ar PHP veidojas problēma un tā ir tāda, ka ir pieejami tik daudz ietvari, katrs ar saviem plusiem un mīnusiem, ka paliek jau grūti izvēlēties īsto ar kuru strādāt.
Kādi ir mīnusi izmantojot ietvarus?
Protams monētai ir divas puses!
- Dažādiem ietvariem ir dažādas sintakses. Tev būs jāmācās jauna koda sintakse, atkarībā no ietvara kuru izvēlēsies. Tādēļ ietvars var likt tev mācīties visu no nulles.
- Kodēšanas procesā izmantojot ietvaru, dažreiz var rasties situācija, kad tu nevarēsi atrast bibliotēku kura derētu tavai problēmai, tādēļ var nākties kādu laiciņu pacīnīties.
- Ja tev nav OOP pieredzes tad PHP MVC ietvari nav domāti tev. No sākuma mans ieteikums būtu iegūt pamatzināšanas par OOP un tikai tad domāt par ietvaru izmantošanu.
- Manā skatījumā ietvari nav domāti maziem projektiem, tādēļ ka nelielā projektā paša rakstīts kods strādās ātrāk par ietvaru. Nav nepieciešams mušas nogalināšanai izmantot lielgabalu!
Kad izmantot ietvaru?
Uz šo jautājumu nav vienotas atbildes. Bēt kā jau minēju iepriekš, nebūtu prāta darbs izmantot ietvaru kalkulatora veidošanai vai tamlīdzīga tipa darbam.
Nav jābūt ģēnijam lai saprastu ka ietvars samazinās gan izstrādes laiku, gan pieliktos pūliņus, tāpēc es noteikti ieteiktu izmantot ietvaru ja tuvojas deadline.
Kādu ietvaru izmantot?
Lietas kurām būtu jāpievērš uzmanība izvēloties ietvaru:
- Vai tas ir labi dokumentēts?
Es uzskatu ka dokumentācija ir būtiska ikvienam produktam - tātad tādai ir jābūt arī priekš ietvara. Iedomājies kur PHP šobrīd atrastos ja tai nebūtu lieliska dokumentācija! Kā es varētu apgūt kādu programmēšanas valodu ja tai nebūtu labas dokumentācijas? Tas būtu mokpilns process... un visdrīzāk es tādu valodu nemācītos, ja komplektā nebūtu dokumentācija no kuras ir arī jēga. Vēl nesen bija doma, izmantot extjs viena projekta ietvaros, bet šī doma atkrita pēc tam, kad biju mēģinājis kaut ko saprast no viņu dokumentācijas. Labi, piemēri, dokumentācijai:
- Vai ietvaram ir kopiena?
Ietvars kuru neviens neizmanto ir nelietojams. Ko tu darīsi, ja tev radīsies kādas problēmas? Vai tev būs iespēja kādam pajautāt pēc padoma? Kā tas būs iespējams, ja to neviens nelietos? Nedomāju, ka kāds tērēs laiku lai meklētu risinājumu tavai problēmai, ja viņam nebūs bijusi saskare ar to ievaru kuru tu izmanto savai izstrādei. Vismaz es netērētu...
- Vai ietvars izmanto tev pieņemamu licenci?
Vienalga kādu licenci izmanto ietvars vai tā būtu MIT, BSD-Style vai LGPL, jautājums paliek tāds pats: Vai tavam darbam der viņu licence?
- Vai tavs serveris ir savietojams ar ietvaru?
Svarīgs ir arī punkts par servera savietojamību ar ietvaru. Nav jēgas no ietvara, ja tu nevari nodrošināt prasības kādas tas nosaka. Daudzi ietvari mūsdienās strādā sākot no PHP 5. Tāpēc pirms izvēlies ietvaru izpēti viņa prasības! Varbūt, ka paredzamā projekta hostinga nodrošinātājs nemaz nenodrošina minimālās ietvara prasības pēc PHP, MySQL vai Apache versijām.
Manuprāt TOP 3, šobrīd pieejamie ietvari!
- CodeIgniter ir labi zināms un viegli lietojams ietvars, kas šobrīd ir arī mans favorīts. Pretēji Symfony šis PHP ietvars ir ideāls priekš šārētajiem hostingiem. Tas piedāvā vienkāršu risinājumu un tam ir milzīga video pamācību bibliotēka, forums un lietotāju rokasgrāmata. Iesācējiem noteikti vajadzētu apsvērt CodeIgniter izmantošanu.
- The Zend Framework'am ir milzīga koderu kopiena. Tas ir vērsts uz web 2.0 un web servisu stila aplikācijām. Zend ir viens no, ja ne pats populārākais ietvars kas šobrīd ir pieejams. Tam ir plašas iespējas un domāts galvenokārt lielu projektu izstrādāšanai. Lai to lietotu ir jābūt plašām PHP zināšanām.
- CakePHP ir laba izvēlē gan priekš iesācējiem, gan priekš pieredzējušākiem PHP koderiem. Tas ir balstīts uz tādiem pašiem principiem kā Ruby on Rails padarot to par lielisku ietvaru priekš kodēšanas kurai nav atveltīts daudz laika. Lai gan CakePHP nav tā labākā dokumentācija tomēr tā strauji aug un vienkāršība, kas piemīt CakePHP, padara to par iekārojamu objektu daudziem koderiem.
Namespace beidzot arī PHP
Namespace ir viena no ievērojamākajām lietām, kas ir ieviesta sākot ar PHP 5.3.
Kam ir nepieciešams Namespace?
Pieaugot koda garumam pieaug arī iespējamība, ka tā ietvaros var tik atkārtoti nodefinēts tāds pats funkcijas vai klases nosaukums divas vai vairākas reizes. Tas protams nav pieļaujams, bet problēmu vēl vairāk saasināja, tas ka ja tika izmantotas trešās puses klases tad funkciju un klašu atkārtotā definēšana pieauga vēl vairāk.
Līdz šim vienīgais variants kā to atrisināt bija vai nu garu klašu un funkciju nosaukumu definēšanu vai prefixu pielikšana, piemēram, WordPress izmanto WP_ prefixu. Par to vairs nav jāuztraucas, jo PHP tas ir labots ieviešot namespaces.
Namespace lietošana citās valodās un izvēle par labu "\"
Java: Attribute/Method access: foo.bar Static method access: Foo.bar Package access: foo.bar.baz C#: Attribute/Method access: foo.bar Static method access: Foo.bar Namespace access: foo.bar.baz Python: Attribute/Method access: foo.bar Static method access: Foo.bar Module access: foo.bar.baz PHP: Attribute/Method access: $foo->bar Static method access: Foo::bar Namespace access: foo\bar\baz
Tātad kā var redzēt tad šajā ziņā PHP atšķiras ar savu dažādību :). Šeit var sīkāk palasīt par to kādēļ tika izvēlēts tieši "\" simbols. Jāatzīst, ka sakumā es pret to attiecos nedaudz negatīvi, likās dīvaini izmantot escape simbolu šim nolūkam. Kā jau RFC diskusijā tika minēts, \ ir vienkārši uzrakstāms, tas satur tikai vienu simbolu un windows pasaulē tas jau ir zināms kā hierarhijas atdalītājs (C:\Mani_Faili\utt).
Sākumā tika apsvērta ideja arī izmantot ::, bet tā tika atmesta, jo tad rastos nesaprašanās, tādēļ ka tas jau tiek izmantots kā statisko metožu operators.
class Foo {
static function bar() { }
}
namespace Foo;
function bar() { }
Foo::bar(); // kas tad šeit tiek izsaukts? Klase Foo::bar vai namespace Foo::bar?
Protams, izcēlās arī diskusijas par to, ka \ izskatās pretīgi un ir nepiemērots namespaciem, bet ar ko tad \ ir pretīgāks par $, /, ::, ->? Tas man atgādina laiku, kad Longhorn pārsauca par Vistu, tas pats ir vērojams arī tagad, bet jo ātrāk cilvēki sapratīs, ka tas ir tikai vārds vai simbols jo labāk. lasi tālāk...
PHP goto operators
Par jauno PHP goto operatoru, kas ir ieviests ar PHP 5.3 versiju ir vairāki viedokļi. Vieni saka, ka tāds nav nepieciešams tādā programmēšanas valodā, citi atkal atbalsta goto ieviešanu.
Tad nu neliels apkopojums par goto:
Goto ir ļauns
Atceros savu pirmo pieredzi ar Basic, vairākus gadus atpakaļ, kad es vēl nezināju neko par procedūrām un funkcijām. Strādājot ar goto (bāzētiem uz līniju numuriem) bija vienīgais veids kā kaut ko panākt. Tāda ir mana sākotnējā programmēšanas pieredze. Kods izskatījās briesmīgi un praktiski nebija lasāms (iedomājies par rindiņu pārnumurēšanu, kad tu vēlies ievietot kodu). Tad universitātē sākās Pascal laiki un goto bija velns zemes virsū...
Vai tagad redzi problēmu kāpēc goto tiek uzskatīts par ļaunu? Manās acīs goto ir citu iespēju nezināšanas trūkums.

Goto konfiktē ar OOP jēdzienu
Manuprāt šis apgalvojums nav īsti pareizs. Kas man vienmēr ir paticis PHP ir tas, ka man ir iespēja izvēlēties kā atrisināt savu problēmu. OOP ir laba lieta, bet tā nav obligāta. Iespēja izvēlēties kā atrisināt kārtējo projektu ir brīvība, kas man patīk. Vēl labāk ir iespējams arī kombinēt. Tātad kur ir tā sliktā puse, tam ka tiek pievienota jauna kodēšanas tehnika un dota iespēja lietotājam izvēlēties? Vai tiešām kāds domā, ka kods tiks radīts nelietojams tikai tāpēc, ka tagad ir dota tāda iespēja?
Switch piedāvā to pašu
Savā ziņā tam nevar nepiekrist, bet izmantojot switch kā goto a) tas izskatās pretīgi un b) nodrošina tikai vienu lēcienu atkarībā no vērtības.
Manuprāt goto lietošanas iespējamība nav nekas slikts un drošības ierobežojumi priekš goto liekas pietiekami, lai neradītu problēmas:
- Nav iespējams lēkāt starp funkcijām
- Nav iespējams lēkāt no vienas koda daļas vienā failā uz citu koda daļu citā failā
Piemērs, kā goto strādā:
<?php
$counter = 0;
main: $counter++;
echo "Esmu sākumā\n";
if ( $counter <= 10 ) {
goto subcat;
} else {
exit;
}
subcat:
echo "Mainam pozīciju\n";
goto main;
?>