<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>David Steinsland - informatikkstudent og webutvikler &#187; Programmering</title>
	<atom:link href="http://davidsteinsland.net/emner/webprogrammering/feed/" rel="self" type="application/rss+xml" />
	<link>http://davidsteinsland.net</link>
	<description>Personlig blogg om programmering og andre uinteressante emner</description>
	<lastBuildDate>Sun, 05 Feb 2012 15:26:20 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Kompilere Java-prosjekter med Apache Ant</title>
		<link>http://davidsteinsland.net/2012/02/kompilere-java-prosjekter-med-apache-ant/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=kompilere-java-prosjekter-med-apache-ant</link>
		<comments>http://davidsteinsland.net/2012/02/kompilere-java-prosjekter-med-apache-ant/#comments</comments>
		<pubDate>Sun, 05 Feb 2012 14:52:54 +0000</pubDate>
		<dc:creator>David Steinsland</dc:creator>
				<category><![CDATA[Apache]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Programmering]]></category>
		<category><![CDATA[apache ant]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[notepad++]]></category>
		<category><![CDATA[windows]]></category>

		<guid isPermaLink="false">http://davidsteinsland.net/?p=678</guid>
		<description><![CDATA[&#160; Når en jobber med store Java-prosjekter som inneholder mange klasse- og kildefiler, kan det være et mareritt å holde styr på alle disse. For ikke å snakke om å sørge for å kompilere alle, én etter én. Apache Ant ble laget for akkurat dette formålet, og har mange likhetstrekk med Make (for de som [...]]]></description>
			<content:encoded><![CDATA[<p>&nbsp;</p>
<p>Når en jobber med store Java-prosjekter som inneholder mange klasse- og kildefiler, kan det være et mareritt å holde styr på alle disse. For ikke å snakke om å sørge for å kompilere alle, én etter én. <a href="http://ant.apache.org/">Apache Ant</a> ble laget for akkurat dette formålet, og har mange likhetstrekk med <em>Make</em> (for de som er kjent med Unix). Ant er et <em>automatisert kompileringsverktøy</em> som kan brukes for å kompilere hele Java-prosjekter med én kommando.</p>
<p>Programmet tar utgangspunkt i en konfigurasjonsfil som er formatert i XML, og styrer hvilke filer som kan kompileres og hvor klassefilene skal ligge. Du kan også velge om du skal opprette JAR-filer for hele prosjektet.</p>
<h3>Installasjon</h3>
<p>Gå til <a href="http://ant.apache.org/bindownload.cgi">nedlastningssiden for Apache Ant</a> og last ned siste versjon. Pakk ut mappen til for eksempel <var>C:\ant\</var>.</p>
<p>Sørg deretter for at du har en miljøvariabel kalt <var>JAVA_HOME</var> med verdien tilsvarende mappen som inneholder JDK. For eksempel slik:<br />
<var>c:\Progra~1\Java\jdk1.7.0\</var></p>
<p>Du må også huske å inkludere <var>C:\ant\bin\</var> i miljøvariabelen <var>PATH</var>.</p>
<h3>Forberedelse</h3>
<p>Opprett en helt enkelt Java-klasse med en <em>main</em>-metode, som du lagrer i en mappe kalt <var>src</var>.</p>
<p>Deretter oppretter du en XML-fil som du kaller <var>build.xml</var> med følgende innhold:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;?xml version=&quot;1.0&quot;?&gt;
&lt;project name=&quot;MySQL&quot; default=&quot;compile&quot;&gt;

	&lt;!-- Configuration --&gt;
	&lt;property name=&quot;src.dir&quot;     value=&quot;src&quot;/&gt;
    &lt;property name=&quot;build.dir&quot;   value=&quot;build&quot;/&gt;
    &lt;property name=&quot;classes.dir&quot; value=&quot;${build.dir}/classes&quot;/&gt;
    &lt;property name=&quot;jar.dir&quot;     value=&quot;${build.dir}/jar&quot;/&gt;
    &lt;property name=&quot;main-class&quot;  value=&quot;Test&quot;/&gt;
	&lt;!-- End Configuration --&gt;

	&lt;target name=&quot;clean&quot;&gt;
        &lt;delete dir=&quot;${build.dir}&quot;/&gt;
    &lt;/target&gt;

   &lt;target name=&quot;compile&quot;&gt;
        &lt;mkdir dir=&quot;${classes.dir}&quot;/&gt;
        &lt;javac srcdir=&quot;${src.dir}&quot; destdir=&quot;${classes.dir}&quot;/&gt;
    &lt;/target&gt;

	&lt;target name=&quot;jar&quot; depends=&quot;compile&quot;&gt;
        &lt;mkdir dir=&quot;${jar.dir}&quot;/&gt;

		&lt;jar destfile=&quot;${jar.dir}/${ant.project.name}.jar&quot; basedir=&quot;${classes.dir}&quot;&gt;
            &lt;manifest&gt;
                &lt;attribute name=&quot;Main-Class&quot; value=&quot;${main-class}&quot;/&gt;
            &lt;/manifest&gt;
        &lt;/jar&gt;
    &lt;/target&gt;

	&lt;target name=&quot;run&quot; depends=&quot;jar&quot;&gt;
		&lt;java jar=&quot;${jar.dir}/${ant.project.name}.jar&quot; fork=&quot;true&quot;/&gt;
    &lt;/target&gt;
&lt;/project&gt;
</pre>
<p>I starten trenger du ikke tenke på mer enn å endre &laquo;TestApp&raquo; til prosjektets navn, samt endre &laquo;main-class&raquo; til den klassen som inneholder main-metoden.</p>
<p>De ulike <em>target</em>-blokkene utgjør kommandoene du kan gjøre med Ant. For eksempel vil vi med denne filen ha følgende kommandoer tilgjengelige:</p>
<pre class="brush: plain; title: ; notranslate">
ant compile
ant jar
ant run
ant clean
</pre>
<p>Dersom du legger merke til linje nummer to, så står det blant annet <var>default=&raquo;compile&raquo;</var>. Dette gjør at dersom vi kjører kommandoen:</p>
<pre class="brush: plain; title: ; notranslate">
ant
</pre>
<p>Så vil den kjøre <em>compile</em>-oppgaven.</p>
<p>Konfigurasjonsfilen skal lagres i prosjektmappen, slik at du ender opp med følgende mappestruktur;</p>
<pre class="brush: plain; title: ; notranslate">
TestApp
+ src/
|	Test.java
+ build.xml
</pre>
<h3>Gjennomføring</h3>
<p>Nå er det lille prosjektet vårt klar til å kompileres.<br />
Start opp kommandolinjen og endre mappe til prosjektet.</p>
<p>For å kompilere prosjektet, skriver du inn kommandoen:</p>
<pre class="brush: plain; title: ; notranslate">
ant
</pre>
<p>Denne kommandoen gjør oppgaven som er spesifisert under <var>&lt;target name=&raquo;compile&raquo;&gt;</var>.<br />
Den oppretter mappen <var>build\classes</var> og lagrer klassefilene der.</p>
<p>For å lage en JAR-fil for videre distribusjon, utfører vi kommandoen:</p>
<pre class="brush: plain; title: ; notranslate">
ant jar
</pre>
<p>Denne er avhengig av at prosjektet først er kompilert, men dette sørger Apache Ant for å gjøre dersom du ikke har gjort det.<br />
Det vil si at vi faktisk ikke trenger å utføre kommandoen <var>ant compile</var> på forhånd.</p>
<p>For å teste at JAR-filen fungerer, kan vi bruke kommandoen <var>ant run</var>.</p>
]]></content:encoded>
			<wfw:commentRss>http://davidsteinsland.net/2012/02/kompilere-java-prosjekter-med-apache-ant/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Tips: Enkle feilmeldinger med animasjon</title>
		<link>http://davidsteinsland.net/2011/07/tips-enkle-feilmeldinger-med-animasjon/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=tips-enkle-feilmeldinger-med-animasjon</link>
		<comments>http://davidsteinsland.net/2011/07/tips-enkle-feilmeldinger-med-animasjon/#comments</comments>
		<pubDate>Sun, 24 Jul 2011 13:34:33 +0000</pubDate>
		<dc:creator>David Steinsland</dc:creator>
				<category><![CDATA[Guider]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[feilmelding]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[jquery]]></category>

		<guid isPermaLink="false">http://blog.davidsteinsland.net/?p=563</guid>
		<description><![CDATA[Her følger en liten kodesnutt som viser en feilmelding i ca. fem sekunder før den fjernes igjen. I dét feilmeldingen vises, blir bakgrunnsfargen forsterket for å få en &#171;se her!&#187;-opplevelse. Dersom musen blir holdt over feilmeldingen, blir den ikke fjernet før etter musepekeren er fjernet fra den. For å få koden til å fungere trenger [...]]]></description>
			<content:encoded><![CDATA[<p>Her følger en liten kodesnutt som viser en feilmelding i ca. fem sekunder før den fjernes igjen. I dét feilmeldingen vises, blir bakgrunnsfargen forsterket for å få en &laquo;se her!&raquo;-opplevelse. Dersom musen blir holdt over feilmeldingen, blir den ikke fjernet før etter musepekeren er fjernet fra den.</p>
<p>For å få koden til å fungere trenger du jQuery og jQuery UI.</p>
<h3>JavaScript:</h3>
<pre class="brush: jscript; title: ; notranslate">
$(function ()
{
	$('div.message').hide().effect ('highlight', {
		color:'#ff8a8a'
	}, 2000).delay(3000).animate({
		height: 'toggle',
		opacity: 'toggle'
	}, 'slow').hover (function ()
	{
		$(this).stop(true, true);
	}, function ()
	{
		$(this).delay(2000).animate({ height: 'toggle', opacity: 'toggle' }, 'slow');
	});
});
</pre>
<p>Om du studerer JavaScript-koden, vil du se at vi bruker effekten &laquo;Highlight&raquo;. Effekten angir feilmeldingsboksen med angitt bakgrunnsfarge, før den fader tilbake til bakgrunnsfargen som er satt i CSS. Alternativt kan en benytte seg av &laquo;pulsate&raquo;, som også gir en ganske behagelig animasjon:</p>
<pre class="brush: jscript; title: ; notranslate">
 $(function() {
    $('div.message').hide().effect('pulsate', {
        times: 2
    }, 450).delay(4000).animate({
        height: 'toggle',
        opacity: 'toggle'
    }, 'slow').hover(function() {
        $(this).stop(true, true);
    }, function() {
        $(this).delay(2000).animate({
            height: 'toggle',
            opacity: 'toggle'
        }, 'slow');
    });
});
</pre>
<p><em>Pulsate</em>-effekten her veksler mellom å skjule/vise feilmeldingsboksen iløpet av 450 millisekunder.</p>
<h3>CSS:</h3>
<pre class="brush: css; title: ; notranslate">
div.message
{
    display:none;
    border:1px solid;
    padding:10px;
    color: #D8000C;
    background-color:#FFBABA;
}

div.message h4
{
    font-weight:bold;
    font-size:14px;
}

div.message p
{
    padding:5px 0;
    font-size:12px;
}
</pre>
<h3>HTML:</h3>
<pre class="brush: xml; title: ; notranslate">
&lt;div class=&quot;message&quot;&gt;
    &lt;h4&gt;An Error has Occured!&lt;/h4&gt;
    &lt;p&gt;
        There was a problem while editing the article. Your data has been saved, and you can go &lt;a href=&quot;#&quot;&gt;back&lt;/a&gt; to continue editing.
    &lt;/p&gt;
    &lt;p&gt;
        Error ID: #1337
    &lt;/p&gt;
&lt;/div&gt;
</pre>
<h3>Resultatet:</h3>
<p>Klikk på &laquo;Result&raquo; i vinduet under.<br />
<iframe style="width: 100%; height: 400px;" src="http://jsfiddle.net/davidsteinsland/y96kw/3/embedded/" width="320" height="240"></iframe><br />
<a href="http://jsfiddle.net/davidsteinsland/y96kw/3/embedded/result/">Eget vindu</a></p>
]]></content:encoded>
			<wfw:commentRss>http://davidsteinsland.net/2011/07/tips-enkle-feilmeldinger-med-animasjon/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Komprimere CSS og JavaScript</title>
		<link>http://davidsteinsland.net/2011/04/komprimere-css-og-javascript/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=komprimere-css-og-javascript</link>
		<comments>http://davidsteinsland.net/2011/04/komprimere-css-og-javascript/#comments</comments>
		<pubDate>Wed, 13 Apr 2011 08:19:39 +0000</pubDate>
		<dc:creator>David Steinsland</dc:creator>
				<category><![CDATA[Programmering]]></category>
		<category><![CDATA[compress]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[komprimering]]></category>
		<category><![CDATA[opensource]]></category>

		<guid isPermaLink="false">http://blog.davidsteinsland.net/?p=496</guid>
		<description><![CDATA[Sliter du med store CSS- og JavaScript-filer? Føler du at det drar opp lastetiden din? Jeg skriver om en god metode for å korte ned filstørrelsene, og dermed redusere lastetiden.]]></description>
			<content:encoded><![CDATA[<p><a href="http://davidsteinsland.net/wp-content/uploads/2011/04/yui-compressor.png"><img class="alignright size-full wp-image-499" title="YUI Compressor" src="http://davidsteinsland.net/wp-content/uploads/2011/04/yui-compressor.png" alt="" width="349" height="370" /></a>Jeg har ved et par anledninger skrevet om hvordan du kan dra opp ytelsen i nettsidene dine, ved å for eksempel introdusere mellomlagring (cache) <a title="MySQL Query Cache" href="http://davidsteinsland.net/2010/12/mysql-query-cache/">på databasen din</a> eller <a title="Cache PHP-sider: kort og enkelt" href="http://davidsteinsland.net/2011/01/cache-php-sider-kort-og-enkelt/">i applikasjonen</a>.</p>
<p>I dag tenkte jeg å dekke litt om &laquo;minifisering&raquo; av JavaScript og CSS-kode.</p>
<p>Først av alt: hva er det for noe, og hva betyr det for meg?</p>
<p>Når du skriver CSS- og JavaScript-kode (og alle andre typer..) så pleier mange å skrive på en slik måte at det er mest mulig lesbart og forståelig. Dette kan være aktivt bruk av whitespace, TAB, newlines, variabel- og funksjonsnavn blant annet.</p>
<p>Resultatet er da at koden blir lang, noe som er unødvendig: en maskin bryr seg ikke om hvor fint koden er skrevet når den skal tolke koden. Et menneske bryr seg, derimot.</p>
<p>Og som vi alle vet: dess flere bytes, dess lengre lastetid. Og på Internett har dette en stor betydning, spesielt for brukere med lav Internetthastighet (ikke alle har fått gleden av fiber ennå).</p>
<p>Det er derfor et godt tips å gjøre koden så liten som overhodet mulig, ved å fjerne whitespace og gjøre funksjonsnavn og variabelnavn kortere. Denne prosessen kalles gjerne &laquo;komprimering&raquo; eller &laquo;minifisering&raquo; (eng. <em>minify</em>).</p>
<p>Om du har lastet ned for eksempel en jQuery-plugin før, har du ofte fått to filer presentert: en &laquo;vanlig&raquo; fil, og en som slutter med &laquo;.min&raquo;.</p>
<p>Her er to eksempler på dette:</p>
<p>jquery.js<br />
jquery.min.js</p>
<p>Forskjellen her er at <em>jquery.min.js</em> er en miniversjon av <em>jquery.js</em>, og er dermed mindre i filstørrelse.</p>
<p>jquery.min.js er egnet til produksjonsbruk, mens jquery.js er egnet til videre utvikling. Det vil si at dersom du skal gjøre endringer i koden din, må du gjøre dette i kildefilen for så og lage en komprimert versjon av den etterpå.</p>
<div id="attachment_503" class="wp-caption aligncenter" style="width: 585px"><a href="http://davidsteinsland.net/wp-content/uploads/2011/04/javascript-minified-non-minified.png"><img class="size-large wp-image-503 " title="JavaScript: komprimert og vanlig" src="http://davidsteinsland.net/wp-content/uploads/2011/04/javascript-minified-non-minified-575x357.png" alt="" width="575" height="357" /></a><p class="wp-caption-text">Forskjell mellom vanlig og komprimert JavaScript</p></div>
<h3>Hvilke program er tilgjengelige?</h3>
<p>Det finnes mange gode verktøy for å minifisere CSS- og JavaScript-filer, hvor de mest brukte er <a href="http://developer.yahoo.com/yui/compressor/">Yahoo! Compressor</a> og <a href="http://code.google.com/intl/no/closure/">Google Closure</a>. Dette er to Java-filer som du må kjøre lokalt på PC-en via kommandolinjen. Kanskje ikke det beste alternativet for alle, som er årsaken til at det finnes mange gode nettbaserte verktøy også.</p>
<h3>Egenutviklet program</h3>
<p>Jeg har utviklet et program for Windows basert på Yahoo! Compressor, som gjør at du slipper å benytte kommandolinjen for å minifisere filer.</p>
<p>Programmet er skrevet i C#, og fungerer derfor kun på Windows (som jeg vet om). Det er likevel et nyttig verktøy som er lett å bruke!</p>
<p><img src="http://davidsteinsland.net/wp-content/themes/eikeland/images/download_icon.png" alt="Last ned" class="icon" /> <a href="http://davidsteinsland.net/YuiCompressor.zip">Last ned programmet her</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://davidsteinsland.net/2011/04/komprimere-css-og-javascript/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Datoer i PHP &#8211; på den enkle måten</title>
		<link>http://davidsteinsland.net/2011/03/datoer-i-php-pa-den-enkle-maten/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=datoer-i-php-pa-den-enkle-maten</link>
		<comments>http://davidsteinsland.net/2011/03/datoer-i-php-pa-den-enkle-maten/#comments</comments>
		<pubDate>Fri, 18 Mar 2011 16:53:20 +0000</pubDate>
		<dc:creator>David Steinsland</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[datetime]]></category>
		<category><![CDATA[dato]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://blog.davidsteinsland.net/?p=486</guid>
		<description><![CDATA[I en verden med rundt 25 ulike tidssoner, kan datoer og klokkeslett bli et mareritt. Hvordan skal vi lagre datoene, og hvordan skal vi vise dem? Følg med, og lær om PHPs nye DateTime-bibliotek!]]></description>
			<content:encoded><![CDATA[<p>Å jobbe med datoer kan være riktig slitsomt til tider. Hvor mange ganger har du ikke klødd deg litt i bakhodet, og tenkt hvordan i huleste du kan formatere datoer som enten er formatert forskjellig, er fra ulike tidssoner eller som du må trekke fra / legge til dager/uker/måneder &#8230; ?</p>
<p>Ja, det <span style="text-decoration: underline;">har</span> vært et problem. Med det mener jeg at løsningen er på plass, og at du kan slappe ekstra godt av. Dette innebærer <em>selvfølgelig</em> at du har en PHP-installasjon tilsvarende 5.3.x.</p>
<h3>Alle dager i mars måned</h3>
<p>Tidligere har vi måttet brukt PHPs datofunksjoner (date/strtotime/strftime &#8230;), men siden PHP 5.3 kan vi nemlig dra nytte av de nye <a href="http://no2.php.net/manual/en/book.datetime.php">DateTime</a>-klassene og godene som medfølger.<br />
Se bare hvor enkelt det er å skrive ut alle dagene i Mars 2011:</p>
<pre class="brush: php; title: ; notranslate">
$march = new DateTime ('March 2011');

$days = new DatePeriod (
    $march,
    new DateInterval ('P1D'),
    $march-&gt;modify ('first day of next month')
);

foreach ($days as $day)
{
    echo $day-&gt;format ('Y-m-d'), &quot;\n&quot;;
}</pre>
<p>Årsaken til at jeg valgte å skrive &laquo;first day of next month&raquo; fremfor &laquo;last day of&raquo; er på grunn av at siste datoen blir ekskludert, som hadde betydd at 31. mars ikke hadde blitt skrevet ut.</p>
<p>I eksempelet mitt har jeg benyttet meg av alle klassene som inngår i <a href="http://no2.php.net/manual/en/book.datetime.php">DateTime-biblioteket</a> (med unntak av <a href="http://no2.php.net/manual/en/class.datetimezone.php">DateTimeZone</a>) hvor:</p>
<ul>
<li>DateTime lager et objekt med 1. mars 2011 utifra &laquo;March 2011&#8243;</li>
<li><a href="http://no2.php.net/manual/en/class.dateperiod.php">DatePeriod</a> lager et objekt som inneholder alle datoer fra 1. mars til 1. april (eksklusivt) hvor det er 1 dag mellom hver instans (dette bestemmes av <a href="http://no2.php.net/manual/en/class.dateinterval.php">DateInterval</a>)</li>
</ul>
<h3>Antall dager mellom to datoer</h3>
<p>DateTime-klassen har et stort bruksområde, og kan for eksempel brukes til å finne differansen mellom to datoer:</p>
<pre class="brush: php; title: ; notranslate">

$january = new Datetime ('January 2011');

$diff = $january-&gt;diff ( new DateTime ('April 2011') );

echo 'Difference between January and April: ',
$diff-&gt;format ('%R%a days');  // 90 days
</pre>
<p><em>%a</em> fungerer slik at den skal gi meg det totale antallet dager mellom de to datoene. Denne funksjonaliteten fungerer dessverre ikke optimalt på Windows, og kan skape endel frustrasjoner. Men i lag med PHP 5.3 kan du også sammenligne to DateTime-instanser ved bruk av &laquo;<a href="http://no2.php.net/manual/en/language.operators.comparison.php">comparison operators</a>&raquo; (større/mindre enn, osv.) Dette gjør oss istand til å lage en &laquo;work-around&raquo; til Windows-problematikken:</p>
<pre class="brush: php; title: ; notranslate">

$january = new DateTime ('January 2011');
$april = new DateTime ('April 2011');

// clone variable to keep $january clean..
$currdate = clone $january;

for ($days = 0; $currdate-&gt;modify ('+1 day') &lt;= $april; ++$days);

echo &quot;Difference between January and April: {$days} days&quot;;
</pre>
<h3>Utvide DateTime med støtte for MySQL Datetime</h3>
<p>Det er også ganske tilfredsstillende å benytte seg av DateTime ilag med MySQL DATETIME. I dette eksempelet har jeg valgt å utvide DateTime-klassen:</p>
<pre class="brush: php; title: ; notranslate">
class MyDateTime extends DateTime
{
    const MYSQL = 'Y-m-d H:i:s';

    public static function createFromMySQL ($datetime)
    {
        return self::createFromFormat (self::MYSQL, $datetime);
    }
}

// date from MySQL
$date = MyDateTime::createFromMySQL ($row['my_date']);

$timestamp = $date-&gt;getTimestamp ();

echo &quot;Date: {$date-&gt;format ('d.m.Y H:i')}\n&quot;;
</pre>
<p>Poenget mitt var ikke å utvide klassen for å legge til en enkel funksjon, men heller illustrere at det kan være lurt å gjøre det (DateTime-klassen har tross alt ikke tatt høyde for absolutt alt).<br />
Kanskje det kunne vært en idé å gjøre Windows work-arounden min til en funksjon som utvider DateInterval ?</p>
<p>Som regel er det kun DateTime du har behov for i det daglige, men du kan også få god nytte av både DateInterval og DatePeriod om du for eksempel skal jobbe med kalendere.</p>
]]></content:encoded>
			<wfw:commentRss>http://davidsteinsland.net/2011/03/datoer-i-php-pa-den-enkle-maten/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Lære Regular Expressions</title>
		<link>http://davidsteinsland.net/2011/02/laere-regular-expressions/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=laere-regular-expressions</link>
		<comments>http://davidsteinsland.net/2011/02/laere-regular-expressions/#comments</comments>
		<pubDate>Sun, 20 Feb 2011 11:18:37 +0000</pubDate>
		<dc:creator>David Steinsland</dc:creator>
				<category><![CDATA[Programmering]]></category>
		<category><![CDATA[regex]]></category>
		<category><![CDATA[regexbuddy]]></category>
		<category><![CDATA[regexp]]></category>
		<category><![CDATA[regular expressions]]></category>

		<guid isPermaLink="false">http://blog.davidsteinsland.net/?p=480</guid>
		<description><![CDATA[Dersom du ikke vet hva Regular Expressions er for noe, er det på høy tid å finne dette ut. Kort fortalt er det et verktøy du bruker for å søke igjennom en string med tekst med et gitt mønster, slik at du kan forandre på teksten, fjerne den, eller gjøre hva du vil. Muligens en [...]]]></description>
			<content:encoded><![CDATA[<p>Dersom du ikke vet hva <a href="http://en.wikipedia.org/wiki/Regular_expressions"><strong>Reg</strong>ular <strong>Ex</strong>pressions</a> er for noe, er det på høy tid å finne dette ut. Kort fortalt er det et verktøy du bruker for å søke igjennom en string med tekst med et gitt mønster, slik at du kan forandre på teksten, fjerne den, eller gjøre hva du vil. Muligens en smule dårlig forklart fra min side, men &laquo;verktøyet&raquo; er iallfall i bruk i de aller fleste operativsystemer (se etter <em>grep</em> i Linux) samt programmeringsspråk.</p>
<p>I starten kan RegExs virke litt skremmende, spesielt det å lese og forstå et mønster. Ta for eksempel dette:</p>
<pre class="brush: plain; title: ; notranslate">upload/(bruker|system)/(?P&lt;additional_dir&gt;[a-z0-9/]+/)?(?P&lt;image&gt;[\w._-]+\.(?:jpe?g|gif|png))?</pre>
<p>Kan du gjette hva jeg prøver på her?</p>
<p>Selv har jeg ønsket å lære meg RegExps <em>skikkelig</em>, men har manglet både motivasjon og insentiv. I dag er situasjonen forandret, og jeg fryder meg med å lære Regular Expressions!</p>
<h3>Hvordan jeg lærte meg Regexp</h3>
<p>Da jeg virkelig bestemte meg for å gjøre noe med det, gikk jeg til innkjøp av boken <a href="http://www.amazon.com/Mastering-Regular-Expressions-Jeffrey-Friedl/dp/0596528124">Mastering Regular Expressions</a> samt programmet <a href="http://www.regexbuddy.com/">RegexBuddy</a>. I lag med kunnskapen jeg satt inne med fra før, så har jeg hatt en jevn og fin lærekurve (du trenger dog ikke ha noen kunnskaper før du leser boken!).</p>
<p>Det noe kontroversielt om hvor nyttig Regular Expressions faktisk her, med tanke på at mange har en tendens til å forelske seg i dem og bruke de overalt (såkalt blind kjærlighet..). Men trikset er bare å bruke RegEx fornufting.</p>
<p>I løpet av de siste dagene har jeg blant annet benyttet meg av RegExs til å hente ut URL-er til både linker og bilder i systemet vårt på jobb, slik at jeg for eksempel kan bytte ut originalbilder med thumbnails og erstatte URL-ene med andre. Dette gjorde vi da vi skulle bygge en mobilversjon av systemet, uten å måtte bruke mange titalls timer på å endre selve systemet. Resultatet er en nettside med små bilder optimalisert for mobilenheter, samt at alle interne URL-er nå peker til mobil-domenet.</p>
<h3>Tips</h3>
<p>Om du bruker Twitter jevnlig kan det være interessant å følge <a href="http://twitter.com/regextip">RegexTip</a> for daglige tips!</p>
<p>Jeg <em>elsker</em> Regular Expressions! Gjør du?</p>
]]></content:encoded>
			<wfw:commentRss>http://davidsteinsland.net/2011/02/laere-regular-expressions/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Cache PHP-sider: kort og enkelt</title>
		<link>http://davidsteinsland.net/2011/01/cache-php-sider-kort-og-enkelt/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=cache-php-sider-kort-og-enkelt</link>
		<comments>http://davidsteinsland.net/2011/01/cache-php-sider-kort-og-enkelt/#comments</comments>
		<pubDate>Thu, 20 Jan 2011 18:32:03 +0000</pubDate>
		<dc:creator>David Steinsland</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[cache]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://blog.davidsteinsland.net/?p=450</guid>
		<description><![CDATA[Når man skriver nettsider med PHP er det mye som kan være med på å dra opp lastetiden. For ikke å snakke om alle CSS- og JavaScript-filer som også må lastes ned. Hva kan man så gjøre? Om du jobber med databaser kan du for eksempel skru på MySQL Query Cacher, samtidig som du kan [...]]]></description>
			<content:encoded><![CDATA[<p>Når man skriver nettsider med PHP er det mye som kan være med på å dra opp lastetiden. For ikke å snakke om alle CSS- og JavaScript-filer som også må lastes ned. Hva kan man så gjøre?</p>
<p>Om du jobber med databaser kan du for eksempel skru på <a href="http://davidsteinsland.net/2010/12/mysql-query-cache/">MySQL Query Cacher</a>, samtidig som du kan mellomlagre resultatet i HTML-, JSON eller XML-format. Men alt dette krever igrunn litt arbeid, samt at noen koder her og der må endres.</p>
<pre class="brush: php; title: ; notranslate">
$lastModified = filemtime (__FILE__);
$etagFile = md5_file (__FILE__);
$ifModifiedSince = isset ($_SERVER['HTTP_IF_MODIFIED_SINCE']) ? $_SERVER['HTTP_IF_MODIFIED_SINCE'] : FALSE;
$etagHeader = isset ($_SERVER['HTTP_IF_NONE_MATCH'] ? trim ($_SERVER['HTTP_IF_NONE_MATCH']) : FALSE;

header(&quot;Last-Modified: &quot; . gmdate(&quot;D, d M Y H:i:s&quot;, $lastModified) . &quot; GMT&quot;);
header(&quot;Etag: $etagFile&quot;);
header('Cache-Control: public');

//check if page has changed. If not, send 304 and exit
if (@strtotime ($ifModifiedSince) == $lastModified || $etagHeader == $etagFile)
{
       header (&quot;HTTP/1.1 304 Not Modified&quot;);
       exit;
}

//your normal code below
</pre>
<p>Om du limer inn koden ovenfor i starten på de PHP-filene du ønsker å mellomlagre, merker du forskjellen med én gang. Jeg har selv testet koden i flere prosjekter, og den fungerer utmerket. Det som er verdt å merke seg, er at den ikke fanger opp endringer i dynamisk innhold med én gang.<br />
Den merker så klart endringer på seg selv, men dersom du henter innhold fra en database så kan det ta noen minutter før det vises.</p>
<p>Denne prosessen kan, så vidt jeg vet, ikke fremskyndes siden mellomlageret ligger i nettleseren, og det er ikke mulig å fjerne det (dette må sluttbruker gjøre manuelt).</p>
]]></content:encoded>
			<wfw:commentRss>http://davidsteinsland.net/2011/01/cache-php-sider-kort-og-enkelt/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Oppgraderingsdag</title>
		<link>http://davidsteinsland.net/2010/12/oppgraderingsdag/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=oppgraderingsdag</link>
		<comments>http://davidsteinsland.net/2010/12/oppgraderingsdag/#comments</comments>
		<pubDate>Mon, 20 Dec 2010 18:40:29 +0000</pubDate>
		<dc:creator>David Steinsland</dc:creator>
				<category><![CDATA[Apache]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://blog.davidsteinsland.net/?p=439</guid>
		<description><![CDATA[I disse &#171;sene&#187; juledager har jeg fått oppgradert serveren min, deriblant PHP, MySQL og Apache til aller siste versjon. Mest hyggelig er det jo med en etterlengtet MySQL-oppgradering, som såvidt har blitt oppdatert Oracle kjøpte dem opp. Anbefaler også at du gjør det samme, og da spesielt MySQL 5.5-oppgraderingen hvor InnoDB endelig er satt som [...]]]></description>
			<content:encoded><![CDATA[<p>I disse &laquo;sene&raquo; juledager har jeg fått oppgradert serveren min, deriblant PHP, MySQL og Apache til aller siste versjon. Mest hyggelig er det jo med en etterlengtet MySQL-oppgradering, som såvidt har blitt oppdatert Oracle kjøpte dem opp.</p>
<p>Anbefaler også at du gjør det samme, og da spesielt <a href="http://www.mysql.com/downloads/mysql/">MySQL 5.5</a>-oppgraderingen hvor InnoDB endelig er satt som standard og som kan skiltes som 540 % mer effektiv (Windows)!</p>
<p>Så nå kjører jeg altså PHP 5.3.4, MySQL 5.5 og Apache 2.2.17, på en Windows 7-maskin, som tok meg i underkant av 15 minutter å gjøre.</p>
<p>PS:</p>
<ul>
<li>Oppdater <a href="http://www.apachelounge.com/viewtopic.php?p=17092">eAccelerator for PHP 5.3.4</a> i samme slengden</li>
<li>Få også med deg notatet om <a href="http://dev.mysql.com/doc/refman/5.5/en/windows-upgrading.html">oppgradering av MySQL på Windows</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://davidsteinsland.net/2010/12/oppgraderingsdag/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MySQL Query Cache</title>
		<link>http://davidsteinsland.net/2010/12/mysql-query-cache/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=mysql-query-cache</link>
		<comments>http://davidsteinsland.net/2010/12/mysql-query-cache/#comments</comments>
		<pubDate>Wed, 08 Dec 2010 00:02:25 +0000</pubDate>
		<dc:creator>David Steinsland</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://blog.davidsteinsland.net/?p=428</guid>
		<description><![CDATA[Når du bygger applikasjoner for nettet, vil du komme til et punkt hvor enkelte komponenter kan dra ned ytelsen eller lastetiden. Dette kan for eksempel være krevende PHP-kode som store løkker, behandling av store mengder data, eller krevende MySQL-spørringer. Du tenker da kanskje å implementere et mellomlager. Dette kan du gjøre på applikasjonsnivå og på [...]]]></description>
			<content:encoded><![CDATA[<p>Når du bygger applikasjoner for nettet, vil du komme til et punkt hvor enkelte komponenter kan dra ned ytelsen eller lastetiden. Dette kan for eksempel være krevende PHP-kode som store løkker, behandling av store mengder data, eller krevende MySQL-spørringer.</p>
<p>Du tenker da kanskje å implementere et mellomlager. Dette kan du gjøre på applikasjonsnivå og på servernivå.</p>
<p>La oss si at du har bygget deg en RSS-leser, som henter XML-data fra nyhetsstrømmer fra nettet. Over tid vil serveren bruke mye ressurser på å laste disse ned fra nettet hele tiden, og som mottiltak kan du lagre XML-dataene på din egen server (som blir oppdatert jevnlig). På den måten har du implementert et mellomlager på applikasjonsnivå, hvor du lagrer data i en gitt periode før du oppdaterer mellomlageret med ny data (for eksempel hver 30. minutt).</p>
<p>Du kan også implementere løsninger på servernivå, som kan bedre ytelsen til PHP ved at den kompilerer koden og lagrer den på RAM. Her har du eksempler som <a href="http://www.php-accelerator.co.uk/">PHP-Accelerator</a>, <a href="http://eaccelerator.net/">eAccelerator</a> og <a href="http://www.zend.com/en/products/guard/runtime-decoders">Zend Optimizer</a>.</p>
<p>Men hva når det kommer til MySQL-spørringer?</p>
<p>Her kan du også implementere et mellomlager på applikasjonsnivå, men da må du sette opp dine egne metoder som kjører spørringer etc. Du følger da samme tankegangen som med RSS-leseren:</p>
<ul>
<li>Når spørringen blir kjørt for første gang, lagrer du resultatet som spørringen gir i en tekstfil.</li>
<li>Neste gang spørringen blir kjørt, returnerer du dataene fra tekstfilen istedenfor å kjøre spørringen på nytt.</li>
</ul>
<p>Men dette kan være uønskelig i flere tilfeller:</p>
<ul>
<li>du må sette opp egne metoder, da PHPs innebygde MySQL-bibliotek ikke støtter caching</li>
<li>dataene kan være unøyaktige, og du bør hele tiden sørge for at tekstfilene inneholder oppdatert informasjon</li>
</ul>
<p>Typisk implementering ville vært noe slik:</p>
<pre class="brush: php; title: ; notranslate">
class MySQL
{
	public function query ($query)
	{
		$cache = 'cache/' . md5 ($query) . '.mysql';

		if ( file_exists ($cache))
		{
			$data = unserialize (file_get_contents ($cache));
		}
		else
		{
			$query = mysql_query ($query);

			$data = array ();

			while ($row = mysql_fetch_assoc ($data))
			{
				$data[] = $row;
			}

			file_put_contents ($cache, $data);
		}

		return $data;
	}
}

$mysql = new MySQL ('localhost', 'user', 'pw', 'db');

$data = $mysql-&gt;query ('SELECT foo FROM bar');
</pre>
<h3>MySQL Query Cache</h3>
<p>Men en bedre løsning vil være å dra nytte av MySQLs egen <a href="http://dev.mysql.com/tech-resources/articles/mysql-query-cache.html">Query Cacher</a>. Denne returnerer mellomlagret data dersom det er forblitt uforandret, og oppdaterer så snart det er ny data. I tillegg blir spørringene utført på tilnærmet 0 sekunder. Altså en veldig grei sak, dette her!</p>
<p>I de fleste tilfeller er Cache-muligheten skrudd av som standard, og du kan sjekke dette ved å kjøre følgende kommando til MySQL:</p>
<pre class="brush: plain; title: ; notranslate">
mysql&gt; show variables like 'query%';
+------------------------------+---------+
| Variable_name                | Value   |
+------------------------------+---------+
| query_alloc_block_size       | 8192    |
| query_cache_limit            | 1048576 |
| query_cache_min_res_unit     | 4096    |
| query_cache_size             | 0       |
| query_cache_type             | ON      |
| query_cache_wlock_invalidate | OFF     |
| query_prealloc_size          | 8192    |
+------------------------------+---------+
</pre>
<p>Her ser vi at query_cache_size er satt til 0, noe som fører til at Cache-funksjonaliteten er skrudd av. For å aktivere denne, kjør følgende kommando:</p>
<pre class="brush: plain; title: ; notranslate">
mysql&gt; set global query_cache_size=50000000;
</pre>
<p>Det er i bunn og grunn alt du trenger å gjøre! Og dette fungerer flott som fjell.</p>
<p>Lykke til!</p>
]]></content:encoded>
			<wfw:commentRss>http://davidsteinsland.net/2010/12/mysql-query-cache/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ActionScript 3 og nøkkelordet &#171;with&#187;</title>
		<link>http://davidsteinsland.net/2010/11/actionscript-3-og-n%c3%b8kkelordet-with/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=actionscript-3-og-n%25c3%25b8kkelordet-with</link>
		<comments>http://davidsteinsland.net/2010/11/actionscript-3-og-n%c3%b8kkelordet-with/#comments</comments>
		<pubDate>Wed, 24 Nov 2010 12:56:39 +0000</pubDate>
		<dc:creator>David Steinsland</dc:creator>
				<category><![CDATA[ActionScript 3]]></category>

		<guid isPermaLink="false">http://blog.davidsteinsland.net/?p=394</guid>
		<description><![CDATA[Nylig kom jeg over nøkkelordet &#171;with&#187; i ActionScript 3. Etter å ha programmert AS3.0 en liten stund, har jeg aldri kommet over bruken av nøkkelordet til nå. Første gangen jeg så bruken av det, var i en kildekode jeg fant ved en tilfeldighet på Sniplr.com. Det kan bli brukt til å skrive renere kode når [...]]]></description>
			<content:encoded><![CDATA[<p>Nylig kom jeg over nøkkelordet &laquo;with&raquo; i ActionScript 3. Etter å ha programmert AS3.0 en liten stund, har jeg aldri kommet over bruken av nøkkelordet til nå. Første gangen jeg så bruken av det, var i en kildekode jeg fant ved en tilfeldighet på Sniplr.com.</p>
<p>Det kan bli brukt til å skrive renere kode når du skal sette flere verdier til samme objekt, som for eksempel i en slik situasjon:</p>
<pre class="brush: as3; title: ; notranslate">
var printer:PrintJob = new PrintJob();

if (printer.start())
{
    printer.addPage (content_mc);
    printer.send();
}
</pre>
<p>Med &laquo;with&raquo; blir det:</p>
<pre class="brush: as3; title: ; notranslate">
with (new PrintJob())
{
	if (start()) {
		addPage (content_mc);
		send();
	}
}
</pre>
<p>Lekkert?</p>
]]></content:encoded>
			<wfw:commentRss>http://davidsteinsland.net/2010/11/actionscript-3-og-n%c3%b8kkelordet-with/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>RecursiveIterator med egne filtre</title>
		<link>http://davidsteinsland.net/2010/11/recursiveiterator-med-egne-filtre/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=recursiveiterator-med-egne-filtre</link>
		<comments>http://davidsteinsland.net/2010/11/recursiveiterator-med-egne-filtre/#comments</comments>
		<pubDate>Tue, 16 Nov 2010 15:45:30 +0000</pubDate>
		<dc:creator>David Steinsland</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[recursiveiterator]]></category>
		<category><![CDATA[spl]]></category>

		<guid isPermaLink="false">http://blog.davidsteinsland.net/?p=386</guid>
		<description><![CDATA[Er det noe jeg virkelig elsker med PHP, må det være Standard PHP Library, eller SPL som det også heter. Det er en samling av innebygde klasser som gjør deg istand til for eksempel å kjøre (iterere) gjennom arrays, filer, mappestrukturer (endimensjonalt) eller flerdimensjonalt (rekursiv). Alt dette ved en solid OOP-struktur! Scenario: du skal iterere [...]]]></description>
			<content:encoded><![CDATA[<p>Er det noe jeg virkelig elsker med PHP, må det være <a href="http://no2.php.net/manual/en/book.spl.php">Standard PHP Library</a>, eller SPL som det også heter. Det er en samling av innebygde klasser som gjør deg istand til for eksempel å kjøre (iterere) gjennom arrays, filer, mappestrukturer (endimensjonalt) eller flerdimensjonalt (rekursiv). Alt dette ved en solid OOP-struktur!</p>
<p><strong>Scenario</strong>: du skal iterere rekursivt gjennom en mappestruktur, og ønsker kun å hente ut filer med endelsen &laquo;txt&raquo;.</p>
<p>Hva gjør du? Du kunne brukt en kombinasjon av scandir() og din egen rekursive funksjon, eller glob(), eller, eller&#8230;</p>
<p>Hva dersom du ønsker å bruke kodene senere, flere ganger, bare med små endringer? Det er virkelig en grense for hvor fleksibelt et system kan være når det er satt til å utføre én bestemt oppgave. Utnytter du OOP, kan du snu på dette.</p>
<p>I koden nedenfor henter jeg ut <em>alle</em> filer (uansett nivå) som befinner seg inni mappen filer/.</p>
<pre class="brush: php; title: ; notranslate">
foreach (new RecursiveIteratorIterator(
	new RecursiveDirectoryIterator('filer')
) as $file
)
{
    echo $file-&gt;getFilename();
}
</pre>
<p>Men skulle ikke jeg filtrere bort enkelte filer? Hvordan gjør jeg det?</p>
<p>Det vi trenger å gjøre, er å lage en klasse i PHP som arver egenskaper fra <a href="http://no2.php.net/manual/en/class.filteriterator.php">FilterIterator</a>. Den må fyre i gang <a href="http://no2.php.net/manual/en/class.recursivedirectoryiterator.php">RecursiveDirectoryIterator</a> og <a href="http://no2.php.net/manual/en/class.recursiveiteratoriterator.php">RecursiveIteratorIterator</a>, i tillegg må den ha metoden <var>accept()</var>.</p>
<p>Her har jeg skrevet enda et enkelt eksempel, hvor jeg kun henter ut filer med endelsen &laquo;txt&raquo;.</p>
<pre class="brush: php; title: ; notranslate">
class RecursiveFilter extends FilterIterator
{
	protected $_extensions = array ();

	public function __construct ($path, array $extension = array ())
	{
		$this-&gt;_extensions = $extensions;

		parent::__construct(new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path)));
	}

	/**
	 * Bestemmer hvilke filer som skal bli godtatt
	 * Metoden må returnere FALSE eller TRUE, alt ettersom
	 * om filen er godtatt eller ei.
	 */
	public function accept ()
	{

		// get the file that are being iterated
		$item = $this-&gt;getInnerIterator ();

		return in_array ( pathinfo ($item-&gt;getBasename(), PATHINFO_EXTENSION), $this-&gt;_extensions);
	}
}

$iterator = new RecursiveFilter ('filer', array ('txt'));

foreach ($iterator as $item)
{
	echo $item-&gt;getBasename();
}
</pre>
<p>Så enkelt kan det gjøres. I teorien har vi igrunn fjernet sjekken ut av foreach-løkken, og inn i egen klasse. Det virker unødvendig, men med tanke på gjenbruk og abstraksjon så er dette en meget god idé.</p>
<p>Om du ønsker alle filer som ikke har endelsen &laquo;txt&raquo;, så snur du bare på sjekken som utføres i <var>accept()</var> til:</p>
<pre class="brush: php; title: ; notranslate">
return ! in_array ( pathinfo ($item-&gt;getBasename(), PATHINFO_EXTENSION), $this-&gt;_extensions);
</pre>
<p>Du kan selvfølgelig utvide <var>accept()</var> til så mye du vil, og ta høyde for alt du ønsker. <var>$item</var> inneholder et <a href="http://no2.php.net/manual/en/class.splfileinfo.php">FileInfo</a>-objekt, så da kan du bare slå deg løs!</p>
]]></content:encoded>
			<wfw:commentRss>http://davidsteinsland.net/2010/11/recursiveiterator-med-egne-filtre/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

