"Christmas - the time to fix the computers of your loved ones" « Lord Wyrm

[PHP] pro teil-Timestamp eine eigene Tabelle

UnleashThebeast 11.02.2018 - 14:40 18284 7
Posts

UnleashThebeast

Mr. Midlife-Crisis
Avatar
Registered: Dec 2005
Location: 127.0.0.1
Posts: 3545
Hallo,

folgendes Script liest mir Sachen aus einer MySQL Datenbank aus und erstellt dann eine Tabelle.
Code: PHP
<!DOCTYPE html>
<?php include "dbconnect.php" ?>
<html lang="de">
  <head>
	<meta charset="utf-8" />
	<meta name="viewport" content="width=device-width, initial-scale=1.0" />
	<title>UPC Speedtest</title>
	<link rel="stylesheet" href="styles.css">
  </head>
  <body>
	<table>
		<tbody>
			<tr>
				<th>Timestamp</th>
				<th>Ping (ms)</th>
				<th>Download<br />(MBit/s)</th>
				<th>Upload<br />(MBit/s)</th>
				<th>Server</th>
			</tr>
		<?php
			include "table.php";
		?>
		</tbody>
	</table>
  </body>
</html>

Code: PHP
<?php

// connect to MySQL
$conn = new mysqli($db_host, $db_user, $db_passwd, $db_name);
// check connection
if ($conn->connect_error) {
    die("Connection failed: " . $conn->connect_error);
} 


$sql = "SELECT timestamp, ping, download, upload, server FROM $db_table ORDER BY timestamp desc";
$result = $conn->query($sql);

if ($result->num_rows > 0) {
    // output data of each row
    while($row = $result->fetch_assoc()) {
		// if $download is lower than 80 give the row a special class
		if ((int) $row["download"] < 80) {
			echo "
			<tr>
				<td>".$row["timestamp"]."</td>
				<td class=\"shortnumber\">".$row["ping"]."</td>
				<td class=\"shortnumber lownumber\">".$row["download"]."</td>
				<td class=\"shortnumber\">".$row["upload"]."</td>
				<td>".$row["server"]."</td>
			</tr>";
		}
		// if its not under 80 print as normal
		else {
			echo "
				<tr>
					<td>".$row["timestamp"]."</td>
					<td class=\"shortnumber\">".$row["ping"]."</td>
					<td class=\"shortnumber\">".$row["download"]."</td>
					<td class=\"shortnumber\">".$row["upload"]."</td>
					<td>".$row["server"]."</td>
				</tr>";
		}
    }
}

else {
    echo "0 results";
}
$conn->close();
?>

Da aber nun sehr viele Daten kommen und die Tabelle relativ lang wird, hätte ich gerne pro YYYY-MM-DD vom Timestamp eine eigene <table>. Ich kenn mich leider mit PHP quasi garned aus, der Code oben hat ca 10 Stunden geschluckt, bis er endlich funktioniert hat... Kann jemand helfen? Auch mein Google-Fu lässt mich hier irgendwie im Stich.

der timestamp kommt als YYYY-MM-DD HH:MM:SS, siehe:
capture_228755.png
Bearbeitet von UnleashThebeast am 11.02.2018, 14:44

Obermotz

Fünfzylindernazi
Avatar
Registered: Nov 2002
Location: OÖ/RI
Posts: 5262
Vor der while-Schleife machst du eine Variable
$actDay = date('d', $row["timestamp"]);

Dann machst du in der Schleife ein if, das abfragt, ob der aktuelle Tag der gleiche ist wie der gespeicherte - falls ja, gibst du den Tabellenkopf aus (also neue Tabelle).
Am Ende der Schleife ueberschreibst du actDay mit dem aktuellen Wert.

Du koenntest btw. dein if ((int) $row["download"] < 80) - Konstrukt deutlich kleiner machen, da nur eine einzige Zeile unterschiedlich ist im if und else-Zweig.

Weiters am besten prepared Statements verwenden fuer die SQL-Abfrage.

UnleashThebeast

Mr. Midlife-Crisis
Avatar
Registered: Dec 2005
Location: 127.0.0.1
Posts: 3545
Sorry, hab das letzte Mal vor ~20 Jahren was "gecodet", und das war QBasic in der Schule... Ich schau mal :D.

kleinerChemiker

Here to stay
Avatar
Registered: Feb 2002
Location: Wien
Posts: 4282
Willst du überhaupt alle Daten? Falls nicht, kannst du bei der Abfrage ein LIMIT anhängen.

Falls du alle Daten willst, verstehe ich nicht den Vorteil, mehrere Tabellen zu haben.

In welcher Form ist der Timestamp gespeichert?

Im Grunde den Tag (mittels date()) in einer Variablen speichern. Dann überprüfen ob der Tag in der aktuellen Schleife derselbe ist, wie in der Variablen gespeichert. Wenn nicht -> echo </table><table>

UnleashThebeast

Mr. Midlife-Crisis
Avatar
Registered: Dec 2005
Location: 127.0.0.1
Posts: 3545
Ich will schon alle Daten haben, aber wenn die pro Tag in einer eigenen Tabelle sind, kann ich zB die Tabellen vom nicht-aktuellen Tag einfach (lol) per JS ausblenden / einklappen.

Timestamp kommt als YYYY-MM-DD HH:MM:SS. Vielleicht wäre es intelligenter gewesen, für Tag und Uhrzeit getrennte Spalten in der DB zu machen :S.

das if-Konstrukt hab ich jetzt bisschen "optimiert".
Code: PHP
if ($result->num_rows > 0) {
    // output data of each row
    while($row = $result->fetch_assoc()) {
		//create table rows
			echo "
				<tr>
					<td>".$row["timestamp"]."</td>
					<td class=\"shortnumber\">".$row["ping"]."</td>
			";
				// if $download is lower than 80 give the row a special class
				if ((int) $row["download"] < 80) {
					echo "
						<td class=\"shortnumber lownumber\">".$row["download"]."</td>
					";
				}
				// if its not under 80 print as normal
				else {
					echo "
							<td class=\"shortnumber\">".$row["download"]."</td>
					";
				}
			echo "
					<td class=\"shortnumber\">".$row["upload"]."</td>
					<td>".$row["server"]."</td>
				</tr>
			";
    }
}

//edit: und oh wow, prepared statements sind eine riesen Dose Würmer für mich, das zerfickt mir meinen Kopf ein bisschen tbh. ISt das wirklich wichtig, die zu benutzen, wenn ich kein Formular habe, mit dem Werte übergeben werden können?
Bearbeitet von UnleashThebeast am 11.02.2018, 15:19

mat

Administrator
Legends never die
Avatar
Registered: Aug 2003
Location: nö
Posts: 25423
Am einfachsten ist es, wenn du in PHP mit UNIX Timestamp arbeitest. Wenn die Performance des Queries egal ist, dann mach folgendes:

SELECT UNIX_TIMESTAMP(timestamp) AS timestamp FROM table ORDER BY timestamp

Schneller ist es, wenn du die Rows gleich als UNIX Timestamp in den Table abspeicherst (einfach als Integer, wenn du ein ORDER im Query auf die Spalte hast, dann einen Index setzen).

Die Trennung in Tagen ist mit einem UNIX Timestamp dann relativ einfach. Du machst dir einfach ein assoziatives Array aus den Query-Daten:

Code: PHP
$sorted = array();

while($row = $result->fetch_assoc())
{
    $daykey = date('d.m.Y',$row['timestamp']);

    if (!array_key_exists($daykey,$sorted))
        $sorted[$daykey] = array();

    $sorted[$daykey][] = $row;
}

Jetzt kannst du deine Tabellen pro Tag auflisten lassen und entsprechend stylen:

Code: PHP
$today = date('d.m.Y');

foreach ($sorted as $day)
{
    foreach ($day as $daykey => $entry)
    {
        if ($daykey == $today)
            echo "Show open table from today");
        else
            echo "Show closed table from $daykey";
    }
}

mat

Administrator
Legends never die
Avatar
Registered: Aug 2003
Location: nö
Posts: 25423
Zitat aus einem Post von UnleashThebeast
//edit: und oh wow, prepared statements sind eine riesen Dose Würmer für mich, das zerfickt mir meinen Kopf ein bisschen tbh. ISt das wirklich wichtig, die zu benutzen, wenn ich kein Formular habe, mit dem Werte übergeben werden können?
Nein, prepared Statements können nur einen Overhead vom Query entfernen, weil sie bereits vorgeparsed sind. Das ist eine reine Performance-Sache, die oft wiederholte Queries trotz unterschiedlichen Parametern schneller machen können. Das brauchst du derzeit garantiert nicht. ;)

Snoop

Here to stay
Registered: Jun 2002
Location: Gablitz
Posts: 1088
nachdem die results bereits nach timestamp sortiert rauskommen würde ich keine zwei schleifen basteln, weils mMn. unnötig wäre.
Code: PHP
<?php

// connect to MySQL
$conn = new mysqli($db_host, $db_user, $db_passwd, $db_name);
// check connection
if ($conn->connect_error) {
    die("Connection failed: " . $conn->connect_error);
}


$sql = "SELECT timestamp, ping, download, upload, server FROM $db_table ORDER BY timestamp desc";
$result = $conn->query($sql);

if ($result->num_rows > 0) {
    // output data of each row
    $temp_current_day = 0;
    while ($row = $result->fetch_assoc()) {
     $date = date("d.m.Y", strtotime($row['timestamp']));

        if ($date !== $temp_current_day) { ?>
            <table>
        <?php } ?>
        <tr>
            <td><?php echo $row["timestamp"]; ?></td>
            <td class="shortnumber <?php echo ($row["download"] < 80) ? 'lownumber' : ''; ?>"><?php echo $row["download"]; ?></td>
            <td class="shortnumber"><?php echo $row["upload"]; ?></td>
            <td><?php echo $row["server"]; ?></td>
        </tr>
        <?php if ($date !== $temp_current_day) { ?>
            </table>
            <?php
            $temp_current_day = $date;

        }
    }
}
Bearbeitet von Snoop am 11.02.2018, 16:11
Kontakt | Unser Forum | Über overclockers.at | Impressum | Datenschutz