RSS Facebook Pusha Bloggy TwitThis Google Digg

DateTime och Fileinfo – Nyheter i PHP 5.3

Detta är del tre i serien om nyheter i PHP 5.3. Tidigare har jag skrivit om Namespaces, Lambda och closures och idag tänkte jag skriva om nyheterna i DateTime-objektet samt fileinfo funktionen.

Ingen av de här funktionerna är helt nya, DateTime klassen har funnits sedan 5.2 men i PHP 5.3 har det tillkommit nya funktioner, Fileinfo har tidigare funnits som PECL paket.

Hantera datum med DateTime

I första delen tänkte jag visa lite nyheter på DateTime-objektet, hur vi lägger till och tar bort ett tidsinterval samt hur vi räknar ut skillnaden mellan två datum.

Definiera tidszon

Innan vi börjar hantera datum måste vi första definiera vilken tidszon vi befinner oss i, detta gör vi på följande sätt.

date_default_timezone_set('Europe/Stockholm');

Skapa ett DateTime-object

$dateObject = new DateTime();
echo $dateObject->format('Y-m-d H:i:s'); //Prints 2010-02-03 22:33:55

Lägg till 2 dagar och en timma

$dateObject = new DateTime();
$dateObject->add(new DateInterval('P2DT1H'));
echo $dateObject->format('Y-m-d H:i:s');

Här skapar vi ett nytt DateTime-objekt. Sedan använder vi funktionen add för att lägga till ett tidsintervall. Detta gör vi med ett DateInterval objekt som tar en inparameter som vid en första anblick ser ganska konstigt ut, P2DT1H.
Delar vid upp den blir det ganska logiskt, P står för Period, vilket betyder år, månad eller dag. T står för time och betyder således tid. P2DT1H betyder alltså, Period, 2 Dagar, Tid, 1 Timma.

Med funktionen add blir det relativt enkelt att lägga till ett intervall på ett datum. Vill du istället ta bort en tid från ett datum använder du funktionen sub.

Ta bort 2 dagar och 1 timma

$dateObject = new DateTime();
$dateObject->sub(new DateInterval('P2DT1H'));
echo $dateObject->format('Y-m-d H:i:s');

Räkna ut skillnaden mellan två datum

$dt1 = new DateTime('2010-02-13');
$diff = $dt1->diff(new DateTime());

Vi använder funktionen diff på DateTime-objektet. Skriver vi ut $diff innehåller den följande.

Här kan vi väldigt enkelt se hur lång tid det skiljer mellan datumen, 8 dagar, 4 timmar, 27 minuter, 5 sekunder. Vi kan enkelt skriva ut hur många dagar det är kvar, i detta fall till min födelsedag.

 echo $diff->days

Hämta filinformation med Fileinfo

Som jag nämnt tidigare har Fileinfo tidigare funnits tillgängligt via PECL. Via Fileinfo kan man ta reda på vilken content-type och encoding en fil har.

<?php
$finfo = finfo_open(FILEINFO_NONE);
$info = finfo_file($finfo, 'logo.png');
echo "FILEINFO_NONE => " . $info;
finfo_close($finfo);
?>

Vi börjar med att skapa en ny finfo resurs med finfo_open. Här skickar vi med fördefinierade konstanter och i detta fall, FILEINFO_NONE. Här hittar du fler fördefinierade konstanter.

Sedan använder vi funktionen finfi_file och skickar med finfo-resursen och vilken fil vi ska kontollera, i detta fall en png bild. Sist anropar vi funktionen finfo_close för att stänga resursen.

Här är resultatet av FILEINFO_NONE och FILEINFO_MIME

FILEINFO_NONE => PNG image, 250 x 48, 8-bit/color RGBA, non-interlaced
FILEINFO_MIME => image/png; charset=binary

Vidare läsning

Hoppas denna lilla introduktion gav dig något och vill du läsa mer om dessa klasser rekommenderar jag självklart php.net.
DateTime
Fileinfo information

Demo och källkod

Se Demo eller ladda ner källkoden här

RSS Facebook Pusha Bloggy TwitThis Google Digg

Facebook lanserar HipHop för PHP

I min förra post, veckans länktips, berättade jag att Facebook bygger om PHP och eventuellt utvecklar en ny kompilator för PHP, riktigt så var det inte. Men idag kom svaret på denna gåta?, Facebook lanserar HipHop. Med HipHop har teamet på Facebook lyckats reducera CPU användningen med ca 50%.

Vad är HipHop?

HipHop är alltså ingen ny kompilator för PHP utan snarare en källkodsomvandlare. HipHop omvandlar nämligen PHP kod till optimerad C++ kod för att sedan kunna kompileras med g++.  Koden kommer fortfarande att köras på ett likvärdigt sätt men vissa funktioner  som används sällan som till exempel eval() har tagits bort för bättre prestanda.

Facebook levererar 400 miljarder php-baserade sidvisningar varje månad, ja du läste rätt.

Enligt utvecklarna var den största utmaningen att bygga ihop klyftan mellan PHP och C++, en av anledningarna är att PHP har dynamiska funktioner och det är löst typat medan C++ är hårt typat.

Vill du läsa mer om HipHop och utveckling rekommenderar jag den officiella bloggen.

Ta del av HipHop

Teamet bakom HipHop har skrivit över 300.000 rader kod och över 5.000 enhetstester. Det fina i kråksången är att de kommer släppa HipHop under  PHP Open Source License och det ska finnas tillgängligt att ladda ner via github inom kort.

RSS Facebook Pusha Bloggy TwitThis Google Digg

iPhonebilder på Google Maps via GPS-tag

Det var ett tag sedan jag skrev en guide inom PHP nu, därför tänkte jag skriva lite Google Maps och PHP:s funktion exif_read_data.

Jag kommer i detta exemplet visa hur du plockar ut GPS-information från bilder tagna med en iPhone för att sedan visa vart bilden är tagen på Google Maps. Som nämnt tidigare kommer jag använda funktionen exif_read_data som hämtar ut exif-information från jpg bilder.

Beroende på vilken kamera bilden är tagen med kan man få ut information om bilden, till exempel GPS position, när bilden är tagen, vilken bländarinställning som användes med mera, men nu ska vi fokusera på att hämta ut GPS position.


Läs hela “iPhonebilder på Google Maps via GPS-tag

RSS Facebook Pusha Bloggy TwitThis Google Digg

Nyheter i PHP 5.3 Del 2 – Namespaces

I en tidigare post skrev jag om Nyheter i PHP 5.3 och visade funktionaliteten med Lambda och Closures. Naturligtvis var inte detta de ända nyheterna. Jag tänkte därför i denna post gå igenom den kanske bästa nyheten, nämligen Namespaces.

Den främsta anledningen att använda Namespaces är för att komma ifrån problemet med namnkollisioner. Zend har tidigare löst det med en hierarki, till exempel Zend_Db_Table. Dessa kan dock bli väldigt långa som till exempel denna Zend_Search_Lucene_Analysis_Analyzer_Common_TextNum_CaseInsensitive()

Ett exempel med Namespace

Jag kommer gå igenom ett väldigt enkelt exempel med namespace.

namespace Blog;
class User
{
	public function Hello()
	{
		echo "Hello World! from " . __NAMESPACE__ . " - " . __CLASS__;
	}
}
 
namespace CMS;
class User
{
	public function Hello()
	{
		echo "Hello World! from " . __NAMESPACE__ . " - " . __CLASS__;
	}
}

I detta exemplet har vi skapat två stycken namespaces, Blog och CMS. Här ser man redan fördelar med att använda namespaces, vi kan i detta exemplet nämligen ha två klasser med samma namn, User.

För att avända våra namespaces, klasser och funktioner använder vi följande kod.

$object = new CMS\User();
$object2 = new Blog\User();
 
$object->Hello();
$object2->Hello();

Resultatet av följande kod kommer bli:
Bild 20
Ett annat tips när det gäller namespaces är att du kan skapa ett alias för en klass.

use CMS\User as cmsuser;
use Blog\User as bloguser;
$object = new cmsuser();
$object2 = new bloguser();

Här skapar vi två stycken alias, cmsuser och bloguser, dessa kan vi sedan använda för att skapa objektet.

Sub-namespaces

Namespaces fungerar i stort sätt som en katalogstruktur. Du kan alltså skapa sub-namespaces, till exempel.

namespace Baronen\Blog;
class User
{
	public function Hello()
	{
		echo "Hello World! from " . __NAMESPACE__ . " - " . __CLASS__;
	}
}

Notera här att jag har ändrat namnet till Baronen\Blog. Tillvägagångssättet för att använda klassen är detsamma.

$object = new Baronen\Blog\User();

Vill du läsa mer om namespaces rekommenderar jag som vanligt den officiella dokumentationen.

Vill du veta mer om nyheterna i PHP 5.3 hittar du det här.

Som jag nämnt tidigare hoppas jag webbhotellen tar till sig nya versionen av PHP så snart som möjligt.

RSS Facebook Pusha Bloggy TwitThis Google Digg

Nyheter i PHP 5.3

I somras lanserades PHP 5.3 och det innebar mycket nyheter och trevliga godsaker. Jag har idag tagit tag i saken och installerat PHP 5.3 på vår server på kontoret, det tog lite tid med till slut gick det. Jag är väldigt exalterad över den nya versionen och all ny funktionalitet, jag hoppas verkligen inte det tar alltför lång tid innan PHP 5.3 blir standard på webbhotellen.

Det är väldigt mycket gamla saker som är förbättrade i nya versionen till exempel är md5() snabbare och konstanter är flyttade till read-only minnet. Enligt uppgifter ska prestandan vara 5%-15% bättre.

Men det är inte bara förbättringar utan väldigt mycket nya funktioner också, Namespaces, Lambda, Closures, Late static binding och garbage collector är några av nyheterna. Jag tänkte gå igenom några av nyheterna och visa kodexempel. Jag kommer göra detta i två delar, i denna del kommer jag att titta på Lambda och Closures. Detta är nytt för mig så vi får se hur det går.

Lambda funktioner och Closures

Lambda eller anonyma funktioner är funktioner som kan skapas när som helst och är ofta knutna till en variabel. Har du programmerat javascript kommer du känna igen det.

Jag tänkte visa ett exempel där vi använder lambda ihop med funktionen array_filter.

$input = array('andreas', 'tord', 'bo', 'kim', 'johannes');
$output = array_filter($input, function ($v) { return strlen($v) > 3; });
print_r($output);

Vi börjar med att skapa arrayen input som innehåller ett antal namn. Vi använder sedan funktionen array_filter som tar $input och andra parametern är det som kallas Lambda eller anonyma funktioner.
Vi skapar alltså en anonym funktion, i denna funktionen kontrollerar vi vilka namn som är längre än tre tecken och returnerar dom.
Kollar vi på resultatet ser det ut som följande.

Bild 13

Som vi ser nu är bara tre namn kvar, de som är längre än tre bokstäver.

Closures

Att skapa anonyma funktioner har man kunnat göra tidigare med funktionen create_function(). Nu ska vi titta vidare på det som kallas Closures. Closures är nästan som anonyma funktioner med skillnaden att de känner till variabler som inte är skapade i sig själva.

Om vi tittar på exemplet nedan så har vi $globalVar som ligger utanför funktionen, denna kan vi sedan använda i funktionen genom att använda ordet use. Vi skickar den som referens genom att använda &.

$globalVar = 1;
$closure = function($arg) use (&$globalVar) {
	echo "Medskickad parameter: " . $arg . " - " . ++$globalVar;
};
$closure('Parameter 1') . "<br />";
$closure('Parameter 2') . "<br />";

Det här var två exempel på Lambda och Closures i nya PHP 5.3

Ny Magisk metod __invoke

Slutligen tänkte jag visa den nya magiska funktionen __invoke. Detta är en funktion som körs när man försöker köra ett objekt som en funktion, $object('hej').

class Demo{
	public function __invoke($args){
		echo $args;
	}
}
$object = new Demo();
$object('hej');

Anropar man nu objektet som som en funktion så kommer __invoke rycka och och i detta exemplet skriva ut ‘hej’.

Som jag nämnde tidigare såg är jag väldigt uppjagad över nya PHP och jag hoppas verkligen att flertalet webbhotell kommer uppgradera sina versioner inom kort.

RSS Facebook Pusha Bloggy TwitThis Google Digg

Förenkla PHP med autoload

När man bygger webbplatser i PHP är det ganska lätt att antalet klasser springer iväg. Använder du dig av “require” eller “include” för att inkludera dessa klasser kan det bli väldigt omständligt och rörigt.

Jag tänkte därför tips om en funktion som heter spl_autoload_register som gör att PHP kan själv ladda in de klasser som behövs. Det är väldigt enkelt och det behövs inte mycket kod för att åstadkomma detta.

Börja koda

Vi kommer i första delen av exemplet använda en index-fil, en mapp som innehåller en klass.

Bild 27

//Set the includepath
set_include_path(get_include_path().PATH_SEPARATOR."lib");
function autoload($class) {
	include $class.".php";
}
spl_autoload_register('autoload');

Här börjar vi alltså med att ställa sökvägen till inkluderingsmappen, i detta fall mappen “lib”. Vi skapar sedan en vanlig funktion vi kallar autoload som helt enkelt inkluderar den klass vi skapar. Slutligen använder vi funktionen spl_autoload_register och skickar med namnet på vår autoload-funktion.

Notera, för att detta ska fungera ska klassnamnet och filnamnet vara likadant, vilket ändå är en bra regel att använda sig efter.

I mappen “lib” skapar vi en testklass där filnamnet blir “Test.php” och klassnamnet blir alltså “Test”. Nu kan vi alltså skapa nya objekt/klasser och PHP kommer automatiskt att inkludera dessa när det behövs.

$test = new Test();

Använda undermappar och autoload

Som jag nämnde inledningsvis är autoload kanon när man har många klasser i sin applikation. Men att lägga alla klasser i mappen “lib” kan bli väldigt rörigt. Därför tänkte jag även visa ett exempel på hur man kan ha undermappar och ändå ladda in klasser automatiskt.

Vi börjar med att skapa undermappar i mappen “lib” och skapar sedan två nya klasser.

Bild 28

För att kunna ladda in klasser som ligger i undermappar måste vi förändra vår autoload-funktion en aning.

set_include_path(get_include_path().PATH_SEPARATOR."lib");
function autoload($class) {
	$class = str_replace('_', '/', $class);
	include $class.".php";
}
spl_autoload_register('autoload');

Det vi har lagt till nu är att vi använder str_replace för att byta ut “_” till “/”.

I och med denna metod måste vi döpa våra klasser på följande sätt “Mapp_Klassnamn”. Vill du läsa mer om standard för namngivning rekommenderar jag Zend’s standard.

Klassen Mailer kommer alltså sen ut enligt följande:

class Mail_Mailer
{
	public function __construct()
	{
		echo "Created a mailer object <br />";
	}
}

För att skapa ett nytt Mailer-objekt gör vi enligt följande.

$mailer = new Mail_Mailer();

Den här metoden med “Mapp_Namn” lämpar sig bra för PHP-versioner under 5.3 då stöd för Namespaces finns i 5.3.

Demo och källkod

Se demo eller ladda ner källkoden här.

RSS Facebook Pusha Bloggy TwitThis Google Digg

Skapa korta länkar med bit.ly och PHP

I och med att användandet av mikrobloggtjänster har ökat och folk delar mycket länkar har förkortningtjänster blivit väldigt populära. Jag tänkte därför visa hur du bygger en enkel PHP-klass och använder en av de populära tjänsterna, bit.ly. Notera att för att använda förkortningstjänsten bit.ly krävs det att du har ett konto och en API-nyckel från tjänsten.

När du väl har fixat din API-nyckel och har ett konto så är det dags att börja koda. Kollar vi på den officiella dokumentation så ser vi att länken vi använder ser ut enligt följande: http://api.bit.ly/shorten?version=2.0.1&longUrl=http://baronen.org&login=anvadare&apiKey=APINyckel&format=json
Vi skapar sedan vår ganska enkla klass som innehåller en statisk funktion, GetShortUrl.

class Bitly
{
	public static function GetShortUrl($url, $login, $api, $format = 'json')
	{
		$bitly = "http://api.bit.ly/shorten?version=2.0.1&longUrl=".$url."&login=".$login."&apiKey=".$api."&format=".$format;
		$response = file_get_contents($bitly);
 
		if($format == 'json') {
			$resultJson = json_decode($response, true);
			return $resultJson['results'][$url]['shortUrl'];
		} elseif ($format == 'xml') {
			$resultXml = simplexml_load_string($response);
			return $resultXml->results->nodeKeyVal->shortUrl;
		} else {
			return "Wrong type supplied: " . $this->format;
		}
	}
}

APIet tillåter att man väljer vilket format man vill ha tillbaka resultatet i, jag har byggt denna klass så man kan välja både json och xml.
För att sedan använda klassen anropar du den statiska funktionen. I detta exempel förkortar jag baronen.org, jag skickar även med bitly-användare, api-nyckel samt att jag vill använda formatet xml.

<?php echo Bitly::GetShortUrl('http://www.baronen.org', 'Anvandare', 'API-Nyckel', 'xml'); ?>

Resultat och demo

Se demo eller ladda ner källkoden.

RSS Facebook Pusha Bloggy TwitThis Google Digg

Så här använder du INI-filer med PHP

Nu var det ett tag sedan jag skrev nåt här på baronen, så jag tyckte det var dags nu. I denna post tänkte jag bara tipsa om PHP-funktionen parse_ini_file, som tillåter dig att enkelt använda en konfigurationsfil i form av en .ini.

Vi börjar med att skapa settings.ini där vi ska spara lite information. I denna fil har vi lagt till två sektioner, site och database, dessa innehåller sedan olika värden.

[site]
version = 0.1
develop = true
 
[database]
host = localhost
username = root
password = root
table = site

För att sedan läsa ut inställningarna använder vi alltså funktionen parse_ini_file. Denna funktion returnerar en eller flerdimensionella arrayer beroende på parametrar.

$iniFile = parse_ini_file('settings.ini', true);

Som andra inparameter i funktionen skickar vi med true, detta för att få med alla sektioner i INI-filen. Om vi nu kollar vad $iniFile innehåller ser vi följande.

Bild 6

Vi kan nu använda denna information som en vanlig array, där vi kan hämta ut version, databasanvändare med mera.

Här är två små exempel på hur man kan använda detta.

if($iniFile['site']['develop']) {
	error_reporting(E_ALL|E_STRICT);
	ini_set('display_errors', 1);
}
echo "Du använder just nu version: " . $iniFile['site']['version'];

Svårare än så är det inte att använda sig av en INI-fil för att spara  inställningar. Detta är bara ett väldigt enkelt exempel också, man bör har en egen klass som sköter detta på ett bättre sätt, samt använda Singleton-mönstret.

Värt att tänka på är att lägga INI-filen utanför “www-mappen”, detta för att inga obehöriga ska kunna öppna och läsa filen, kan bli så dumt om man sparar databasuppgifter och annan känslig data.

Vill du veta mer om parse_ini funktionen rekommenderar jag den officiella dokumentationen.

RSS Facebook Pusha Bloggy TwitThis Google Digg

Method Chaining i PHP – metodkedjor

I och med PHP 5+ och stödet för objekt finns det något som kallas Method Chaining. Detta innebär att du kan köra flera funktioner/metoder efter varandra.

Ett ganska vanligt förekommande sätt att använda objekt på är följande.

$userObj = new User();
$userObj->setUsername('baronen');
$userObj->setEmail('mail@mail.com');
$userObj->RegisterUser();

Här skapar vi ett nytt User objekt, sedan anropar vi två set-funktioner för att sedan köra funktionen RegisterUser.

Använd Method Chaining

Man behöver inte göra stora ändringar för att skapa metodkedjor. Jag har här skapat en väldigt enkelt User-klass som har två set funktioner och en funktion för att skriva ut egenskaperna.

class User
{
    private $username;
    private $email;
 
    public function setEmail($email) {
        $this->email = $email;
	return $this;
    }
    public function setUsername($username) {
        $this->username = $username;
	return $this;
    }
    public function RegisterUser() {
	echo "Register user with email <strong>" . $this->email . "</strong>";
	echo " and username <strong>" . $this->username . "</strong>";
    }
}

Den ända skillnaden från en “vanlig” klass är att set-funktionerna returnerar hela objektet, detta för att kunna bygga på med fler funktioner på följande sätt.

$userObj = new User();
$userObj->setEmail('baronen@mail.org')->setUsername('baronen')->RegisterUser();

Resultatet blir i detta fall följande:
Register user with email baronen@mail.org and username baronen

Svårare än så är det inte att använda sig av “Method Chaining”.

Resultat

Se demo eller Ladda ner källkod här.

RSS Facebook Pusha Bloggy TwitThis Google Digg

Antal RSS-läsare via Feedburner API

I denna lilla guide tänkte jag gå igenom hur man kan använda Feedburners API för att hämta ut antalet prenumeranter man har på sitt RSS-flöde.

När jag gjorde ny design till bloggen ville jag inte ha Feedburners fula “widget” Bild 2 som visar antal prenumeranter. Jag började istället undersöka deras API i, och jag kom fram till att den inte var alls svårt att hämta ut antalet.
Läs hela “Antal RSS-läsare via Feedburner API

Nästa