Vecka 06, Måndag 6 Februari 2012 Prenumerera

Arkiv för kategori ‘Praktiska PHP-tips’

ImageMagick utan exec()

onsdag, 19 januari, 2011

ImageMagick används för att hantera bilder med t.ex. PHP och ofta med funktionen exec(). Många webbhotell blockerar exec() av säkerhetsskäl men med lite tur finns ändå ImageMagick installerat.

Under arbete åt en kund som använder Webbkonsulterna upptäckte jag att de har ImageMagick som kan användas genom PHPs klass istället för med exec(). Ett exempel på vad man kan göra, en tumnageln av en PDF-fil:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/* 
 * Jag skapar inställningarna i variabler för att lättare kunna 
 * ändra och ev fixa till en funktion
 */
$input_file = '/path/to/inputfile.pdf[0]'; // Sökväg till filen, [0] anger pdffilens sidnummer
$output_file = '/path/to/outputfile.jpg'; // Sökväg till tumnageln, här har jag valt en .jpg
$thumbnail_width = 400; // Ställ in maxbredd
$thumbnail_height = 0; // Maxhöjd, 0 betyder att den ska gå efter bredd
$jpeg_quality = 80; // jpeg kvalitet
 
$im = new imagick($input_file);  // Skapa objektet med filen
$im->setImageColorspace(255); // Färginställning
$im->setCompression(Imagick::COMPRESSION_JPEG); // Använd jpg-kompression
$im->setCompressionQuality($jpeg_quality); // Kvalitet på jpeg
$im->setImageFormat('jpeg'); // Format på filen
$im->thumbnailImage($thumbnail_width, $thumbnail_height); // Skapa tumnagel med bredd/höjd
$im->writeImage($output_file); // Spara filen
$im->clear();
$im->destroy();

Kombinerat med lite filuppladdning, felhantering, jQuery reflect m.m. blir det här en mycket trevlig PDF-funktion.

Jag vet inte ens om detta hade varit möjligt att göra med det bibliotek som vanligen är inbyggt, GD2.

Offset i MySQL

onsdag, 3 november, 2010

Vill du hämta innehåll med offset i MySQL, dvs start några rader in och hämta resten av raderna? Där finns en liten egenhet hos MySQL, du måste ange hur många rader som ska hämtas (LIMIT) för att kunna ange var hämtningen ska starta.

För att göra en hämtning av alla poster från databastabellen men hoppa över de första anger du den största siffra som går som LIMIT. Så här kan det se ut:

SELECT * FROM mytable LIMIT 18446744073709551610 OFFSET 10;

Koden ovan bör hämta alla rader utom de 10 första. Kanske inte så snyggt, men fungerar.

strtolower och encoding

tisdag, 6 juli, 2010

Ett problem som kan vara svårt att hitta är hantering av strtolower och encoding. Under en tid har jag jobbat med ett projekt som till viss del ligger på en Windows-plattform vi har begränsad kontroll över. Ibland blir det problem när man ska göra jämörelser av textsträngar och vill använda strtolower. Eftersom ”Mattias” inte är samma sak som ”mattias” vill man se till att båda värden man jämför bara innehåller gemener (eller versaler). Men strtolower() vill inte lira med å,ä,ö etc i UTF-8.

En lösning på problemet kan vara att ändra tecken till något annat – varför inte htmlentities(). Så här kan det se ut att förvandla ett värde till gemener och komma runt encoding problem:

1
2
3
$value = htmlentities($value, ENT_COMPAT, 'UTF-8');
$value = trim(strtolower($value));
$value = html_entity_decode($value, ENT_COMPAT, 'UTF-8');

En annan lösning är mb_strtolower() om den funktionen finns tillgänlig.

Vanliga fel att se upp med

torsdag, 11 mars, 2010

Den senaste tiden har jag diskuterat med mina kollegor om det vanligaste PHP-felet att se upp med. Vi är överens om ett av de mest irriterande, ett glömt likamed tecken i en if-sats.

När man jämför två värden i PHP kan man använda dubba lika-med tecken, så här:

1
2
3
if ($mittnamn == 'Mattias') {
	echo 'Hello Mattias';
}

När man tilldelar värden till variabler används ett lika-med tecken:

1
$mittnamn = 'Mattias';

Tänk dig då vad som händer med den här koden:

1
2
3
if ($mittnamn = 'Mattias') {
	echo 'Hello Mattias';
}

Den jämför inte värden, den testar om det går att tilldela $mittnamn värdet ‘Mattias’. If-satsen som var till för kontrollera om variabeln $mittnamn har värdet ‘Mattias’ kommer nu alltid vara sant. Även om $mittnamn innehåller namnet ‘Vera’ kommer ‘Hello Mattias’ skrivas ut.

Eftersom det är fullt möjligt att använda en if-sats på båda visen genereras inget felmeddelande. Och är man lite trött och stirrat sig blind på samma skript länge kan det vara väldigt svårt att hitta.

Tvinga en bild att laddas om

lördag, 9 januari, 2010

Jag jobbade här om dagen med bildbeskärning, och behövde tvinga en bild att laddas om istället för att hämtas från webbläsarens cache. De vanliga tricken med att sätta headers och meta-taggar användes i skriptet, men bilden ville ändå inte laddas om direkt. Lösningen är att lägga till ett slumpat tal som querystring i bildnamnet. För att enkelt få ut slumptal använder jag funktionen rand(). Kanske inte den snyggaste av lösningar, men den fungerar.

<img src="bild.jpg?<?php echo rand(1,3000); ?>" />

Webbläsaren noterar att det är annorlunda adress vid varje besök och laddar om bilden, men ignorerar delen efter ”?”.

Läs även andra bloggares åsikter om bildhantering, skript, php, cache

Plocka bort och lägg till variabler som skickas i URL

torsdag, 7 maj, 2009

Snubblade på två bra funktioner som enkelt låter dig lägga till och ta bort variabler från en URL (dvs en s.k. querystring). Själv använder jag den när en sida ska laddas om men med lite annan data.

Funktionen på Added Bytes har skapats med reguljära uttryck (en. regular expressions) och PHP-funktionen preg_replace. Med reguljära uttryck kan man matcha en textsträng, även om den förändras, och arbeta med delar av den.

querystring-regexp-addedbytes

Läs även andra bloggares åsikter om regexp, url, snippets, kodtips, php

Dynamiska konstanter i PHP

fredag, 17 april, 2009

I de moderna versionerna av PHP kan man använda dynamiska konstanter, när de tilldelas värdet. En konstant är ungefär som en variabel, men behåller värdet genom hela skriptet och är global. De har heller inga dollar-tecken i namnet. För att tilldela värdet till en konstant gör du så här:

<?php
define('KURSNAMN', 'Php-kurs');
?>

Du kan sedan använda konstanten genom skriptet:

<?php
echo KURSNAMN;
?>

Men du kan alltså tilldela ett dynamiskt värde numera:

<?php
define('PATH_THIS',  basename($_SERVER['PHP_SELF']));
?>

Mycket smidigt. Tycker jag :)

Läs även andra bloggares åsikter om konstanter, php, kurser, skript

Formatera datum i WordPress

fredag, 16 januari, 2009

Jag fick en fråga idag hur man ändrar datumet i WordPress-teman. Det är ganska smidigt, WordPress funktioner the_date() och the_time() använder formatet från PHP-funktionen date(). Det betyder att du kan ändra datumets format med hjälp av olika tecken, som finns listade i en tabell i dokumentationen.

Datum finns oftast utspridda lite överallt i temafilerna. Öppna dem i en texteditor och leta reda på the_date(). Testa att ändra till

<?php
the_date('Y-m-d');
?>

Det borde ge datumformatet 2009-01-16. Y stå för år, m för månad och d för dag. Bindestrecken skrivs ut som just bindestreck. Det här går precis lika bra att använda i ditt eget kodande med funktionen date(). Skapa ett PHP-skript och laborera med olika teckenkombinationer. Här skriver jag ut datum och tid:

<?php
echo date('Y-m-d H:i:s');
?>

Enkel slumpning av array

tisdag, 13 januari, 2009

Om du ska slumpa fram innehåll i en array så kan det här vara ett bra litet skript. Jag har bland annat använt det för att välja en vinnare i Xodas bildutmaning.

<?php
// Jag skapar en array med de värden vi vill använda
$input = array("Malin", "Magnus", "Terje", "TomasJ1", "TomasJ2", "Stefan", "Johnny", "Calandrella");
 
// Jag slumpar sedan fram numret på ett av värden i arrayen
// med PHPs inbyggda funktion array_rand()
$rand_key = array_rand($input);
 
// Jag skriver ut det slumpade värdet i arrayen. Jag känner inte till
// värdet utan får använda varibeln från rad 7.
echo $input[$rand_key];
 
// Svårare än så behöver det inte vara, men det beror lite på vad du 
// vill slumpa fram. För lösenord och liknande berhöver man göra 
// mer avancerade saker.
?>

Flexibel config.php-fil för webbapplikationer

tisdag, 6 januari, 2009

Vill du ha alla dina webbplatser installerade lokalt OCH på webbhotell? Då kan du göra det enkelt med en flexibel config.php för webbapplikationer som WordPress, Moodle, PHPBB3, XodaGallery etc.

Din lokala testserver och webbhotellets server har ofta olika kontoinställningar och gör att du inte kan spara över konfigurationsfilen hur som helst.

Jag använder metoden nedan för att slippa joxa med flera konfigurationsilfer, så kan jag bara skriva över dem fram och tillbaka med mitt FTP-program utan att det gör något. Test att köra följande i en PHP-fil på ditt webbhotell och på din egen server:

<?php echo $_SERVER['SERVER_NAME']; ?>

Förhoppningsvis får du ”localhost” på egen server och liknande ”www.domänen.se” på ditt webbhotell. Du kan använda server-värdet och en if-sats i config.php för att använda olika kontonamn beroende på var filen körs. Här ett exempel med variabeln för databasvärd i WordPress config.php:

if ($_SERVER['SERVER_NAME'] == 'www.domänen.se') {
    define('DB_HOST', 'mysql.domänen.se');
} else {
    define('DB_HOST', 'localhost');
}

Du behöver förstås byta ut ”domänen.se” ovan med ditt eget domännamn. Gör också ett test för att se resultatet av $_SERVER['SERVER_NAME'] också, servrar kan ha olika inställningar.