Beim Erstellen von Internetseiten kommt es oft vor, dass dem Benutzer die Anzahl der Datensätze ausgegeben wird, etwa: “Es befinden sich (x) Produkte in Ihrem Warenkorb”. Die Zahl der Datensätze bestimmt aber auch, wie der Rest des Satzes aussieht: “Es befinden sich 1 Produkte in Ihren Warenkorb” klingt nicht schön.
Mit einer simplen if/else-Struktur verschafft man sich Abhilfe:
1 2 3 4 5 6 7 8 9 10 11 12 | <?php $count = $pdo_statment->rowCount(); if($count === 0) { echo 'Es befinden sich noch keine Artikel im Verzeichnis!'; } elseif($count === 1) { echo 'Es befindet sich ein Artikel im Verzeichnis'; } elseif($count > 1) { echo 'Es befinden sich ' . $count . ' Artikel im Verzeichnis!'; } ?> |
Leider müssen diese Zeilen immer wieder neu geschrieben werden, schnell entsteht “bloated code”. Das Verfahren einer automatischen Pluralerstellung wird im Englischen “pluralization” genannt. Im Netz habe ich eine Anregung für eine praktische Funktion gefunden und diese noch etwas “handlicher” gemacht. Ich habe sie “textcount” genannt – mir ist einfach kein besserer Name eingefallen. Die Benutzung dieser Funktion demonstriere ich an drei Beispielen:
1 2 3 4 5 6 7 | $text1 = 'Es [sind keine Artikel|ist ein Artikel|sind %n Artikel] im Verzeichnis!'; $text2 = 'Keine Kommentare bisher|Ein Kommentar bisher...|Es sind %n Kommentare vorhanden'; $text3 = 'Bitte geben Sie die Bewertung fuer [ein Produkt|%n Produkte] ein!'; echo textcount($text1, 1) . '<br />'; echo textcount($text2, 0) . '<br />'; echo textcount($text3, 6) . '<br />'; |
Man übergibt den Text und die Anzahl an die Funktion “textcount”. Dabei werden innerhalb des Textes zwei bis drei “Parameter” übergeben, die durch einen senkrechten Balken (“|”) getrennt werden. Der erste Parameter gibt den Text für “0 Datensätze” an, der zweite für “1 Datensatz” und der letzte für mehrere gefundene Datensätze. Werden nur zwei Parameter übergeben, wird der Text für “0 Datensätze” nicht näher beachtet. Für ihn wird dann die Pluralform (2. Parameter) genommen (“Es befinden sich 0 Produkte im Warenkorb”).
Die Funktion ist wirklich ein netter Helfer, wenn es darum geht dem Benutzer die Anzahl der Datensätze korrekt auszugeben. Hier die Funktion:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | function textcount($text, $count, $divider = '|') { /* * Check if the text containts braces [] and save it to * $parts - use the whole text when no braces are defined * * $orig_replace: Copy for the braces text (incl. braces) * for later use */ if(preg_match('/\[(.*?)\]/', $text, $matches)) { $orig_replace = $matches[0]; $parts = $matches[1]; } else { $parts = $orig_replace = $text; } $fragments = explode($divider, $parts); /* * When there are just two arguments, take the * second parameter ($fragments[1]) as zero-text. */ if(count($fragments) == 2) $fragments = array_pad($fragments, -(count($fragments) + 1), $fragments[1]); /* * Get text for the amount */ if($count <= 0) { $return_text = $fragments[0]; } elseif ($count === 1) { $return_text = $fragments[1]; } elseif ($count > 1) { $return_text = str_replace('%n', number_format($count), $fragments[2]); } /* * Replace the text between the braces [] and return */ return str_replace($orig_replace, $return_text, $text); } |
Vielleicht ist sie auch für euch eine Hilfe!



Hmm, wenn das nicht gerade die Templateengine selbst kann, finde ich das Verfahren einen ganz schönen Overhead für so eine Funktionalität. Und ander Stelle „Get text for the amount“ solltest Du wenigstens so konsequent sein und in jedem Teilstring eine %n Ersetzung anbieten (wäre IMHO auch nötig für den Fall der 0 statt n). Überhaupt gäbe es an der Stelle einiges Optimierungspotenzial:
- Benutzung eines Arrayzugriffs statt if
- %d und sprintf statt %d und Ersetzung
- array_unshift statt array_pad
Das sind gute Tipps, danke. Was meinst du mit Arrayzugriff statt if?
Der Code unter /* Get text for the amount */ ist im Prinzip immmer gleich. Kleinstes gemeinsames Vielfaches:
$return_text = str_replace(‘%n’, number_format($count), $fragments[2]);
$fragments[2] kannst Du hier also durch $i austauschen und die If-Struktur z.B. mit Arrayzugriff abbilden:
$fragments[min (2 , $count)]
Das ist echt genial. Vielen Dank!