David Steinsland – informatikkstudent og webutvikler

Fremhevede innlegg

Github

| Ingen kommentarer »

Jeg har i en stund brukt bloggen som en plattform for å bidra til det «åpne samfunnet», men nå blir det meste av kodesnutter, eksempler og andre kildekoder publisert via Github-repoene mine.

Så for å følge med i tidene som kommer, så er du mer enn velkommen til å følge noen av mine repoer:

http://github.com/davidsteinsland/

Utvidelse av registerklassen i Java

| Ingen kommentarer »

I februar skrev jeg et innlegg om hvordan du kunne sette opp et register i Java, som inneholdt for eksempel datastrukturen din, og som sørget for at dataen ble lagret ved programslutt. I dag tenkte jeg å utvide denne klassen litt, med generiske metoder.

import java.util.Map;
import java.util.HashMap;

public class Registry implements Serializable
{
    private static final long serialVersionUID = 7422025143560909873L;
    private static Map registry = new HashMap<>();

    public static void addObject (String k, Object v)
    {
        this.registry.put (k, v);
    }

    public static  T getObject (String key)
	{
		return (T) this.registry.get(key);
	}
}

Her har jeg gjort følgende endringer:

  • Gjort klassen statisk, slik at du ikke behøver å opprette en instans av klassen før du benytter den.
  • Innført generisk metode for å hente frem et objekt, slik at du slipper å kaste om objektet når du henter det frem.

I praksis, så vil klassen fungere slik:

public class Main
{
	public static void main (String[] args)
	{
		Registry.addObject ( "node", new Node("someName"));

		// begge disse er like:
		Node n = Registry.getObject ("node");
		Node n2 = Registry.getObject ("node");
	}
}

Vise hvor lang tid nettsiden laster

| Ingen kommentarer »

I PHP 5.4 har det kommet en ny SERVER-variabel som heter REQUEST_TIME_FLOAT og gir oss tiden da nettsiden begynner å laste (i millisekunder). Denne muliggjør at vi slipper å definere en konstant helt i begynnelsen av koden vår, som inneholder verdien av microtime(true). Nå kan vi i stedet for gjøre hele prosessen slik:

register_shutdown_function (function ()
{
	$s = $_SERVER['REQUEST_TIME_FLOAT'];
	$e = microtime (true);
	
	echo "\n\nPage Rendered: ", sprintf ("%0.5f", ($e - $s)), " seconds";
});

Koden kan ligge hvor som helst i koden din (men legg den helst litt langt oppe …). Poenget med å dra nytte av register_shutdown_function() er at metoden blir kalt selv om nettsiden avslutter uventet, for eksempel via exit og die.

Uavhengige cronjobber i PHP

| Ingen kommentarer »

PHP tips og triks

Cron er et ganske nyttig verktøy som gjør deg istand til å utføre spesielle oppgaver på et gitt tidspunkt, men er uheldigvis kun tilgjengelig på UNIX-systemer. I Windows har man noe som heter planlagte oppgaver, som også går an å anvende.
Men hva er dette godt for, når mange webhotell-tilbydere ikke engang har funksjonen(e) aktivert?

Det eneste alternativ som står igjen, er å lage en cron-emulator med PHP (eller lignende). Vi ønsker altså å lage et system som selv kan utføre oppgaver på gitte tidspunkt.

Ved et par Google-søk er det mulig å finne utallige slike eksempler, men personlig har jeg alltid følt de har manglet noe. Jeg ønsker det skal være enkelt og lett forståelig, samt enkelt å integrere i andre systemer.

I stedet for å bruke mye tid på å finne «det perfekte scriptet», så satte jeg av en liten time til å utvikle noe slikt selv.

Jeg endte opp med noe jeg selv mener er ganske enkelt å forstår seg på, samtidig som det er ganske enkelt å utvide også.

Hvordan koden fungerer

Totalt inneholder applikasjonen tre klasser:

  • Scheduler — inneholder de ulike handlingene, og bestemmer hvilke som skal kjøres
  • SchedulerEvent — egen klasse for hver handling. Her lagres informasjon om hvilken kommando som skal kjøres, og hvor mange sekunder det går mellom hver gang
  • SchedulerInterval — en bitteliten klasse som bestemmer intervallet en handling skal kjøres i.

Scheduler tar i bruk Singleton-mønsteret, slik at du kan få tak i klasseinstansen hvor som helst, uten å miste data som objektet lagrer.

Jeg har benyttet meg av et par ukjente triks for å oppnå ønsket resultat:

  • For å sikre meg om at koden skal utføres, uansett hva brukeren velger å gjøre, har jeg tatt i bruk ignore_user_abort()
  • For at data er lagret til neste sidevisning, har jeg tatt i bruk register_shutdown_function. Der utføres det en kode som lagrer de ulike handlingene i en fil, som blir hentet opp ved neste sidevisning
  • Til slutt lar jeg SchedulerEvent-klassen implementere Serializable. På den måten kan jeg lagre hele objektet i eksempelvis en tekstfil, og så gjenopprette det igjen

Opprette handlinger

Koden under legger til en handling, som bestemmer at filen cron_scripts/my_file.php skal kjøres hver time. En gyldig URL gis.

$scheduler = Scheduler::getInstance ();

$event = new SchedulerEvent ("http://example.com/cron_scripts/my_file.php",
    new SchedulerInterval (SchedulerInterval::HOURLY));
$scheduler->addEvent ($event);

Kjøre handlinger

Koden for å kjøre handlinger er nødt til å ligge i en fil som blir kjørt på hver sidevisning, eksempelvis index.php.
Dette gjør vi for å være sikker på å utføre handlingene med best mulig presisjon.

// Sørger for at koden under blir utført uansett.
ignore_user_abort(true);

include_once 'class.scheduler.php';
include_once 'class.schedulerevent.php';
include_once 'class.schedulerinterval.php';

// sørger for at objektene blir lagret til neste sidevisning.
register_shutdown_function ('Scheduler::shutdown');

$scheduler = Scheduler::getInstance ();

foreach ($scheduler->getEvents() as $event)
{
	// utfører handlinger som ennå ikke har blitt utført,
    // eller som skal utføres basert på tiden gitt av metoden
	if ($event->getNextRunTime() <= new DateTime() )
    {
        $event->run ();
    }
}

Når en handling skal utføres, blir det sendt et separat POST-request til den valgte filen. Dette er for å unngå at handlingen ikke skal trekke ned hastigheten på siden.

Last ned

Last ned PHP Scheduler (241 nedlastninger)   (krever PHP >= 5.2.2)