Problem mit dem MySql-connect in einer Klasse

  • Im unten stehenden Script bekomme ich keine Datenbank-Verbindung beim UPDATE über die Funktion 'set_score'..
    Der erste Aufruf von '__construct($table)' funktioniert, sowohl beim SELECT als auch im INSERT.
    Allerdings erhalte ich beim 'set_score' die Meldung
    " DB-Fehler: 1045 : Access denied for user...".
    Für Tipps wäre ich sehr dankbar.

    Udo

    <?php
    class rating{

    public $average = 0;
    public $votes;
    public $gesrating = 0;
    public $status;
    public $table;

    function __construct($table)
    {
    include("rating/connect/rating.open.inc.php");
    $conn = @new mysqli($server, $user, $pass, $dbase);

    if (mysqli_connect_errno() == 0)
    {
    $sql = "SELECT * FROM sterne where bericht = '$table'";
    $ergebnis = $conn->query( $sql );

    while ( $zeile = $ergebnis->fetch_object() )
    {
    $this->id = $zeile->id;
    $this->votes = $zeile->anzahl;
    $this->ipbereich = $zeile->ip;
    $this->gesrating = $zeile->gesrating;
    $this->average = $zeile->average;
    $this->table = $zeile->bericht;
    }
    }
    else
    {
    echo 'DB-Fehler: <span>' .mysqli_connect_errno(). ' : ' .mysqli_connect_error(). '</span>';
    }

    if ($this->id == "" || $this->id == 0)
    {
    $sqln = "INSERT INTO `sterne` (`bericht`, `anzahl`, `rating`, `gesrating`, `average`, `ip`) VALUES ('$table', 0, 0, 0, 0, 'auto');";

    $ergebnis = $conn->query( $sqln );
    }

    $conn->close();
    }


    function set_score($score, $ip)
    {
    $rown = "SELECT ip FROM sterne where bericht = $this->table";
    $ergebnis = $conn->query( $rown );

    while ( $zeile = $ergebnis->fetch_object() )
    {
    $this->ip = $zeile->ip;
    }

    $iparray = explode("#", $this->ip);

    if (!(in_array($ip, $iparray)))
    {
    $average = round(( ($this->gesrating + $score) * 20 / ($this->votes + 1) ), 0);

    $sqlu = "UPDATE sterne SET anzahl = anzahl + 1, ip = CONCAT(ip, '#', '$ip'), rating = '$score', gesrating = gesrating + '$score', average = '$average' WHERE bericht = $this->table";

    $ergebnis = $conn->query( $sqlu );


    $this->votes++;
    $this->average = $average;
    $this->status = '<span style=\'color:#00ff00; float:right;\'>Danke!&nbsp;</span>';
    }
    else
    {
    $this->status = '<span style=\'color:#00ff00\'>ist schon bewertet</span>';
    }

    }
    }


    function rating_form($table)
    {
    $ip = $_SERVER['REMOTE_ADDR'];
    if(!isset($table) && isset($_GET['table']))
    {
    $table = $_GET['table'];
    }
    $rating = new rating($table);
    $status = "<p class='score'>
    <a onmouseover='Tip(\"schlecht\", ABOVE, true, BGCOLOR, \"#0000ff\", FONTSIZE, \"8pt\", FONTCOLOR, \"#ffffff\", FONTWEIGHT, \"bold\", OPACITY, 94, FADEOUT, 0, PADDING, 5, BORDERWIDTH, 0)' onmouseout='UnTip()' class='score1' href='?score=1&amp;table=$table&amp;user=$ip'>1</a>
    <a onmouseover='Tip(\"bescheiden\", ABOVE, true, BGCOLOR, \"#0000ff\", FONTSIZE, \"8pt\", FONTCOLOR, \"#ffffff\", FONTWEIGHT, \"bold\", OPACITY, 94, FADEOUT, 0, PADDING, 5, BORDERWIDTH, 0)' onmouseout='UnTip()' class='score2' href='?score=2&amp;table=$table&amp;user=$ip'>2</a>
    <a onmouseover='Tip(\"geht so\", ABOVE, true, BGCOLOR, \"#0000ff\", FONTSIZE, \"8pt\", FONTCOLOR, \"#ffffff\", FONTWEIGHT, \"bold\", OPACITY, 94, FADEOUT, 0, PADDING, 5, BORDERWIDTH, 0)' onmouseout='UnTip()' class='score3' href='?score=3&amp;table=$table&amp;user=$ip'>3</a>
    <a onmouseover='Tip(\"gut\", ABOVE, true, BGCOLOR, \"#0000ff\", FONTSIZE, \"8pt\", FONTCOLOR, \"#ffffff\", FONTWEIGHT, \"bold\", OPACITY, 94, FADEOUT, 0, PADDING, 5, BORDERWIDTH, 0)' onmouseout='UnTip()' class='score4' href='?score=4&amp;table=$table&amp;user=$ip'>4</a>
    <a onmouseover='Tip(\"klasse\", ABOVE, true, BGCOLOR, \"#0000ff\", FONTSIZE, \"8pt\", FONTCOLOR, \"#ffffff\", FONTWEIGHT, \"bold\", OPACITY, 94, FADEOUT, 0, PADDING, 5, BORDERWIDTH, 0)' onmouseout='UnTip()' class='score5' href='?score=5&amp;table=$table&amp;user=$ip'>5</a>
    </p>
    ";
    if(isset($_GET['score']))
    {
    $score = $_GET['score'];
    if(is_numeric($score) && $score <=5 && $score >=1 && ($table==$_GET['table']) && isset($_GET['user']) && $ip==$_GET['user'])
    {
    $rating->set_score($score, $ip);
    $status = $rating->status;
    }
    }
    if(!isset($_GET['update'])){ echo "<div class='rating_wrapper'>"; }
    ?>
    <div class="sp_rating">

    <div class="rating"></div>

    <div class="status">
    <?php echo $status; ?>
    </div>

    <div class="base">
    <div class="average" style="width:<?php echo $rating->average; ?>%">
    <?php echo $rating->average; ?>
    </div>
    </div>

    <div class="votes">(<?php echo $rating->votes; ?>)</div>


    </div>
    <?php
    if(!isset($_GET['update'])){ echo "</div>"; }
    }


    if(isset($_GET['update'])&&isset($_GET['table']))
    {
    rating_form($_GET['table']);
    }
    ?>

  • Ok, hab $conn->close entfernt, die Fehlermeldung bleibt. Ist evtl. etwas am Konstruktor falsch? Der erste Aufruf mit SELECT und INSERT funktioniert ja, allerdings nicht beim Aufruf über set_score.

  • Woher soll die Funktion $conn kennen?

    Richtig debuggen
    1. Man bemerkt, dass ein Skript nicht das tut, was es soll.
    2. Man schreibt an den Anfang des Scriptes die Zeile: error_reporting(E_ALL); und ini_set("display_errors", true);
    3. Man versucht, die Stelle die daran Schuld sein kann, schonmal einzugrenzen. Falls dies nicht geht, wird zunächst das komplette Skript als fehlerhaft angesehen.
    4. An markanten Stellen im Skript lässt man sich wichtige Variableninhalte ausgeben und ggf. auch in bedingten Anweisungen eine kurze Ausgabe machen, um zu überprüfen, welche Bedingung ausgeführt wurde (oder auch nicht).
    5. Schritt 3 wird so lange wiederholt, bis Unstimmigkeiten im Skript auffallen
    6. Damit hat man das Problem (Unstimmigkeit) gefunden und kann versuchen diese zu beheben. Hierzu dienen dann die PHP-Dokumentation und andere Quellen als Ratgeber.
    7. Lässt sich das konkrete Problem trotzdem nicht beheben, kann man in Foren um Rat fragen.
    8. Das Programm läuft und man kann die Debug-Ausgaben wieder entfernen.

  • Vielen Dank.
    Ich denke, ich komme dem Problem auf die Spur (4.-6.).
    Falls es dennoch weitere Probleme gibt, melde ich mich wieder (7.).

  • Hab mir nur mal grad set_score angeschaut.

    a) Das funktioniert so nicht, $this->table muß entweder konkateniert oder in geschweifte Klammern gesetzt werden:

    PHP
    // entweder so:
    $rown = "SELECT ip FROM sterne where bericht = ".$this->table;
    // oder:
    $rown = "SELECT ip FROM sterne where bericht = {$this->table}";
    // Damit hättest du schonmal ein funktionierendes Äquivalent zu dem was du geschrieben hast. Da ich aber mal davon ausgehe, dass in $this->table ein String steht, fehlen noch die einfachen Hochkommata:
    $rown = "SELECT ip FROM sterne where bericht = '{$this->table}'";

    b) Woher soll die Funktion set_score die Variable $conn kennen? Eigentlich müsste da eine Fehlermeldung kommen wie: Fatal error: Call to a member function query() on a non-object in
    Es sei denn du hast hier gekürzten Code gepostet, was natürlich Hilfestellungen erschwert oder gar völlig unmöglich macht.


    Ansonsten hatte Bandit ja schon geschrieben, dass $conn->close() rausmuss und hast du ja wohl auch schon entfernt.
    Du solltest $conn als private Eigenschaft deiner Klasse anlegen, dann kannst du in set_score auch mit $this->conn auf die Verbindung zugreifen.
    Und du solltest die Verbindung nicht in der Klasse herstellen, sondern im Programmcore und dann an den Konstruktor übergeben.
    Selbst wenn du momentan ausschließlich in dieser Klasse eine DB-Verbindung benötigst, kannst du sicher sein, dass sich das nichtmal ändert? Außerdem verhindert es eine anpassungsfreie Wiederverwendbarkeit der Klasse für andere Projekte die bereits eine Datenbankverbindung bereitstellen.

    "Programming today is a race between software engineers
    striving to build bigger and better idiot-proof programs,
    and the universe trying to build bigger and better idiots.
    So far, the universe is winning."
    Rick Cook

  • nur mal so am rande.. wieso kommt dann nen access denied for user??



    Das frage ich mich auch. Bei dem Code den er hier gepostet hat kommt Fatal error: Call to a member function query() on a non-object in...

    Daher ja meine Vermutung, dass er geänderten Code hier gepostet hat, und nicht 1zu1 den der seine Fehlermeldung erzeugt.

    "Programming today is a race between software engineers
    striving to build bigger and better idiot-proof programs,
    and the universe trying to build bigger and better idiots.
    So far, the universe is winning."
    Rick Cook