02 mars, 2011

MySQL: InnoDB Foreign keys och Cascade

Förord
Hej på er! Nu ska jag förklara lite mer om databasen MySQL och en av databasmotorerna InnoDB. Jag upptäckte igår vad detta innebär och då började jag komma ihåg att jag hade läst om detta förut i en bra bok om just MySQL databashantering. Boken heter "MySQL handboken : [den snabba vägen till grunderna i MySQL]" och passar utmärkt till den som vill lära sig MySQL och gå in lite mer på djupet.

När jag läste boken förstod jag inte så mycket om foreign keys, som på svenska heter "främmande nycklar", men det förstår jag bättre nu. Därför har jag tänkt att visa ett exempel på när det kan vara mycket användbart.

Mycket bra läsning på engelska finns i en artikel publicerad på InnoDB.com [2]

Introduktion
Vad är MySQL?
Okej, som de flesta vet så är MySQL en typ av databas där man kan lagra information på ett strukturerat sätt. Och för er som inte vet, så vet ni nu vad MySQL är för något.,

SQL = Structured Query Language

Men vad kan MySQL användas till?
MySQL använder s.k. SQL-frågor för att skicka och hämta data från en databas. MySQL kan användas till att lagra information strukturerat om t.ex kunder som har bokat klipptider hos en frisör, eller produkter och artiklar som man vill sälja via en hemsida. När någon sedan har lagt en beställning kan man koppla produkterna till en specifik beställning som i sin tur hör till en registrerad kund.

Ett vanligt exempel från gymnasiet är en databas med elever som kommer att börja på skolan nästkommande termin. Vi fick lära oss hur man designar en databas med tabeller som är relaterade till varandra och hur man endast kan tillåta unika personer i databasen baserat på unika personnummer.

Fint, men vad är InnoDB för något?
I MySQL används olika databasmotorer (engines) för att spara och hämta data på olika sätt. Ska datans integritet kontrolleras eller spelar det ingen roll? Ska tabeller relateras med varandra eller skötas med programmering? Det är uppgiften som en databasmotor har.

InnoDB är inte så vanlig bland nybörjare eftersom standardmotorn heter MyISAM och många vet inte eller bryr sig inte om att kontrollera vilken databasmotor man använder. Databasen funkar ju fortfarande på samma sätt, eller? Ja det är sant men InnoDB kan kontrollera data i databasens tabeller så att länkarna, relationerna och integriteten inte bryts om en ändring sker i databasen.

Huvudregeln säger att i en relationsdatabas (en databas med relationer vilket hörs på namnet) så måste relaterade nycklar ha en korrekt länkning - nyckel1 med ID 4 i tabell A måste vara samma som nyckel1 med ID 4 i tabell B. Med InnoDB kan man kontrollera att ID-numret måste vara samma i båda tabellerna som är relaterade med varandra genom användning av främmande nycklar.

Om du inte förstår så är det helt förståeligt. Det kan vara ett svårt koncept i början innan man lär sig. Jag kommer strax gå igenom skillnaderna mellan InnoDB och MyISAM (den vanligaste databasmotorn).


Först en kort beskrivning om primärnycklar och främmande nycklar
En primärnyckel måste vara unik i en tabell. Dubbletter och kopior får inte förekomma. Ett vanligt exempel på en primärnyckel är ett ID i en tabell som automatiskt räknar uppåt när nya rader med data läggs till. Om man ska ha ett personnummer i en databas så passar personnumret utmärkt som en primärnyckel eftersom det ska vara unikt. Detta är bra så att man inte råkar fylla i ett som redan finns.


När ska man använda InnoDB och MyISAM?
Kortfattat
Om du har en t.ex en hemsida med en databas som innehåller en tabell som kommer att uppdateras och ändras kontinuerligt och väldigt ofta, då passar InnoDB. Speciellt om du har flera tabeller som är relaterade till varandra. Då kan InnoDB säga till när det blir fel och hjälpa till med uppdatering i andra tabeller. InnoDB är långsammare när det gäller SELECT och ändringar.

MyISAM ska man helst använda om det sällan sker INSERT, UPDATE och DELETE i tabellerna. Alltså om det sker mycket SELECT. MyISAM är snabbast men är också enklast att arbeta med.


Det bästa scenariot är...
Om man kan köra två databaser som master och slave med replikering. Då kan en av dem innehålla tabeller med InnoDB som håller koll på all integritet, och den andra har kopior av alla tabeller från den första fast med MyISAM istället för InnoDB. När data ska hämtas så anropas den andra med MyISAM. När data ska läggas till, uppdateras eller tas bort så anropas den första. Då får man det bästa av två världar - nja två olika tekniker i alla fall.


Nu ett exempel med InnoDB

Exempel 1
Beskrivning: Vi kommer ha en tabell där vi lagrar information om kategorier för produkter som säljs på en hemsida. Observera att detta exempel inte kommer fungera med MyISAM.

Skapa först en databas. Skapa sedan nedanstående tabeller.

CREATE TABLE tbl_products(
product_id INT UNSIGNED NOT NULL,
product_name VARCHAR(20),
PRIMARY KEY(product_id)
) ENGINE=InnoDB;
Detta är tabellen med produkter som sedan ska kopplas till kategorier.


CREATE TABLE tbl_categories(
category_id INT UNSIGNED NOT NULL,
category_name VARCHAR(20),
PRIMARY KEY(category_id)
) ENGINE=InnoDB;
Detta är tabellen med kategorier. Tabellerna ovanför beskriver inte hur de är relaterade med varandra. För det behöver vi ännu en tabell.

CREATE TABLE tbl_categories_products(
category_id INT UNSIGNED NOT NULL,
product_id INT UNSIGNED NOT NULL,
PRIMARY KEY(product_id, category_id),
FOREIGN KEY (category_id) REFERENCES tbl_categories(category_id),
FOREIGN KEY (product_id) REFERENCES tbl_products(product_id)
) ENGINE=InnoDB;


Nu kan vi se på bilden här nedanför hur relationen mellan tabellerna ser ut.

(Bild 1) Relation mellan tabeller produkter och kategorier

Lägga till lite data till tabellerna. Här lägger vi till några produkter:
INSERT INTO tbl_products(product_id, product_name)
VALUES
(1, 'MP3 spelare'),
(2, 'iPod'),
(3, 'iPad'),
(4, 'Dell Dimension 1111 PC'),
(5, 'PHP och MySQL Handboken'),
(6, 'Bäverdalen'),
(7, 'Samsung Galaxy Tab')


Lägg till några kategorier för produkterna:
INSERT INTO tbl_categories(category_id, category_name)
VALUES
(1, 'Musikspelare'),
(2, 'Läsplattor'),
(3, 'PC'),
(4, 'Böcker')


Skapa relationer mellan kategorier och produkter:
INSERT INTO tbl_categories_products(category_id, product_id)
VALUES
(1, 1),
(1, 2),
(2, 3),
(3, 4),
(4, 5),
(4, 6),
(2, 7)


Försök att lista ut själv hur relationen är uppbyggd. Första kolumnen är vilken kategori som den andra kolumnen tillhör. T.ex "PHP och MySQL Handboken" tillhör kategori nr 4 vilket är "Böcker".

Resultat
Nu måste utvecklaren och alla mjukvaror som tänker använda tabellerna tänka på att kontrollera integriteten själva genom att uppdatera alla tabeller som ändras för varje SQL-fråga till databasen. ID numren måste stämma överens annars får man ett felmeddelande av databasen. Så om jag nu skulle råka fylla i data (en post) i tabellen tbl_categories_products med följande SQL-fråga, så skulle jag få ett felmeddelande eftersom kategori ID-numret inte finns i tabellen tbl_categories.

INSERT INTO tbl_categories_products(category_id, product_id) VALUES (8, 2)



Exempel för MyISAM
Tyvärr har jag inte några exempel för tabeller som har MyISAM men jag vet att det fungerar genom att skapa sk Triggers. Läs gärna referensen [1] för att läsa mer.


Vad händer om man vill ändra ett ID-nummer i tabellen för kategorier?
Då blir det fel. Man måste ändra i båda tabellerna samtidigt har jag för mig. Men det problemet kan vi lösa i kommande text och exempel.


Cascade för "delete" och "update"
Med nyckelordet "Cascade" kan man tillåta att InnoDB själv ska ha kontroll över alla tabellerna automatiskt. Säg nu att jag vill byta ut ID-numret för kategorin "Läsplattor" till ID 17, då kan jag uppdatera numret för category_id i tabellen tbl_categories och ändringen sker även automatiskt i tabellen tbl_categories_products eftersom den är relaterad till category_id och måste vara likadan. Ändras en tabell så måste den andra tabellen också ändras.

Detsamma gäller när en rad tas bort. Om jag känner för att ta bort hela kategorin "Böcker" (ID nr 4) så kommer raden/raderna i tabellen tbl_categories_products med category_id = 4 att också tas bort.

Hur gör man då detta... man kan använda Cascade när man skapar en främmande nyckel. Nu kommer jag visa med ett exempel hur man gör. Man kan använda CREATE TABLE och ALTER TABLE för att ändra i efterhand. Jag kommer visa hur man gör via CREATE TABLE.

CREATE TABLE tbl_categories_products(
category_id INT UNSIGNED NOT NULL,
product_id INT UNSIGNED NOT NULL,
PRIMARY KEY(product_id, category_id),
FOREIGN KEY (category_id) REFERENCES tbl_categories(category_id) ON UPDATE CASCADE ON DELETE CASCADE,
FOREIGN KEY (product_id) REFERENCES tbl_products(product_id) ON UPDATE CASCADE ON DELETE CASCADE
) ENGINE=InnoDB;


Detta betyder nu att tabellen övervakar de främmande nycklarna i de främmande tabellerna tbl_categories och tbl_products.

Om du nu testar att köra följande SQL-fråga så kan du se att två tabeller uppdateras. Den ena som du valde och den andra som har en relation med den du valde.

UPDATE tbl_categories SET category_id = 14 WHERE category_id = 2

Kontrollera tabellerna

SELECT * FROM tbl_categories
SELECT * FROM tbl_products
SELECT * FROM tbl_categories_products (har ändrat sitt category_id som var 2 automatiskt till 14)

Det borde se ut ungefär så här nu i tabellen tbl_categories:
+-------------+---------------+
| category_id | category_name |
+-------------+---------------+
| 1 | Musikspelare |
+-------------+---------------+
| 14 | Läsplattor |
+-------------+---------------+
| 3 | PC |
+-------------+---------------+
| 4 | Böcker |
+-------------+---------------+

tbl_categories_products:
+-------------+------------+
| category_id | product_id |
+-------------+------------+
| 1 | 1 |
+-------------+------------+
| 1 | 2 |
+-------------+------------+
| 14 | 3 |
+-------------+------------+
| 3 | 4 |
+-------------+------------+
| 4 | 5 |
+-------------+------------+
| 4 | 6 |
+-------------+------------+
| 14 | 7 |
+-------------+------------+


Slutsats
Slutsatsen med detta testet är att jag nu kommer överväga att använda InnoDB för mer kritiska applikationer där det sker många ändringar i databasen. Om jag kör detta system på en hemsida kommer jag att köra cachelagring av all data så behöver data bara hämtas en gång med SELECT från databasen och resten sparas i textfiler.

Det kommer också bli svårare att designa sin databas så jag får planera bättre i framtiden exakt vilka tabeller jag vill använda och hur man eventuellt kan uppdatera databasen i framtiden för att minska problem och fel så mycket som möjligt.

Nu behöver jag bara uppdatera en tabell och behöver inte tänka på vilka andra tabeller som är indirekt relaterade till tabellen genom "osynliga" relationer. Med detta menar jag att jag alltid innan har skrivit applikationer som själva måste hålla reda på att ändra i t.ex tabellen tbl_categories_products så fort jag uppdaterar ett kategori ID eller tar bort en kategori.

Ett bra scenario är kommentarer som är kopplade till ett blogginlägg. Tar man bort blogginlägget så ska alla tillhörande kommentarer tas bort automatiskt utan att jag som programmerare behöver tänkta på att skriva kod som måste utföra det manuellt. Nu sköts allt i databasen och koden blir mer abstract och enklare att underhålla.

Slutord
Det var allt för den här gången. Jag hoppas att artikeln har varit till någon nytta för er.

Mvh
Waschman


Referenser
[1] http://dev.mysql.com/tech-resources/articles/mysql-enforcing-foreign-keys.html
[2] http://blogs.innodb.com/wp/2010/09/mysql-5-5-innodb-as-default-storage-engine/

10 februari, 2011

jQuery: Ny version 1.5 av jQuery men bug om man använder jQuery UI 1.8.9

jQuery version 1.5 släpptes för några dagar sedan men redan har jag hittat ett fel, vilket är ganska allvarligt. Versionen blockerar kod som använder sortable och draggable i paketet jQuery UI om de är anslutna till varandra (connectedWith)

Ni kan läsa mer på detta foruminlägg: http://forum.jquery.com/topic/weird-weird-error-on-draggable

Följande kod kommer alltså inte att fungera i nuläget om ni använder version 1.5:
$('.cms-block-container').addClass('cms-sortable');
$('.cms-sortable').sortable({
appendTo: 'body',
connectWith: '.cms-sortable',
revert: true,
placeholder: 'sortable-placeholder',
delay: 300,
opacity: 0.75,
handle: '.cms-block-move-handle',
cancel: '.cms-drop-zone-placeholder',
helper: function(event) {
return $('sortable-html-code-here');
},
... and activate, deactivate etc.


$('.cms-draggable').draggable({
appendTo: 'body',
connectToSortable: '.cms-block-container',
helper: 'clone',
cursor: 'move',
opacity: 0.75,
cursorAt: { left: -3, top: -3},
helper: function(event) {
return $('sortable-html-code-here');
}
}).disableSelection();

Lösningen på problemet är att använda en tidigare version, v.1.4.4 är bekräftad och fungerar.

Detta är varför jag inte använder skript som heter latest.js när man infogar kod från exempelvis googlecode.

04 augusti, 2010

XHTML/Javascript: Ej blockerad nedladdning och optimering av websida när Javascript och CSS används

English title: Non-Blocking download and optimization of webpages when using Javascript and CSS

Förord
Är du webbutvecklare/webbdesigner som vill att din websida ska ladda snabbare? Använder du skript som tar lång tid att ladda? Då kanske du finner din lösning här. Fortsätt läs för att få veta mer.


Introduktion
När en webbsida laddas i en webbläsare skickas det ett anrop för varje skript, stilmal och bild som existerar i koden för webbsidan. När skript och stora stilmallar måste hämtas och läsas in tar det tid. Detta blockerar webbläsaren från att fortsätta tills nedladdningen av filerna är klara. Om man då har ett stort skript som måste laddas in först, börjar text och bilder inte synas förrän den har laddat klart.

Lösningen? Komprimera skript och stilmallar för att minska på filstorleken och försök få allt att laddas ned samtidigt. Försök också att ha så får anrop som möjligt. Webbläsarna använder mestadels GET- och POST-anrop och de bör hållas till ett minimum.

Tipsen i denna artikel kan även användas på webbsidor anpassade för mobiltelefoner och t.ex iPad, som är begränsade till hastigheter inom GSM/GPRS/3G/4G som varierar mycket beroende på var man befinner sig geografiskt. De har även i många fall sämre RAM och CPU-kraft som krävs för att rendera webbsidor. Färre anrop förbättrar upplevelsen.


Tester
Jag har utfört tre tester på min egna webbsida med följande uppsättning:
  • Firefox 3.6.8
  • Firebug 1.5.4
  • PHP (957 b)
  • XHTML Strict
  • CSS (883 kB)
  • Javascript (310 kB)
  • Stor bild (2.7 MB)

Att tänka på innan man börjar
Javascript brukar vara stora och ta upp mycket utrymme samt ha tunga beräkningar. Se till att komprimera alla skript så de tar upp så lite utrymme som möjligt. Då går det snabbare att ladda in dem.

Min fil med Javascript är bara komprimerad till hälften och innehåller många olika skript och bibliotek som har infogats i en enda fil istället för att använda flera.

Istället för:
<script type="text/javascript" src="skript1.js"></script>
<script type="text/javascript" src="skript2.js"></script>
<script type="text/javascript" src="skript3.js"></script>
<script type="text/javascript" src="skript4.js"></script>
<script type="text/javascript" src="skript5.js"></script>

Använder jag:
<script type="text/javascript" src="alla_skript.js"></script>

Detsamma gäller också för alla mina stilmallar. Använd inte "@import" i CSS för att ladda in externa stilmallar. Det skapar extra anrop i vissa webbläsare. Ni bör avstå från det. Det bästa är att sammanfoga alla stilmallar till en enda stilmall.


Komprimering
Många webbapplikationer, webbtjänster och skript erbjuder möjligheten att komprimera (minska) filernas storlek. Här är ett exempel på en sökning

För er som vill testa på att komprimera skript med PHP kan läsa följande artikel http://www.devirtuoso.com/2009/07/how-to-compress-cssjavascript-files-with-php/


Laddningstider och blockering av laddning
http://www.stevesouders.com/blog/2009/04/27/loading-scripts-without-blocking/ är en av de bästa artiklarna jag har läst som beskriver vad ämnet handlar om och vad man kan använda för att lösa problemen.

En lösning som jag har börjat använda är enkel att använda och effektiv. Metoden kallas "Script DOM Element" och går ut på att man med hjälp av lite Javascript, inuti head-sektionen på en webbsida, kan skapa en skript-tagg dynamiskt när webbsidan börjar laddas. Man anger att källan (eng. source, xhtml. src) ska peka mot skriptfilen.

Då skapar man parallell nedladdning i webbläsaren, det vill säga att skriptet laddas ned samtidigt som resten av sidan.

Viktigt! Lösningen med "Script DOM Element" varierar mellan olika webbläsare och jag rekommenderar att ni läser artikeln jag nämnde ovanför och tar en titt på bilden här http://stevesouders.com/efws/images/0405-load-scripts-decision-tree-04.gif Det har att göra med om skriptet ligger på samma domän som webbsidan eller inte, samt om inbäddade skript är beroende av skriptet eller inte.


Förklaring av mitt test
Jag utförde tre tester i webbläsaren Firefox version 3.6.8 och till min hjälp använde jag Firebug version 1.5.4 för att ta tid och för eventuell felsökning. I Firebug kan man se fina grafer över nedladdningen av webbsidan. Man kan se vilka delar i koden som tar längst respektive kortast tid att utföra. Mer information om tester hittar ni under rubriken Scenario.

Exempel på graf i Firebug

(Klicka på bilden för att förstora)

I graferna kan man se vilket svar man fick från webbservern (Response, GET, POST, 404, 200, 304, m.fl) samt tiden. Det bästa är om stilmallar, skript och bilder kan laddas ned parallellt (samtidigt).

Viktigt
Innan varje test utförs måste man rensa webbläsarens cache och Internetfiler för den aktuella dagen. Annars får man cachade filer vilket ger ett vilseledande resultat. I Firefox görs det via menyn:
  1. Verktyg
  2. Rensa ut tidigare historik
  3. Välj Idag
  4. Kryssa för Besökta sidor och filhämtningshistorik samt Cache.



Så glöm inte rensa webbläsarens cache!!

Testerna påverkas även av din Internethastighet. En annan notering är att kommentarerna i min kod i testet är på engelska för att hjälpa engelska besökare som läser artikeln.


Scenario
Preparera en webbsida med lite text, en stor bild som helst ska vara minst 1MB, en stor stilmall och ett stort Javascript. Då ser man skillnanden tydligt och millisekunder är svårt att mäta eftersom det kan skilja ganska många från test till test. Ni kan referera till min kod som jag visar under testerna här nedanför.

I vanliga fall laddas objekten och resurserna i följande ordning.
  1. CSS och Javascript laddas parallellt
  2. Bilder laddas sist, ibland även text.
Men som jag sagt tidigare i artikeln, blockerar oftast Javascriptet resten av webbsidan från att börja ladda.


Test 1
En vanlig implementation av en webbsida.

Följande kod användes i testet:
<?php
//
// Test 1
// File: test.php
//
header("Cache-Control: no-cache");
header("Pragma: no-cache");
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>Testa laddning av Javascript</title>
<link rel="stylesheet" type="text/css" media="all" href="css2.css" />
<script type="text/javascript" src="javascript2.php"></script>
</head>
<body>
<p>Text som visas på hemsidan snabbt.</p>
<p><img src="stor_bild.jpg" alt="stor bild" width="700" /></p>
<p>Sista texten</p>
</body>
</html>

Resultat - Test 1

(Klicka på bilden för att förstora och se resultatet)

Beskrivning av resultatet
Vi ser att stilmallen och Javascriptet laddas parallellt medan bilden laddas senare (sist). På vissa webbsidor kan skripten vara sega och då tar det längre tid för hela webbsidan att laddas. Detta vill vi ändra på.


Test 2
Nu använder vi tekniken "Script DOM Element" för både stilmallen och Javascriptet. Tänk på att även använda taggen "noscript" om en besökare har en webbläsare med Javascript avstängt. Då måste de fortfarande kunna använda stilmallen som annars slutar fungera eftersom den inte kan laddas korrekt.

Följande kod användes i testet:
<?php
//
// Test 2
// File: test2.php
//
header("Cache-Control: no-cache");
header("Pragma: no-cache");
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />

<title>Testa laddning av Javascript</title>
<noscript>
<link rel="stylesheet" type="text/css" media="all" href="css2.css" />
</noscript>
<script type="text/javascript">
/* <![CDATA[ */

// If you are using both CSS and JS DOM load, then you need to put the CSS link also inside a noscript tag

// CSS
var domscript_css = document.createElement('link');
domscript_css.rel = "stylesheet";
domscript_css.type = "text/css";
domscript_css.media = "all";
domscript_css.href = "css2.css";
document.getElementsByTagName('head')[0].appendChild(domscript_css);

// Javascripts
var domscript = document.createElement('script');
domscript.type = "text/javascript";
domscript.src = "javascript2.php";// Contains all Javascript
document.getElementsByTagName('head')[0].appendChild(domscript);
/* ]]> */

</script>
</head>
<body>
<p>Text som visas på hemsidan snabbt.</p>
<p><img src="stor_bild.jpg" alt="stor bild" width="700" /></p>

<p>Sista texten</p>
</body>
</html>

Resultat - Test 2


(Klicka på bilden för att förstora och se resultatet)

Beskrivning av resultatet
Nu ser vi att hela webbsidan laddas samtidigt och stilmallen och Javascriptet laddas ned parallellt. Detta kallas på engelska för "Non-Blocking Javascript" eftersom det gör att resten av webbsidan inte blockeras. Notera att det bara tar så lång tid det tar att läsa in filen test2.php och bilden. Vi har just nu minskat våra laddningstider med en hel sekund (1 sekund) om vi jämför med föregående Test 1.


Test 3
I det sista testet länkar jag till stilmallen precis som vanligt men Javascriptet laddas in dynamiskt. Ett tips är att alltid ladda in stilmallar innan skript.

Följande kod användes i testet:
<?php
//
// Test 3
// File: test3.php
//
header("Cache-Control: no-cache");
header("Pragma: no-cache");
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>Testa laddning av Javascript</title>
<link rel="stylesheet" type="text/css" media="all" href="css2.css" />
<script type="text/javascript">
/* <![CDATA[ */

// Javascripts
var domscript = document.createElement('script');
domscript.type = "text/javascript";
domscript.src = "javascript2.php";// Contains all Javascript
document.getElementsByTagName('head')[0].appendChild(domscript);
/* ]]> */

</script>
</head>
<body>
<p>Text som visas på hemsidan snabbt.</p>
<p><img src="stor_bild.jpg" alt="stor bild" width="700" /></p>

<p>Sista texten</p>
</body>
</html>

Resultat - Test 3

(Klicka på bilden för att förstora och se resultatet)

Beskrivning av resultatet
I det sista testet var det stilmallen som tog tid att ladda in och blockerar därför resten av webbsidan.


Analys
Testen visade tydligt vilken skillnad det var om man använde tekniken eller inte, eller om man blandade tekniken med vanlig kodning. Tiderna i resultaten kan variera men ni får gärna räkna ut ett genomsnittlig tid för varje test och sedan jämföra dem.

Nu testade jag med en extremt liten webbsida med endast två stycken och en bild. Stilmallen lästes in men användes inte på webbsidan. Om man testar med en större webbsida, tror jag man får bättre resultat och man upptäcker nog även enklare eventuella prestandaförbättringar.

Kontrollera även cache mm
Om det tar tid att ladda in koden skriven i HTML/XHTML varje gång en sida laddas, ska man tänka på följande:
  • Hämtas data från ren HTML?
  • Hämtas data från en databas (XML, MySQL, MS Access, MS SQL Server, ...)?
  • Används cache på servern?
  • Används cache på klienten?
  • Hur länge är ett objekt eller en resurs cachad?
  • Är data komprimerat eller i klartext?
  • Är data krypterad (ex. HTTPS, CHAP)?
Cachad data hjälper till att öka prestandan oerhört mycket och det märks tydligt på användningen av minne och processor på servern. Kryptering och omkodning av data kan också ta tid. Komprimera data om det är möjligt.

Snabbt om data redan finns i cache
Testerna visade att det bara tog några millisekunder att ladda webbsidan om man glömde rensa cache och Internetfiler innan man utförde varje test.

Tänk på antalet besökare
Om man inte har så många skript tror jag inte man behöver tänka på detta, men då måste man istället tänka på hur många besökare som besöker webbsidan. Om väntetiden är för lång när man laddar en webbsida (absolut max 10 sekunder enligt vissa rapporter) förlorar man besökare. För många företag betyder det förlust i intäkter och mindre pengar.

Låsning och blockering
Om ett skript låser sig i en evig loop eller om skriptet måste beräkna tunga data innan webbsidan laddas, blockeras resten av innehållet.

Kommer det fungera på din webbsida?
Kontrollera först noga om metoden ovan i testerna kommer fungera på just din webbsida eller i ditt scenario. Det finns vissa begränsningar som beskrivs i de andra artiklarna jag länkade till.

Testat i andra webbläsare?
Testerna har endast utförts i Firefox för att jag inte har haft tillgång till andra webbläsare, utom Internet Explorer. Jag vet inte riktigt om det finns något insticksprogram tillInternet Explorer


Slutsats
Min slutsats av testerna och analysen är att man först måste tänka på om det lönar sig att använda metoden. Metoden fungerar bra och jag kommer använda den när jag utvecklar mina webbapplikationer.

Lycka till

24 mars, 2010

PHP/MySQL: Konvertera från datetime till sekunder från epoch

English translation:MySQL and PHP Convert datetime to seconds

Undrar du hur man kan omvandla data från en kolumn i MySQL med datetime som datatyp till antalet sekunder från "epoch" (1970-01-01)? Det undrade jag och nu tänker jag dela med mig av lösningen.

Jag gillar att programmera med PHP och utveckla dynamiska hemsidor tillsammans med MySQL som backbone. Just nu för en liten stund sedan letade jag efter en lösning för att omvandla datetime till sekunder för att enklare formatera datum med PHP funktionen date().

Notis:
Jag vet att det finns utmärkta lösningar inbyggda i MySQL men i koden jag använder nu går det inte att lösa på det sättet. Det datum som returneras från databasen är alltid i formatet yy-mm-dd tt:mm:ss

<?php
echo strtotime('2010-03-24 12:26:00') .'<br/>';
echo strtotime('2010-03-24 12:27:00') .'<br/>';

// Resultat
// 1269458760
// 1269458820

// Verifiera att det fungerar
echo date('Y-m-d H:i:s', strtotime('2010-03-24 12:27:00') ) .'<br/>';

// Resultat
// 2010-03-24 12:27:00

// Ett annat format
echo date('l F j, Y, G:i', strtotime('2010-03-24 12:27:00'));

// Resultat
// Wednesday March 24, 2010, 12:27
?>

Men för er som verkligen vill lösa det på MySQL-viset kommer här ett exempel:

// Skriver ut 1269458820
SELECT UNIX_TIMESTAMP('2010-03-24 12:27:00')

Ganska enkelt eller hur? Vill ni veta mer om funktionen strtotime() [1] i PHP så hittar ni information i den grymma dokumentationen på www.php.net [2]

Lycka till med programmeringen

Referenser
[1] www.php.net/manual/en/function.strtotime.php
[2] www.php.net

10 mars, 2010

Nätverk: ARP - Address Resolution Protocol i datanätverk

Hej!

För er som undrar över hur kommunikation fungerar i ett nätverk mellan två enheter (t.ex två datorer) genom en switch och router kan ni läsa mitt svar här nedanför som jag gav till en utländsk student vid Halmstad högskola som jag hade i kursen IP-telefoni och trådlösa nätverk när jag var kursansvarig. Texten är på engelska. Om jag får in några kommentarer som vill ha en svensk översättning så fixar jag det.

Studenten frågade efter hur en PC känner till sin destinations IP-adress och hur datapaketen tar sig dit, utan att man specificerar subnätmasken i ICMP (ping) meddelandet. Allt har att göra med protokollet ARP - Address Resolution Protocol.

Till min hjälp har jag använt programmet Packet Tracer 5.2 för att felsöka kommunikationen. Jag har även bifogat en simpel topologi över nätverket.

--------------------------


(Klicka på bilden för att förstora)
--------------------------

Question: How does a PC know about the destination IP-address and how to get to it without sending the subnetmask in the ICMP (ping) message?

Answer:
Hi,
I tried a scenario in Packet Tracer just now and here it how it works.
  1. I choose to ping from 192.168.1.10 to 192.168.1.11
  2. ARP constructs a request for target IP-address 192.168.1.11, and sets the broadcast MAC-address to FF:FF:FF:FF:FF:FF
  3. ARP encapsulates PDU into Ethernet frame
  4. Frame goes to switch on the wire
  5. Switch receives frame on port fa0/2
  6. Switch processes frame up to OSi layer 2 "Data link"
  7. It is a broadcast (FF:FF:FF:FF:FF:FF), send out on all switch ports except the receiving port, so this is sending packets to router (192.168.1.1) and PC (192.168.1.11)
  8. Packets are sent out fa0/1 and fa0/3
  9. Router receives ARP request on port fa0/0
  10. The ARP request's target IP address does not match the receiving port's IP address, (192.168.1.11 is not matching routers IP of 192.168.1.1)
  11. The ARP process on the router checks the routing table whether the requested IP address is reachable, and the IP-address is reachable on source port fa0/0

    Router# show ip route
    C 192.168.1.0/24 is directly connected, FastEthernet0/0
    C 192.168.2.0/24 is directly connected, FastEthernet0/1

  12. ARP table on router is updated with souce IP-address (192.168.1.10) and MAC-address
  13. Router discards ARP-request
  14. Now the destination PC receives the ARP request on its ethernet port from the switch as a broadcast (FF:FF:FF:FF:FF:FF)
  15. The ARP request's target IP address matches the receiving port's IP address. (192.168.1.11 is matching 192.168.1.11)
  16. ARP-process on destination PC updates the ARP-table.
  17. ARP-process on destination PC replies to source PC with source port MAC-address, and encapsulates PDU into ethernet frame.
  18. Switch port fa0/3 receives request and looks in its ARP-table.
  19. The frame source MAC-address was found in its ARP-table.
  20. This is a uniucast frame (from PC 192.168.1.11 to PC 192.168.1.10) so switch looks in ARP-table for destination MAC-address
  21. Switch is sending unicast reply out fa0/2 port
  22. PC 192.168.1.10 receives ARP-reply on ethernet port and does now know about the PC 192.168.1.11 MAC-address on OSI layer 2
  23. It saves the information (mapping) MAC-address to IP-address.
  24. PC 0 can now send an ICMP (ping) message to PC 1 using only IP-addresses on OSI layer 3 "Network".

Now, if the ping is going to IP-address 192.168.2.10, then the ICMP-message will reach the router (which MAC-address is also in PC A's ARP-table). The router will check the routing table for destination IP-address network, if it's reachable. It is reachable through port router's fa0/1 to network 192.168.2.0/24

Then the ARP-process will start all over again on the other side, so the router will ask the switch, which in turn will broadcast the ARP out all switchports except receiving port (fa0/1). The request is going out fa0/2 to PC 2 with IP 192.168.2.10 and the IP is correct. An ARP-reply is then sent back to the router. ICMP (ping) can now continue.

I really recommend you to test Packet Tracer to look at TCP/IP and ARP messages going. You can also debug DHCP and some other protocols.

-----------------------------

Innan jag svarade studenten på hans fråga, trodde jag att jag kunde ARP, men efter en djupdykning i protokollet fick jag mer kunskap. Nu vet jag mycket bättre själv hur kommunikationen i ett datanätverk går till. Visst kunde jag detta utantill när jag studerande CCNA vid högskolan och gymnasiet men det är alltid bra att fräscha upp minnet lite.

Lycka till alla

26 december, 2009

God Jul och ett Gott Nytt År

Till er från mig önskar jag alla en god jul och ett gott nytt år.. eller man kanske ska säga god fortsättning denna Annandag Jul.

Jag jobbar mycket och får väldigt lite tid över till bloggen, men PHP-artiklarna är skriva för hand redan plus att jag funderar på att skriva mer om Cisco och etisk hacking.

Ha en fortsatt trevlig vinternatt

- Waschman

22 oktober, 2009

Windows 7: Visa skrivbordet

Hej! Jag kände att det var dags att uppdatera lite på bloggen, därför skriver jag här ett tips till er om Windows 7.

Ikonen i snabbstartfältet för att visa skrivbordet fanns i Windows XP och Windows Vista. Men i Windows 7 är ikonen borttagen. Jag fann en guide på Internet hur man gjorde för att få ikonen tillbaka och likna den i Windows Vista. Det fungerade bra. Men det bästa hade väl varit om den funktionen redan fanns i nya Windows 7.

Jag har upptäckt att det finns tre sätt att visa skrivbordet.

Steg för att visa skrivbordet i Windows 7:
  1. Klicka med musen i den vertikala rutan längst ner till höger


    (Klicka på bilden för att endast visa den) Visa skrivbordet i Windows 7 - Alternativ 1

  2. Man kan även högerklicka på aktivitetslisten längst ner på skärmen och sedan välja "Visa skrivbordet" eller "Show the desktop" i engelska versionen.


    (Klicka på bilden för att endast visa den) Visa skrivbordet i Windows 7 - Alternativ 2

  3. Man kan även använda tangentkombinationen Windows + D. Tack för tipset från BosseWeb

För fler tips om Windows 7 kan ni även läsa en artikel från webbtidningen IDG Windows 7 på 2 minuter [1]

Själv kan jag inte använda alla tips för Windows 7 eftersom jag inte har en sån bra laptop där Aero-temat inte fungerar över huvud taget. Aero-temat är (för de som inte vet) det tema i Windows 7 som aktiverar snyggare färger, genomskinlighet, extra funktioner, musrörelser, m.fl. Jag får nöja mig med Firefox och Notepad++ när jag utvecklar webbsidor och ska surfa på Internet.

Ha en fortsatt trevlig dag!

Källreferens
[1] http://www.idg.se/2.1085/1.261217/snabbkoll-windows-7--pa-2-minuter

13 september, 2009

Ljus höst framför oss

Semestern är över och solen närmar sig horisonten fortare för var dag som kommer och tittar förbi. Mycket har hänt och mycket kommer hända nu till hösten. Det kanske inte kommer märkas så mycket på bloggen men jag har många saker att göra, samt några projekt som måste färdigställas.

Några av uppgifterna är att utbilda studenterna vid Halmstad Högskola inom nätverksdesign och datordrift med Cisco-nätverk. Min egna webbsida skall också utvecklas med mitt egna CMS (Content Management System) plus lite annat.

Så hösten tror jag blir väldigt lärorik och medan höstmörkret närmar sig, ser det fortfarande ljust ut på IT fronten. Det kommer fortfarande komma nya artiklar om t.ex PHP, Cisco och Windows 7 och annat smått och gott.

Så jag hoppas ni får trevlig läsning framöver.

MVH
Waschman

30 juni, 2009

Semester: Sommar och härlig ledighet

Äntligen sommar och härligt väder är det också. Jag är ledig och ska snart i början på augusti börja förbereda inför min anställning på Halmstad högskola som labbinstruktör och lärare i olika datorkurser.

Det är så skönt att få bada i havet och temperaturen bara stiger och stiger, med senast uppmätta temperatur på 20-21 grader celcius vid Åsa camping i Halland. Jag umgås mycket med min flickvän och mina kompisar nu och sitter därför mycket lite vid datorn. Det händer att man ser efter om man har fått någon ny e-post nån gång ibland, men annars gör jag inte så mycket mer på datorn.

Detta leder naturligtvis till färre artiklar på bloggen, vilket det också har blivit nu den sista perioden i slutet av våren p.g.a. mitt examensarbete tillsammans med en klasskompis.

Artikelserien om PHP för riktiga nybörjare fortsätter att utvecklas och jag har redan skrivit några utkast på nästa del. Jag och en klasskompis tänker skriva mer om Cisco-nätverk nu till hösten, och under samma period kommer utvecklingen av en festivals webbsida komma igång på riktigt. Vilken festival det rör sig om tänker jag inte berätta. Det är mycket som är på gång och det börjar snart klia i fingerspetsarna inför nya artiklar och utvecklingsprojekt.

Försök ta del av sommaren vi har så mycket ni kan och när regnet kommer och när sommaren börjar nå sitt slut, då börjar man komma i fas igen.

Jag vill bara önska er alla en mycket trevlig sommar med många mysiga och härliga dagar i solen, skuggan, vattnet och där ni nu helst vill vara.

Glad sommar!

Tips/Administration: 100 Windows XP smarta genvägar

Vilken härlig sommar vi har. Allt är helt underbart förutom att det ibland är lite för varmt. I värmen behöver man dricka mycket vätska och då är det ju typiskt att vattnet i husområdet läcker och måste stängas av. Man blir lite dåsig i huvudet och nästa lite yr om man dricker för lite och om det är för varmt. Om man då ska sätta sig vid datorn och sköta lite av administrationen är chansen stor att man snabbt tröttnar på tröga laddningar av det grafiska gränssnittet. Speciellt för mig när jag sitter vid pappas dator i hans varma, kvava och lilla klädgarderob och hjälper till att fixa datorproblem.

Men nog om det.

För att ni enklare ska komma igång med administrationen i den både härliga och hemska värmen tipsar jag nu om 100 textkommandon för Windows XP som underlättar och snabbar upp väntetiden. Jag fann dem för inte så länge sedan och kände direkt att dessa behövs.

OBS! Man kör kommandona genom att öppna rutan "Kör" på startmenyn eller genom att klicka på Windowslogotyp-tangenten + R

Listan med kommandon

Accessibility Controls
access.cpl

Add Hardware Wizard
hdwwiz.cpl

Add/Remove Programs
appwiz.cpl

Administrative Tools
control admintools

Automatic Updates
wuaucpl.cpl

Bluetooth Transfer Wizard
fsquirt

Calculator
calc

Certificate Manager
certmgr.msc

Character Map
charmap

Check Disk Utility
chkdsk

Clipboard Viewer
clipbrd

Command Prompt
cmd

Component Services
dcomcnfg

Computer Management
compmgmt.msc

Date and Time Properties
timedate.cpl

DDE Shares
ddeshare

Device Manager
devmgmt.msc

Direct X Control Panel (If Installed)*
directx.cpl

Direct X Troubleshooter
dxdiag

Disk Cleanup Utility
cleanmgr

Disk Defragment
dfrg.msc

Disk Management
diskmgmt.msc

Disk Partition Manager
diskpart

Display Properties
control desktop

Display Properties
desk.cpl

Display Properties (w/Appearance Tab Preselected)
control color

Dr. Watson System Troubleshooting Utility
drwtsn32

Driver Verifier Utility
verifier

Event Viewer
eventvwr.msc

File Signature Verification Tool
sigverif

Findfast
findfast.cpl

Folders Properties
control folders

Fonts
control fonts

Fonts Folder
fonts

Free Cell Card Game
freecell

Game Controllers
joy.cpl

Group Policy Editor (XP Prof)
gpedit.msc

Hearts Card Game
mshearts

Iexpress Wizard
iexpress

Indexing Service
ciadv.msc

Internet Properties
inetcpl.cpl
IP Configuration (Display Connection Configuration)
ipconfig /all

IP Configuration (Display DNS Cache Contents)
ipconfig /displaydns

IP Configuration (Delete DNS Cache Contents)
ipconfig /flushdns

IP Configuration (Release All Connections)
ipconfig /release

IP Configuration (Renew All Connections)
ipconfig /renew

IP Configuration (Refreshes DHCP & Re-Registers DNS)
ipconfig /registerdns

IP Configuration (Display DHCP Class ID)
ipconfig /showclassid

IP Configuration (Modifies DHCP Class ID)
ipconfig /setclassid
ava Control Panel (If Installed)
jpicpl32.cpl

Java Control Panel (If Installed)
javaws

Keyboard Properties
control keyboard

Local Security Settings
secpol.msc

Local Users and Groups
lusrmgr.msc

Logs You Out Of Windows
logoff

Mcft Chat
winchat

Minesweeper Game
winmine

Mouse Properties
control mouse

Mouse Properties
main.cpl

Network Connections
control netconnections

Network Connections
ncpa.cpl

Network Setup Wizard
netsetup.cpl

Notepad
notepad

Nview Desktop Manager (If Installed)
nvtuicpl.cpl

Object Packager
packager

ODBC Data Source Administrator
odbccp32.cpl

On Screen Keyboard
osk

Opens AC3 Filter (If Installed)
ac3filter.cpl

Password Properties
password.cpl

Performance Monitor
perfmon.msc

Performance Monitor
perfmon

Phone and Modem Options
telephon.cpl

Power Configuration
powercfg.cpl

Printers and Faxes
control printers

Printers Folder
printers

Private Character Editor
eudcedit

Quicktime (If Installed)
QuickTime.cpl

Regional Settings
intl.cpl

Registry Editor
regedit

Registry Editor
regedit32

Remote Desktop
mstsc

Removable Storage
ntmsmgr.msc

Removable Storage Operator Requests
ntmsoprq.msc

Resultant Set of Policy (XP Prof)
rsop.msc

Scanners and Cameras
sticpl.cpl

Scheduled Tasks
control schedtasks

Security Center
wscui.cpl

Services
services.msc

Shared Folders
fsmgmt.msc

Shuts Down Windows
shutdown

Sounds and Audio
mmsys.cpl

Spider Solitare Card Game
spider

SQL Client Configuration
cliconfg

System Configuration Editor
sysedit

System Configuration Utility
msconfig

System File Checker Utility (Scan Immediately)
sfc /scannow

System File Checker Utility (Scan Once At Next Boot)
sfc /scanonce

System File Checker Utility (Scan On Every Boot)
sfc /scanboot

System File Checker Utility (Return to Default Setting)
sfc /revert

System File Checker Utility (Purge File Cache)
sfc /purgecache

System File Checker Utility (Set Cache Size to size x)
sfc /cachesize=x

System Properties
sysdm.cpl

Task Manager
taskmgr

Telnet Client
telnet

User Account Management
nusrmgr.cpl

Utility Manager
utilman

Windows Firewall
firewall.cpl

Windows Magnifier
magnify

Windows Management Infrastructure
wmimgmt.msc

Windows System Security Tool
syskey

Windows Update Launches
wupdmgr

Windows XP Tour Wizard
tourstart

Wordpad
write

Lycka till!

Källa
http://www.techtalkz.com/blog/general/100-windows-xp-run-commands.html

02 juni, 2009

Programmering: Artikelserie PHP för riktiga nybörjare

Förord
Jag håller på att skriva en artikelserie om PHP för riktiga nybörjare och jag tänker ha en lista här med alla delar. Då blir det enklare för er att hitta dem och enklare för mig att underhålla.

Delar i artikelserien

Programmering: PHP för riktiga nybörjare - Del 2

Artikelserien är tillägnad min bror

Förord
Detta är del 2 i min artikelserie om PHP för riktiga nybörjare. Mitt mål är att försöka lära ut PHP till så många som möjligt och berätta på ett så enkelt och lättläst sätt som möjligt. Om något är oklart för er så tveka inte att skriva en kommentar och berätta vad ni tycker är bra och/eller mindre bra.

Delar i artikelserien
Lista med alla delar i artikelserien [6]

Vad vi kommer att gå igenom
  • Olika typer av variabler
  • Ingående om talsystem
  • Omvandla från en variabeltyp till en annan
Introduktion
I del 1 gick vi igenom de första stegen mot ett första PHP-skript, vad kommentarer används till, hur man lagrar data i s.k. variabler, lite grundläggande om text och siffror och hur man visar text på en webbsida.

I denna delen kommer jag beskriva de olika typer av variabler som finns samt hur man omvandlar data från en typ till en annan. Det kan vara rätt svårt att ta till sig allt första gången så läs gärna igenom artikeln flera gånger.

Olika typer av variabler
Vad är en datatyp för något?
I del 1 sade jag att en variabel är en slags kakburk som kan innehålla olika typer av kakor med olika smak och storlekar. En kaka i detta fallet är data som du som programmerare vill spara någonstans för att sedan göra saker med den. Man kan säga att en datatyp i PHP är vilken smak kakan har.

Kom ihåg nu att i alla framtida artiklar, inklusive den du läser nu, så är det variabler jag berättar om och inte kakor. Det är bara för att ni skall förstå lite bättre.

Exempel på datatyper
En variabel (kaka) kan vara en av följande typer. Notera att den engelska betäckningen står inom parentes.
  • Heltal (integer)
  • Decimaltal / Flyttal (float, double)
  • Boolesk: Sant eller falskt (boolean)
  • Sträng: Vanlig text (string)
  • Vektor: Lista som innehåller en eller flera datatyper vilka kan vara likadana eller olika (array)
  • Resurs: Koppling till resurser som t.ex databaser, filer, nätverksanslutningar m.fl (resource)
  • Objekt: Samla verktyg och egenskaper i ett s.k. objekt för att skapa mer återanvändbar kod (object)
Datatyperna Resurs, Vektor och Objekt är svåra att förstå och begripa så därför kräver de en ny artikel var för sig.

Överkurs
Datatypen Objekt är överkurs så jag kommer endast visa principen och några mycket enkla exempel i en framtida artikel.

Datatyper i andra programmeringsspråk
I andra programmeringsspråk så används datatyperna på ett mer låst sätt. Man kan inte göra hur som helst. Vill man skapa en variabel som man vet kommer innehålla en viss typ av data, måste variabeln deklareras först. Det betyder att man väljer datatypen först och sedan får den inte ändras. Men den kan ändras men då måste man använda andra lite svårare tekniker.

Datatyperna i PHP
I PHP omvandlas variablerna automatiskt till den datatyp som datan har när den sparas i variabeln. Om en variabel innehåller text får den datatypen "string" men om man sedan sparar några heltal i samma variabel, omvandlas datatypen automatiskt till "integer".

Det finns både för- och nackdelar med detta men jag tycker det är skönt att slippa tänka på vilka typer av variabler man använder i sin kod. Man behöver bara kontrollera data bättre för att det inte ska bli fel. Man måste även kontrollera data bättre i andra programmeringsspråk för att slippa få komplicerade fel och s.k. undantag.

Heltal
Heltal heter på engelska "integer".

Positivt och negativt

Heltal i PHP är tal/siffror som kan vara antingen positiva (+) eller negativa (-). Man använder de precis som man gör i vanlig matematik i skolan.

Nybörjartips
Ni behöver egentligen bara koncentrera er på människans talsystem i första hand. Ni kan hoppa över de andra talsystemen. De andra beskriver jag endast eftersom jag tror det finns några som vill känna till de andra talsystemet i alla fall.


Människans talsystem basen 10
Vi människor har ett talsystem från 0 till 9. Man säger att vårt talsystem har basen 10 (0 1 2 3 4 5 6 7 8 9). Vi kan alltså beskriva tal med 10 olika siffror. Det finns även andra sätt att representera heltal vilka beskrivs här nedanför.
Exempel:
10, 27, 10254, +56, +79, -62, -2, -9
Datorernas talsystem basen 2
Datorer använder basen 2 (0 1). Här får vi bara använda siffrorna 0 (noll) och 1 (ett). De kallas för binära tal.
Exempel:
101, 10010110101, 11110, 11010, 0, 1
Program och utveckling basen 16
Ett vanligt sätt att beskriva stora tal är med basen 16 i det s.k. hexadecimala talsystemet från 0 till 9, sedan från A till F (0 1 2 3 4 5 6 7 8 9 A B C D E F). Dessa tal används vanligen när man programmerar stora program och system med avancerade konfigurationer. Det är också vanligt när man arbetar med kryptering.

Ett hexadecimalt tal måste inledas med 0x eller 0X.
Exempel:
0x5, 0x2F, 0x694FA, 0x101
Oktala talsystemet basen 8
Jag har inga bra exempel på när det är bra att använda det oktala talsystemet med basen 8. Det är tal från 0 till 7 (0 1 2 3 4 5 6 7). Ett användningsområde jag känner till är i Unix/Linux när man behöver konfigurera behörigheter i filsystemet (läsa [4], skriva [2], köra [1]). Då får man tal som kan se ut så här: 777, 644, 500, 100.

För att arbeta med oktala tal i PHP måste de börja med 0 (noll).
Exempel:
0100, 08, 012, 029, 0777
Exempel i PHP med olika heltalstyper
Nu ska jag visa hur vi kan använda oss utav det jag precis har gått igenom.
<?php
// Exempel 1 på talsystem i PHP
$tal = 1234; // Positivt heltal basen 10
$tal = -1234; // Negativt heltal basen 10
$tal = 0x101FA; // Hexadecimalt heltal basen 16
$tal = 0777; // Oktalt heltal basen 8

// Binära heltal basen 2 måste skrivas som text
$tal = "10110"; // Binärt heltal basen 2
?>
<?php
// Exempel 2 på talsystem i PHP
$tal1 = 12;
$tal2 = 26;
$summa = $tal1 + $tal2;
echo $summa; // Skriver ut summan av 12 + 26 vilket är 38
?>
<?php
// Exempel 3 på talsystem i PHP
$tal1 = 0xFA2; // Hexadecimalt blir 4002 när 0xFA2 omvandlas till heltal basen 10
$tal2 = 1024; // Heltal basen 10
$summa = $tal1 + $tal2;
echo $summa; // Skriver ut summan av 4002 + 1024 vilket är 5026
?>
Heltal kan vara max 2147483647. Heltal som är större än det omvandlas automatiskt till decimaltal, eller flyttal som det även kallas.

Decimaltal / Flyttal
Decimaltal i PHP kallas även för flyttal och det är tal som kan bestå av decimaler (inte hela tal). Man separerar heltals- och decimaltalsdelen med punkt ( . ). Flyttal kallas även för "float", "double" och "real" i andra programmeringsspråk. I PHP hanteras de alla likadant.

Överkurs
Vill man ha högre precision när man beräknar data i PHP måste man använda ett s.k. bibliotek med kodverktyg som är anpassat för detta. Två exempel på bibliotek är BC Math [1] och GMP [2].

I PHP blir 1/3 = 0.333333333333 och floor( 0.1+0.8) * 10 ) blir 7 när det egentligen ska bli 8. [3]

Exempel på decimaltal
1.2 8.6 0.1 0.7
Här nedanför ser ni exempel på kod i PHP
<?php
// Använda decimaltal i PHP
$float1 = 1.2;
$float2 = 3.6;
$produkt = $float1 * $float2;
echo $produkt; // Skriver ut produkten 4.32 av multiplikationen 1.2 * 3.6
?>
Boolesk - Sant eller falskt
Boolesk heter på engelska "boolean" och är en datatyp som bestämmer att en variabel bara får innehålla värdet sant "true" eller falskt "false". Den datatypen är väldigt användbar när man vill styra programflödet i koden. Hur man styr programflödet kommer jag gå igenom i en framtida artikel.

Resultat från en uträkning eller ett resultat från ett verktyg eller funktion i PHP blir alltid sant eller falskt, även om resultatet är ett heltal.

0 (noll) i PHP är lika med falskt och alla tal under och över 0 är lika med sant.
Exempel
true = sant
false = falskt
-1 = sant (mindre än noll)
0 = falskt
1 = sant (större än noll)
Här nedaför kan ni se ett exempel på datatypen boolesk
<?php
// Test med boolean variabler
$bool1 = false;
$bool2 = true;
$bool3 = 1-2;
$bool4 = 0;

//
// Överkurs test
// - Kontrollera programflödet
//
if (bool4 == true) {
echo "sant";
} else {
echo "falskt";
}
?>
Sträng
En sträng i PHP är helt vanlig text. På engelska heter det "string". Ni kom i kontakt med denna datatyp i del 1. Då sparade vi texten "Patrik" i en variabel som vi döpte till "$variabel_3".

Strängar används väldigt ofta i PHP. Ett exempel på det är när man skickar data via formulär skapade med HTML/XHTML. Det är det man håller på med när man arbetar med webbdesign för er som inte vet vad HTML är för något.

För att skapa data i PHP som ska vara en text, sätter vi texten innaför apostrofer ( ' ) eller citationstecken ( " ).
Exempel
"Emelie", "Pelle", "Anna", 'Patrik', 'Erik', 'Fredrik'
Här nedanför kan ni se ett exempel med strängar
<?php
// Använda strängar i PHP
$text1 = "Pelle";
$text2 = "Anna";
$text3 = 'Waschman';
$text4 = '<b>detta visar html kod som omvandlas till fet stil</b>';
echo "Hej och välkommen $text1 !"; // Skriver ut texten: Hej och välkommen Pelle !
?>
En text kan innehålla variabler som i sin tur kan innehålla text, heltal eller decimaltal. I exemplet ovanför, omvandlas först variabeln $text1 till värdet den innehåller som är Pelle. Sedan läggs den texten in i texten runtomkring

För att förstå ännu bättre visar jag ett exempel till
<?php
// Använda olika sorters strängar i PHP
$namn1 = "Pelle";
$namn2 = "Erik";
echo "Du heter $namn1 !";
echo ' och din kompis heter $namn2 !';
?>
Apostrofer ( ' ) omvandlar inte variabler inuti texten. Men det gör däremot citationstecken ( " ).

Överkurs
Om man arbetar med mycket text i PHP och man får många besökare till sin webbsida som använder tjänsten så att PHP körs, då är det bra att använda apostrofer iställer för citationstecken runt sina texter. Om citationstecken används söker PHP tolken efter variabler och annan data i texten. Det tar lite extra tid och processorkraft av webbservern där PHP körs. Det medför lägre prestanda och i kritiska webbapplikationer kan man tjäna flera sekunder. Innanför apostroferna söker PHP tolken inte efter några variabler och då går det snabbare att översätta PHP-koden till HTML-kod.

Flera datatyper
Jag har nämnt att det finns flera datatyper men de är lite svårare att förstå. Därför skriver jag om de i framtida artiklar.

Omvandla mellan olika datatyper
I PHP kan man omvandla en datatyp till en annan datatyp mycket enkelt. Man använder en teknik som kallas "typkonvertering". Det visas senare. Nu visar jag bara ett enkelt exempel på att en variabel kan ändra sin typ beroende på innehållet som sparas inuti den.
<?php
// Omvandla datatyper i PHP
$text1 = "Pelle";
$text1 = 34;
$text1 = 1.5;

/* Här använder vi oss utav en funktion i PHP
som vi använder som verktyg för att utföra en viss uppgift.
var_dump() skriver ut en beskrivning av variabeln och dess
datatyp samt dess innehåll. */
var_dump($text1); // Skriver ut: float(1.5)
?>
Här i ovanstående exempel ser vi att vi använder samma variabel men vi sparar olika data inuti den. Först sparar vi en textsträng i variabeln vilket ger datatypen "string". Sedan ändrar vi innehållet till ett heltal vilket automatiskt omvandlar datatypen till "integer". Till sist ändrar vi innehållet i variabeln till ett decimaltal vilket automatiskt omvandlar datatypen till "float".

I kommentarerna kan ni läsa att funktionen var_dump() [4] används som ett verktyg för att beskriva variabeln åt oss. Den funktionen används mycket när man letar efter fel i sin kod och vill undersöka sina variabler och datan som är sparad i dem.

Men hur gör man om t.ex. $text1 innehåller decimaltalsvärdet 1.5 och du vill omvandla det till ett heltal? Vi kan använda oss av typkonvertering. Det görs genom att skriva datatypen inom parentes innan variabeln som ska omvandlas.
<?php
// Typkonvertering 1 i PHP
$tal = 1.8; // Är av typen float
$nytt_tal = (int) $tal; // Nu är den av typen int
var_dump($nytt_tal); // Skriver ut: int(1)
?>
Nackdelen med typkonvertering är att man kan förlora data och viss precision. Problemet är att vi förväntar oss utskriften int(2) istället för int(1) eftersom decimaltalet 1.8 avrundas uppåt till 2, eller hur!? Detta problem inträffar även i många andra programmeringsspråk än PHP.

För att lösa problemet måste vi först använda ett slags verktyg för att avrunda ett decimaltal upp till närmaste heltal, innan vi kan omvandla det till ett riktigt heltal. Ett bra verktyg vi kan använda är round() [5].

Efter att man har använt round() använder man typkonverteringen (int) för att omvandla variabelns datatyp till heltal "int".
<?php
// Typkonvertering 2 i PHP
$tal = 1.8; // Är av typen float
$nytt_tal = round($tal); // Avrundad till 2.0 och fortfarande av datatypen float
$nytt_tal = (int) $nytt_tal; // Typkonvertera till heltal
var_dump($nytt_tal); // Skriver ut: int(2)
?>
Typkonvertering är bra att använda när man verkligen vill kontrollera att en variabel får rätt datatyp.

Sammanfattning
Vi har gått igenom lite olika datatyper i PHP och hur de kan användas. För att förstå lite mer har jag beskrivit grunderna i talsystemen med baserna 2, 8, 10 och 16.

Datatyperna vi har gått igenom är heltal "int", decimaltal "float", boolesk "boolean" och strängar "string". Jag bestämde också att beskriva några andra bra datatyper vid ett annat tillfälle i en framtida artikel.

Nästa gång kommer jag prata om vektorer som är variabler med listor av lika eller olika datatyper. Men mer om det nästa gång.

Slutord
Ni har nu läst del 2 i min artikelserie om "PHP för riktiga nybörjare". Artikelserien är tillägnad min bror och alla nybörjare inom PHP eller programmering överhuvudtaget.

Om något är oklart eller svårt att förstå så tveka inte att kontakta mig med en kommentar. Klicka på länken "Kommentarer" eller "Skicka en kommentar".

Jag försöker beskriva programmering på ett så enkelt sätt som möjligt, men eftersom jag är en erfaren programmerare så är vissa saker för självklara för mig och det kan då vara svårt att beskriva med enklare ord. Därför ber jag er snällt att påpeka eventuella problem ni har att förstå innehållet i artikeln.

Ni kan också skicka in begäran om att jag ska visa fler kodexempel om hur man använder tekniken som beskrivs.

Jag hoppas ni har haft en mycket trevlig läsning.

Källor
[1] http://www.php.net/manual/en/ref.bc.php - BC Math
[2] http://www.php.net/manual/en/ref.gmp.php - GMP
[3] http://www.php.net/manual/en/language.types.float.php - Floating point numbers
[4] http://se.php.net/var_dump - Beskriv variabler
[5] http://se.php.net/round - Funktionen round()
[6] http://waschman.blogspot.com/2009/06/programmering-artikelserie-php-for.html

01 juni, 2009

Google Apps: Fräschare utseende, gränssnitt och layout

Idag fann jag ett insticksprogram till Firefox som ger några av Googles webbapplikationer nytt utseende. Gmail har exempelvis fått en mycket proffsig "look" och där är även inloggningsfasen är inräknad. Se bilden nedanför.


(Klicka på bilden för att förstora) Logga in på Gmail med ny "look"

Insticksprogrammet är från Google Redesigned [1] via Globex Designs. Det innefattar inte bara ändringar i Gmail utan även Google Reader och Google Calendar. Se exempel på gränssnittet [2]. Flera bilder och exempel visas under alternativet "Screenshots" i menyn på sidan.

Om man tröttnar på de nya ändringarna kan man snabbt gå tillbaka till Googles egna design.

Källor
[1] http://www.globexdesigns.com/gr/
[2] http://www.globexdesigns.com/gmail/screenshots/03.jpg

30 april, 2009

Office Powerpoint 2007: Gratis mallar för presentationer

Letar du efter nya mallar (eng. templates) till ditt Microsoft Office Powerpoint 2007 (eller 2003)? I så fall behöver du inte söka längre eftersom jag här nu vill tipsa om en bra källa för nedladdningar av mallar.

Webbsidan jag vill tipsa om [1] hör faktiskt till Microsoft själva och de har publicerat ett par gratis mallar som är tillgängliga för alla. Några är riktigt snygga medan vissa är lite sämre utformade. Alla mallarna finns representerade av grupper så det är enklare att finna en presentationsmall som passar just dig.

Det finns även mallar för de som vill presentera fotoalbum, projektplaneringar, affärer, ekonomi, företag och många fler. Se exempel bild 1.


(Klicka på bilden för att förstora) Bild 1

Finner du ingen mall som passar dina behov kan du ju alltid googla. Tänk bara på att det kan förekomma virus i nedladdningsbar media så du bör ha ett fungerande och uppdaterat antivirusskydd på din dator.

Källa
[1] Presentations - Templates (http://office.microsoft.com/en-us/templates/CT101172721033.aspx)

28 april, 2009

Säkerhet/Webbutveckling: Stjäla källkod från PHP/ASP/JSP

Förord
Denna artikel handlar om ett sätt att få tag på källkoden för ett serverbaserat skript som exempelvis PHP, ASP (även .NET) och JSP med flera. Observera dock att det inte går på alla servrar och skript. Det hela går ut på att utvecklaren inte tänker igenom sin uppladdning och redigering av skripten tillräckligt.

Introduktion
Jag har för mig att jag har läst om detta någonstans på Internet i en artikel om just säkerhet vid webbutveckling och nu upptäckte jag det själv av en slump och lite nyfikenhet. Det går att visa källkoden för serverbaserade skript som t.ex PHP, ASP och JSP på några olika sätt och ett av dem tänker jag beskriva lite för er om nu i denna artikeln.

Server Operativsystem
Min testserver Apache2 kör på Ubuntu 8.10 med PHP 5.2.6 och säkerhetsbristen kan fungera även på andra system men det har jag inte prövat. Som textredigerare för skripten använder jag programmet gedit, men i vanliga fall använder jag Zend Studio.

Vad är säkerhetsbristen?
Bristen går ut på att vissa textredigerare sparar en säkerhetskopia av skripten innan de sparas. I Ubuntu 8.10 Intrepid använder jag gedit för teständamål och utan att jag tänkte på det så skapade programmet säkerhetskopior av mina php-skript och placerade dem i samma katalog. Det är ju bra att det gör det automatiskt men ur säkerhetssynvinkel är det dåligt.

Varje säkerhetskopia får suffixet "~" (se exempel 1)
Exempel 1:
index.php redigeras och sparas vilket även skapar filen index.php~
Om man sedan råkar kopiera alla filerna (även inkluderat säkerhetskopiorna) till sin produktionsserver så har man en ganska stor säkerhetsbrist. Detta händer ibland och det räcker med att utvecklaren inte tänker på det och glömmer det en gång. Då sparas en extra kopia med källkoden som kan laddas ned istället för att tolkas av PHP interpretatorn hos Apache.

Laga säkerhetshålet
I programmet gedit som jag använder kan man välja att ställa in så att inga säkerhetskopior skapas före man sparas sina dokument (i vårt fall skript).
gedit > Edit > Preferences > Editor
Ta bort markeringen för "Create a backup copy of files before saving". Se bild 1.

(Klicka på bilden för att förstora) Bild1
Ta bort markeringen för att inte spara några kopior av filerna du redigerar.

Observera att du inte få glömma att radera eventuella säkerhetskopior som redan har sparats vid ett eller flera tidigare tillfällen.

Resultat av säkerhetshål

(Klicka på bilden för att förstora) Bild 2
Skriptet som körs är http://localhost/phpinfo.php


(Klicka på bilden för att förstora) Bild 3
Om man istället går till URL http://localhost/phpinfo.php~ visas källkoden för phpinfo.php från en säkerhetskopia.

Analys
Allt går ut på att utvecklaren är klantig och missar att det även finns gamla säkerhetskopior av skripten i den publika webbkatalogen som är tillgänglig för alla besökare. Om någon besökare är illvillig så kan det hända att han eller hon prövar att lägga till tecknet tilde "~" efter ett filnamn.

Hacket har störst chans att lyckas om det underliggande operativsystemet för servern är någon typ/variant av Linux/Unix (*nix) eller om utvecklaren sitter och programmerar i en sådan miljö lokalt på sin dator (server kan då vara t.ex IIS) och sedan laddar upp alla filer (alla skript inklusive säkerhetskopior) till den publika servern.

Det behöver inte vara "~" (vanligen kallas det för temporär i *nix) som läggs bakom utan även ".bak" som står för backup som är vanligt i Windowssystem.

Slutord
Var försiktiga och tänk noga på att det kan finnas en kopia av din kod som går att ladda ner. Man behöver endast gissa sig till filens filändelse (suffix).

I denna artikeln beskrev jag hur man på ett sätt kunde få tag på källkoden för ett serverbaserat webbskript (t.ex PHP, ASP, JSP, ...) genom att ladda ner publika säkerhetskopior från webbservern.

Välkomna till bloggen

Välkomna ska ni vara kära besökare. Jag skriver om IT för att det är kul och för att jag vill dela med mig av information och kunskap. Jag försöker hålla bloggen så kategoriserad som möjligt för att ni enklare ska hitta intressanta länkar och artiklar.