{"id":1325,"date":"2018-07-05T13:17:15","date_gmt":"2018-07-05T11:17:15","guid":{"rendered":"http:\/\/evileu.de\/zum-schwarzen-pinguin\/?p=1325"},"modified":"2018-11-09T06:23:47","modified_gmt":"2018-11-09T05:23:47","slug":"nummerische-pagination-mit-werten-aus-array-pure-php","status":"publish","type":"post","link":"https:\/\/evileu.de\/zum-schwarzen-pinguin\/2018\/07\/05\/nummerische-pagination-mit-werten-aus-array-pure-php\/","title":{"rendered":"Nummerische Pagination mit Werten aus Array (pure PHP)"},"content":{"rendered":"<p>Das hat jetzt mit WordPress nur noch insofern etwas zu tun, als es einem auch hier mal unterkommen kann, dass die Daten f\u00fcr eine seitenweise nummerierte Ausgabe in Form eines Arrays ankommen und nicht direkt mit SQL aus der Datenbank abgefragt werden. Typischerweise passiert sowas, wenn man \u00fcber eine API auf die Datenbank zugreift und die Ergebnisse der Abfrage als JSON zur\u00fcckgegeben werden. Das kann man mit Hilfe von json_decode() flugs in ein Array umwandeln und mit einem foreach() wie gehabt seitenweise ausgeben. Wenn allerdings die Datens\u00e4tze pro Seite einen Rest ergeben, fliegt PHP bei der letzten Seite auf die Nase und spuckt so etwas aus:<\/p>\n<pre><b>Notice<\/b>: Undefined offset: 334 in\u00a0<b>C:\\xampp\\htdocs\\kleine_api\\err_num_page.php<\/b>\u00a0on line\u00a0<b>74<\/b><\/pre>\n<h2>Die kleine T\u00fccke: der Rest<\/h2>\n<p>Wir haben, sagen wir mal, 334 Datens\u00e4tze. Und wir legen die Anzahl der Datens\u00e4tze pro Seite auf 10 fest. Das gibt 33 ganze Seiten a 10 Datens\u00e4tze, und auf der letzten Seite haben wir nur noch vier Datens\u00e4tze. Da muss man jetzt eine Sonderbehandlung f\u00fcr den Rest einbauen, weil unser Array ja nur einen Index bis 333 zul\u00e4\u00dft &#8211; Offset by one, den 334. Array-Entrag gibt es nicht mehr. Dieses Dilemma hat man nicht, wenn man direkt auf die Datenbank zugreift und mit einem SQL-Limit arbeiten kann, da ist es egal wenn am Ende die Seite nicht ganz voll wird, es gibt keine Fehlermeldung.<\/p>\n<p>Aber, wir arbeiten ja mit einem Array, und da muss man die ganze Logik ein bisschen umstricken. Also, frisch ans Werk!<\/p>\n<h2>Das Array<\/h2>\n<p>&#8230; enth\u00e4lt 334 Kochrezepte und sieht nach einem json_decode in etwa so aus:<\/p>\n<pre>array(1) \r\n{ [\"rezepte\"]=&gt; array(334) {\r\n\u00a0[0]=&gt; array(3) { [\"ID\"]=&gt; string(4) \"1828\" [\"post_title\"]=&gt; string(31) \"Pudding nach Art des Hauses Leu\" [\"post_content\"]=&gt; string(37) \"Vanille oder Schoko oder Johannisbeer\" }\r\n\u00a0[1]=&gt; array(3) { [\"ID\"]=&gt; string(4) \"1827\" [\"post_title\"]=&gt; string(5) \"Milch\" [\"post_content\"]=&gt; string(23) \"reicht nicht bis morgen\" } \r\n\u00a0[2]=&gt; array(3) { [\"ID\"]=&gt; string(4) \"1825\" [\"post_title\"]=&gt; string(14) \"Petersilwurzel\" [\"post_content\"]=&gt; string(29) \"hab ich abgeerntet, ist nicht\" }<\/pre>\n<p>Das hei\u00dft, um beispielsweise an die ID und den Titel eines Datensatzes heranzukommen, muss ich folgende Syntax verwenden:<\/p>\n<pre>$akt_id = $dataObject['rezepte'][<span style=\"color: #008000;\">$i<\/span>]['ID'];\r\n$akt_titel = $dataObject['rezepte'][<span style=\"color: #008000;\">$i<\/span>]['post_title'];<\/pre>\n<p>Das ist jetzt noch nicht weiter tragisch, ich muss nur daran denken dass mein Array bei 0 anf\u00e4ngt, das hei\u00dft bei einer Anzahl Datens\u00e4tze pro Seite von X darf ich nur von 0 bis X-1 ausgeben. Praktisch sieht das z.B.bei 10 Datens\u00e4tzen pro Seite so aus:<\/p>\n<p>Seite 1: Datens\u00e4tze 0&#8230;9<br \/>\nSeite 2: Datens\u00e4tze 10&#8230;19<br \/>\nSeite 3: Datens\u00e4tze 20&#8230;29<br \/>\n&#8230;<br \/>\nletzte Seite: der Rest<\/p>\n<p>Das heisst aber, ich muss f\u00fcr meine ganzen Seiten eine andere Logik anwenden als f\u00fcr die letzte Seite, auf der auch weniger als 10 Datens\u00e4tze stehen k\u00f6nnen.<\/p>\n<p>Aber fangen wir erstmal vorne an:<\/p>\n<h2>Ermitteln der Seitenzahl und des Restes<\/h2>\n<p>Mein Array mit den 334 Datens\u00e4tzen hei\u00dft $dataObject und wurde aus einem JSON in ein Array umgewandelt. Jetzt rechne ich erstmal aus, wieviele ganze Seiten das ergibt, wenn ich hier beispielsweise 10 Datens\u00e4tze pro Seite ausgebe, und welcher Rest bleibt.<\/p>\n<pre>&lt;?php\r\n\r\n\/\/JSON alle Rezepte abholen und in Array umwandeln\r\n$json = file_get_contents('http:\/\/localhost\/kleine_api\/rezepte\/rezeptelesen.php');\r\n$dataObject = json_decode($json,true);\r\n\r\n\/\/Rezepte pro Seite ausrechnen\r\n<span style=\"color: #ff0000;\">$pro_seite = 10; \/\/Wert kann beliebig ge\u00e4ndert werden<\/span>\r\n<span style=\"color: #008000;\">$anzahl<\/span> = count($dataObject['rezepte']);\r\necho \"Datens&amp;auml;tze gesamt = \".$anzahl.\"&lt;br&gt;\";\r\necho \"Das macht \".floor($anzahl\/$pro_seite).\" ganze Seiten\r\n bei \".$pro_seite.\" Rezepten pro Seite, Rest: \".$anzahl%$pro_seite.\"&lt;br&gt;\";<\/pre>\n<p>Ich habe mit Absicht eine sehr geschw\u00e4tzige echo-Ausgabe eingebaut, zur besseren Kontrolle. Der Output sieht jetzt mal so aus:<\/p>\n<div id=\"attachment_1327\" style=\"width: 622px\" class=\"wp-caption alignnone\"><img aria-describedby=\"caption-attachment-1327\" decoding=\"async\" loading=\"lazy\" class=\"size-full wp-image-1327\" src=\"http:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-content\/uploads\/2018\/07\/echo_kennzahlen.jpg\" alt=\"echo_kennzahlen\" width=\"612\" height=\"129\" srcset=\"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-content\/uploads\/2018\/07\/echo_kennzahlen.jpg 612w, https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-content\/uploads\/2018\/07\/echo_kennzahlen-300x63.jpg 300w\" sizes=\"(max-width: 612px) 100vw, 612px\" \/><p id=\"caption-attachment-1327\" class=\"wp-caption-text\">echo_kennzahlen<\/p><\/div>\n<p>Damit kann ich mir jetzt schon mal die Buttons f\u00fcr die einzelnen Seiten zusammenbauen. Das mache ich wieder mit einem Formular. Ich z\u00e4hle mein i von Seite 1 bis zur letzten Seite inklusive hoch, als Value kriegt jeder Button den aktuellen Wert von i. Ausserdem kriegt jeder Button noch eine ID, die brauchen wir sp\u00e4ter noch.<\/p>\n<pre>\/\/Formular mit Buttons f\u00fcr die Seitenzahlen, Start 1, Ende: n\u00e4chsth\u00f6here Ganzzahl\r\nfor ($i=1; $i &lt;=ceil($anzahl\/$pro_seite); $i++){\r\n\u00a0\u00a0 \u00a0echo \"&lt;form action = 'array_num_page.php' method = 'get'&gt;\";\r\n\u00a0\u00a0\u00a0 echo <span style=\"color: #ff0000;\">\"&lt;input type='submit' id='el_num_button_\".$i.\"' name=akt_i value='\".$i.\"'&gt;\";<\/span>\r\n}\r\necho \"&lt;\/form&gt;\";<\/pre>\n<p>Das sieht jetzt schonmal so aus:<\/p>\n<div id=\"attachment_1328\" style=\"width: 1003px\" class=\"wp-caption alignnone\"><img aria-describedby=\"caption-attachment-1328\" decoding=\"async\" loading=\"lazy\" class=\"size-full wp-image-1328\" src=\"http:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-content\/uploads\/2018\/07\/buttons.jpg\" alt=\"buttons\" width=\"993\" height=\"150\" srcset=\"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-content\/uploads\/2018\/07\/buttons.jpg 993w, https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-content\/uploads\/2018\/07\/buttons-300x45.jpg 300w, https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-content\/uploads\/2018\/07\/buttons-768x116.jpg 768w, https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-content\/uploads\/2018\/07\/buttons-624x94.jpg 624w\" sizes=\"(max-width: 993px) 100vw, 993px\" \/><p id=\"caption-attachment-1328\" class=\"wp-caption-text\">buttons<\/p><\/div>\n<p>Jetzt gehts daran zu ermitteln, welche Seite gerade aktuell ist. Ich starte als Default mit der 1, und je nachdem welchen Button der Anwender angeklickt hat hole ich mir den Wert aus dem Formular.<\/p>\n<pre>\/\/Checken ob eine Seite geklickt wurde\r\n$seitenstart=1;\r\nif (isset($_GET['akt_i'])){\r\n\u00a0\u00a0 \u00a0$seitenstart = $_GET['akt_i'];\r\n\u00a0\u00a0 \u00a0}else{\r\n\u00a0\u00a0 \u00a0$seitenstart=1;\r\n\u00a0\u00a0 \u00a0}\r\n\/\/versteckte Ausgabe f\u00fcr farbige Markierung der aktuellen Seite mit Script\u00a0\u00a0 \u00a0\r\necho \"&lt;div id ='seitenstart' style='display:none;'&gt;\".$seitenstart.\"&lt;\/div&gt;\";<\/pre>\n<p>Meinen Seitenstart schreibe ich mir noch in eine versteckte Div, die brauche ich nachher f\u00fcr die farbige Markierung der aktuellen Seite.<\/p>\n<p>Jetzt gehts erst mal an die Ausgabe.<\/p>\n<h2>Die ganzen Seiten<\/h2>\n<p>Hier darf ich nur bis zur letzten ganzen Seite hochz\u00e4hlen, die letzte Seite mit den weniger Datens\u00e4tzen kommt sp\u00e4ter dran:<\/p>\n<pre>\/\/Ausgabe aller ganzen Seiten von 1 bis zum letzten ganzzahligen Vielfachen\r\nif (($seitenstart &gt; 0) and (<span style=\"color: #ff0000;\">$seitenstart &lt; floor($anzahl\/$pro_seite)<\/span>)){\r\n\r\n\/\/Tabelle f\u00fcr Ausgabe aller Rezepte zusammenbauen\r\necho \"&lt;table border : 1px&gt;\";\r\necho \"&lt;th&gt;ID&lt;\/th&gt;&lt;th&gt;Titel&lt;\/th&gt;&lt;th&gt;Content&lt;\/th&gt; \r\n\/*Ausgabe als Tabelle*\/<\/pre>\n<p>Jetzt wird es ein bisschen knifflig. Ich bleibe mal bei einem Wert pro Seite von 10 Datens\u00e4tzen, es klappt aber auch mit jedem anderen Wert.<\/p>\n<p>Auf Seite eins muss ich bei 0 anfangen und bis eins weniger als die Anzahl der Datens\u00e4tze pro Seite hochz\u00e4hlen, also bis 9. Auf Seite zwei muss ich bei 10 anfangen und bis 19 hochz\u00e4hlen, usw.:<\/p>\n<pre>\/\/Bei 0 anfangen, bis max. eins weniger als die Anzahl der ganzen Seiten hochz\u00e4hlen (0..9, 10..19 usw...)\r\nfor ($i=($seitenstart-1)*$pro_seite; $i &lt;= $pro_seite*$seitenstart-1; $i++){<\/pre>\n<p>Die ganze for-Schleife mit der Ausgabe der einzelnen Werte aus dem Array in Tabellenzeilen sieht so aus:<\/p>\n<pre>\/\/Bei 0 anfangen, bis max. eins weniger als die Anzahl der ganzen Seiten hochz\u00e4hlen (0..9, 10..19 usw...)\r\nfor ($i=($seitenstart-1)*$pro_seite; $i &lt;= $pro_seite*$seitenstart-1; $i++){\r\n\r\necho \"&lt;tr&gt;\";\r\n\/\/Werte aus dem Array auf Var. legen\r\n$akt_id = $dataObject['rezepte'][<span style=\"color: #ff0000;\">$i<\/span>]['ID'];\r\n$akt_titel = $dataObject['rezepte'][<span style=\"color: #ff0000;\">$i<\/span>]['post_title'];\r\n\/\/Content tags raus und auf 100 Zeichen k\u00fcrzen\r\n$akt_content = substr(strip_tags($dataObject['rezepte'][<span style=\"color: #ff0000;\">$i<\/span>]['post_content']),0,200);\r\n\r\necho \"&lt;td&gt;\".$akt_id.\"&lt;\/td&gt;&lt;td&gt;\".$akt_titel.\"&lt;\/td&gt;&lt;td&gt;\".$akt_content.\"&lt;\/td&gt;\";\r\necho \"&lt;\/tr&gt;\";\r\n}<\/pre>\n<p>Damit haben wir die Ausgabe aller ganzen Seiten erledigt. Jetzt k\u00fcmmern wir uns um den Rest. Da nehmen wir nur noch die Indizes aus dem Array, die gr\u00f6sser als der letzte Wert vor dem letzten ganzzahligen Vielfachen der Seitenzahl sind, und marschieren nach oben durch bis 1 vor der Gesamtzahl der Datens\u00e4tze.<\/p>\n<pre>\/\/****Ausgabe Rest wenn Seitenzahl gr\u00f6sser als das letzte ganzzahlige Vielfache ist\r\nif($seitenstart &gt; floor($anzahl\/$pro_seite)){\r\n...\r\n\r\n\/\/starten beim letzten ganzzahligen Vielfachen der Gesamt-Seitenzahl, \r\n\/\/stoppen eins unter Gesamtzahl\r\nfor ($i=floor($anzahl\/$pro_seite)*$pro_seite; $i &lt; $anzahl; $i++){<\/pre>\n<p>Voila, das wars! Der ganze Code mit Ausgabe der Tabelle sieht so aus:<\/p>\n<pre>\/\/**************************Ausgabe Rest wenn Seitenzahl gr\u00f6sser als das letzte ganzzahlige Vielfache ist\r\nif($seitenstart &gt; floor($anzahl\/$pro_seite)){\r\n\u00a0\u00a0 \u00a0\r\n\r\n\/\/Tabelle f\u00fcr Ausgabe des Rests zusammenbauen\r\necho \"&lt;table border : 1px&gt;\";\r\necho \"&lt;th&gt;ID&lt;\/th&gt;&lt;th&gt;Titel&lt;\/th&gt;&lt;th&gt;Content&lt;\/th&gt;\";\r\n\r\n\/\/starten beim letzten ganzzahligen Vielfachen der Gesamt-Seitenzahl, stoppen eins unter Gesamtzahl\r\nfor ($i=floor($anzahl\/$pro_seite)*$pro_seite; $i &lt; $anzahl; $i++){\r\n\r\necho \"&lt;tr&gt;\";\r\n\/\/Werte aus dem Array auf Var. legen\r\n$akt_id = $dataObject['rezepte'][$i]['ID'];\r\n$akt_titel = $dataObject['rezepte'][$i]['post_title'];\r\n\/\/Content tags raus und auf 100 Zeichen k\u00fcrzen\r\n$akt_content = substr(strip_tags($dataObject['rezepte'][$i]['post_content']),0,200);\r\n\r\necho \"&lt;td&gt;\".$akt_id.\"&lt;\/td&gt;&lt;td&gt;\".$akt_titel.\"&lt;\/td&gt;&lt;td&gt;\".$akt_content.\"&lt;\/td&gt;\";\r\necho \"&lt;\/tr&gt;\";\r\n}\r\necho \"&lt;\/table&gt;\";\r\n\u00a0\u00a0 \u00a0\r\n}<\/pre>\n<h2>Noch ein Javascript-Zuckerl: aktuelle Seite farbig markieren<\/h2>\n<p>Ich hab mir ja zu jedem Seitenzahl-Button eine ID generiert, das sah so aus:<\/p>\n<pre>echo <span style=\"color: #000000;\">\"&lt;input type='submit' <span style=\"color: #ff0000;\">id='el_num_button_\".$i.\"'<\/span> name=akt_i value='\".$i.\"'&gt;\";<\/span><\/pre>\n<p>Und ich habe mir den Wert der aktuellen Seite (default 1) in eine versteckte div geschrieben:<\/p>\n<pre>\/\/versteckte Ausgabe f\u00fcr farbige Markierung der aktuellen Seite mit Script\u00a0\u00a0 \u00a0\r\necho \"&lt;div id ='seitenstart' style='display:none;'&gt;\".$seitenstart.\"&lt;\/div&gt;\";<\/pre>\n<p>Damit habe ich mir ein kleines Javascripterl gebastelt, das die aktuelle Seite farbig markiert:<\/p>\n<pre>&lt;script&gt;\r\n\r\n\u00a0\u00a0 \u00a0$(document).ready(function() {\r\n\u00a0\u00a0\u00a0 var <span style=\"color: #ff0000;\">dieid<\/span> = document.getElementById('seitenstart').innerHTML;\r\n\u00a0\u00a0 \u00a0\/\/alert(dieid);\r\n\u00a0\u00a0 \u00a0document.getElementById('el_num_button_'<span style=\"color: #ff0000;\">+dieid<\/span>).style.backgroundColor = \"lightgreen\";\r\n\u00a0\u00a0\u00a0 }); \r\n\r\n\r\n&lt;\/script&gt;<\/pre>\n<p>Ich klaube mir die aktuelle Seitenzahl aus der verstecken Div und spreche damit die zugeh\u00f6rige Button-ID an, die style ich mir nach Belieben, das war auch schon alles. H\u00fcbscher kleiner Effekt!<\/p>\n<div id=\"attachment_1329\" style=\"width: 1025px\" class=\"wp-caption alignnone\"><img aria-describedby=\"caption-attachment-1329\" decoding=\"async\" loading=\"lazy\" class=\"size-full wp-image-1329\" src=\"http:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-content\/uploads\/2018\/07\/seite_farbig.jpg\" alt=\"seite_farbig\" width=\"1015\" height=\"297\" srcset=\"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-content\/uploads\/2018\/07\/seite_farbig.jpg 1015w, https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-content\/uploads\/2018\/07\/seite_farbig-300x88.jpg 300w, https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-content\/uploads\/2018\/07\/seite_farbig-768x225.jpg 768w, https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-content\/uploads\/2018\/07\/seite_farbig-624x183.jpg 624w\" sizes=\"(max-width: 1015px) 100vw, 1015px\" \/><p id=\"caption-attachment-1329\" class=\"wp-caption-text\">seite_farbig<\/p><\/div>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Das hat jetzt mit WordPress nur noch insofern etwas zu tun, als es einem auch hier mal unterkommen kann, dass die Daten f\u00fcr eine seitenweise nummerierte Ausgabe in Form eines Arrays ankommen und nicht direkt mit SQL aus der Datenbank abgefragt werden. Typischerweise passiert sowas, wenn man \u00fcber eine API auf die Datenbank zugreift und [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[1,11,47,4,59],"tags":[],"_links":{"self":[{"href":"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-json\/wp\/v2\/posts\/1325"}],"collection":[{"href":"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-json\/wp\/v2\/comments?post=1325"}],"version-history":[{"count":3,"href":"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-json\/wp\/v2\/posts\/1325\/revisions"}],"predecessor-version":[{"id":1331,"href":"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-json\/wp\/v2\/posts\/1325\/revisions\/1331"}],"wp:attachment":[{"href":"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-json\/wp\/v2\/media?parent=1325"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-json\/wp\/v2\/categories?post=1325"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-json\/wp\/v2\/tags?post=1325"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}