Fehler bei zu kürzendem String
Enrico
- php
0 Der Martin1 ChrisB
Hallo,
ich habe auf unserer Seite einen Abschnitt, in dem ich die derzeitig im Warenkorb abgelegten Artikel aufzähle.
Da hierbei nur eine bestimmte Breite zur Verfügung steht, kürze ich die Ausgabe, falls erforderlich, und hänge drei Punkte als Auslassungszeichen an.
Desweiteren kennzeichne ich Artikel, die nur an Personen ab 18 verkauft werden dürfen, im Artikelnamen mit der Raute, die bei der Ausgabe natürlich nicht angezeigt werden soll.
Hier der relevante Code:
if (isset ($_SESSION["Warenkorb"]))
{
$w = count ($_SESSION["Warenkorb"]);
for ($x = 0; $x < $w; $x++)
{
if (substr ($_SESSION["Warenkorb"][$x]["Artikel"], 0, 1) == "#")
$Artikel = '<span class="Ab18">' . $_SESSION["Warenkorb"][$x]["Menge"] . "x " . substr ($_SESSION["Warenkorb"][$x]["Artikel"], 1, strlen ($_SESSION["Warenkorb"][$x]["Artikel"])) . "</span>";
else
$Artikel = $_SESSION["Warenkorb"][$x]["Menge"] . "x " . $_SESSION["Warenkorb"][$x]["Artikel"];
if (strlen ($Artikel) > 22)
{
if (substr ($Artikel, 22, 1) == " ")
$Laenge = 19;
else
$Laenge = 20;
}
else
$Laenge = strlen ($Artikel);
echo '<a class="Liste">' . substr ($Artikel, 0, $Laenge) . "..." . "</a>";
if ($x < $w - 1)
echo "<br>";
}
}
Was ich jetzt aber nicht verstehe, ist, dass mir Artikel mit dem Kennzeichen "#" im Artikelnamen nur mit der Menge als Zahl, aber ohne das "x", sowie den drei Punkten, angezeigt werden, beispielsweise "1...", alle anderen Artikel hingegen vollständig in der gekürzten Form, beispielsweise "1x Mit Eisenplatten ...".
Wo liegt der Fehler?
Vielen Dank für eure Hilfe und Gruß,
Enrico
Moin,
if (substr ($_SESSION["Warenkorb"][$x]["Artikel"], 0, 1) == "#")
um auf das erste Zeichen eines Strings zuzugreifen, würde ich nicht die Funktion substr() bemühen, sondern den Zugriff im Array-Stil, etwa so:
if ($_SESSION["Warenkorb"][$x]["Artikel"][0]=="#")
$Artikel = '<span class="Ab18">' . $_SESSION["Warenkorb"][$x]["Menge"] . "x " . substr ($_SESSION["Warenkorb"][$x]["Artikel"], 1, strlen ($_SESSION["Warenkorb"][$x]["Artikel"])) . "</span>";
Hier ist substr() zwar richtig, aber warum machst du dir die Mühe, die gewünschte Länge noch extra auszurechnen (und dann auch noch falsch/zu lang)? Du willst den String ab Offset 1 bis zum Ende, also lass doch den length-Parameter einfach weg.
Was ich jetzt aber nicht verstehe, ist, dass mir Artikel mit dem Kennzeichen "#" im Artikelnamen nur mit der Menge als Zahl, aber ohne das "x", sowie den drei Punkten, angezeigt werden, beispielsweise "1...", alle anderen Artikel hingegen vollständig in der gekürzten Form, beispielsweise "1x Mit Eisenplatten ...".
Wo liegt der Fehler?
Kann ich nicht auf Anhieb erkennen, dafür ist mir dein PHP-Code im ersten Moment zu unübersichtlich. Wie sieht das erzeugte HTML aus? Versuche von dort aus Rückschlüsse auf das falsche Verhalten des PHP-Codes zu ziehen.
Ciao,
Martin
Hallo Martin,
danke für Deine schnelle Antwort.
Ist der Zugriff auf ein bestimmtes Zeichen im Array-Stil schneller als substr?
Kürzer ist der Code allemal, was evtl. ein kleines Quentchen an Performance-Gewinn bedeutet.
Der html-Code im Browser sieht wie folgt aus:
<a class="Liste"><span class="Ab18">1...</a><br>
<a class="Liste">1x Mit Eisenplatten ...</a><br>
<a class="Liste">1x Mittelbraune Lede...</a>
Warum ignoriert mein php-Code die Ausgabe des schliessenden span-Tags?
Den Session-Warenkorb habe ich zu Testzwecken fest definiert:
$_SESSION["Warenkorb"][0]["Bild"] = "GewandungMuetzen1";
$_SESSION["Warenkorb"][0]["Artikel"] = "#Mittelalter Langgürtel mit Greif und Löwenmotiv";
$_SESSION["Warenkorb"][0]["Farbe"] = "Schwarz";
$_SESSION["Warenkorb"][0]["Groesse"] = "M";
$_SESSION["Warenkorb"][0]["Preis"] = "34.90";
Die (warum falsche/zu lange?) Längenberechnung habe ich jetzt rausgenommen, am Endergebnis ändert sich aber leider nichts:
$Artikel = '<span class="Ab18">' . $_SESSION["Warenkorb"][$x]["Menge"] . "x " . substr ($_SESSION["Warenkorb"][$x]["Artikel"], 1) . "</span>";
Gruß,
Enrico
Hi,
Ist der Zugriff auf ein bestimmtes Zeichen im Array-Stil schneller als substr?
Kürzer ist der Code allemal, was evtl. ein kleines Quentchen an Performance-Gewinn bedeutet.
etwas schneller ist es möglicherweise; ich vermute(!), dass ein simpler Datenzugriff schneller ist als ein Funktionsaufruf. Der Performancegewinn dürfte aber eher akademisch sein und im Rauschen untergehen. Allerdings ist es IMO übersichtlicher zu lesen.
Der html-Code im Browser sieht wie folgt aus:
<a class="Liste"><span class="Ab18">1...</a><br>
<a class="Liste">1x Mit Eisenplatten ...</a><br>
<a class="Liste">1x Mittelbraune Lede...</a>
Okay, die Daten fehlen also schon im Quellcode. Ich wollte sichergehen, dass sie nicht aufgrund eines HTML-Fehlers oder einer bestimmten CSS-Regel bloß einfach nicht angezeigt werden.
> Warum ignoriert mein php-Code die Ausgabe des schliessenden span-Tags?
Gute Frage. Nächste Frage? ;-)
Ich greife deinen ursprünglichen Code hier nochmal auf, weil du da einen kapitalen Bock drin hast, den ich jetzt erst sehe.
> ~~~php
if (substr ($_SESSION["Warenkorb"][$x]["Artikel"], 0, 1) == "#")
> $Artikel = '<span class="Ab18">' . $_SESSION["Warenkorb"][$x]["Menge"] . "x " . substr ($_SESSION["Warenkorb"][$x]["Artikel"], 1, strlen ($_SESSION["Warenkorb"][$x]["Artikel"])) . "</span>";
> else
> $Artikel = $_SESSION["Warenkorb"][$x]["Menge"] . "x " . $_SESSION["Warenkorb"][$x]["Artikel"];
>
> if (strlen ($Artikel) > 22)
> {
> if (substr ($Artikel, 22, 1) == " ")
> $Laenge = 19;
> else
> $Laenge = 20;
> }
> else
> $Laenge = strlen ($Artikel);
>
> echo '<a class="Liste">' . substr ($Artikel, 0, $Laenge) . "..." . "</a>";
Du betrachtest hier strlen($Artikel), nachdem du diesen String komplett als HTML-Code zusammengebaut hast. Die öffnenden und schließenden span-Tags, die zusammen 21+5 Zeichen ausmachen, gehen also voll in die Länge mit ein. Also trifft die Abfrage auf strlen()>22 bei Ab18-Artikeln in jedem Fall zu, und du schneidest nach 22 Zeichen ab. Übrig bleibt das öffnende Tag (21 Zeichen) und das erste Zeichen des Nutzinhalts (die erste Ziffer der Mengenangabe). Das beantwortet wohl deine obige Frage.
Was lernen wir daraus? - Genau, jedwede Verarbeitung (in diesem Fall das Kürzen der Einträge) sollte auf den Rohdaten passieren, nicht auf dem generierten Ausgabe-Code.
Andere Frage: Warum sind Ab18-Einträge nicht verlinkt? Klar, weil's dein PHP-Code so erzeugt. Aber ist das Absicht?
Die (warum falsche/zu lange?) Längenberechnung habe ich jetzt rausgenommen
Warum falsch? Weil du die gesamte Stringlänge angibst, aber vorn schon ein Zeichen weglassen willst. Du "bestellst" den String also um ein Zeichen zu lang. Das macht nichts, weil strlen() nicht über das String-Ende hinaus arbeitet, aber es ist dennoch ein Logikfehler.
Ciao,
Martin
Hallo,
Andere Frage: Warum sind Ab18-Einträge nicht verlinkt? Klar, weil's dein PHP-Code so erzeugt. Aber ist das Absicht?
sorry, ich habe wohl Gespenster gesehen. Vergiss die Anmerkung einfach. ;-)
Schönes Wochenende,
Martin
Hallo Martin,
nachdem du diesen String komplett als HTML-Code zusammengebaut hast
Menschenskinder! Oftmals sind es so dermaßen banale, kleine Fehler, die einem ein gewünschtes Ergebnis verhageln, dass man auf die ersten 1, 2, 3... Blicke gar nicht dahinterkommt.
Jetzt klappt es! :-)
Besten Dank für Deine Hilfe.
Gruß,
Enrico
Tach!
Menschenskinder! Oftmals sind es so dermaßen banale, kleine Fehler, die einem ein gewünschtes Ergebnis verhageln, dass man auf die ersten 1, 2, 3... Blicke gar nicht dahinterkommt.
Deswegen macht man ja auch Kontrollausgaben mit var_dump(). Du willst Daten verarbeiten, also kontrolliere die Eingabedaten und nach einer anscheinend nicht richtig arbeitenden Funktion deren Ausgabedaten.
dedlfix.
Moin,
hier ein lügendes Beispiel:
$str = "Gürtel";
echo $str." ist ".strlen($str)." Zeichen lang";
Ausgabe: Gürtel ist 7 Zeichen lang
Also besser mb_strlen und mb_substr verwenden.
Gast
Hi,
Desweiteren kennzeichne ich Artikel, die nur an Personen ab 18 verkauft werden dürfen, im Artikelnamen mit der Raute
Entwerfe doch erst mal ein vernünftiges Datenmodell, anstatt so einen Unfug zu betreiben.
MfG ChrisB
Hallo ChrisB,
Entwerfe doch erst mal ein vernünftiges Datenmodell, anstatt so einen Unfug zu betreiben.
Sicher ist das nur ein optischer Gimmick, aber ich möchte die Ausgabe so haben.
Die Session-Struktur habe ich nur aus der alten Version übernommen, final wird sie auch anders aufgebaut sein.
Gruß,
Enrico
Hi,
Entwerfe doch erst mal ein vernünftiges Datenmodell, anstatt so einen Unfug zu betreiben.
Sicher ist das nur ein optischer Gimmick, aber ich möchte die Ausgabe so haben.
Das bezog sich nicht auf das optische Gimmick, sondern darauf, wie du die „über Achtzehn”-Angebote kennzeichnest.
MfG ChrisB
Hallo ChrisB,
Das bezog sich [...] darauf, wie du die "über Achtzehn"-Angebote kennzeichnest.
Wie würdest Du es anders machen?
Ich finde ein simples Kennzeichen nicht "verwerflich".
Gruß,
Enrico
Hallo,
Das bezog sich [...] darauf, wie du die "über Achtzehn"-Angebote kennzeichnest.
Wie würdest Du es anders machen?
besser. ;-)
Ich finde ein simples Kennzeichen nicht "verwerflich".
Ich auch nicht. Aber die Ab18-Kennzeichnung hat nichts mit dem Namen zu tun, sondern ist eine eigenständige Information. Also sollte sie auch nicht im Namen stecken, sondern in einer eigenen Spalte. In einer Datenbank wäre das _ein_ Aspekt dessen, was man als Normalisierung bezeichnet.
Die einzige "Entschuldigung" für dein bisheriges Vorgehen wäre, dass du die Daten aus einer externen Quelle bereits so angeliefert bekommst.
Ciao,
Martin