• Jetzt anmelden. Es dauert nur 2 Minuten und ist kostenlos!

Problem mysqli Suchfunktion

xXxPeterPanxXx

Neues Mitglied
Hi @ all,
nachdem meine Job Anfrage leider unbeantwortet geblieben ist. Habe ich es nochmal versucht meine Suchfunktion auf mysqli umzustellen, jedoch folgt eine Fehlermeldung nach der anderen:sad:.

An der momentanen komm ich nicht weiter, sie lautet:
Fatal error: Call to a member function bind_param() on a non-object in /is/htdocs/wp1158326_JHB43K6EP5/www/coder/suche.php on line 94

Die besagte Zeile ist diese hier:

PHP:
$prepare_ein->bind_param('si', $_POST['key'], $_POST['cat']);
aus dieser Suchabfrage:

PHP:
$suche = "SELECT * FROM eintraege WHERE MATCH name, tutorial AGAINST ??";
$prepare_ein = $db->prepare($suche);
$prepare_ein->bind_param('si', $_POST['key'], $_POST['cat']);
$prepare_ein->execute();
$prepare_ein->bind_result($ein_id,$ein_name,$ein_name_url,$ein_kategorie,$ein_tutorial,$ein_time);
$prepare_ein->fetch();
$prepare_ein->close();




So hier kommt nochmal ganz viel Code der aber mit der Suchfunktion zussamenhängt:

Die Suchfunktion(suche.php)
Code:
<?php
require_once("config.inc.php");

$title = $_POST['key']. " - Suche";
include("header.php");






if(isset($_POST['key'])) {

if(isset($_POST['adv']))
{

if($_POST['titel'] == 1 && $_POST['text'] == 1) 
{
$match = "name, tutorial"; 
$ausgabe ="Titel und Text";
}
elseif($_POST['titel'] == 1 && $_POST['text'] == 0) {
$match = "name";
$ausgabe ="Titel";
}
elseif($_POST['titel'] == 0 && $_POST['text'] == 1) {
$match = "tutorial";
$ausgabe = "Text";
}
else {
$match = "name, tutorial";
$ausgabe = "Titel und Text";
}

if($_POST['cat'] == 0) 
{
$cat = "";
$kategorie = "allen Kategorien";
}
else 
{
$cat = " AND kategorie = '".$_POST['cat']."'";
$kategorien = "SELECT * FROM kategorien WHERE id = ?";
$prepare = $db->prepare($kategorien);
$prepare->bind_param('i', $_POST['cat']);
$prepare->execute();
$prepare->bind_result($id,$name,$name_url); 
$prepare->fetch();
$prepare->close();

$kategorie = $name;
}

$suche = "SELECT * FROM eintraege WHERE MATCH ? AGAINST ??";
$prepare_ein = $db->prepare($suche);
$prepare_ein->bind_param('ssi', $match, $_POST['key'], $cat);
$prepare_ein->execute();
$prepare_ein->bind_result($ein_id,$ein_name,$ein_name_url,$ein_kategorie,$ein_tutorial,$ein_time);
$prepare_ein->fetch();
$prepare_ein->close();


}
else
{






if(isset($_POST['cat'])) 
{
$cat = " AND kategorie = '".$_POST['cat']."'";
echo $cat;
$kategorien = "SELECT * FROM kategorien WHERE id = ?";
$prepare_3 = $db->prepare($kategorien);
$prepare_3->bind_param('i', $_POST['cat']);
$prepare_3->execute();
$prepare_3->bind_result($id,$name,$name_url);
$prepare_3->fetch();
$prepare_3->close();
$kategorie = $name;
}
else
{
$kategorie = "allen Kategorien";
$cat = "";
}

$ausgabe = "Titel und Text";
$suche = "SELECT * FROM eintraege WHERE MATCH name, tutorial AGAINST ??";
$prepare_ein = $db->prepare($suche);
$prepare_ein->bind_param('si', $_POST['key'], $_POST['cat']);
$prepare_ein->execute();
$prepare_ein->bind_result($ein_id,$ein_name,$ein_name_url,$ein_kategorie,$ein_tutorial,$ein_time);
$prepare_ein->fetch();
$prepare_ein->close();

}
}









echo "<h2>Suchergebnisse</h2>";
if($prepare_ein->num_rows == 0) {
echo "<p class=\"error\">Ihre Suche erzielte leider keinen Treffer</p>";
}
if ($_POST['key'] == "") {
echo "<p class=\"error\">Bitte geben Sie einen Suchbegriff ein.</p>";
}
echo "<ul class=\"ausgabe\">";


while($prepare_ein->fetch())
{
echo "<li class=\"ausgabe\"><a href=\"tutorial.php?nameurl=".$ein_name_url. "\"class=\"ausgabe\" >".$ein_name. "</a></li>";
}
echo "</ul>";

if ($_POST['key'] != "") {
echo "<p class=\"ausgabe\">Es wurde nach ".$_POST['key']. " in ". $kategorie ." gesucht (" .$ausgabe. ")</p>";
}



include("footer.php");
?>
Die erweiterte Suche:
Code:
<form action="suche.php" method="POST">
<fieldset class="esuche">
<label for="key">Suchbegriff<input type="text" name="key" id="key" /> <br />
<label for="cat">Kategorie</label><select name="cat" id="cat"><option name="cat" value="0">Alle Kategorien</option>





<?php 
$kategorien = "SELECT * FROM kategorien WHERE id != '5'";
$ergebnis = $db->query( $kategorien );
while ($kategorie = $ergebnis->fetch_array())




{
echo "<option name=\"cat\" value=\"".$kategorie['id']."\">".$kategorie['name']."</option>";
}

?>
</select>
<label class="esuche">Suchen in:</label><input type="checkbox" name="titel" value="1" checked="checked" /> <p>Titel</p> <input type="checkbox" name="text" value="1" checked="checked"/> <p>Text</p> 
<input type="hidden" name="adv" value="1" />

<input type="submit" value="Suchen" />
</fieldset>
</form>
Die Suchfunktion im Header:

Code:
    <form action="suche.php" method="POST">
    <fieldset>
      <input class="search" type="text" name="key" /><input class="but" type="submit" value="Suchen" />
      <a href="erweitertesuche.php" class="header">Erweiterte Suche</a>
      </fieldset>
      </form>
Lieber etwas zu viel als zu wenig:mrgreen:.

Man wird sicherlich nicht alles brauchen.

Den Link zu Seite findet ihr in der Signatur, so wie Username und Password.


Danke im Vorraus!

MfG xXxPeterPanxXx




Hoffentlich ist die Datenbank jetzt nicht überfüllt.:mrgreen:
 
Zuletzt bearbeitet:
hmmm hast du der variable $db die mysqli klasse hinzugefuegt?
da in zeile 93 keine fehlermeldung kommt vermute ich mal, dass du irgendwo der varibale $db die mysqli klasse zugewiesen hast oder eine klasse die um die mysqli klasse erweitert ist.

probier mal das
$prepare_ein->bind_param('si', $_POST['key'], $_POST['cat']);
in
Code:
[COLOR=#000000][COLOR=#0000BB]$db[/COLOR][COLOR=#007700]->[/COLOR][COLOR=#0000BB]bind_param[/COLOR][COLOR=#007700]([/COLOR][COLOR=#DD0000]'si'[/COLOR][COLOR=#007700], [/COLOR][COLOR=#0000BB]$_POST[/COLOR][COLOR=#007700][[/COLOR][COLOR=#DD0000]'key'[/COLOR][COLOR=#007700]], [/COLOR][COLOR=#0000BB]$_POST[/COLOR][COLOR=#007700][[/COLOR][COLOR=#DD0000]'cat'[/COLOR][COLOR=#007700]]);[/COLOR][/COLOR]
umzuschreiben und schau was passiert.
 
Hi Mad Dog und Danke für deine Hilfe.

Ich hab den Code ersetzt jedoch hat dies nicht gebracht. Jett erscheint folgende Fehlermeldung:
Fatal error: Call to undefined method mysqli::bind_param() in /is/htdocs/wp1158326_JHB43K6EP5/www/coder/suche.php on line 94

$db müsste auch stimmen, weil ich in anderen Dateien schon erfolgreiche Abfragen gemacht habe.

Aber hier ist der Code:
PHP:
<?php
$db_host = "localhost";
$db_usr = "----------";
$db_pw = "----------";
$db_name = "--------";

$db = @new mysqli($db_host, $db_usr, $db_pw, $db_name);  
?>

MfG xXxPeterPanxXx
 
ah bei im php manuel sagen sie, das mysqli_bind_param()
dafuer gibt es noch mysqli_stmt_bind_param()
das sollte funktionieren.
mach es am besten so.
schreibe dir eine eigene klasse:
Code:
class Database extends MySQLi
{    

public function __construct($Location = '', $Username = '', $Password = '', $DBname = '')
{
    parent::__construct($Location, $Username, $Password, $DBname);
}

public function insertTimestamp($Timestamp, $Username)
{
// hier kann stehen was immer du willst, wichtig ist die naechste zeile
$mysqli_stmt = parent::stmt_init()
// jetzt kannst du den rest ausfuehren z.b.:
$mysqli_stmt->bind_param();
// oder
$mysqli_stmt->execute();
}

das mysqli_stmt ist wichtig.
 
ist genauso eine klasse wie mysqli. PHP: MySQLi_STMT - Manual
musst natuerlich
Code:
[COLOR=#000000][COLOR=#0000BB]$db [/COLOR][COLOR=#007700]= @new [/COLOR][COLOR=#0000BB]mysqli[/COLOR][COLOR=#007700]([/COLOR][COLOR=#0000BB]$db_host[/COLOR][COLOR=#007700], [/COLOR][COLOR=#0000BB]$db_usr[/COLOR][COLOR=#007700], [/COLOR][COLOR=#0000BB]$db_pw[/COLOR][COLOR=#007700], [/COLOR][COLOR=#0000BB]$db_name[/COLOR][COLOR=#007700]);

den teil in mysqli_stmt umaendern
[/COLOR][/COLOR]
 
Mit Beispiel eintraegen:
Code:
-- phpMyAdmin SQL Dump
-- version 2.11.9.1
-- http://www.phpmyadmin.net
--
-- Host: localhost
-- Erstellungszeit: 26. September 2009 um 12:51
-- Server Version: 5.0.32
-- PHP-Version: 5.2.10

SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";

--
-- Datenbank: `-------------`
--

-- --------------------------------------------------------

--
-- Tabellenstruktur für Tabelle `eintraege`
--

CREATE TABLE `eintraege` (
  `id` int(7) NOT NULL auto_increment,
  `name` varchar(120) collate latin1_german2_ci NOT NULL,
  `nameurl` varchar(120) collate latin1_german2_ci NOT NULL,
  `kategorie` varchar(30) collate latin1_german2_ci NOT NULL,
  `tutorial` mediumtext collate latin1_german2_ci NOT NULL,
  `time` int(10) unsigned NOT NULL,
  PRIMARY KEY  (`id`),
  FULLTEXT KEY `name` (`name`,`tutorial`),
  FULLTEXT KEY `tutorial` (`tutorial`),
  FULLTEXT KEY `name_2` (`name`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 COLLATE=latin1_german2_ci AUTO_INCREMENT=40 ;

--
-- Daten für Tabelle `eintraege`
--

INSERT INTO `eintraege` VALUES(28, 'erweitern', '22222222', '1', '222222222222222222dsfnjhsbdvdjshbvdjrfhbvhjdf<bvjdhrfbvzhdjf\r\ndvfghnbd<vcfn<vbdfhvdfvdf\r\nfffffffffff\r\nfffffffffeeeeeeeeeeeee\r\neeeeeeeeee', 1249415810);
INSERT INTO `eintraege` VALUES(29, '33333333333333333333', '333333333333333333', '1', '3333333333333333', 1249592951);
INSERT INTO `eintraege` VALUES(27, 'aaaa', 'aaaa', '4', 'aaaaa', 1249079667);
INSERT INTO `eintraege` VALUES(34, '111111111', '1111111111111', '1', '1111111111111111', 1249821848);
INSERT INTO `eintraege` VALUES(35, '111111111', '1111111111111', '1', '11111111111', 1249821860);
INSERT INTO `eintraege` VALUES(31, '5555555555555555', '5555555555', '1', '55555555555555', 1249592811);
INSERT INTO `eintraege` VALUES(36, '222222222222222', '222222222222222222', '1', '22222222222222222222ff\r\nffrrgrg\r\nfrhdgsawse\r\ndawfawf', 1249821955);
INSERT INTO `eintraege` VALUES(33, 'aa', 'aa', '3', 'aa', 1249334208);
INSERT INTO `eintraege` VALUES(37, 'lorem ipsum', 'lorem-ipsum', '4', 'lorem ipsum peter hans wurst ', 0);
INSERT INTO `eintraege` VALUES(38, 'peter wurts', 'peter-wurts', '3', 'peter kaka pups igitt', 0);
INSERT INTO `eintraege` VALUES(39, 'hallö', 'halloe', '1', 'hülölä', 1251988005);
 
SO ein kleines Update:

Ich kriege normale mysqli Abfragen hin, aber mit prepare schaffe ich es nicht.:sad:

Hier ist z.B noch ein Code mit prepare:

PHP:
<?php

require_once("config.inc.php");

$sql = "SELECT * FROM eintraege WHERE nameurl = ?";
$htmltutorial = $db->prepare($sql);
$prepare->bind_param('s', $_GET['nameurl']);
$prepare_ein->execute();
$prepare_ein->bind_result($ein_id,$ein_name,$ein_name_url,$ein_kategorie,$ein_tutorial,$ein_time);
$prepare_ein->fetch();
$prepare_ein->close();



$title = $ein_name." - Htmltutorial";

include("header.php");
echo $ein_tutorial;

include("footer.php");
?>

ich erhalte diese Fehlermeldung:
Fatal error: Call to a member function bind_param() on a non-object in /is/htdocs/wp1158326_JHB43K6EP5/www/coder/tutorial.php on line 7




$db steht in der Datei config.inc.php.


MfG xXxPeterPanxXx
 
So ein Schei...:mrgreen::mrgreen:,
ich finde den Fehler einfach nicht.

Das hier funktioniert zum Beispiel:
PHP:
$sql = "SELECT * FROM eintraege WHERE nameurl = ?";
$htmltutorial = $db->prepare($sql);
$htmltutorial->bind_param('s', $_GET['nameurl']);
$htmltutorial->execute();
$htmltutorial->bind_result($ein_id,$ein_name,$ein_name_url,$ein_kategorie,$ein_tutorial,$ein_time);
$htmltutorial->fetch();
$htmltutorial->close();
und das leider nicht:
PHP:
$sql = "SELECT * FROM eintraege WHERE MATCH name, tutorial AGAINST ??";
$prepare_ein = $db->prepare($sql);
$prepare_ein->bind_param('si', $_POST['key'], $_POST['cat']); 
$prepare_ein->execute();
$prepare_ein->bind_result($ein_id,$ein_name,$ein_name_url,$ein_kategorie,$ein_tutorial,$ein_time);
$prepare_ein->fetch();
$prepare_ein->close();

Wo ist da der Unterschied?

Bei dem zweiten Code erhalte ich immernoch diese Fehlermeldung:

Fatal error: Call to a member function bind_param() on a non-object in /is/htdocs/wp1158326_JHB43K6EP5/www/coder/suche.php on line 94

MfG xXxPeterPanxXxx
 
Ich bin mit der Mysql Fulltext Suche auch nicht mehr so vertraut:oops:, aber ich glazbe so war es mal:
Code:
SELECT * FROM eintraege WHERE MATCH (name, tutorial) AGAINST ($_POST['key'], $_POST['cat'])
So müsste es gewesen sein:oops:

MfG xXxPeterPanxXx
 
Eine korrekte Query sähe zum Beispiel ungefähr so aus:

Code:
SELECT
    e.`id`,
    e.`name`,
    k.`id` AS `category_id`,
    k.`name` AS `category_name`
FROM
    `eintraege` e
LEFT JOIN
    `kategorien` k ON e.`kategorie` = k.`id`
WHERE
    MATCH (e.`name`, e.`tutorial`) AGAINST ('lorem ipsum')
    AND `kategorie` = '4'

Kann sein, dass sie auf deinen Daten funktioniert, ich bin mir nicht sicher (in meiner Version im Anhang habe ich das DB-Schema etwas verändert).

Mir war es ehrlichgesagt zu kompliziert, an der Stelle mit Prepared Statements zu arbeiten, denn die Query setzt sich aus variablen Teilen zusammen, die nicht durch Platzhalter ersetzbar sind. (Zum Beispiel muss die AND-Bedigung im WHERE-Teil komplett entfernt werden, wenn bei Kategorien "alle" ausgewählt ist. Das ist mit einem "Fragezeichen" aber nicht getan.)

PHP:
function performSearch(mysqli $db, $keywords, $category = 0, $inTitle = true,
                       $inText = true)
{
    /* Parameter validieren */

    $keywords = trim($keywords);
    $category = (int) $category;
    $inTitle  = (bool) $inTitle;
    $inText   = (bool) $inText;
    $results  = array();

    /* Abbruchbedingungen */

    if ($keywords == '') return array();

    /* WHERE-Bedingungen zusammenstellen */

    $conditions = array();

    $fields = array();
    if ($inTitle) $fields[] = 'name';
    if ($inText)  $fields[] = 'tutorial';
    if (count($fields) == 0) $fields = array('name', 'tutorial');
    $conditions[] = "MATCH (e.`" . implode("`, e.`", $fields) . "`) "
                    . "AGAINST ('" . $db->real_escape_string($keywords) . "')";

    if ($category > 0) {
        $conditions[] = "`kategorie` = '" . $db->real_escape_string($category) . "'";
    }

    $wherePart = " WHERE " . implode(' AND ', $conditions);

    /* Query zusammenbauen */

    $query = "SELECT
                    e.`id`,
                    e.`name`,
                    k.`id`   AS `category_id`,
                    k.`name` AS `category_name`
                FROM
                    `eintraege` e
                LEFT JOIN
                    `kategorien` k
                    ON
                        e.`kategorie` = k.`id`";

    if ($wherePart != '') {
        $query .= $wherePart;
    }

    /* Query zu Debugzwecken anzeigen */

    echo '<pre style="white-space: normal;">' . preg_replace('/\s{2,}/', ' ', $query) . '</pre>';

    /* Query ausführen */

    $result = $db->query($query);
    while ($row = $result->fetch_assoc()) {
        $results[] = $row;
    }

    /* Rückgabe */

    return $results;
}

Vielleicht kannst du damit was anfangen... Ich habe mal versucht, den relevanten Teil zu extrahieren, denn der Code des Gesamtbeispiels wurde leider immer länger und länger.

Hintergrund: Seit geraumer Zeit probiere ich, ein nicht zu kompliziertes Beispiel für ein FrontController-/MVC-Layout zu basteln. (Also u. a. mit einer zentralen index.php und stark schematisierten URLs. Das ist imo die beste Möglichkeit, eine Anwendung zu designen.) Im Anhang befindet sich der jüngste Versuch, denn das bot sich hier an. Aber je mehr man von Objektorientierung weggeht, desto mehr muss um Probleme "herumprogrammiert" werden, was meistens arg in die falsche Richtung geht. (Hier wollte ich etwa das Controller-Konzept erstmal "verdecken", musste dann aber Actions "tutorialview" nennen. Das wäre normalerweise wohl eher Controller: "Tutorial", Action: "view". :?)

Na ja, wie auch immer. Wer mag, kann ja mal reinschauen und mir sagen, wie verständlich der Grundaufbau bzw. das Dateisystemlayout so noch ist.
 

Anhänge

Ja, habe ich bekommen. Im Prinzip ist die Funktion, die ich in den letzten Post reinkopiert habe, die Lösung.

Hab's mit deinem Dump (siehe Post #10) noch mal getestet. Für die Tabelle "kategorien" habe ich die beiden Felder "id" und "name" angenommen. Wenn das passt, sollte der Code hier prinzipiell laufen.

suche.php:

PHP:
<?php

require_once 'config.inc.php';

/**
 * Führt Suche durch, gibt Ergebnisse als Array zurück
 *
 * @param mysqli $db       Das MySQL-Objekt
 * @param string $keywords Nach welchem Begriff(en) suchen?
 * @param int    $category In welcher Kategorie suchen? (0 für alle)
 * @param bool   $inTitle  Im Titel suchen?
 * @param bool   $inText   Im Text suchen?
 * @return array
 */
function performSearch(mysqli $db, $keywords, $category = 0, $inTitle = true,
                       $inText = true)
{
    /* Parameter validieren */

    $keywords = trim($keywords);
    $category = (int) $category;
    $inTitle  = (bool) $inTitle;
    $inText   = (bool) $inText;
    $results  = array();

    /* Abbruchbedingungen */

    if ($keywords == '') return array();

    /* WHERE-Bedingungen zusammenstellen */

    $conditions = array();

    $fields = array();
    if ($inTitle) $fields[] = 'name';
    if ($inText)  $fields[] = 'tutorial';
    if (count($fields) == 0) $fields = array('name', 'tutorial');
    $conditions[] = "MATCH (e.`" . implode("`, e.`", $fields) . "`) "
                    . "AGAINST ('" . $db->real_escape_string($keywords) . "')";

    if ($category > 0) {
        $conditions[] = "`kategorie` = '" . $db->real_escape_string($category) . "'";
    }

    $wherePart = " WHERE " . implode(' AND ', $conditions);

    /* Query zusammenbauen */

    $query = "SELECT
                    e.`id`,
                    e.`name`,
                    k.`id`   AS `category_id`,
                    k.`name` AS `category_name`
                FROM
                    `eintraege` e
                LEFT JOIN
                    `kategorien` k
                    ON
                        e.`kategorie` = k.`id`";

    if ($wherePart != '') {
        $query .= $wherePart;
    }

    /* Query zu Debugzwecken anzeigen */

    echo '<pre style="white-space: normal;">' . preg_replace('/\s{2,}/', ' ', $query) . '</pre>';

    /* Query ausführen */

    $result = $db->query($query);
    while ($row = $result->fetch_assoc()) {
        $results[] = $row;
    }

    /* Rückgabe */

    return $results;
}

$title = $_POST['key'] . ' - Suche';
include 'header.php';

/*
 * An dieser Stelle musst du die Variablen aus $_POST so auswerten, dass du der
 * Funktion passende Parameter übergeben kannst. Das solltest du hinbekommen.
 * Der folgende Aufruf ist nur ein Beispiel.
 *
 * (Anstelle von 'peter' also prinzipiell $_POST['key'] übergeben usw.)
 */

$results = performSearch($db, 'peter', 0, true, true);

if (count($results) == 0) {
    echo '<p>Nichts gefunden!</p>';
} else {
    foreach ($results as $result) {
        echo '<p>' . htmlspecialchars($result['name']) . '</p>';
    }
}

include 'footer.php';
 
Boah!!!
Riesen Dank!

Es hat schon funtioniert, als ich aber die Ausgabe anpassen wollte habe ich schon wieder eine Fehlermeldung bekommen:

Parse error: syntax error, unexpected T_ENCAPSED_AND_WHITESPACE, expecting T_STRING or T_VARIABLE or T_NUM_STRING in /is/htdocs/wp1158326_JHB43K6EP5/www/coder/suche.php on line 99

Line 99:
PHP:
echo "<li class=\"ausgabe\"><a href=\"$result['nameurl']\" class=\"ausgabe\">" . htmlspecialchars($result['name']) . "</a></li>";

aus diesem Bereich:

PHP:
else {
    echo "<ul class\"ausgabe\">";
    foreach ($results as $result) {
        echo "<li class=\"ausgabe\"><a href=\"$result['nameurl']\" class=\"ausgabe\">" . htmlspecialchars($result['name']) . "</a></li>";
       }
    echo "</ul>";
    
    }

Kleine Frage klappt es schon mit der Kategorie?

Ich habe nirgendts gesehen wo die Variable $categorie definiert wird.

MfG xXxPeterPanxXx
 
Zurück
Oben