slide1.php

2.6 Uppgift 5

[ 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.

 

[ Klicka här för att ladda ner de bilder jag kommer att använda i mitt exempel - fem blder i ett zip arkiv ]

Skapa en katalog för bilderna

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).

Först måste vi kunna lista alla filer

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 );
?>
Listning 2.6.1 - samples/s_slide1.php

.
..
blue.jpg
clock.jpg
i misstag kom det en textfil hit.txt
sun.jpg
water.jpg
winter.jpg
ws_ftp.log
_notes
_vti_cnf
Resultat av listning 2.6.1

Förbättrad version

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 );

?>
Listning 2.6.2 - samples/s_slide2.php

blue.jpg
clock.jpg
sun.jpg
water.jpg
winter.jpg
Resultat av listning 2.6.2

Visa bilderna

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 );

?>
Listning 2.6.3 - samples/s_slide3.php
[Visa i separat fönster]

Sätt in bildens storlek i taggen

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 );
?>
Listning 2.6.4 - samples/s_slide4.php
[Visa i separat fönster]

Visa en bild åt gången

Idén bakom en slideshow är följande:

  1. Sätt ut den första bilden

  2. Sätt länkar till de ävriga bilderna

  3. Sätt vid behov "föregående" och "nästa" länkar

  4. När vi klickar på någon av dessa länkar skall sidan laddas om, men med en ny bild.

För att implementera detta behöver vi göra följande:

  1. Använd url-parametrar. I vårt fall skall vi sätta ?vilken=bildnummer till adressraden. t.ex. ?vilken=2 för att visa en viss bild. Vi måste komma ihåg att i datavärden är första=0, andra=2, tredje=2 o.s.v

  2. Kontrollera i programmet om ?vilken= finns i adressen.
    Om det finns använder vi detta nummer, och om inte så skall vi visa den första bilden.

  3. Räkna ut vilket nummer föregående och nästa bild har.

  4. Vi bör även beakta att det kan sättas ett bildnummer i adressen som inte finns, t.ex. att vi vill se den femte bilden av fyra.

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 . "\">&lt;&lt;</a>\r\n";
    }
    else
    {
        
# i annat fall lämnar vi bara lite plats
        # med några mellanslag
        
echo " &nbsp;&nbsp; ";
    }
    
# 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 . "\">&gt;&gt;</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 );  
?>
Listning 2.6.5 - samples/s_slide5.php
[Visa i separat fönster]

slide3.php

2.6.1 Din uppgift

Allmän uppgift

  1. Tillsnyggning
    Skapa / stjäl två bilder - en för föregående- och en för nästalänken. Sätt in dem i din kod istället för << och >> (&lt; och &gt;). Du skall även se till att det blir en korrekt websida henom att se till att <html>, <head>, <body> mm taggar sätts in på sidan. Du har även fria händer att modifiera utseendet ytterligare samt prova med egna bilder...

  2. Filnamn
    Se även till att bildfilens namn visas under bilden.

Uppladdning

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:

  1. Uppladdning
    Det som laddas upp skall sättas till pictures katalogen. Du behöver modifiera exemplets move_uploaded_file så att den andra parametern börjar med pictures. (använd något i stil med "./pictures/" . $_FIL... för den andra parametern)

  2. Filtyper
    Eftersom nyare php versioner inte har stöd för gif så måste du modifiera koden så att den inte godkänner andra bilder än png och jpeg.

  3. Extra bonusuppgift
    Där du behöver beakta följande:

    1. I mitt uploadexempel (se upload1.php) så raderar jag ju filen omeddelbart. Därifrån får du således exempel på hur filer raderas.

    2. I början av denna slideshowuppgift (se slide1.php) listades bara filernas namn, utan att visa dem.

    3. I uppgift 4 (file_del1.php) visades även där en lista. Denna modifierades senare så att man kunde klicka på en länk och därigenom radera ur filen.

    4. Om man lyckas sända filens namn via url är det troligtvist enkelt att radera denna fil med hjälp av unlink (se filerna_fil2.php#unlink).

    5. Vill man var på säkra sidan så ser man till att lösenorsskydda filraderingssidan. (se aut.php)

    Kan du då göra en separat sida som visar alla bildfiler du har, och som ger dig möjligheten att radera bland filerna bara genom att klicka på filens namn?

slide2.php

2.6.2 Extra uppgift

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):

Koden

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");
        }
    }
}
?>
Listning 2.6.2.2 - samples/visabild.php

Resultat av listning 2.6.2.2


© anders enges, 2003