Self-Generating Class Objetcs in PHP

March 3rd, 2010

I have a directory on the webserver in my development environment where I do little experiments. I try out stuff that I cant figure out by looking into the PHP documentation – either because I can’t find the right place to look or because it’s just not explained.

Sadly I need to use that directory quite often. Almost daily.

Today I found this little gem:

1
2
$x->y->z = 123;
echo $x->y->z;

Without trying, what would you guess what happens when I try to set a value to a property of a property of a variable that I never initialized with an object?

I thought, this would fail and quit with some kind of error message. But no: This script prints “123″.

When I add a print_r($x) to my code I get this:

1
2
3
4
5
6
7
8
stdClass Object
(
    [y] => stdClass Object
        (
            [z] => 123
        )
 
)

That means that PHP creates an object for me when I try to access properties of a variable that is not set, yet.

So: What happens when the variable HAS a value before I try to set a property?
I have to answer with “Well, that depends…”

  • If the variable is NULL or an empty string (!), an object will be auto-generated
  • If the variable is numeric (including “0″ (!)) or a string with a length of at least 1 character nothing happens at all. No error message, nothing.
  • If the variable already is an object, nothing needs to be done. But note that if the object has no property of the given name, a property is added automatically

I find it quite strange that an empty string seems to be handled the same way as NULL while the numeric value 0 is not.

Another magic behavior uncovered… Let’s see what comes next…

Dominik Deobald PHP , , , , ,

Clean CSS for Various Browsers with Conditional Comments

December 15th, 2009

I was asked if I could explain a comment I left on 10 best CSS practices to improve your code on Webdesigner Depot some months ago.

The suggestion there was…

10. Keep a tidy house

Separate browser-specific CSS to its own individual style sheet, and include as needed with Javascript, server-side code or conditional comments. Use this method to avoid dirty CSS hacks in your main style sheets. This will keep your base CSS clean and manageable.

and I added…

I prefer to have all “browser tweaks” in the main CSS file, too. I use conditional comments to add a DIV around the whole page content identify IE browsers and then have…

.ie6 h1 {font-size: 20px} /* just an example */

… in the CSS file especially for IE6 tweaks.

Conditional comments allow you to have HTML in your page which is only visible to Internet Explorer or even only to Internet Explorer if it has a specific version.

By writing this you could load a CSS File only if the page is loaded in Internet Explorer 6:

1
2
3
<!--[if IE 6]>
<link rel="stylesheet" type="text/css" href="ie6.css" />
<![endif]-->

So if you follow rule 10 on Webdesigner Depot, you end up having several different CSS files which have almost the same content. But that means, that if you change something, you’ll have to apply those changes to every CSS file – and if you forget one of the files, users with a specific browser version will get a broken layout.

My suggestion is to stay with just one (slightly bigger) CSS file and have all those minor browser tweaks in there – in a clean way, not with CSS hacks.

1
2
3
4
5
6
7
8
9
10
11
...
<body>
<!--[if lte IE 6]><div class="ie6"><![endif]-->
<!--[if IE 7]><div class="ie7"><![endif]-->
<!--[if IE 8]><div class="ie8"><![endif]-->
... do your html here
<!--[if IE 8]></div><![endif]-->
<!--[if IE 7]></div><![endif]-->
<!--[if lte IE 6]></div><![endif]-->
</body>
</html>

You’ll end up with a “full page container” of the Internet Explorer version as class. Now, if you need some specific code for one version of IE, you can just say so in your CSS:

1
2
3
4
5
/* All other browsers */
div.box {height: 94px; width: 194px; padding: 2px; border: 1px solid red;}
 
/* Internet Explorer 6 */
.ie6 div.box {height: 100px; width: 200px; border: 1px solid green;}

Note that “padding: 2px” is not overwritten and also applies to IE6. So if you decide to go to 3 pixels it’s just one location to change that.

There might be cases where you are better off with a seperate CSS for every browser – especially for pixel-exact designs. But in my experience it’s just small tweaks for old browser versions to fix major problems.

This approach has worked for me for some years now. Just give it a try and see yourself if you like it :)

(BTW: It would be nice to see some other browsers to support conditional comments, too. They are just “tweaks”, but they are quite helpful.)

Dominik Deobald English, Webdesign , , ,

Seltsame User-Agents aussperren, Search-Bots reinlassen

October 30th, 2009

Vor lauter Bots kann man sich als Webseiten-Betreiber zur Zeit ja kaum noch schützen. Die nervigsten und gefährlichsten sperre ich bei unseren Webprojekten seit gewisser Zeit schon über die Webserver-Konfiguration oder .htaccess Datei aus. Beispielsweise die Kennung “Mozilla/4.0″ oder “Mozilla/5.0″ ohne jegliche weitere Information.

Normale Browser-Kennungen, wie beispielsweise die vom Internet Explorer oder von Firefox, beginnen in der Regel auch mit dieser Kennung, beinhalten dann aber weitere Informationen dahinter in Klammern.

Zugriffe, die in der Browser-Kennung keine weitere Information enthalten, sind in der Regel Angreifer-Tools, die als Ziel haben, Sicherheitslücken zu finden oder Spam-Kommentare zu hinterlassen.

Seit kurzem sind mir aber sehr häufig auch Zugriffe aufgefallen, die vom MSNBot, also dem Suchmaschinen-Spider von Bing, Microsoft’s Suchmaschine, kommen – und die sich auch nur mit “Mozilla/4.0″ identifizieren. Den will ich reinlassen.

Glücklicherweise kann man den MSNBot anhand der IP-Adresse identifizieren.

Also sieht meine mod_rewrite-Rule für die .htaccess so aus:

1
2
3
4
5
RewriteEngine On
 
RewriteCond %{REMOTE_ADDR} !^65.55.
RewriteCond %{HTTP_USER_AGENT} ^Mozilla/[1-9]\.[0-9]$ [NC]
RewriteRule ^.*$ - [F,L]

Mit der ersten Rewrite Condition wird festgelegt, dass die folgende Regel nur für Zugriffe von IPs gilt, die NICHT Mit 65.55. anfangen.

Die folgende Condition beschränkt das ganze weiter auf User_Agent-Strings, die die Form “Mozilla/” gefolgt von einer Versionsnummer in der Form “x.y” (x und y nur einstellie Ziffern) haben.

Und die Rewrite-Rule am Ende legt fest, dass alle derartigen Zugriffe mit einem Forbidden (HTTP Fehler 403) beantwortet werden sollen.

Dominik Deobald .htaccess, Security , , , , , ,

wget und administrative cronjobs

October 28th, 2009

Wer – so wie ich – gerne seine CRON-Tabelle mit Hintergrund-Jobs füllt, die der Server beispielsweise ein mal pro Tag erledigen soll, der sollte gerade in der Kombination wget und PHP-Script etwas aufpassen. Es gibt da einen Fallstrick, der nicht auf den ersten Blick sichtbar ist:

Angenommen, das PHP-Script braucht etwas länger. Und genau das ist ja in der Regel der Fall. Dazu legt man solche Aufgaben in den Hintergrund.

WGET fängt also an, die PHP-Seite abzurufen – und wartet, und wartet, und wartet… Das macht es 900 Sekunden, also 15 Minuten lang. Wenn das Script dann noch nicht fertig ist, dann gibt wget auf zu warten. Und hier kommt der Haken: Es hört dann nicht auf, sondern es versucht es gleich noch mal. Standardmäßig 20 mal.

Wozu das führt ist relativ klar: Es läuft jetzt ein weiterer Prozess, der noch mal das gleiche tut wie der erste Prozess. Der bremst in der Regel den ersten Prozess noch weiter aus und läuft selbst auch langsamer, da er mit dem ersten Prozess konkurriert. Nach 15 Minuten kommt dann der nächste Prozess dazu, alles wird noch langsamer, …

Deshalb immer dafür Sorgen, dass es nur einen einzigen Versuch gibt:
wget --tries=1 --spider http://www.example.com/cronjob.php

Oder alternativ:
curl http://www.example.com/cronjob.php

cURL setzt standardmäßig auf “Nicht wieder Versuchen“.

Dominik Deobald Webserver , , , , ,

Did You Know 4.0

September 25th, 2009

… wie schon mal vor einem halben Jahr (da war’s 3.0):

Did You Know 4.0

via BloggingTom

Dominik Deobald Internet , , , ,

JavaScript-Tests mit TestSwarm

August 27th, 2009

JavaScript testen ist eine etwas mühselige Arbeit. Inzwischen gibt es fünf relevante Browser (Firefox, Internet Explorer, Opera, Chrome und Safari) und von jedem gibt es verschiedene Versionen – insbesondere von den Browsern, die schon ein paar Jahre auf dem Markt sind.

Wie testet man also sein JavaScript auf all diesen Browsern?

Es gibt von Mozilla ein junges Projekt namens TestSwarm, dessen Funktionsweise eigentlich in folgendem Video sehr gut gezeigt wird:

Grob zusammengefasst funktioniert das so:

Es gibt einen Haufen “Testrechner”, die unterschiedliche Browser unter verschiedenen Betriebssystemen installiert haben. Diese warten darauf, von einem Zentralserver neue Aufgaben zugeteilt zu bekommen.

Und diesen Zentralrechner kann man nun damit beauftragen, JavaScript-Testschnipsel an die verschiedenen Browser zu verteilen. Heraus fällt am Ende eine Grafik, die eine Übersicht bietet, wo das Script problemlos lief und wo Fehler aufgetreten sind.

TestSwarm ist jetzt in “Alpha” Betrieb gegangen.

Dominik Deobald JavaScript , , , , , , ,

Did You Know?

March 31st, 2009

History of the Internet

March 22nd, 2009

History of the Internet (by picolsigns)

Dominik Deobald Internet , , ,

Mit der .htaccess gegen Hotlinking von Bildern

February 9th, 2009

Es gibt ein paar unbelehrbare, die der Meinung sind, dass man Dateien – insbesondere Bilder – von anderen Servern einfach so in die eigene Webseite “reinladen” kann. Ist ja technisch kein Problem – sogar gewollt. Von der rechtlichen Fragestellung mal ganz abgesehen sieht es aber so aus, dass derjenige, der die Dateien auf seinem Webserver liegen hat, den Traffic bezahlen muss, den der verursacht, der die Bilder in seiner Webseite verwendet. Von der Rechenleistung und der Netzwerkbandbreite mal ganz zu schweigen.

Was kann man dagegen tun?

Erstens kann man natürlich denjenigen Kontaktieren, der die Daten verwendet. Der ist oft aber gar nicht aufzuspüren.

An dem Punkt helfen dann technische Maßnahmen. So weit auf dem Webserver mod_rewrite installiert ist reichen zwei einfache Zeilen in der .htaccess.

Da die Problemkinder oft Grafiken sind, gibt es eine wirksame, eigentlich ganz unterhaltsame Option: Statt der angeforderten Grafik verschickt man eine andere, riesig große Grafik in grausamen Farben. Wenn man die einfarbig hält, dann bleibt die Dateigröße auch bei einer hohen Pixelzahl schön klein – in der Regel wesentlich kleiner als die zu ersetzende Datei. Und wenn alles gut läuft, dann will die Ersatzgrafik sowieso niemand sehen, also wird sie auch nicht so oft abgerufen :)

Also: Datei hochladen und folgende Zeilen in die .htaccess:

1
2
3
4
RewriteCond %{HTTP_REFERER} bandbreiteklauer\.com [OR,NC]
RewriteCond %{HTTP_REFERER} beepworld\.de [OR,NC]
RewriteCond %{HTTP_REFERER} facebook\.com [NC]
RewriteRule jpg$ /dont_hotlink.png [L]

Dabei einfach “bandbreiteklauer\.com”, “beepworld\.de” und “facebook\.com” durch die Domains der Bösewichte ersetzen. Will man mehr oder weniger Server aussperren, dann einfach weitere Zeilen mit RewriteCond einfügen. Es ist nur wichtig, dass die letzte Zeile am Ende nur [NC], alle anderen aber [OR,NC] enthalten, damit das ganze als ein zusammengehörender Block gehandhabt wird.

Dominik Deobald .htaccess , , , , , ,

High-End Workstation PC

January 20th, 2009

Ich habe gerade meinen neuen Arbeitsplatz-PC zusammengeschraubt und bin jetzt gerade dabei parallel die Festplatten zu formatieren und Windows-Updates zu installieren.

Meine Anforderungen waren:

  • Intel Core2Quad Prozessor
  • 8GB RAM
  • 4x DVI Out
  • Er soll leise sein

Klare Ansage: Für einen “Normalanwender” oder normale Büro-Arbeiten ist diese Maschine total überdimensioniert. Für einen Entwickler wie mich ist das aber derzeit eine absolute Traummaschine.

Warum?

Bisher habe ich hier teilweise bis zu drei Rechner parallel laufen, die jetzt durch den neuen PC ersetzt werden sollen:

  • meine normale “Workstation”
  • einen alten AMD 1700+ PC mit Debian Linux, der meinen Entwicklungs-Webserver mimt und
  • einen Dell Dimension 3100 mit Windows, der als ein IIS/ASP/SQL Entwicklungs-Webserver im Einsatz ist.

Alle drei hängen an der Steckdose und verbrauchen im eingeschalteten Zustand jeweils zwischen 100 und 150 Watt Strom. Sie brauchen physikalisch Platz und einen Steckplatz auf dem Netzwerk-Switch. Um den AMD einzuschalten muss ich aufstehen und quer durch mein Arbeitszimmer laufen. Er fährt zudem altersbedingt nicht mehr jedes mal sauber hoch – und wenn es mal Probleme gibt, dann muss ich mir erst mal einen Monitor suchen, den ich an’s System hängen kann.

Lange Rede, kurzer Sinn: Virtuelle Maschinen sind ab jetzt mein Lösungsansatz. Alleine mit dem gesparten Stromverbrauch sollte sich der neue Rechner innerhalb von zwei bis drei Jahren amortisiert haben.

Jetzt zum Schmuckstück selbst:

Als Betriebssystem kommt Windows Vista (64bit) zum Einsatz, was ich aber nicht extra kaufen musste sondern noch hier “herumliegen” hatte. Als Virtualisierungs-Lösung werde ich wohl auf VMware Workstation setzen, da ich mit den kostenfreien alternativen VirtualBox und VirtualPC zu viele Probleme hatte.

Alles in allem hat der PC also rund einen Tausender gekostet, zuzüglich der Software Lizenzen.

Ich konnte zwar noch nicht wirklich mit dem PC arbeiten, da ich wie gesagt noch beim Installieren, Formatieren und ersten Updaten bin – aber bisher bin ich begeistert. Das ichbinleise-Gehäuse trägt seinen Namen nicht umsonst und die offensichtliche Leistung ist absolute Spitzenklasse, die die drei vorher im Einsatz befindlichen Rechner problemlos ersetzen dürfte.

Dominik Deobald Arbeitsplatz , , , , , ,