Posts Tagged ‘PHP’

Mittwoch, 11. April 2012

XING-Bilder grösser machen

Da ich keinen Sinn darin sehe, für eine XING Premium-Mitgliedschaft Geld auszugeben, habe ich ab und zu das Problem, dass ich erraten muss, wer mein Profil so alles besucht hat.

XING zeigt mir dabei die Besucher mit einem klitzekleinen Bildchen an, worauf ich die Person partout nicht erkennen kann. Wenn ich meine Neugier befriedigen möchte, muss ich eine XING-Mitgliedschaft kaufen.

Doch zumindest etwas Licht ins Dunkel lässt sich bringen, indem man etwas mit der Bild-URL spielt. Hier ein Beispiel:

image-5069

https://www.xing.com/pubimg/users/1/6/c/2450328df.16473797,2.30x40.jpg

Hmmm! Löschen wir doch mal die Pixeldimensionen nach dem Komma. Oh:

image-5070

https://www.xing.com/pubimg/users/1/6/c/2450328df.16473797,2.jpg

So sieht der Mitmensch also aus, der mein Profil besucht hat …

Mein Tipp an XING: Die verschiedenen Grössen der Bilder sollten einen variablen Bestandteil haben, der von aussenstehenden weder erraten noch hergeleitet werden kann. Beispielsweise mittels md5($imageSize . $internalUserId).

Tags: , , , , , ,
Labels: Web

Keine Kommentare | neuen Kommentar verfassen

Samstag, 11. Februar 2012

Vom Nutzen einer PHP Debug-Klasse

Seit mehreren Jahren verwende ich eine Sammlung von selber entwickelten emeidi*-PHP-Klassen, um Web-Sites und -Applikationen zu entwickeln. Leider hege ich immer noch grosse Skrupel, diese Klassen via Github als Open Source Software freizugeben — einerseits weil sich im Quellcode doch der eine oder andere unschöne Bock findet, andererseits, weil die Klassen Sicherheitslücken enthalten könnten, die bei produktiven Web-Sites ausgenützt werden könnten. Hinzu kommt mein Amazon-API-Key, den ich kurzerhand in die emeidiAmazon-Klasse festkodiert habe …

Unverzichtbares Kernstück ist dabei meine emeidiDebug-Klasse, welche für die professionelle, effiziente Web-Entwicklung unabdingbar ist. Jede andere meiner Klasse instanziert beim Laden die emeidiDebug-Klasse, mit welcher ich im ganzen Programmcode nützliche Fehlermeldungen und/oder Informationen zum Programmablauf festhalte.

Auf produktiven Web-Sites gebe ich den Inhalt des Debug-Objektes natürlich nicht aus, aber auf dem Entwicklungsserver ist es eine grosse Unterstützung, wenn ich am Ende der ausgegebenen Web-Seite noch folgenden Code hinpflanze:

...
<?php print $klasse->debug->getHtml(); ?>
</body>
</html>

Im ganzen PHP-Code finden sich zur Befüllung dieses Objekts Konstrukte wie

$this->debug->add('Not dumping descriptions because length new ' . $lenNew . ' is smaller than lenght old ' . $lenOld,'error');

Teilweise gebe ich auf produktiven Web-Sites wichtige Warnmeldungen auch in das PHP Error-Log aus. Während ich das früher direkt mit error_log(); gemacht habe, benutze ich heute ebenfalls meine Debug-Klasse dafür.

Der Grund dafür ist simpel: Nicht nur möchte ich das gesamte Debugging über meine Debug-Klasse laufen lassen, nein, meine Debug-Klasse ist auch geschwätziger und hilft mir im Falle meines Testservers, das fehlerhafte Script zu lokalisieren.

Vor einigen Tagen fand ich auf meinem Testserver folgende Einträge in der php.err-Datei:

[06-Feb-2012 00:07:43 UTC] Not dumping descriptions because length new 1778 is smaller than lenght old 1780

Mittlerweile habe ich das ausgebende Script (es wird täglich per Cron-Job aufgerufen) lokalisiert und die Programmierung angepasst. Alt hiess es:

error_log('Not dumping descriptions because length new ' . $lenNew . ' is smaller than lenght old ' . $lenOld);

Neu heisst es:

$this->debug->add('Not dumping descriptions because length new ' . $lenNew . ' is smaller than lenght old ' . $lenOld,'error',true);

Der letzte der Funktion übergebene Parameter true weist meine Debug-Klasse an, einen Eintrag in die php.err-Datei zu machen. Dieser schaut folgendermassen aus:

[11-Feb-2012 16:57:16 UTC] Not dumping descriptions because length new 1778 is smaller than lenght old 1780 in /var/www/apps/weather2ics/weather2ics.class.php on line 95 for URI </bern>

Anhand dieser Informationen kann ich nicht nur die Datei und die verantwortliche Zeile auf einen Blick lokalisieren, welche den Fehler ausgibt, sondern sehe auch noch gerade die URI, mit welcher die Web-App aufgerufen wurde.

Tags: , ,
Labels: Web

1 Kommentar | neuen Kommentar verfassen

Sonntag, 13. November 2011

Der Associate Tag ist für die Amazon Product Advertisting-API nun zwingend

Seit einigen Jahren verwende ich eine selber geschriebene schicke kleine PHP-Klasse, um Produkte mit ihrer ISBN oder EAN aus dem Amazon-Katalog abzufragen. Seit einigen Wochen (oder sind es gar Monaten?) scheint der Zugriff nicht mehr zu funktionieren.

Ursache ist eine neue Bedingung von Seiten Amazons, die für jeden Request neu nicht nur den AWSAccessKeyId verlangt, sondern auch den AssociateTag.

Diesen erstellt man, in dem man sich einen Account unter affiliate-program.amazon.com einrichtet — wer Wert auf einen schönen und einfachen Tag legt, sollte sich beim Formularfeld für den Titel der Web-Site einen einprägsamen Namen einfallen lassen. Bei mir lautet der AssociateTag dementsprechend emeidicom-20.

Wird dieser zusätzliche Parameter mit Requests mitgeschickt, kriegt man keine Fehlermeldung mehr zu Gesicht, sondern die tatsächlich erwarteten Daten zu Büchern, Audio-CDs und DVDs.

Tags: , ,
Labels: Allgemein

1 Kommentar | neuen Kommentar verfassen

Dienstag, 26. Oktober 2010

Darf ein Web-Entwickler seine geliebte Scripting-Sprache aufgeben?

How do you hire a programmer if you’re not one yourself? Some things to look for …

1. How opinionated are they?

Ask them about a juicy programming topic (e.g. Ruby or Python?). The tone and reasoning of the answer will reveal a lot. In our recent podcast on programming, Jeff said, “When people have strong opinions about things — when they can talk at length about something — it’s a good indication that they’re passionate about it.”

Quelle: How to hire a programmer when you’re not a programmer – (37signals)

Genau dies habe ich letzte Woche erlebt. Ich auf der Seite des Programmierers, auf der anderen Seite ein Headhunter, der für ein „internationales“ Unternehmen in Zürich einen Web-Entwickler suchte. Er war über Xing an meine Kontaktangaben gelangt.

Auf die Frage, ob ich Erfahrung in ASP.NET hätte, erwiderte ich ein klares Nein, um anzufügen, dass ich das letzte Mal im Jahr 2000 ASP programmiert hätte. ASP war damals mein erster Einstieg in webbasierte Scriptingsprachen. Innert weniger Monate wurde ich dann aber äusserst rasch auf die gute Seite der Macht gezogen — und entwickelte fortan auf den LAMP-Stack aufbauend.

Der Headhunter hakte nach: Ob ich es mir denn vorstellen könne, ASP.NET zu erlernen? Darauf erwirderte ich ein klares und dezidiertes „Nein“. Ich, der Mac OS X/Linux-Fan, der plötzlich in Visual Studio rumeiert? Das wäre wie wenn ein Kommunist zur SD überlaufen würde. Oder ein Wechselstromverfechter ins Camp der Gleichstromfreaks übertreten würde.

Ich habe mich noch ein/zwei Male gefragt, ob ich wirklich die richtige Antwort gegeben habe — doch mit obiger Bemerkung von Seiten der Web-Entwicklerprofis bin ich ein für allemal sicher, dass ich mich richtig entschieden habe.

Tags: , , , , , , ,
Labels: IT, Linux, Web

Keine Kommentare | neuen Kommentar verfassen

Mittwoch, 22. September 2010

Höhere Datenbankkunde mit Facebook

„We need some way of applying the changes that we missed after the copy was started,“ he said. OSC does so using database triggers. „When the copy finishing, we replay all of the changes that were logged by the triggers, and then we briefly – for a fraction of a second – block access to the table and then we switch the original table with the copy.“

Quelle: Facebook open sources live MySQL makeover • The Register

Jede populäre Web-Applikation kann an einen Punkt heranwachsen, bei dessen Überschreitung das mit den Datenbanken kein Spass mehr ist, sondern eine grosse, grosse Bürde. Inkrementelle Backups und Schema-Upgrades — halleluja. Aber meist gibt es halt keinen Weg drumherum.

Tags: , , ,
Labels: IT, Web

Keine Kommentare | neuen Kommentar verfassen

Dienstag, 27. Juli 2010

Vacation-Meldung als Antwort auf automatisch generierte Mails verhindern

Sommerzeit — Ferienzeit — Vacation-Meldungszeit!

Dies hat heute dazu geführt, dass auf der Arbeit auf automatisch generierte Mails (mit Infos über Änderungen im Personalverzeichnis) mit Vacation-Meldungen der angeschriebenen Mitarbeiterinnen geantwortet wurde.

Um dies zu verhindern, sollte es ausreichen, wenn dem automatisch generiert Mail folgende zwei Header-Zeilen mitgegeben werden:

...
Precedence: bulk
Auto-submitted: auto-generated
...

Die meisten aktuellen Mail-Server sollten auf solche Mails nicht mehr mit einer Vacation-Meldung reagieren.

PHP Mailer

In meinem konkreten Fall sah die Anpassung im PHP-Script folgendermassen aus (ich verwende die vorzügliche Klasse PHP Mailer, um Mails zu generieren und zu versenden):

...
$mail->AddCustomHeader('Precedence: bulk');
$mail->AddCustomHeader('Auto-submitted: auto-generated');
...

Und still ward’s auf dem Web-Server …

Tags: , , ,
Labels: Allgemein

Keine Kommentare | neuen Kommentar verfassen

Samstag, 20. Februar 2010

Zugriff auf SVN-Verzeichnisse im Web-Root verhindern

Vor einigen Monaten standen auf unzähligen Web-Sites von professionellen Web-Entwicklern die Tore sperrangelweit offen: Auf Grund der Nachlässigkeit der Entwickler waren deren mit SVN versionierten Projekte statt mit svn export mit svn checkout auf das Produktivsystem ausgecheckt worden — und so gelangten automatisch die .svn-Verzeichnisse mit ins Web-Root.

Da Apache nachlässig konfiguriert war, hatte anschliessend jedermann mit einer klitzekleinen spielerischen Ader Zugriff auf die Struktur und den Source-Code einer jeden so Web-Site. Versuchen wir es gleich mal: Man hänge an die Domain versuchsweise „.svn“ an, wie beispielsweise bei www.stromzukunft.ch/.svn. In diesem Fall ist ein .svn-Ordner vorhanden, weil nicht ein 404er, sondern ein 403er angezeigt wird. Der Server wurde aber glücklicherweise längst gegen solche „Schnupperattacken“ gesichert …

Auch ich gehöre zu jenen Entwicklern, die sich bis zu diesem Zeitpunkt kaum über die „Best Practices“ der Entwicklergemeinde geschert hatten — tatsächlich bin ich auch heute immer noch so faul und verwende oftmals das verpönte svn checkout auf Produktivsystemen.

Um sich dennoch nicht gleich mit heruntergelassenen Hosen im Netz zu präsentieren, sollten solche unbelehrbaren Entwickler immerhin ihre /etc/apache2/apache2.conf anpassen und in dieser den Zugriff auf jedes .svn-Verzeichnis grundsätzlich verwehren:

...
<DirectoryMatch \.svn>
   Order allow,deny
   Deny from all
</DirectoryMatch>
...

Tags: , , ,
Labels: Web

2 Kommentare | neuen Kommentar verfassen

Dienstag, 17. November 2009

Du sollst HTML nicht mit Regex parsen!

or many novice programmers, there’s something unusually seductive about parsing HTML the Cthulhu way instead of, y’know, using a library like a sane person. Which means this discussion gets reopened almost every single day on Stack Overflow. The above post from five years ago could be a discussion from yesterday.

Quelle: Coding Horror: Parsing Html The Cthulhu Way

Auch für mich waren Reguläre Ausdrücke während Jahren das Allheiltmittel, um Informationen im HTML-Format aus dem Web auf den lokalen Server zu ziehen und danach gewisse Informationsstücke daraus zu extrahieren.

Meine (mittlerweile verflossene) Anstellung bei Liip öffnete mir aber die Augen. Das erste Mal, als ich mit Marc Ammann, dem Entwickler von GottaGo, über die Abfrage von Fahrplänen über das Web-Interface der SBB fachsimpelte (die Informatikbeamten des Transportunternehmens stehen nicht so auf frei zugängliche APIs). Ich war völlig naiv der Auffassung, dass auch er den HTML-Output des SBB Online-Fahrplans mit Regex durchparsen würde. Stimmte aber nicht, für etwas gibt es ja DOM! Ich machte mir aber keine weiteren Gedanken dazu, weil ich mir nicht vorstellen konnte, dass es etwas besseres als Regex gäbe, um HTML zu zähmen (dabei arbeitete ich doch für eine XML-Bude).

Das zweite, nun definitiv den Ausschlag gebende Aha-Erlebnis ereignete sich im Frühjahr 2009: Bei den Arbeiten zu energiezukunft.ch setzten wir ein Glossary-Plugin für WordPress ein. Als ich einen Blick auf den Sourcecode dieses Plugins warf, entdeckte ich es — die wohl aus PHP-Sicht heilsbringendste Zeile der letzten Monate:

DOMDocument::loadHTML();

Quelle: DOMDocument::loadHTML();

Weiter ausführen möche ich diesen Fingerzeig nicht weiter. Ich darf aber mit gutem Gewissen sagen, dass ich dank dieser Erleuchtung mittlerweile eine kleine, private Applikation in Version 2 realisiert habe. Während die erste Version munter Reguläre Ausdrücke einsetzt (und dabei immer wieder grandios scheitert), benutzt Version 2 ebendiese Klassen, um die Aufgabe mit schönem, einfachen und leicht wartbaren Code auszuführen. Und plötzlich gehört das Gefrickel der Vergangenheit an.

(Aber ja, HTML kann man weiterhin mit Regulären Ausdrücken parsen — und sollte es auch, wenn es nur darum geht, ein kleines Informationsstückchen aus HTML-Code zu extrahieren, ohne dass man gleich einen ganzen Tag daran rumprogrammieren möchte. Wie beispielsweise ubs.mad4you.homeip.net — wobei ich hier auch eher einen JSON-Parser als Reguläre Ausdrücke verwendet hätte. Was solls, der Kern des Scripts war dank Regulären Ausdrücken innert Minuten geschrieben.)

Tags: , ,
Labels: Web

Keine Kommentare | neuen Kommentar verfassen

Donnerstag, 1. Januar 2009

WordPress 2.7 nach blanker Installation extrem langsam

Gerade habe ich auf einem Entwicklungsserver WordPress 2.7 installiert. Die Installation verlief wie gewohnt in einigen wenigen Schritten – doch das böse Erwachen folgte kurz darauf: Obwohl die Installation noch über keinen einzigen Blog-Artikel verfügte, betrug die Ladezeit pro Seite 60 bis 90 Sekunden!

Dank Google stiess ich rasch auf einige Hinweise (von Endanwendern) und fand schlussendlich einen dazugehörigen Bug-Report mit Informationen, die im Gegensatz zum vorangehenden Link auch für Sysadmins und Entwickler nützlich waren.

Die Lösung des Problems lautete in meinem Fall:

# apt-get install php5-curl

Jetzt laden die Seiten (des Frontends!) nur noch mit etwa 5 Sekunden Verzögerung …

Nachtrag: Administrationsoberfläche („Dashboard“)

Seit ich das LDAP-Plugin aktiviert habe, lädt die Web-Site wieder unterträglich langsam. Ein Grund könnte sein, dass der Testserver im Intranet steht und nur über einen Proxy-Server Kontakt ins Internet aufnehmen kann. Leider spinnt der Proxy-Server derzeit und kann auf keine URL verbinden …

Nach dem ich http.php gemäss Anleitung gepatcht habe, sieht man die Wurzel allen Übels:

[Thu Jan 01 23:06:02 2009] [error] [client 0.0.0.0] Requesting http://api.wordpress.org/plugins/update-check/1.0/
[Thu Jan 01 23:07:03 2009] [error] [client 0.0.0.0] Requesting http://api.wordpress.org/plugins/update-check/1.0/, referer: http://www.ma.hist-web.unibe.ch/wp-admin/

Die 60 Sekunden Ladezeit deuten auf ein – man verzeihe es mir – bescheuert hohes Timeout für HTTP-Requests hin. Ich versuche deshalb nun, Disable WordPress Core Update sowie Disable WordPress Plugin Updates zu installieren, um HTTP-Anfragen an jedwelche Server zu verhindern.

Weitere Informationen bietet beispielsweise WordPress 2.7 Core Update.

Tags: ,
Labels: Blogosphäre, Web

Keine Kommentare | neuen Kommentar verfassen

Montag, 27. Oktober 2008

Regex (Reguläre Ausdrücke) im Sandkasten testen

Regular Expression sind für viele Voodoo, für den fortgeschrittenen Programmierer aber ein unentbehrliches Hilfsmittel. Hier einige Tools, die dem Anfänger helfen, Reguläre Ausdrücke am „lebenden Beispiel“ zu meistern:

Empfehlungen Dritte

Tags: ,
Labels: IT

Keine Kommentare | neuen Kommentar verfassen