• Das Erstellen neuer Accounts wurde ausgesetzt. Bei berechtigtem Interesse bitte Kontaktaufnahme über die üblichen Wege. Beste Grüße der Admin

[FRAGE] Browserauflösung an PHP-Variable übergeben und in Datenbank speichern

HeinrichK

New member
Hallo,

ich habe wenig Ahnung von JS und hoffe auf euer Verständnis. In den relevanten Threads, die ich hier gefunden habe, konnte ich leider keine Lösung für mein Problem finden.

Ich will per JS Breite und Höhe des Browsers ermitteln, per HTTPRequest an eine PHP-Datei auf dem Server schicken, die die Werte in eine Datenbank abspeichert.

Dazu steht in meiner counter.php, die am Ende der index.php per include eingebunden ist folgendes JS:
Code:
<script type="text/javascript">

	var request = false;
	// Request senden
	function setRequest(height, width) {
		// Request erzeugen
		if (window.XMLHttpRequest) {
			request = new XMLHttpRequest(); // Mozilla, Safari, Opera
		} else if (window.ActiveXObject) {
			try {
				request = new ActiveXObject('Msxml2.XMLHTTP'); // IE 5
			} catch (e) {
				try {
					request = new ActiveXObject('Microsoft.XMLHTTP'); // IE 6
				} catch (e) {}
			}
		}
		// überprüfen, ob Request erzeugt wurde
		if (!request) {
			alert("Kann keine XMLHTTP-Instanz erzeugen");
			return false;
		} else {
			var url = "http://www.meinewebseite.de/js/statistik_aufloesung.php";			 
			// Request öffnen
			request.open('post', url, true);
			// Requestheader senden
			request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
			// Request senden
			request.send('height='+height+'&width='+width);
		}
	}

var height = screen.height;
var width = screen.width;

setRequest(height, width);

</script>
Nach meinem Verständnis werden die Werte für Breite und Höhe in den JS-Variablen width und height erfasst, dann wird die Funktion setRequest aufgerufen, die sie an die statistik_aufloesung.php sendet, deren Code so aussieht:
PHP:
<?php

$width = $_POST['width'];
$height = $_POST['height'];
$aufl = $width."x". $height;

// Eintrag in Dauerstatidtik BROWSERAUFLÖSUNG
				  
                  $stmt_auf_drin = $pdo->prepare("SELECT aufl, zahl FROM ".TAB_STAT_AUFL." GROUP BY aufl;");
				  $stmt_auf_drin->execute();
                         while($row = $stmt_auf_drin->fetch()) {
                              $aufl_drin = $row['aufl'];
                              $aufl_zahl = $row['zahl'];
							  $aufl_zahl_neu = $aufl_zahl+1;	
						  
							  if ($aufl == $aufl_drin) {
								  $stmt_auf = $pdo->prepare("UPDATE ".TAB_STAT_AUFL." SET zahl = :aufl_zahl_neu WHERE aufl = :aufl_drin");
                                  $stmt_auf->execute(array('aufl_drin' => $aufl_drin, 'aufl_zahl_neu' => $aufl_zahl_neu));
							  }
							  else {
                                  $stmt_auf_neu = $pdo->prepare("INSERT INTO ".TAB_STAT_AUFL." (aufl, zahl) VALUES (?, ?);");
                                  $stmt_auf_neu->execute(array($aufl, 1));								  
    						  }
						 }					 
?>
Ergebnis ist, dass bei Aufruf meiner Webseite ab und zu etwas in die Datenbank eingetragen wird, meistens aber nicht. Hat jemand dazu eine Idee? Danke schon mal für gute Tipps.
 
Zuletzt bearbeitet von einem Moderator:
screen height und screen width ist die Bildschirm Auflösung und nicht die vom Browserfenster ist das Absicht?
Ich habe das JS im chrome getestet und es funktioniert.
Muss wohl am PHP Script liegen oder der Datenbank ?
 
console.log(height, width); direkt vor das setRequest().

Und wo immer Du das AJAX her hast: es ist zwar noch nicht so alt wie ich, aber es ist verdammt alt! :cool: IE5 und IE6 Unterstützung ... das lasse ich nur gelten, wenn Du in China sitzt, wo IE6 noch verwendet wird. Also? Sack Reis, Rikscha, Jackie Chan und Volkspartei? :D

Ich würde das Script nicht unmittelbar sofort ausführen, sondern erst, wenn wirklich der User bedient wurde.


Code:
<script>
(function() {
   // hier machste das setRequest()
})();
</script>


Kommen wir zum PHP-Teil: TAB_STAT_AUFL ist bekannt, da nur Ausschnitt? Falls nicht, so fehlt das und darum geht es nicht ... ! Ebenso wird es nicht gehen, wenn der erste SELECT keinen Grund sieht, die while-Schleife zu betreten, wodurch der INSERT nie ausgeführt wird, wenn die Auflösung noch nicht bekannt ist. Ist Deine Table demnach leer, führt er nie INSERT aus und Du bekommst gar keinen Eintrag.

Wenn Du Dir PHP-seitig ein echo() einbastelst, kannst Du das zum Debuggen nehmen und in der Konsole Deines Browser lesen (die Antwort des XHR).

Viele Grüße aus den Untiefen anderer Projekte. ;)
 
@andreax, danke für den Test. Der Witz ist ja, dass es ab und zu funktioniert, meistens aber nicht. Eventuell doch ein Browserproblem?

@SteelWheel, danke. Das console.log habe ich eingebaut, mal schauen...

Keine Lust, in China zu sitzen. Wenn das aber nix Böses tut, kann es ja drin bleiben. Die Frage ist eher, ob irgendwelche andere Browser eine Sonderbehandlung bräuchten.

Warum ich die function setRequest() in eine weitere function() setzen soll, versteh ich nicht. Die ganze Statistiksache wird sowieso erst am Ende der index.php aufgerufen.

Der PHP-Teil funktioniert. Hab meine includierten Pfade zu den Konstanten (TAB_STAT_AUFL) hier im Posting weg gelassen. In der Tabelle steht auch was drin, so dass die while-Schleife ordentlich schleift.
 
Das hat was mit dem Moment zu tun, wann Dein Script ausgelöst wird. function() wird ausgelöst, wenn alles für den User geladen und gerendert wurde (heißt: er sieht was). Dann kannst Du diesen Nebenquest abfeuern.

Ich bleibe bei meiner Aussage, dass Deine Table - wenn leer - auch leer bleibt. Dass jetzt was drin steht ist eher dem Development anzulasten. Sobald die Table geleert produktiv geht, erhälst Du keine Auflösungen eingetragen.

Und doch, es tut was Böses: Es müllt völlig unnötig Deinen Source und den User zu. Spätestens im Refactoring solltest Du das entnehmen.
 
@SteelWheel

würde das dann so aussehen?
Code:
function() {
setRequest();
}) ();
Sorry, aber das kommt von meiner JS-Ahnungslosigkeit.

Mit dem PHP-Teil hast du natürlich recht, wenn nix stünde. Deshalb habe ich zu Beginn manuell einen Eintrag geschrieben. Vielleicht nicht die eleganteste Art. Da dies alles sowieso nur mein Privatvergnügen ist...

Jetzt für mich schon schwieriger - den IE-Teil aus dem Request raus. Ist das so richtig?
Code:
	var request = false;
	// Request senden
	function setRequest(height, width) {
		// Request erzeugen
		if (window.XMLHttpRequest) {
			request = new XMLHttpRequest(); // Mozilla, Safari, Opera
		} [COLOR="#FF0000"]else if (window.ActiveXObject) {
			try {
				request = new ActiveXObject('Msxml2.XMLHTTP'); // IE 5
			} catch (e) {
				try {
					request = new ActiveXObject('Microsoft.XMLHTTP'); // IE 6
				} catch (e) {}
			}
		}[/COLOR]
		// überprüfen, ob Request erzeugt wurde
		if (!request) {
			alert("Kann keine XMLHTTP-Instanz erzeugen");
			return false;
		} else {
			var url = "http://www.krobbach.de/js/statistik_aufloesung.php";			 
			// Request öffnen
			request.open('post', url, true);
			// Requestheader senden
			request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
			// Request senden
			request.send('height='+height+'&width='+width);
		}
	}
Also das rote weg?
 
Korrekt bzgl. function().

Keine Gewähr auf Funktionalität - Coding hier im Fenster ist immer ... "unübersichtlich". :)

Code:
function setRequest(height, width) {
	var request = {}; // in die Funktion geholt und 

	if (window.XMLHttpRequest) {
		request = new XMLHttpRequest();
	} else {
		request = new ActiveXObject("Microsoft.XMLHTTP"); // old as hell, wenn Du den unbedingt enthalten haben willst
	}
	
	try {
		var url = "/js/statistik_aufloesung.php"; // gekürzt auf relativen Pfad; u. U. Kollision mit "same origin policy" (kurz: SOP)
		
		request.onreadystatechange = function() {
			if (this.readyState == 4 && this.status == 200) {
				console.log("Serverantwort: " + this.responseText); // u. U. bekommst Du hier eine Fehlermeldung vom Server zurück - im Dev-Mode ist das seeehr hilfreich!
		   }
		};
		
		request.open('post', url, true);
		request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
		request.send('height='+height+'&width='+width);
		
	} catch(c){
		console.log("... kein Request möglich."); // statt alert() - auch für den Dev-Mode
	}
}

Was mir gar nicht gefällt: "request" - sowohl als Variablennamen als auch der Switch von initialisiertem Boolean auf Object; darum direkt Object gesetzt.

Dev-Mode: Entwicklungsprozess ... nicht für den produktiven Teil später angedacht.

In jQuery (ein JavaScript Framework) wäre Dein Vorhaben "so lang":
Code:
$.post("/js/statistik_aufloesung.php", {height:height, width:width}, function(c){
	console.log(c); // Antwort vom Server
});

Kleine Gemeinheit noch: Was würde passieren, wenn ich auf der geladenen Seite immer F5 drücke?
 
Also würde das einfach so aussehen (JQuery ist schon installiert):
Code:
var height = screen.height;
var width = screen.width;

$.post("/js/statistik_aufloesung.php", {height:height, width:width}, function(c){
	console.log(c); // Antwort vom Server
});
Habe ich das richtig verstanden, dass console.log dafür sorgt, das es in die Logdatei (also bei Firefox in die Webkonsole geschrieben wird.

Zur Gemeinheit: Zur zeit hättest du mit F5 noch Erfolg. Wenn's richtig funktioniert, kommt die Sache in einen script-Teil mit IP-Sperre (also alle 3 Stunden nur einmal zählen).
 
Öhm, wenn jQ präsent ist, warum dann nicht nutzen?

Die Konsole des FF findest Du mittels Drücken der F12-Taste - im Reiter "Konsole" kannst dann mitlesen. Dort zeigt er Dir dann Rückmeldungen, die in der Korrespondenz zwischen Client-Server gezeigt werden. Alternativ - ohne log() - kannst Du den XHR auch direkt lesen (also die Antwort). Aber etwas bequem darf es ja auch mal sein. Nicht vergessen: Gehst Du online, haben console.logs() keine Daseinsberechtigung mehr.

Zum F5: IP-Sperre ist unsexy. Habe eine Proxy (eine IP) zwischen Internet und einer 30 Mann Firma - 10 Mann dieser Firma besuchen Deine Seite mit individuellen Geräten (Laptop, Desktop-PC, Mac, Smartphone, Kühlschrank, ...) und nur drei erfasst Du. :)

Vorschlag: Platziere dem User beim Erstbesuch einen Wert in den sessionStorage - ist der Wert nicht da, setRequest() ... ist ein Wert da, nix machen.
 
Danke dir - werde das mit JQ mal so einbauen.

IP-Sperre - meine Seite gucken keine 10 Mann (auch keine Frauen) einer Firma *lach* Aber der Tipp mit Session ist gut, mach ich mich später mal dran.
 
Na, hätten auch 100 Mann sein können ... :D Wollte Dir ja nur zeigen, woran man alles denken sollte, wenn der Begriff "IP-Sperre" so leichtfertig verwendet wird. Kannst auch sonst 'nen Uni-Server gedanklich verwenden - da hocken noch ein paar mehr hinter auf der gleichen IP.

Wichtig ist immer: Hab Spaß dabei! Und wenn es mal nicht läuft, biste hier im Forum genau richtig.
 
function() wird ausgelöst, wenn alles für den User geladen und gerendert wurde (heißt: er sieht was).
Das ist nicht richtig. (function(){}()); wird sofort ausgeführt. Damit schafft man nur einen Funktionsscope, damit man keine globalen Variablen erzeugt.

@Heinrich: Die komplette Logik für das INSERTs ist trotzdem falsch. Wenn du z.B. in der DB schon zwei Einträge drin hast, diese aber nicht passen, werden zwei INSERTs ausgeführt. Beim nächsten Aufruf würden zwei INSERTs und ein UPDATE ausgeführt werden...
Im Grunde genommen willst du eigentlich ein INSERT mit ON DUPLICATE KEY - und auf deiner Tabelle einen unique Key auf `aufl` definieren: https://dev.mysql.com/doc/refman/5.7/en/insert-on-duplicate.html
 
@kkapsner

Danke - Recht hast du. Ich sollte beim scripten öfters das Hirn einschalten (mehr Empathie für die Schleife). Also geht's einfach so:
PHP:
$stmt_auf_neu = $pdo->prepare("INSERT INTO ".TAB_STAT_AUFL." (aufl, zahl) VALUES (?, ?) ON DUPLICATE KEY UPDATE zahl = zahl +1;");
$stmt_auf_neu->execute(array($aufl, 1));
Jetzt mal warten, ob dies mein ursprüngliches Problem, nämlich dass bei Besuchen nur ab und zu Einträge erfolgen, löst. Eventuell muss ich die Übergabe der Variablen mal genauer kontrollieren.
 
Hallo,

danke für die bisherige Hilfe. Das PHP-Script macht nun die richtigen Einträge in die Datenbank (INSERT bei neuem Wert, UPDATE bei bekanntem Wert).

Nach wie vor tut es das JS nicht richtig (egal ob ich die JQ-Variante oder den veralteten REQUEST - s.o.) verwende. Beides mal erfolgen bei ca. 5 Besuchen auf der seite 1-2 Einträge zur Auflösung des Browsers. Also, mal klappt's, mal nicht - und ich kann nichts erkennen, was den Unterschied ausmacht.

Das JS ist am Ende der index-php, direkt vor dem abschließenden </body> eingefügt. Hat jemand noch irgendeine Idee, an welchen Faktoren, Umständen, Umgebungskonfigurationen es liegen könnte, also wo ich suchen sollte? Danke schon mal für die weitere Hilfe.
 
Das klingt irgendwie nach einem Cache-Problem. Kannst du in der Browserkonsole (F12) mal in der Netzwerkanalyse nachsehen, welchen Status die Anfragen bekommen?
 
Verstehe ich nicht. Wie soll ich in meinem Browser nachsehen, was in den Browsern der user passiert, wenn sie meine Seite besuchen?

- - - Aktualisiert - - -

Sorry (es ist spät) - du meintest sicher, dass ich es selbst teste. Der Status der statistik_aufloesung.php ist bei mir in der Konsole 200. Also müsste eigentlich klappen, oder?
 
"JavaScript nicht aktiviert" wäre u. U. auch noch eine zu berücksichtigende Option. :)

$.post() wird naturgemäß nicht gecached - aber es soll schon Pferde (kotzend) vor Apotheken gegeben haben. Simpel zur Darstellung: $.post("statistik_aufloesung.php", {x:x, y:y, z:Math.random()}, function(r){ console.log(r); }); trägt einen beliebigen Zufallswert kleiner 1 mit sich (in z; oder beliebiger Name) und modifiziert daher den Versand jeweils. Einen Test wäre es wert ...

Hattest Du den Vorschlag mit dem sessionStorage realisiert? Dann wäre dies mitunter auch ein denkbarer Grund, warum nicht immer Werte kommen.

Zuguterletzt wäre da noch das Treiben auf der PHP-Seite ... Bedingung nicht erfüllt, merkwürdige SQL-Aktionen (was?! Anspielung?? Neeee ... !!) ... lass Dir doch einfach die Queries zeigen, die benutzt werden und drückst diese mal in die Konsole (oben bereits integriert; musst nur den Query zurückliefern).

Das wird was ganz furchtbar Einfaches sein ... mit Sicherheit.
 
Hallo

Statistik von jetzt im Vergleich zu gestern Abend: 10 Besucher / 22 Seitenaufrufe mehr, aber nur 2 zusätzliche Einträge zur Browserauflösung. Das scheint mir heutzutage nicht an deaktiviertem JS zu liegen.

sessionStorage ist noch nicht umgesetzt. Der JS-Request steht ohne Bedingung am Ende der index.php

Query-Strings werden protokolliert und kontrolliert. Böse strings würden zum Abbruch des scripts führen, gabe es aber in den letzten Tagen nur einen.

Das mit dem Zufallswert werde ich gleich mal testen.

Jetzt hoffe ich auf das "furchtbar Einfache"...

- - - Aktualisiert - - -

@SteelWheel

Mit deinem JQ-Vorschlag wurden jetzt bei einem neuen Besuche (und nur 1 Seitenruf) 2 Einträge vorgenommen.

Erklär mal doch mal, was diese function(r) bzw. (in deinem früheren Vorschlag) die function(c) macht. Danke.
 
Zurück
Oben