Datenbankabfragen mit Kommentaren ergänzen

Weiterer Fehler, der mir gerade aufgefallen ist: du wolltest ja exakt nach einem Namen fragen und eben nicht nach der Eingabe des Benutzers. Also statt $_POST['name'], wo laut Beispiel "ill" drin steht, muss mit "Miller" verglichen werden.

Wenn $row->url in deinem Beispiel den Namen "Miller" enthält, dann ist mein $db['name'] dein $row->url.

Demzufolge, wenn du den Kommentar in einer weiteren Spalte ausgeben möchtest, sollte die Tabellenzeile ungefähr so aussehen:

PHP:
echo "<td align='left' style='width:100px'>".$row->url."</td>"; 
if(stristr($row->url, "Miller") !== false)
   echo "<td>hier dein Kommentar</td>"; 
else
   echo "<td>&nbsp;</td>";

Die Prüfung lautet im Endeffekt: Gib mir den Teilstring aus $row->url (wo "Miller" oder irgendwas anderes drin steht) ab dem ersten Vorkommen von "Miller" zurück. Das Ergebnis ist entweder ein String oder false, wenn "Miller" nicht im Namen enthalten ist. Wenn nicht false, gib den Kommentar aus.

Analog ist strpos zu nutzen (und ähnliche, es gibt viele Wege, das zu prüfen)


PHP:
echo "<td align='left' style='width:100px'>".$row->url."</td>"; 
if(strpos($row->url, "Miller") !== false)
   echo "<td>hier dein Kommentar</td>"; 
else
   echo "<td>&nbsp;</td>";

-> Gib mir die numerische Position des ersten Vorkommens von "Miller" in $row->url zurück, kommt false zurück, ist er nicht vorhanden.

Beide Prüfungen klappen auch dann, wenn in $row->url HTML-Tags oder Ähnliches hinzugefügt ist - wichtig ist nur, dass der gesuchte Name exakt als "Miller" vorkommt, ohne weitere Zeichen dazwischen.

Eine evtl. bessere Möglichkeit ist mir mit meinen bescheidenen Kenntnissen nicht eingefallen.

Es gibt auch bei vermeintlich perfekten Skripten immer etwas zu verbessern ;) gibt sicher auch bei dem Punkt genügend Leute, die helfen könnten.
 
Wunderbar - es klappt. Herzlichen Dank an dieser Stelle schon mal, auch für deine hilfreichen Erläuterungen. Möglicherweise kann ich aus deiner Lösung sogar noch die eine oder andere Idee verwirklichen, die ich habe (an Ideen mangelt es mir nicht, nur mit der Umsetzung tue ich mir mitunter schwer ...). :D

Aber ... jetzt kommt leider das aber. Und es tut mir leid, dass ich das noch nicht erwähnt habe, weil ich dieser Tatsache insoweit bisher keine Bedeutung beigemessen habe. In vielen Fällen kommt der Name nicht nur einmal, sondern mehrfach vor. Je nach Abfrage erscheint "Miller" also z. B. dreimal. Das ist auch so gewollt. Entsprechend oft wird dann aber auch der Kommentar generiert. Und das ist nicht gewollt, denn der soll ja nur einmal erscheinen. Ich habe daher die Kommentare in einer gesonderten Datei hinterlegt, die ich mit "require" im Anschluss an die Ergebnistabelle einbinde. Der jeweils zutreffende Kommentar wird dann als Fußnote sozusagen ausgegeben.

Tja, und aus der externen Datei wird nun der Kommentar nicht eingebunden. Stattdessen kommt die Notice: Trying to get property of non-object. Vermutlich bezieht sich dies auf "$row->url". Kann es sein, dass ich jetzt eine ganz andere Lösung benötige?

Viele Grüße
hawaiian
 
Man könnte das Problem sicher auch mit deinem Ansatz lösen, aber die Ausgabe innerhalb der Tabelle war ja eigentlich präferiert, richtig? Ich würde dir also eine andere Herangehensweise empfehlen, was nicht heißt, dass sie zwingend notwendig wäre. Wenn du deinen Ansatz unbedingt weiter verfolgen möchtest beziehungsweise die Kommentare weiterhin auslagern möchtest (legitim), müsstest du mal die komplette Fehlermeldung, die externe Datei und den Code ab require (oder noch besser, den gesamten Code) herumreichen.

Es fehlt mir momentan n bisschen an der Vorstellung, auf welches Ziel du genau mit diesen Kommentaren hinarbeitest; ich bleibe deswegen einfach mal bei diesem Miller-Beispiel (womöglich ist der Ansatz für das Gesamtziel aber nicht optimal):

Du könntest den gesuchten Namen und den booleschen Wert, ob zu diesem Namen bereits ein Kommentar ausgegeben wurde, in ein Array speichern und dementsprechend abfragen:

PHP:
/* diesen Teil vor der Schleife, die dir $row->url gibt */

// befüllt das Array mit dem Suchstring als key und false als value, stellvertretend für "noch nicht kommentiert"
$searcharray = array("Miller" => false);


/* weiter unten */

echo "<td align='left' style='width:100px'>".$row->url."</td>"; 
if(strpos($row->url, key($searcharray)) !== false && !current($searcharray)){
   echo "<td>hier dein Kommentar</td>";
   $searcharray["Miller"] = true;
}else
   echo "<td>&nbsp;</td>";

Erklärung:
PHP:
key($searcharray)
gibt den Index des Arrays $searcharray der aktuellen Position zurück (in diesem Fall immer "Miller"). Die eigentlich durchgeführte Prüfung bleibt also hier dieselbe.
PHP:
 !current($searcharray))
Trifft zu, wenn current($searcharray) false ist. current gibt dir den aktuellen Wert des Arrays $searcharray, zu Beginn also grundsätzlich false.
PHP:
$searcharray["Miller"] = true;
Setzt den Wert auf true, wenn der Kommentar ausgegeben wurde. Damit werden weitere Prüfungen nicht mehr positiv verlaufen.


Wenn man davon ausgeht, dass du grundsätzlich nur einen Kommentar ausgeben willst, kann man natürlich auch auf das Array verzichten:

PHP:
/* diesen Teil vor der Schleife, die dir $row->url gibt */

$echoed = false;

/* weiter unten */

echo "<td align='left' style='width:100px'>".$row->url."</td>"; 
if(strpos($row->url, "Miller") !== false && !$echoed){
   echo "<td>hier dein Kommentar</td>"; 
   $echoed = true;
}else
   echo "<td>&nbsp;</td>";
 
Hm, nein, der Kommentarteil sollte eigentlich nicht innerhalb der Ergebnistabelle erscheinen. In meinem Projekt (das mit rund 3.500 Datensätzen auch schon online ist) geht es um Sport, speziell hier um Leichtathletik. Die gute "Miller" war über 100 m und 200 m erfolgreich. Sie erscheint also, je nach Abfrage, einmal oder zweimal. Sie ist auch mit zwei Datensätzen in der Datenbank hinterlegt. Eine ganze Reihe von Sportlern wird, je nach Zahl der Erfolge, noch häufiger gelistet.

Das, was ich als Kommentar bezeichne, sind im Grunde genommen Zusatzinformationen zu einer Reihe der abgerufenen Datensätze. Das sind manchmal sogar eigenständige Tabellen, zum Teil auch mit Bildern. Dies lässt sich in überschaubarer Weise wohl nur über externe Dateien einbauen und klappt eigentlich auch ganz gut. Na ja, bis auf die beiden geschilderten Probleme. Für die Funktionalität der Datenbankabfrage ist diese Sache ohne Bedeutung. Es sind halt reine Zusatzinfos.

Auch wenn wir das Ziel noch nicht ganz erreicht haben, deine Bemühungen, mir zu helfen, waren nicht umsonst. Ich habe bereits dazu gelernt und bin auch schon dabei, etwas zu vereinfachen.

Hier ein Teil der Ergebnistabelle:

PHP:
{
...
echo "<td align='left' style='width:100px'>". $row->vorname . "</td>";
 echo "<td align='left' style='width:100px'>". $row->url . "</td>";
...
 }
echo "</table><p>";

require "kommentare.php";

Code von "kommentare.php":

PHP:
<?php
...
if(stristr($row->url, "Miller") !== false) {
    echo "<div style='width: 280px;' class='kommentar'>
	Inger Miller ...</div>";
   }
...
?>

Fehlermitteilung: Notice: Trying to get property of non-object.

Der komplette Code beläuft sich momentan auf rund 600 Zeilen (ohne Kommentardateien). Das möchte ich eigentlich niemandem zumuten. Ich hoffe, die Auszüge reichen dennoch.

Viele Grüße
hawaiian
 
Zuletzt bearbeitet:
Ich hoffe, die Auszüge reichen dennoch.

Ich auch, nicht dass ich wieder Murks erzähle ;)

Du versuchst innerhalb von kommentare.php auf $row zuzugreifen. Ich gehe mal stark davon aus, dass dein
PHP:
require "kommentare.php";
außerhalb der Schleife erfolgt, in der du die Datensätze abfragst und ausgibst.
Dann ist $row natürlich nicht mehr das, was es innerhalb der Schleife war.

Ich hatte jetzt schon wieder die abenteuerlichsten Lösungsansätze im Kopf, versuch jetzt aber, nur so viel zu posten dass es (hoffentlich) für deinen reicht:

PHP:
$allURL = '';

{
  ...
 echo "<td align='left' style='width:100px'>". $row->vorname . "</td>";
 echo "<td align='left' style='width:100px'>". $row->url . "</td>";
 ...
 $allURL .= $row->url;
}
echo "</table><p>";

require "kommentare.php";

kommentare.php:
PHP:
<?php
...
if(stristr($allURL, "Miller") !== false) {
    echo "<div style='width: 280px;' class='kommentar'>
    Inger Miller ...</div>";
   }
...
?>

$allURL wird nach und nach mit allen Einträgen der Spalte url aus der Ergebnismenge befüllt.
Innerhalb von kommentare.php wird nun dieser gesamte String nach den speziellen Namen abgegrast und im Erfolgsfall jeweils der Kommentar ausgegeben.
 
Wunderbar, es klappt. Und zwar perfekt. Ich bin begeistert. Habe alle Abfragevariationen durchprobiert. Dir, para_noid, herzlichen Dank für deine Hilfe. Und deine Erläuterungen haben mich auch den Lösungsweg verstehen lassen.

Darf ich jetzt nochmals mein anderes Problem aufgreifen? Da ging es darum, bei bestimmten Formularabfragen Zusatzinfos (ich bezeichne sie auch hier als Kommenatre) ebenfalls aus einer externen Datei einzublenden. Das funktioniert einwandfrei mit folgendem Code:

PHP:
if (!empty ($_POST['geschlecht']) && !empty ($_POST['saison']) && $_POST[geschlecht'] == 'm' && $_POST['saison'] == '2010/11') {
    echo "Kommentar"; }

Handelt es sich nun aber um eine Checkbox, wird, egal was ich abfrage, der Kommentar immer eingeblendet.

Code:
<input type="checkbox" name="weltcup[]" value="Sprint"> Sprint

Entsprechend deinem Tipp hierzu habe ich die Abfrage wie folgt modifiziert:

PHP:
if (!empty ($_POST['geschlecht']) && !empty ($_POST['saison']) && $_POST['geschlecht'] == 'm' && $_POST['saison'] == '2010/11' && (in_array('Sprint', $_POST['weltcup']))) {
  echo "Kommentar ...";}

Und auch diese Lösung war eine grundsätzlich erfolgreiche! Bei meinen Tests habe ich aber festgestellt, dass immer dann, wenn die Checkbox nicht mit abgefragt wird, folgende zwei Hinweise kommen:

Notice: Undefined index: weltcup ...

Warning: in_array() expects parameter 2 to be array, null given ...

Beide beziehen sich auf die Zeile mit dem obigen Code. Sie sind mir zwar in etwa verständlich (ich habe auch schon derartige Hinweis- bzw. auch Fehlermeldungen selbst lösen können), hier ist es mir bisher allerdings noch nicht gelungen. Ich probier's noch weiter, aber vielleicht hast du ja noch einen abschließenden Tipp ...

Viele Grüße
hawaiian
 
@ erster Punkt: schön :)

@ zweiter Punkt:

da du "in etwa verständlich" schriebst, hol ich nochmal den Erklärbär hervor: wenn keine Checkbox gesetzt ist existiert das Array $_POST['weltcup'] nicht. Du müsstest bei solchen Optionen also immer erst abfragen, ob es $_POST['weltcup'] überhaupt gibt (mit isset). Weniger Schreibarbeit bei selben Resultat für die Abfrage wäre ein @ vor die Funktion zu setzen:

PHP:
&& @in_array('Sprint', $_POST['weltcup'])

Das @ ist der s.g. Fehler-Kontroll-Operator, der die Fehlerausgabe unterdrückt. Ich nutze ihn oft um Variablen (meistens Sessions) auf Werte zu prüfen, ohne zu wissen, ob die Variable überhaupt existent ist:

PHP:
if(@$variable == "a")

Somit spar ich mir das

PHP:
if(isset($variable) && $variable == "a")

Ob das aber so'n guter Stil ist will ich nicht behaupten ;)


Bei deinem Beispiel bin ich mir nicht ganz sicher, ob auch vor $_POST['weltcup'] auch ein @ müsste oder ob die Fehlermeldung über die Funktion abgefangen würde, kann hier grad nicht testen.

Du könntest den Code noch ein bisschen verringern, wenn du die empty-Fragen vorher weglässt. Wenn
PHP:
 $_POST['geschlecht'] == 'm'
zutrifft, dann kann die Variable nicht empty sein.

Ungetesteter Vorschlag also:

PHP:
if ($_POST['geschlecht'] == 'm' && $_POST['saison'] == '2010/11' && (@in_array('Sprint', $_POST['weltcup']))) {
  echo "Kommentar ...";}
 
Das Vorgehen mit dem Fehler-Kontroll-Operator @ kannte ich bis jetzt nicht. Der gleiche Effekt wird erreicht, wenn ich
PHP:
error_reporting(E_ALL);
auf 0 setze. Die Notices und Warnings sind dann verschwunden, die Ursache damit allerdings noch nicht. Mit isset hatte ich es schon probiert, allerdings noch keinen Erfolg gehabt. Da mache ich wohl noch irgendetwas falsch. Aber ich probier's fleißig weiter.

Dein Tipp, den Code zu verringern, indem ich empty weglasse, führt übrigens auch zu dem Hinweis: Undefined Index ... hm, jetzt kommt mir in diesem Zusammenhang noch eine andere Idee. Muss ich mal testen.

para_noid, ich möchte mich nochmals herzlich für deine Mühe bedanken. Mein Ziel, die beiden "Ergebniskommentare" zu definieren, ist dank deiner Hilfe erreicht worden. Und mit den beiden Fehlerhinweisen komme ich, denke ich, schon noch klar.

Viele Grüße
hawaiian
 
Gern geschehen. Das mit der Fehlermeldung wundert mich doch etwas, da empty nach meinem Wissen nicht abfragt, ob eine Variable gesetzt ist.

Ich weiß nicht ob du das bereits so hast, aber wenn du mit mehreren Prüfungen auf eine mögliche Formularabsendung zugreifen möchtest, würd ich das Ganze immer in ein

PHP:
if(isset($_POST['name-Attribut_des_Submitbuttons'])){
// Kram
}

packen, weil innerhalb des Zweiges immer alle post-angaben (bis auf Checkboxen) des Formulars verfügbar sind.
Die Gleichsetzung von @ mit no-error-reporting würd ich zwar nicht so sehen, aber das war auch nur ein Vorschlag hinsichtlich Codeverringerung. Funktionieren muss es ja erstmal.

PHP:
if (isset($_POST['geschlecht']) && isset ($_POST['saison']) && isset($_POST['weltcup']) && $_POST['geschlecht'] == 'm' && $_POST['saison'] == '2010/11' &&  in_array('Sprint', $_POST['weltcup'])) {
  echo "Kommentar ...";}

Hattest du das so probiert? Isset gibt btw auch false zurück, wenn der index weltcup existiert, aber der Wert null ist. Vllt hakt es ja da.
 
Wenn du mehrere verschiedene Kombinationen hast, und jeweils einen speziellen Kommentar willst, würde ich das eher so aufbauen:

PHP:
if(isset($_POST['geschlecht']) && isset ($_POST['saison']) && isset($_POST['weltcup']))
{
    if($_POST['geschlecht'] == 'm' && $_POST['saison'] == '2010/11' &&  in_array('Sprint', $_POST['weltcup']))
    {
         echo "Kommentar ...";
    }
    elseif($_POST['geschlecht'] == 'w' && $_POST['saison'] == '2009/10' &&  in_array('Sprint', $_POST['weltcup']))
    {
         echo "Kommentar2 ...";
    }
    //falls keines von alldem zutrifft, was hier eher nicht passieren wird
    else
    {
         echo "Ungültige Kombination ausgewählt ...";
    }
}

gruß
 
Zurück