{"id":1332,"date":"2018-07-05T15:20:57","date_gmt":"2018-07-05T13:20:57","guid":{"rendered":"http:\/\/evileu.de\/zum-schwarzen-pinguin\/?p=1332"},"modified":"2018-11-09T06:23:47","modified_gmt":"2018-11-09T05:23:47","slug":"alphabetische-paginierung-aus-array-die-tuecken-des-php-sort","status":"publish","type":"post","link":"https:\/\/evileu.de\/zum-schwarzen-pinguin\/2018\/07\/05\/alphabetische-paginierung-aus-array-die-tuecken-des-php-sort\/","title":{"rendered":"Alphabetische Paginierung aus Array: die T\u00fccken des PHP-sort()"},"content":{"rendered":"<p>Eigentlich hats mich ja nur interessiert, ob das recht aufwendig ist, aber das hielt sich in Grenzen, deswegen mach ich es noch der Vollst\u00e4ndigkeit halber. Voraussetzung ist wie im letzten Beitrag, dass die auszugebenden Daten in Form eines Arrays vorliegen, ich nehme wieder meine 334 Kochrezepte als JSON, so wie <a href=\"http:\/\/evileu.de\/zum-schwarzen-pinguin\/2018\/07\/05\/nummerische-pagination-mit-werten-aus-array-pure-php\/\">im letzten Beitrag zur nummerischen Pagination<\/a>. Nach dem json_decode sieht die Struktur des Arrays wie gehabt wie folgt 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>Jetzt interessieren mich aber eigentlich nur die post_title, die krieg ich mit:<\/p>\n<pre>$akt_titel = $dataObject['rezepte'][<span style=\"color: #ff0000;\">$i<\/span>]['post_title'];<\/pre>\n<p>Und die Titel der Rezepte m\u00f6chte ich nach Buchstaben seitenweise sortiert ausgeben. Also, pack&#8217;mas.<\/p>\n<h2>Das Formular mit den Buttons<\/h2>\n<p>Daf\u00fcr f\u00fclle ich mir erst einmal ein Array mit den Buchstaben a-z, daraus baue ich dann das Formular:<\/p>\n<pre>\/\/Buchstaben a-z in Array schreiben\r\n$letters = array();\r\nfor ($i = 'a', $j = 1; $j &lt;= 26; $i++, $j++) {\r\n\u00a0\u00a0\u00a0 $letters[$j] = $i;\u00a0\u00a0 \u00a0\r\n}\r\n\/\/Formular mit Buttons a-z erzeugen\r\necho \"&lt;form action = '#' method = 'post'&gt;\";\r\n\r\nfor ($i=1; $i &lt;=26; $i++){\r\n\u00a0\u00a0\u00a0 echo \"&lt;input type='submit' id='el_button' name='\".$letters<span style=\"color: #ff0000;\">[$i]<\/span>.\"' value='\".$letters<span style=\"color: #ff0000;\">[$i]<\/span>.\"'&gt;\";\r\n}\r\n\u00a0\u00a0\u00a0 echo \"&lt;\/form&gt;\";<\/pre>\n<p>Das sieht jetzt erstmal so aus:<\/p>\n<div id=\"attachment_1333\" style=\"width: 630px\" class=\"wp-caption alignnone\"><img aria-describedby=\"caption-attachment-1333\" decoding=\"async\" loading=\"lazy\" class=\"size-full wp-image-1333\" src=\"http:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-content\/uploads\/2018\/07\/alfa_buttons.jpg\" alt=\"alfa_buttons\" width=\"620\" height=\"105\" srcset=\"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-content\/uploads\/2018\/07\/alfa_buttons.jpg 620w, https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-content\/uploads\/2018\/07\/alfa_buttons-300x51.jpg 300w\" sizes=\"(max-width: 620px) 100vw, 620px\" \/><p id=\"caption-attachment-1333\" class=\"wp-caption-text\">alfa_buttons<\/p><\/div>\n<p>Dann ermittle ich, welcher Buchstabe angeklickt wurde, und rufe mit diesem Buchstaben als Parameter meine Ausgabefunktion auf:<\/p>\n<pre>\/\/Ermitteln welcher Buchstabe angeklickt wurde und Ausgabefunktion aufrufen\r\nfor ($j = 1; $j &lt;= 26; $j++){\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 if (isset($_POST[''.$letters[$j].''])){\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 return <span style=\"color: #ff0000;\">el_aufruf<\/span>(\"\".$letters[$j].\"\");\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0\u00a0 }<\/pre>\n<p>In der Ausgabefunktion hole ich mir mein Array mit allen Daten, steppe es ganz durch und picke mir mit dem if nur die Eintr\u00e4ge heraus, wo der post_title mit dem als Parameter \u00fcbergebenen Buchstaben anf\u00e4ngt. Diese werden mit array_push einer nach dem anderen an mein Hilfsarray $ausgabe angeh\u00e4ngt.<\/p>\n<pre>function el_aufruf($stabe){\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0 \u00a0\/\/JSON alle Rezepte abholen und in Array umwandeln\r\n\u00a0\u00a0 \u00a0$json = file_get_contents('http:\/\/localhost\/kleine_api\/rezepte\/rezeptelesen.php');\r\n\u00a0\u00a0 \u00a0$dataObject = json_decode($json,true);\r\n\u00a0\u00a0 \u00a0<span style=\"color: #008000;\">$anzahl<\/span> = count($dataObject['rezepte']);\r\n\u00a0\u00a0 \u00a0echo \"Rezepte insgesamt = \".$anzahl.\"&lt;br&gt;\";\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0\u00a0 <span style=\"color: #ff0000;\">\/\/Hilfsarray f\u00fcr Ausgabe\u00a0\u00a0\u00a0 \u00a0<\/span>\r\n<span style=\"color: #ff0000;\">\u00a0\u00a0 \u00a0$ausgabe = array();<\/span>\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 for ($i=0; <span style=\"color: #008000;\">$i&lt;$anzahl<\/span>; $i++){\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \/\/Ersten Buchstaben vergleichen\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 if (strtoupper(substr(($dataObject['rezepte'][$i]['post_title']), 0, 1))== strtoupper($stabe)){\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\/\/Hilfsarray mit Titeln zum aktuellen Buchstaben f\u00fcllen\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0<span style=\"color: #ff0000;\">array_push<\/span>(<span style=\"color: #ff0000;\">$ausgabe<\/span>, $dataObject['rezepte'][$i]['post_title']);\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0}\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }<\/pre>\n<p>Das Hilfsarray sortiere ich mir noch mit dem einfachen sort() und gebe es zeilenweise aus:<\/p>\n<pre>\/\/Array sortieren und ausgeben\r\n\u00a0\u00a0 \u00a0sort($ausgabe);\r\n\u00a0\u00a0\u00a0 foreach($ausgabe as $out){\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0echo $out.\"&lt;br&gt;\";\r\n\u00a0\u00a0 \u00a0}\r\n} \/\/end function el_aufruf<\/pre>\n<p>Die Ausgabe sieht dann beispielsweise so aus:<\/p>\n<div id=\"attachment_1334\" style=\"width: 625px\" class=\"wp-caption alignnone\"><img aria-describedby=\"caption-attachment-1334\" decoding=\"async\" loading=\"lazy\" class=\"size-full wp-image-1334\" src=\"http:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-content\/uploads\/2018\/07\/buchstabe_c.jpg\" alt=\"buchstabe_c\" width=\"615\" height=\"417\" srcset=\"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-content\/uploads\/2018\/07\/buchstabe_c.jpg 615w, https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-content\/uploads\/2018\/07\/buchstabe_c-300x203.jpg 300w\" sizes=\"(max-width: 615px) 100vw, 615px\" \/><p id=\"caption-attachment-1334\" class=\"wp-caption-text\">buchstabe_c<\/p><\/div>\n<h2>Kleiner Pferdefu\u00df: die Umlauts und Sonderzeichen<\/h2>\n<p>Der PHP sort() ist nicht dazu zu bewegen, die deutschen Umlaute anderswo als am Ende einer Liste nach dem Buchstaben Z einzusortieren. Auch Sonderzeichen wie z.B. mit Accents (B\u00e9chamel) landen gnadenlos am Ende. Das sieht man ganz deutlich am Ende der Liste zum Buchstaben B:<\/p>\n<div id=\"attachment_1335\" style=\"width: 411px\" class=\"wp-caption alignnone\"><img aria-describedby=\"caption-attachment-1335\" decoding=\"async\" loading=\"lazy\" class=\"size-full wp-image-1335\" src=\"http:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-content\/uploads\/2018\/07\/buchstabe_b.jpg\" alt=\"buchstabe_b\" width=\"401\" height=\"448\" srcset=\"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-content\/uploads\/2018\/07\/buchstabe_b.jpg 401w, https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-content\/uploads\/2018\/07\/buchstabe_b-269x300.jpg 269w\" sizes=\"(max-width: 401px) 100vw, 401px\" \/><p id=\"caption-attachment-1335\" class=\"wp-caption-text\">buchstabe_b<\/p><\/div>\n<p>Da m\u00fcsste man jetzt hingehen und eine eigene sort-Funktion schreiben, die aus den deutschen Umlauts Diphtonge mach (\u00e4=ae, \u00f6=oe&#8230;) und erst danach sortieren, vor der Ausgabe aber die Umlaute wieder einsetzen. Ach n\u00f6 Leute, das ist mir echt zu stressig. Ich lebe mal mit der Ausgabe der Umlaute am Ende, vielleicht begegnet mir ja beim Googlen noch irgendwo eine elegantere L\u00f6sung.<\/p>\n<h2>Und prompt hab ich was gefunden: Sortierung der Umlauts wie im Telefonbuch<\/h2>\n<p>Auf der Webseite von Marco Krings habe ich folgende interessante Sortierfunktion gefunden:<\/p>\n<p><a href=\"http:\/\/www.marcokrings.de\/arrays-sortieren-mit-umlauten\/\">http:\/\/www.marcokrings.de\/arrays-sortieren-mit-umlauten\/<\/a><\/p>\n<p>Er arbeitet mit zwei Arrays f\u00fcr die Umlaute und die entsprechenden Diphtonge. Diese Arrays k\u00f6nnte man jetzt noch um die Accent-Zeichen wie z.B. \u00e9 erg\u00e4nzen, ich hab das mal ausprobiert:<\/p>\n<pre>$aSearch\u00a0\u00a0 = array(\"\u00c4\",\"\u00e4\",\"\u00d6\",\"\u00f6\",\"\u00dc\",\"\u00fc\",\"\u00df\",\"-\",<span style=\"color: #ff0000;\">\"\u00e9\"<\/span>);\r\n\u00a0\u00a0\u00a0 $aReplace\u00a0 = array(\"Ae\",\"ae\",\"Oe\",\"oe\",\"Ue\",\"ue\",\"ss\",\" \",<span style=\"color: #ff0000;\">\"e\"<\/span>);<\/pre>\n<p>Funktioniert eins a!<\/p>\n<p>Meine Ausgabe wird jetzt noch um Marcos Funktion ArraySort() erweitert:<\/p>\n<pre>\/\/Array sortieren und ausgeben\r\n\u00a0\u00a0 \u00a0\/\/sort($ausgabe);\r\n\u00a0\u00a0 \u00a0$umlauts = <span style=\"color: #ff0000;\">ArraySort<\/span>($ausgabe);\r\n\u00a0\u00a0\u00a0 foreach($umlauts as $out){\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0echo $out.\"&lt;br&gt;\";\r\n\u00a0\u00a0 \u00a0}<\/pre>\n<p>Jetzt pa\u00dft die Sache. die Umlaute und das \u00e9 werden richtig einsortiert:<\/p>\n<div id=\"attachment_1339\" style=\"width: 491px\" class=\"wp-caption alignnone\"><img aria-describedby=\"caption-attachment-1339\" decoding=\"async\" loading=\"lazy\" class=\"size-full wp-image-1339\" src=\"http:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-content\/uploads\/2018\/07\/e_accent.jpg\" alt=\"e_accent\" width=\"481\" height=\"447\" srcset=\"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-content\/uploads\/2018\/07\/e_accent.jpg 481w, https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-content\/uploads\/2018\/07\/e_accent-300x279.jpg 300w\" sizes=\"(max-width: 481px) 100vw, 481px\" \/><p id=\"caption-attachment-1339\" class=\"wp-caption-text\">e_accent<\/p><\/div>\n<p>Das ist ausbauf\u00e4hig! Vielen Dank an Marco f\u00fcr die geniale Vorlage.<\/p>\n<h2>Nachtrag: woher nehm ich jetzt die ID?<\/h2>\n<p>Ich habe in meiner alfabetischen Ausgabe bis jetzt nur die Titel der Rezepte verarbeitet, das reicht aber unter Umst\u00e4nden nicht. F\u00fcr manche Zwecke w\u00e4re es schick, wenn man auch noch die ID mitnehmen k\u00f6nnte, zum Beispiel in WordPress f\u00fcr die Ausgabe des Permalinks. Man k\u00f6nnte jetzt auf die Idee kommen, in der for-Schleife den array_push umzustricken, so dass ein mehrdimensionales Array mit Titel und ID aufgebaut wird&#8230; ja Pustekuchen, dann f\u00e4llt unser sch\u00f6ner Sortieralgorithmus auf die Nase, das geht leider nicht. Ich hab mir da eine quick&amp;dirty-L\u00f6sung einfallen lassen: ich h\u00e4nge die ID einfach an den Titel mit dran, und setze dazwischen als Trennzeichen ein #. Kann ich so machen, weil in meinen Rezepttiteln das Zeichen # sonst garantiert nirgendwo vorkommt. Die for-Schleife sieht dann so aus:<\/p>\n<pre>for ($i=0; $i&lt;$anzahl; $i++){\r\n\u00a0 \/\/Ersten Buchstaben vergleichen\r\nif (strtoupper(substr(($dataObject['rezepte'][$i]['post_title']), 0, 1))== strtoupper($stabe)){\r\n\/\/Hilfsarray mit Titeln und ID zum aktuellen Buchstaben f\u00fcllen (Trennzeichen#)\r\narray_push($ausgabe, $dataObject['rezepte'][$i]['post_title'].<span style=\"color: #ff0000;\">\"#\".$dataObject['rezepte'][$i]['ID']<\/span>);\r\n\u00a0 \u00a0}\r\n}<\/pre>\n<p>Dann sieht die Ausgabe erstmal so aus:<\/p>\n<div id=\"attachment_1341\" style=\"width: 575px\" class=\"wp-caption alignnone\"><img aria-describedby=\"caption-attachment-1341\" decoding=\"async\" loading=\"lazy\" class=\"size-full wp-image-1341\" src=\"http:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-content\/uploads\/2018\/07\/id_angehaengt.jpg\" alt=\"id_angehaengt\" width=\"565\" height=\"291\" srcset=\"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-content\/uploads\/2018\/07\/id_angehaengt.jpg 565w, https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-content\/uploads\/2018\/07\/id_angehaengt-300x155.jpg 300w\" sizes=\"(max-width: 565px) 100vw, 565px\" \/><p id=\"caption-attachment-1341\" class=\"wp-caption-text\">id_angehaengt<\/p><\/div>\n<p>Das zerpfl\u00fccke ich mir jetzt noch in die Teilstrings vor und nach dem #, gebe nur den Titel aus und kann dann mit der ID noch was anderes anfangen. Die Ausgabeschleife sieht dann so aus:<\/p>\n<pre>foreach($umlauts as $out){\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\/\/alle Zeichen vor dem # = Titel\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0$hilf_titel = substr($out, 0, strpos($out, '#', 0));\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0echo $hilf_titel.\"&lt;br&gt;\";\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\/\/alle Zeichen nach dem # = ID\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0$hilf_id = substr(strrchr($out, \"#\"), 1);\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\/\/hier kann man mit der ID weiterarbeiten\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0}<\/pre>\n<p>Wie gesagt, das ist ein wenig quick&amp;dirty, aber es funktioniert, und ich kann den schicken Sortieralgorithmus von Marco einwandfrei weiterverwenden.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Eigentlich hats mich ja nur interessiert, ob das recht aufwendig ist, aber das hielt sich in Grenzen, deswegen mach ich es noch der Vollst\u00e4ndigkeit halber. Voraussetzung ist wie im letzten Beitrag, dass die auszugebenden Daten in Form eines Arrays vorliegen, ich nehme wieder meine 334 Kochrezepte als JSON, so wie im letzten Beitrag zur nummerischen [&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,4,59],"tags":[],"_links":{"self":[{"href":"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-json\/wp\/v2\/posts\/1332"}],"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=1332"}],"version-history":[{"count":5,"href":"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-json\/wp\/v2\/posts\/1332\/revisions"}],"predecessor-version":[{"id":1342,"href":"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-json\/wp\/v2\/posts\/1332\/revisions\/1342"}],"wp:attachment":[{"href":"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-json\/wp\/v2\/media?parent=1332"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-json\/wp\/v2\/categories?post=1332"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-json\/wp\/v2\/tags?post=1332"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}