Archiv für die Kategorie ‘PHP und MySQL’

Per GD-Library generiertes JPG lässt sich nicht herunterladen

Mittwoch, 24. März 2010

Über die Verwendung der GD-Library zur Bildmanipulation gibt es ja reichlich Quellen im Internet zu finden. Dass allerdings per PHP an den Browser gesendete Bilder in bestimmten Szenarien nicht herunterladbar sein können, wird eher selten erwähnt. Eine Lösung dafür findet sich entsprechend ähnlich schwierig.
In meinem Fall hatte ich es mit einer PHP-Datei zu tun, der per POST ein Dateipfad zu einem JPG übergeben wurde, das per GD-Library-Funktionen mit einem Wasserzeichen verziert werden sollte. Das PHP-Skript wurde aus Flash aufgerufen.
Als Ergebnis eines Skriptaufrufs erhielt ich brav das JPG in einem neuen Browserfenster. Jedoch der Versuch, das Bild via Rechtsklick und “Speichern unter…” auf die Festplatte zu speichern, scheiterte. Im Speichern-Dialog war auch der Name meines PHP-Skripts als Name der zu speichernden Datei voreingetragen, nicht etwa der des JPGs.

So ähnlich sah mein Skript bis zu jenem Zeitpunkt aus (hier gekürzt):
header('Content-Type: image/jpeg');
$original_pic = 'pics/coolpicture.jpg';
$watermark = imagecreatefrompng('watermark.png');
$watermark_width = imagesx($watermark);
$watermark_height = imagesy($watermark);
$image = imagecreatetruecolor($watermark_width, $watermark_height);
$image = imagecreatefromjpeg($original_pic);
$size = getimagesize($original_pic);
$dest_x = $size[0] - $watermark_width - 10;
$dest_y = 10; // $size[1] - $watermark_height - 5;
imagecopymerge($image, $watermark, $dest_x, $dest_y, 0, 0, $watermark_width, $watermark_height, 80);
imagejpeg($image);
imagedestroy($image);
imagedestroy($watermark);
?>

Durch Einfügen folgender Zeilen erhielt ich statt eines neuen Browserfensters einen “Datei herunterladen”-Dialog, der dann immerhin die Datei unter einem festen Namen speicherbar machte:
header('Content-Disposition: attachment; filename=festerName.jpg');

Verzeichnisschutz mit .htaccess und .htpasswd

Mittwoch, 17. März 2010

Mit beispielsweise diesem Generator eine einfache Sache, wenn man weiß, wie der “interne Pfad zum Verzeichnis auf dem Server” lautet. Den bekommt man aber ebenfalls leicht zu fassen mit einem PHP-Schnipsel:
echo "Document root: ".$_SERVER["DOCUMENT_ROOT"];
phpinfo();
?>

Normalerweise sollte phpinfo() bereits alles Nötige liefern. Unter “Environment” findet sich der Eintrag “DOCUMENT_ROOT” und daneben dann das Gesuchte. Zeile 2 stellt eine Alternative dar.

Geocoding mit PHP und dem Google Maps API

Dienstag, 30. Juni 2009

Schöner Artikel zum Thema Geocoding mit PHP in Verbindung mit dem Google Maps API. Mit Downloadmöglichkeit für die besprochenen Listings.

Die im Artikel geschilderte Klasse Geocoder.php macht allerdings PHP5 und cURL-Support erforderlich.

Ordnerzugriff beschränken auf 1blu-Server

Mittwoch, 04. Juli 2007

Da man bei 1blu offenbar darauf verzichtet, KundInnen eine praktische Funktion anzubieten, mittels derer auf einfache Weise ein Verzeichnis mit einem Zugangsschutz versehen werden kann, ist Handarbeit gefragt.

Statt der mir geläufigen Kombination aus .htaccess und .htpasswd muss es hier das Paar .htaccess und .htuser sein. Letztgenannte sieht aber genau so aus wie die bekannte .htpasswd, heißt aber eben nur anders.

Wird beides im ASCII-Modus hochgeladen, klappt auch alles. Aber nur, wenn man sich vorher den absoluten Pfad aus den FAQ herausgepuhlt hat. Der sah bei der aktuellen Kundin so aus: /hp/ag/ae/rd/www/

An diesen Pfad schließt sich dann noch der Rest des Pfades an, der auf die .htuser-Datei zeigt, etwa so: /hp/ag/ae/rd/www/meinGeschuetztesVerzeichnis/

Somit könnte eine schlichte .htaccess-Datei so aussehen:

AuthName “Geschuetzter Bereich”
AuthType Basic
AuthUserFile /hp/ag/ae/rd/www/meinGeschuetztesVerzeichnis/.htuser
AuthGroupFile /dev/null
require valid-user

Beide Dateien, also .htaccess und .htuser, liegen dann im Verzeichnis namens meinGeschuetztesVerzeichnis.

Geodating für den Hausgebrauch

Dienstag, 24. April 2007

Ein Kunde wollte gern für seine eigenen GoogleMaps ein CMS haben, bei dem er nur eine Adresse, wie z.B. “Grindelallee 27c, 20146 Hamburg”, eingeben muss und per Knopfdruck die nötigen Breiten- und Längengraddaten erhält.

Kann ja nicht so schwer sein, dachte ich. Nach ein paar Stunden Recherche und Bastelei habe ich dann auch eine Lösung programmiert, die ohne lästiges GoogleMaps-API-Einbinden auskommt.

Die Demo gibt die zwei Werte Latitude und Longitude lediglich in einem JavaScript-Fenster aus. Im CMS für meinen Kunden hingegen werden gleich diverse Formularfelder (Straße, Hausnummer, Postleitzahl, Stadt, Breiten- und Längengrad) vorausgefüllt, so dass er eine Menge Arbeit einspart.

Die vollständige GoogleMaps-Seite mit allen so eingetragenen Adressen zu generieren, dürfte jetzt nur noch Formsache sein.

Mein Newsgroup-Kollege Dominik machte mich noch auf dieses Projekt (OpenGeoDB – freie Geokoordinaten-Datenbank) aufmerksam. Sicher auch mehr als einen flüchtigen Blick wert.

CMS-Programmierung: De-/Aktivierung einzelner Seiten

Donnerstag, 22. Februar 2007

Man ersetze “MP” durch “Menüpunkt” und “UP” durch “Untermenüpunkt(e/en)”:

Wenn ein MP ohne eigene UP oder ein einzelner UP unsichtbar geschaltet werden soll, ist das kein Problem.
Soll aber ein MP unsichtbar werden, der UP hat, müssen alle UP mit unsichtbar werden und gesperrt bleiben (keine Wieder-Sichtbarmachung möglich), solange der übergeordnete MP nicht (wieder) sichtbar ist.
Wird ein unsichtbarer MP mit UP wieder sichtbar, bleiben dennoch alle UP erst einmal unsichtbar, sind dann aber entsperrt und können sichtbar gemacht werden.

Alles klar? ;-)

Freizeilen von PHP nach Flash

Donnerstag, 25. Januar 2007

Vor einiger Zeit schrieb ich ja bereits über die Tücken der Sonderzeichen und Freizeilen in Bezug auf PHP und Flash (wer der große Schuldige ist, kann ich gar nicht recht sagen). Wenn ich den Artikel lese, erhalte ich am Schluss den Eindruck, dass ich die Probleme ein für allemal gemeistert hätte. Wie ich heute morgen herausfinden musste, befand ich mich mit dieser Annahme auf der nicht-metallischen Straße oder auch dem hölzernen Pfad…
Bei einem aktuellen Projekt werden Daten in HTML-Formularfelder eingegeben, per PHP in einer MySQL-Datenbank abgelegt und später von einem Flashfrontend angefordert. Dazu führt Flash eine PHP-Datei aus, die die Daten aus der Datenbank abholt und per echo-Befehl an Flash liefert. Im Grunde dasselbe Szenario wie Anno 2005. Doch im Gegensatz zu damals spielt es im vorliegenden Fall offenbar keine Rolle, dass ich die Daten (wie damals) per PHP-Skript in die Datenbank einspeise, denn aus einem Testeintrag…

Eine Zeile frei:

Zwei Zeilen frei:

Ende.

…wird in Flash 8…

Eine Zeile frei:
Zwei Zeilen frei:

Ende.

Wo eigentlich eine Zeile frei sein sollte, werden in Flash derer zwei angezeigt. Noch größer klafft die Lücke bei zwei gewünschten Freizeilen.

Warum ich seinerzeit ohne Skript-Manipulationen weitergekommen bin, ist mir heute schleierhaft. Aber ich habe eine Lösung gefunden, die hoffentlich auch beim nächsten Projekt noch funktioniert…:

Statt die Textdaten unverändert aus der Datenbank an Flash zu übergeben mit…

$send2flash = “copy=”.utf8_encode( $row['copy'] ).”&”;

…lasse ich per str_replace erst alle Vorkommen der Steuerzeichen #0D #0A oder Dezimal 13 10 — Erstgenanntes steht für Carriage Return, Letzteres für Line feed — durch ein einfaches \n ersetzen:

$transformedCopy = str_replace( “\r\n”, “\n”, $row['copy'] );
$send2flash = “copy=”.utf8_encode( $transformedCopy ).”&”;

Dann klappt es. Diesmal.

UTF-8-Codierung verhindert Senden eines HTTP-Header

Mittwoch, 26. Juli 2006

Randnotiz für den Fall, dass ich zukünftig nicht wieder Stunden Zeit brauchen möchte, um festzustellen, dass die Konvertierung eines PHP-Dokumentes von ASCII nach UTF-8 (UltraEdit) keine gute Idee ist, wenn das PHP-Dokument einen HTTP-Header senden möchte. Ergebnis wäre die berüchtigte Header-already-sent-Fehlermeldung.

Zeit(punkt) in DB speichern

Mittwoch, 26. Juli 2006

Bevor ich’s wieder vergesse, notiere ich’s mir gerade mal.
Beim Speichern eines Datums im Timestamp-Format funktioniert Folgendes ganz gut:

  • In der DB-Tabelle ein Feld als INT anlegen
  • Im PHP-Skript per $zeitjetzt = time(); den Timestamp schnappen

Der Timestamp liegt in Sekunden vor, d.h. 1090845461 und 1090845521 liegen genau 1 Minute auseinander.

XSS – Muss ich später mal recherchieren…

Donnerstag, 29. Juli 2004

XSS oder Cross site scripting scheint ein Thema zu sein, mit dem ich mich näher befassen sollte, da es mir wichtig ist, potenzielle Gefahren für meine selbst programmierten Websites auszuschalten.
Regentaenzer.de beispielweise läuft noch mit PHPNuke-Backend und sei damit stark von XSS bedroht.

Durch Eric Wagners WeBlog drüben bin ich eben auf diese Seite gestoßen, die ich mir unbedingt zu einem anderem Zeitpunkt mit wachem Verstand anschauen muss.

Auch ein anderer bei Eric gelinkter Artikel klingt vielversprechend und interessant. Er trägt den Titel Smarter Image Hotlinking Prevention und ist unter dieser URL zu finden.