PHP in Javascript ausführen

znukida

Grünschnabel
Hallo zusammen
Auf einer Website werden immer wieder neue Beiträge veröffentlicht, welche in eine mysql-Datenbank geschrieben werden. Nun möchte ich jeweils überprüfen, ob neue Einträge vorhanden sind und dann einen div-Container, worin die Beiträge dargestellt werden, neu laden. Dies möchte ich mit javascript und php machen.
Folgenden Code habe ich bereits geschrieben.

HTML:
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>

<script type="text/javascript">
var alte_eintraege = 0;
var neue_eintraege = 0;

var updateDiv = function nachricht_ueberpruefen () {
    $.ajax({url: "velotour_admin/neue_nachricht.php", async: false});
    neue_eintraege = "<?php echo $_SESSION['eintraege'] ?>" ;
    if (neue_eintraege > alte_eintraege) {
        $('#eintraege').load('velotour_juni_2021_tracking_inhalt.php').hide().fadeIn(1000);
        alte_eintraege = neue_eintraege;
    }
}
</script>

</head>
<body onload="window.setInterval(updateDiv, 10000);">

<div id="eintraege">
<script type="text/javascript">
  $('#eintraege').load('velotour_juni_2021_tracking_inhalt.php');
</script>
</div>

</body>
</html>

Mittels ajax wird die Datei "neue_nachricht.php" aufgerufen, in welcher die Anzahl Einträge in der Datenbank gezählt werden und in einer Session gespeichert werden. Diese Session wird ausgelesen und mit der alten Anzahl Einträge verglichen. Ist die Anzahl grösser, wird der div-Container neu geladen.
Leider funktioniert dies nur beim ersten Intervall. Danach nicht mehr, obwohl ich in der Zwischenzeit einen neuen Eintrag in die Datenbank geschrieben habe.
Ich habe schon viel recherchiert und noch mehr ausprobiert und komme einfach auf keinen grünen Zweig. Wo ist der Wurm begraben?

Hier noch der Code der Datei "neue_nachricht.php":
PHP:
<?php

include("db_connect_velotour.inc.php");
$link = mysql_connect($host, $user, $pwd)
or die("Leider ist momentan keine Datenbank-Verbindung möglich : " . mysql_error());

mysql_select_db($dbname, $link);

$erg = mysql_query ("SELECT text FROM eintraege_velotour")
or die("Es konnten leider keine Einträge aus der Datenbank gelesen werden: " . mysql_error());

$anzahl_eintraege = mysql_num_rows($erg);

session_start();
$_SESSION["eintraege"] = $anzahl_eintraege;

// MySQL-Verbindung schliessen   
mysql_close($link);
?>

Und hier der Code der Datei "velotour_juni_2021_tracking_inhalt.php":
PHP:
<?php
// Erstellen der Datenbankverbindung
include("velotour_admin/db_connect_velotour.inc.php");
$link = mysql_connect($host, $user, $pwd)
or die("Leider ist momentan keine Datenbank-Verbindung möglich : " . mysql_error());
mysql_select_db($dbname, $link);

mysql_query("SET NAMES 'utf8'");

$erg = mysql_query ("SELECT text, bild_link_1, video FROM eintraege_velotour ORDER BY id DESC")
or die("Es konnten leider keine Einträge aus der Datenbank gelesen werden: " . mysql_error());

while ($row = mysql_fetch_row($erg)) {
    if ($row[1]!=""){
        echo "<img src='velotour_bilder/";
        echo $row[1];
        echo ".jpg'>";
        echo "<br /><br />";
    }
    if ($row[2]!="") {
        echo "<video width='700' height='525' controls controlsList='nodownload' preload='metadata'>";
          echo "<source src='velotour_bilder/";
          echo $row[2];
          echo ".mp4' type='video/mp4'>";
        echo "Your browser does not support the video tag.";
        echo "</video>";
        echo "<br /><br />";
        
    }
    echo nl2br($row[0]);
    echo "<br /><br />";
    echo "<hr style='border: 0.5px solid #D8D8D8;'>";
    echo "<br /><br />";
}
 
mysql_close($link);
?>

Es wäre super, wenn mir jemand helfen könnte! Vielen Dank schon im Voraus!
 
Ich habe das jetzt mal nur kurz überflogen, aber für mich liegt das Problem in der Session Variablen. Die wird beim Erstellen der Seite auf dem Server zugewiesen. Auf dem Client wird die Zahl aber nicht mehr verändert, denn alle PHP Teile passieren ausschließlich auf dem Server.

Schreib die neue Anzahl nicht in eine Session Variable, sondern schick sie von "neue_nachricht.php" direkt zurück an das Ajax Script. Dann hast du die tatsächlich neue Anzahl zur Verfügung.
 
Hi,

die Idee sollte sein, den Server asynchron anzufragen und die Anzahl der neuen Einträge zurück zu senden. In der callback-Funktion (done) der ajax Methode kann geprüft werden, ob sich der Wert geändert hat und die updateDiv Funktion aufgerufen werden.

Ein einfaches Beispiel, um die Idee zu verdeutlichen:

HTML
HTML:
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>

<script type="text/javascript">
var alte_eintraege = 0;

var updateDiv = function() {
  document.getElementById("eintraege").innerHTML = alte_eintraege;
  // ToDo: deinen Inhalt einfügen, z.B.
  // $('#eintraege').load('velotour_juni_2021_tracking_inhalt.php');
}

var requestServer = function () {
    $.ajax({
      url: "./server/neue_nachricht.php",
      async: true,
      dataType: 'json',
      type: 'GET',
      data: { "alte_eintraege": alte_eintraege }
    })
      .done(function( data, textStatus, jqXHR ) {
        if (data.neue_eintraege > alte_eintraege) {
          alte_eintraege = data.neue_eintraege;
          updateDiv();
        }
      })
      .fail(function( jqXHR, textStatus, errorThrown ) {
        console.log('fail: ', arguments);
      });
}
</script>

</head>
<body onload="requestServer(); hTimer = window.setInterval(requestServer, 1000);">

<div id="eintraege"></div>

<button onclick="window.clearInterval(hTimer);">stop</button>

</body>
</html>

SERVER (./server/neue_nachricht.php):
PHP:
<?php
$neue_eintraege = isset($_GET['alte_eintraege']) ? ((int) $_GET['alte_eintraege']) : 0;

$return = (object) array("neue_eintraege" => ++$neue_eintraege);

echo json_encode($return);

Vielleicht hilft dir das weiter, die Grundidee zu vestehen.

Ciao
Quaese
 
Hallo Quaese

Vielen Dank für Deine Hilfe! Ich habe nach Deiner Anleitung nun mal folgendes geschrieben:

HTML:
HTML:
<html>
<head>

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>

<script type="text/javascript">
var alte_eintraege = 0;

var updateDiv = function() {
  document.getElementById("eintraege").innerHTML = alte_eintraege;
  $('#eintraege').load('velotour_juni_2021_tracking_inhalt.php');
}

var requestServer = function () {
    //alert("requestServer ist gestartet");
    $.ajax({
      url: "./server/velotour_admin/neue_nachricht.php",
      async: true,
      dataType: 'json',
      type: 'GET',
      data: { "alte_eintraege": alte_eintraege }
    })
      .done(function( data, textStatus, jqXHR ) {
        if (data.neue_eintraege > alte_eintraege) {
          alte_eintraege = data.neue_eintraege;
          updateDiv();
        }
      })
      .fail(function( jqXHR, textStatus, errorThrown ) {
        console.log('fail: ', arguments);
      });
}
</script>

</head>
<body onload="requestServer(); hTimer = window.setInterval(requestServer, 10000);">

<div id="eintraege">

<script type="text/javascript">
  $('#eintraege').load('velotour_juni_2021_tracking_inhalt.php');
</script>

</div>
</html>

SERVER:
PHP:
<?php
echo '<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>';

// Erstellen der Datenbankverbindung
include("db_connect_velotour.inc.php");
$link = mysql_connect($host, $user, $pwd)
or die("Leider ist momentan keine Datenbank-Verbindung möglich : " . mysql_error());

// Auswahl der Datenbank
mysql_select_db($dbname, $link);

//Einträge werden gelesen
$erg = mysql_query ("SELECT text, bild_link_1, video FROM eintraege_velotour")
or die("Es konnten leider keine Einträge aus der Datenbank gelesen werden: " . mysql_error());

$neue_eintraege = mysql_num_rows($erg);

if (isset($_GET['alte_eintraege']) ? ((int) $_GET['alte_eintraege']) : 0) {
    $return = (object) array("neue_eintraege" => + $neue_eintraege);
echo json_encode($return);
}

// MySQL-Verbindung schliessen   
mysql_close($link);
?>

Abgeändert habe ich, dass der Wert für die Variable "neue_eintraege" aus der Datenbank gelesen wird.
Leider funktioniert meine Variante nicht.
 
Beim Durchsehen deines neuen Codes fällt mir nur auf, dass hier das Pluszeichen fehl am Platze ist:
$return = (object) array("neue_eintraege" => + $neue_eintraege);
a) müssten es zwei Pluszeichen sein aber
b) würde das jetzt keinen Sinn mehr machen, weil Du ja die Anzahl unverändert übergeben willst.

Unabhängig davon schlage ich folgende Vereinfachungen vor, dann fällt auch das Debuggen leichter:
1. jQuery hast Du schon eingebunden, daher ist dieses:
echo '<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>'; im Serverscript überflüssig.
2. Die Anzahl der Datensätze könntest Du einfacher mit einem COUNT in der Datenbankabfrage lesen. AFAIK muss Mysql aber auch in dem Fall die ganze Tabelle scannen, so dass der Gewinn begrenzt wäre.
3. Du liest zwei Mal die ganze Tabelle aus, zunächst wenn Du die Anzahl ermittelst und dann wenn Du die das HTML generierst. Ich würde das in einer Anfrage an den Server und einem PHP-Skript erledigen, etwa so:
Code:
<html>
<head>

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>

<script type="text/javascript">
var alte_eintraege = 0;

var requestServer = function () {
    //alert("requestServer ist gestartet");
    $.ajax({
      url: "./server/velotour_admin/neue_nachricht.php",
      async: true,
      dataType: 'json',
      type: 'GET',
      data: { "alte_eintraege": alte_eintraege }
    })
      .done(function( data, textStatus, jqXHR ) {
        if (data.neue_eintraege != alte_eintraege) {
          $('#eintraege').html(data.html);
          $alte_eintraege = data.neue_eintraege;
        }
      })
      .fail(function( jqXHR, textStatus, errorThrown ) {
        console.log('fail: ', arguments);
      });
}
</script>

</head>
<body onload="requestServer(); hTimer = window.setInterval(requestServer, 10000);">

<div id="eintraege">
</div>
</html>
Und im Serverscript:
Code:
<?php
echo '<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>';

// Erstellen der Datenbankverbindung
include("db_connect_velotour.inc.php");
$link = mysql_connect($host, $user, $pwd)
or die("Leider ist momentan keine Datenbank-Verbindung möglich : " . mysql_error());

// Auswahl der Datenbank
mysql_select_db($dbname, $link);

//Einträge werden gelesen
$erg = mysql_query ("SELECT text, bild_link_1, video FROM eintraege_velotour ORDER BY id DESC")
or die("Es konnten leider keine Einträge aus der Datenbank gelesen werden: " . mysql_error());

$neue_eintraege = mysql_num_rows($erg);
if (isset($_GET['alte_eintraege']) && $neue_eintraege != $_GET['alte_eintraege']) {
    // die Anzahl der Eintraege hat sich geaendert
    // das HTML in $html bereit stellen
    // ...
    $return = ['neue_eintraege' => $neue_eintraege, 'html' => $html];
} else {
    $return = ['neue_eintraege' => $alte_eintraege, 'html' => ''];
}
echo json_encode($return);

// MySQL-Verbindung schliessen
mysql_close($link);
?>

Ungetestet.
Jetzt ist zwar das Sortieren überflüssig für den Fall, dass es keine Änderung in der Anzahl gibt aber das würde ich für die Vereinfachung in Kauf nehmen.
 
Zuletzt bearbeitet:
Hi,

desweiteren fällt mir auf, dass du nicht immer eine Antwort zurück sendest, da du das JSON innerhalb der if-Bedingung zurückgibst (auch der ternäre Operator als if-Bedingung ist sehr bedenklich).

Die if-Bedingung ist an dieser Stelle ohnehin sinnfrei, da du die Anzahl der neuen Einträge immer zurückgeben möchtest.

Statt
PHP:
if (isset($_GET['alte_eintraege']) ? ((int) $_GET['alte_eintraege']) : 0) {
    $return = (object) array("neue_eintraege" => + $neue_eintraege);
    echo json_encode($return);
}
sollte
PHP:
$return = (object) array("neue_eintraege" => $neue_eintraege);
echo json_encode($return);
reichen.

Zuletzt würde ich dir empfehlen, dir die Antwort von @Sempervivum anzusehen und zu verstehen.

Ciao,
Quaese
 
Hallo zusammen
Zuerst einmal vielen Dank für Eure grosse Hilfe!
Ich habe nun mal echo '<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>'; rausgenommen.
Das doppelte Abfragen der Datenbank habe ich mal so gelassen, im Wissen, dass dies nicht nötig ist.
Der Code sieht nun so aus:

HTML
HTML:
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>

<script type="text/javascript">
var alte_eintraege = 0;

function updateDiv() {
  $('#eintraege').load('velotour_juni_2021_tracking_inhalt.php').hide().fadeIn(1000);
}

var requestServer = function () {
    $.ajax({
      url: "./server/velotour_admin/neue_nachricht.php",
      async: true,
      dataType: 'json',
      type: 'GET',
      data: { "alte_eintraege": alte_eintraege }
    })
      .done(function( data, textStatus, jqXHR ) {
          alert(data.neue_eintraege);
        /*if (data.neue_eintraege != alte_eintraege) {
          $alte_eintraege = data.neue_eintraege;
          updateDiv();*/
        }
      })
      .fail(function( jqXHR, textStatus, errorThrown ) {
        console.log('fail: ', arguments);
      });
}
</script>

</head>
<body onload="requestServer(); hTimer = window.setInterval(requestServer, 10000);">
    
<div id="eintraege">

</div>
</body>
</html>

Bei .done habe ich alert(data.neue_eintraege); eingefügt, um zu schauen, ob überhaupt etwas zurück kommt. Aber die alert-Meldung erscheint nicht. Kann es sein, dass nichts zurück gesendet wird?

Hier noch er Code der php-Datei:
PHP:
<?php
// Erstellen der Datenbankverbindung
include("db_connect_velotour.inc.php");
$link = mysql_connect($host, $user, $pwd)
or die("Leider ist momentan keine Datenbank-Verbindung möglich : " . mysql_error());

// Auswahl der Datenbank
mysql_select_db($dbname, $link);

//Einträge werden gelesen
$erg = mysql_query ("SELECT text, bild_link_1, video FROM eintraege_velotour")
or die("Es konnten leider keine Einträge aus der Datenbank gelesen werden: " . mysql_error());

$neue_eintraege = mysql_num_rows($erg);

$return = (object) array("neue_eintraege" => + $neue_eintraege);
echo json_encode($return);

// MySQL-Verbindung schliessen   
mysql_close($link);
?>
 
Zurück