• Jetzt anmelden. Es dauert nur 2 Minuten und ist kostenlos!

Browser Daten wie screen.width im PHP

NetAktiv

Senior HTML'ler
Hallo,
ich weiß, dass es oft diskutiert wird, dass es wenig Sinn macht, Browserdaten wie screen.width im PHP zu verarbeiten. Dennoch habe ich einfach mal ein paar Scripts geschrieben, die als Beispiel dienen können, wie man so etwas machen könnte. Die Lösung besteht aus 2 Teilen:
  1. PHP Script empfängt die Daten, speichert sie im $_SESSION Array und gibt ein grünes (OK) bzw rotes (Fehler) 16x16px großes GIF Image zurück. Dazu muss die GD Bibliothek aktiviert sein. Man kann natürlich auf die Erzeugung des Images verzichten.
  2. Im Footer (der in allen Dateien geladen wird) prüfe ich, ob ich die gewünschten Browserdaten schon kenne. Falls nicht, schreibe ich den Request zur Ausführung eines JavaScripts. Das JavaScript fordert das in 1 von PHP erzeugte Bild versteckt (display:none) an.
Eventuell kann ja jemand diese Lösung auch als Basis gebrauchen.

Das PHP Script zum Erzeugen des Bildes
PHP:
<?php

    //Aufruf im Dokument <img src="/scripts/setScreenSize.php?screen_width=xxx&amp;screen_height=yyy" alt="screenSize" >
    $screenWidth  = (isset($_REQUEST['screen_width']))  ? intval($_REQUEST['screen_width'])  : 0;
    $screenHeight = (isset($_REQUEST['screen_height'])) ? intval($_REQUEST['screen_height']) : 0;
    //Bild 16x16px erstellen, Farbe Rot (Fehler bei den Parametern) oder Grün (OK)
    $image        = imagecreate(16, 16) or die('Fehler beim Erstellen des Bildes - imagecreate');
    $colorResult  = (($screenWidth > 0) && ($screenHeight > 0)) ? imagecolorallocate($image, 0, 255, 0) : imagecolorallocate($image, 255, 0, 0);
    //Bild an Browser senden und Ressourcen freigeben
    header('Content-Type: image/gif');
    imagegif($image);
    imagedestroy($image);
    //Daten bei der Session speichern
    if (!isset($_SESSION)) session_start();
    $_SESSION['session_screen_width']  = $screenWidth;
    $_SESSION['session_screen_height'] = $screenHeight;
      
?>

Dynamisch bei Bedarf erzeugtes JavaScript im PHP zum Anfordern des Bildes
PHP:
    if (!isset($_SESSION['session_screen_width']) || true) {
        $imgHtml = "\"<img alt='screenSize' src='/scripts/set_screen_size.php?screen_width=\" + screen.width + \"&amp;screen_height=\" + screen.height + \" 'style='display:none'>\"";
        echo "<script type='text/javascript'> document.write($imgHtml); </script>" . PHP_EOL;
    }
 
Werbung:
Hallo,
ich weiß, dass es oft diskutiert wird, dass es wenig Sinn macht, Browserdaten wie screen.width im PHP zu verarbeiten. Dennoch habe ich einfach mal ein paar Scripts geschrieben, die als Beispiel dienen können, wie man so etwas machen könnte. Die Lösung besteht aus 2 Teilen:
  1. PHP Script empfängt die Daten, speichert sie im $_SESSION Array und gibt ein grünes (OK) bzw rotes (Fehler) 16x16px großes GIF Image zurück. Dazu muss die GD Bibliothek aktiviert sein. Man kann natürlich auf die Erzeugung des Images verzichten.
  2. Im Footer (der in allen Dateien geladen wird) prüfe ich, ob ich die gewünschten Browserdaten schon kenne. Falls nicht, schreibe ich den Request zur Ausführung eines JavaScripts. Das JavaScript fordert das in 1 von PHP erzeugte Bild versteckt (display:none) an.
Eventuell kann ja jemand diese Lösung auch als Basis gebrauchen.

Das PHP Script zum Erzeugen des Bildes
PHP:
<?php

    //Aufruf im Dokument <img src="/scripts/setScreenSize.php?screen_width=xxx&amp;screen_height=yyy" alt="screenSize" >
    $screenWidth  = (isset($_REQUEST['screen_width']))  ? intval($_REQUEST['screen_width'])  : 0;
    $screenHeight = (isset($_REQUEST['screen_height'])) ? intval($_REQUEST['screen_height']) : 0;
    //Bild 16x16px erstellen, Farbe Rot (Fehler bei den Parametern) oder Grün (OK)
    $image        = imagecreate(16, 16) or die('Fehler beim Erstellen des Bildes - imagecreate');
    $colorResult  = (($screenWidth > 0) && ($screenHeight > 0)) ? imagecolorallocate($image, 0, 255, 0) : imagecolorallocate($image, 255, 0, 0);
    //Bild an Browser senden und Ressourcen freigeben
    header('Content-Type: image/gif');
    imagegif($image);
    imagedestroy($image);
    //Daten bei der Session speichern
    if (!isset($_SESSION)) session_start();
    $_SESSION['session_screen_width']  = $screenWidth;
    $_SESSION['session_screen_height'] = $screenHeight;
     
?>

Dynamisch bei Bedarf erzeugtes JavaScript im PHP zum Anfordern des Bildes
PHP:
    if (!isset($_SESSION['session_screen_width']) || true) {
        $imgHtml = "\"<img alt='screenSize' src='/scripts/set_screen_size.php?screen_width=\" + screen.width + \"&amp;screen_height=\" + screen.height + \" 'style='display:none'>\"";
        echo "<script type='text/javascript'> document.write($imgHtml); </script>" . PHP_EOL;
    }

Wenn schon (und ja, man sollte so etwas generell sein lassen), würde ich das gleich als Cookie setzen.
PHP:
$_COOKIE['screen_width']
 
würde ich das gleich als Cookie setzen...[/PHP]
Viele Wege führen nach Rom. Nicht jeder hat Cookies aktiviert und die gehen dann bei jedem Request über die Leitung.

Nachteil von allen Lösungen ist, dass man im PHP erst während der ersten Anforderung merkt, dass man die Informationen noch nicht hat. Selbst wenn man den Request schon weit oben im Dokument (direkt nach <body>) einbaut ist nicht gesagt, dass diese Daten auch rechtzeitig auf dem Server ankommen. Das könnte man nur lösen, wenn man erst einen Redirekt auf eine Seite mit dem JavaSript macht und dann sofort wieder einen Redirect auf die eigentlich angeforderte Seite. Vermutlich kann man das Problem auch nicht mit Web Sockets lösen.
 
Werbung:
Hast Du irgendeinen realen Anwendungsfall bei dem man so etwas verwenden könnte? Oo
Zum einen soll es nur als Beispiel dienen, wie man nur dem Browser bekannte Informationen an den Server schicken könnte, ohne jQuery oder xmlHttpRequest zu verwenden. Das könnten auch andere Informationen sein wie Browser unterstützt sessionStorage oder cookies. Ich habe für zwei Stellen darüber nachgedacht.

Möglickeit 1: Ich habe meine persönliche Homepage nun weitgehend mittels Bootstrap umgebaut, aber nicht gefallen mir noch meine derzeitigen Dropdown Menüs, Die können sehr breit werden wie beispielweise auf der Startseite http://rainer-rosenberger.de/ und klappen dann auf dem Handy um und verwenden mehrere Zeilen. Ich habe Versuche mit dem Hamburger Menü gemacht (siehe http://bootstrap.netaktiv.de/index.php?page=menu&bootstrap=3&style=rr), aber zufrieden bin ich damit auch nicht. Die letzte Idee war, das Menü bei Handies einfach zu verschlanken, also beispielweise die Icons und Caret wegzulassen. Meine Menüs werden durch ein PHP Array(2x2) beschrieben und dynamisch aufgebaut. Wenn ich die Screen-Breite kenne, könnte ich die Reduktion im PHP machen. Aber das könnte ich vermutlich besser mit Media Queries erreichen, indem ich die entsprechenden Elemente mittels CCS display:none auf schmalen Displays verschwinden lasse.

Möglickeit 2: Nach wie vor ist bei mobilen Geräten die Bandbreite eine wesentliche Frage. Ich habe Bildergalerien wie http://rainer-rosenberger.de/x_reisen/index.php?page=tunesien_2006, die werden mittels PHP durch nur zwei Funktionen aufgebaut.
Code:
$rootFolder     = "2006_tunesien";
$g_sBilderListe = makeImageArray("$rootFolder/thumbs/*.jpg", "/Tunesien_2006_..._/i");
makeThumbGrid($g_sBilderListe, $rootFolder, 2);
Nun habe ich aber selbst bei dieser Beispielseite mit nur 12 Bildern und schon stark reduziertem JPG (50% Qualität) noch rund 1MB Download. Die Idee wäre, für kleine Geräte kleinere Bilder bereitzustellen, und das im PHP Code zu erledigen.
 
Werbung:
Der Link ist prinzipiell gut und ich kannte dieses Vorgehen noch nicht. Aber der Artikel sagt zum einen auch deutlich
The only downside right now is (you guessed it) support is still seriously lacking
und zum andern weiß ich nicht, inwieweit das von mir für die eigentliche Show benutze blueimp das unterstütz. Derzeit (zumindest in meiner Konfiguration) übergebe ich dem blueimp-Object die Liste der (gefilterten) <a> Elemente und blueimp verwendet von dort das href-Attribut.

Nachtrag: Ein wirklich nettes Beispiel zur Verwendung der oben vorgeschlagenen Technik habe ich unter http://googlechrome.github.io/samples/picture-element/ gefunden.
 
Zuletzt bearbeitet:
Genau deswegen hatte ich auch gefragt. Was Du erreichen willst, kann man mit einem srcset erreichen.

Allerdings wäre auch das was Du willst möglich - du musst nur eben die Maße nicht direkt an PHP übergeben. Baue die URLs der Bilder per JavaScript zusammen. Auf Serverseite musst Du dann die URLs abhängig vom URL-Aufbau auseinandernehmen und könntest auch so die Bilder in den Größen generieren lassen.

Ich denke jedoch ein srcset wäre eher zukunftsfähig. :)
 
kann man mit einem srcset erreichen
Nun musste ich erst mal gucken, was ein scrset ist und habe dieses Beispiel genommen https://blog.kulturbanause.de/2014/09/responsive-images-srcset-sizes-adaptive Wenn ich das richtig verstehe ist das eher dafür gedacht, bei hochauflösende Displays das Problem den extrem kleinen Pixels zu lösen. Damit würde aber ein Standard Smartphone wie mein altes 5'' Cynus T2 mit 480x854 genauso wie mein 21'' TFT am PC mit 1080x1920 das Normalbild laden.

Auf die Idee, Links vom PHP erzeugen zu lassen und die im Browser mittels JavaScript anhand der Screen-Size zu modifizieren, bevor ich die Liste an blueimp übergebe, hatte ich auch schon. Prinzipell könnte ich im Memory sogar eine völlig neue <a>-Collection erzeugen und die an blueimp übergeben.

Die Bilder über ein Server-Script anzufordern wie gebebild.php?path=...&screen_width=....&screen_height=... und dann die Bilder dynamisch auf dem Server zu resizen ist wohl die einfachste Lösung, weil ich mir dann auf Dauer sogar das Erstellen der kleineren Bilder erpare. Aber da habe ich diverse Bedenken wie
  • Performance auf dem Server
  • Qualität der Bilder (jpg nochmals resizen, oder muss ich die Originale hochladen)
  • Größe der Bilder (werden die wirklich gut komprimiert)
Da sind sicher etliche Tests notwendig. Aber erst mal danke für die vielen Anregungen. Ich denke, das Modifizieren der Links durch JavaScript ist im Moment die von mir bevorzugte Lösung.
 
Werbung:
Zurück
Oben