Jnnbo - Nicht angemeldet: Fatal error: Call to a member function execute()

Hallo,

ich wollte in meine Funktion ein LIMIT mit einbauen:

	function hersteller($mysqli) {

		define ('LIMIT', 4);

		$sql = "SELECT COUNT(*) AS `amount` FROM web_hersteller";
		$res = $mysqli->prepare($sql);
		$res->execute();
		$res->bind_result($amount);
		$res->fetch();
		$res->close();

		$offset=0;

		if (isset($_GET['page']) && $_GET['page'] > 1 ) {
		    $offset = (intval($_GET['page']) - 1 ) * LIMIT;
		}

		$pages = ceil($amount/LIMIT);


		$stmt = $mysqli->prepare("SELECT h_id, h_titel, h_titelURL, h_status 
					  FROM web_hersteller  
					  LIMIT '. LIMIT . ' OFFSET ' . $offset");
		$stmt->execute();
		$stmt->bind_result($h_id, $h_titel, $h_titelURL, $h_status);
		$stmt->store_result();
	 	
		if($stmt->num_rows() >  0) {     
			while ($stmt->fetch()){
				$hersteller[] = array( 
					'h_id' 		=> $h_id, 
					'h_titel' 	=> $h_titel, 
					'h_titelURL' 	=> $h_titelURL, 
					'h_status'	=> $h_status
				);
			}
			return $hersteller;
			}
}

Jetzt erhalte ich diese Meldung: Fatal error: Call to a member function execute() on a non-object

In Zeile 25 steht:

$stmt->execute();

Kann ich ein LIMIT so wie ich es mir vorstelle innerhalb von einer Funktion nicht verwenden?

PS: Ich bin derzeit mit dem neuen Microsoft Edge online. Kann mich leider nicht einloggen.

  1. Hi,

    ich wollte in meine Funktion ein LIMIT mit einbauen:

    gut und schön, nur richtig sollte es sein. ;-)

    	function hersteller($mysqli) {
    		define ('LIMIT', 4);
       [...]
    		$stmt = $mysqli->prepare("SELECT h_id, h_titel, h_titelURL, h_status 
    					  FROM web_hersteller  
    					  LIMIT '. LIMIT . ' OFFSET ' . $offset");
    		$stmt->execute();
    

    Ich hab mal alles weggelassen, was mit dem Fehler nichts zu tun hat.

    Jetzt erhalte ich diese Meldung: Fatal error: Call to a member function execute() on a non-object

    Im Manual heißt es: "mysqli_prepare() returns a statement object or FALSE if an error occurred."

    Letzteres ist hier wohl passiert - prepare() hat wegen des Syntaxfehlers ein lapidares FALSE zurückgegeben, und FALSE hat keine execute-Methode. Immer wieder die ungenügende Kontrolle auf aufgetretene Fehler ...
    Schau dir das SQL-Statement mal genau an. Als erstes fällt auf, dass du den Wert für die LIMIT-Klausel in Anführungszeichen setzen willst. Wozu? Es ist ein simpler Zahlenwert. Und dasselbe gilt für OFFSET, nur dass du hier auch noch das schließende Anführungszeichen vergessen hast. Nein, genaugenommen ist das öffnende schon überflüssig und unsinnig.

    PS: Ich bin derzeit mit dem neuen Microsoft Edge online. Kann mich leider nicht einloggen.

    Das muss ich jetzt vermutlich nicht verstehen.

    So long,
     Martin

    1. Moin!

      PS: Ich bin derzeit mit dem neuen Microsoft Edge online. Kann mich leider nicht einloggen.

      Das muss ich jetzt vermutlich nicht verstehen.

      Der Browser von der 10. M$-Fenstersammlung. Warum er sich nicht einloggen weiss ich aber auch nicht.

      Jörg Reinholz

      1. Moin,

        Der Browser von der 10. M$-Fenstersammlung. Warum er sich nicht einloggen weiss ich aber auch nicht.

        weil ich ständig die Meldung erhalte "Ungültige Zugangsdaten" Bin mir aber 98% sicher dass das Kennwort stimmt, denn ich nehme für alles das gleiche.

        1. Hallo Jnnbo - Nicht angemeldet,

          Der Browser von der 10. M$-Fenstersammlung. Warum er sich nicht einloggen weiss ich aber auch nicht.

          Gerade getestet - ohne Probleme.

          weil ich ständig die Meldung erhalte "Ungültige Zugangsdaten" Bin mir aber 98% sicher dass das Kennwort stimmt,

          Dann ist vielleicht der Benutzername oder die Mailadresse falsch.

          denn ich nehme für alles das gleiche.

          Dass das keine richtig gute Idee ist, weißt du sicher selbst.

          Bis demnächst
          Matthias

          --
          Signaturen sind bloed (Steel) und Markdown ist mächtig.
        2. Moin!

          weil ich ständig die Meldung erhalte "Ungültige Zugangsdaten" Bin mir aber 98% sicher dass das Kennwort stimmt, denn ich nehme für alles das gleiche.

          Wenn Du auf dem gleichen OS einen alternativen Browser installierst kann Du ganz einfach herausfinden ob es an Edge oder den fehlenden 2% liegt.

          Jörg Reinholz

    2. Moin,

      Schau dir das SQL-Statement mal genau an. Als erstes fällt auf, dass du den Wert für die LIMIT-Klausel in Anführungszeichen setzen willst. Wozu? Es ist ein simpler Zahlenwert. Und dasselbe gilt für OFFSET, nur dass du hier auch noch das schließende Anführungszeichen vergessen hast. Nein, genaugenommen ist das öffnende schon überflüssig und unsinnig.

      wenn ich es wie folgt ändere

      $stmt = $mysqli->prepare("SELECT h_id, h_titel, h_titelURL, h_status 
      			  FROM web_hersteller  
      			  LIMIT 4 
      			  OFFSET $offset");
      

      funktioniert es.

      Wenn ich mein //define ('LIMIT', 4); wieder einsetzte knallt es wieder.

    3. Hi,

      		$stmt = $mysqli->prepare("SELECT h_id, h_titel, h_titelURL, h_status 
      					  FROM web_hersteller  
      					  LIMIT '. LIMIT . ' OFFSET ' . $offset");
      

      Schau dir das SQL-Statement mal genau an. Als erstes fällt auf, dass du den Wert für die LIMIT-Klausel in Anführungszeichen setzen willst.

      Meine Vermutung ist eher, daß hier der String beendet und mit dem Wert der weiter oben definierten Konstante LIMIT verknüpft werden soll. Was leider an der falschen Sorte Anführungszeichen scheitert ...

      cu,
      Andreas a/k/a MudGuard

      1. Hallo,

        		$stmt = $mysqli->prepare("SELECT h_id, h_titel, h_titelURL, h_status 
        					  FROM web_hersteller  
        					  LIMIT '. LIMIT . ' OFFSET ' . $offset");
        

        Schau dir das SQL-Statement mal genau an. Als erstes fällt auf, dass du den Wert für die LIMIT-Klausel in Anführungszeichen setzen willst.

        Meine Vermutung ist eher, daß hier der String beendet und mit dem Wert der weiter oben definierten Konstante LIMIT verknüpft werden soll. Was leider an der falschen Sorte Anführungszeichen scheitert ...

        das stimmt auffallend. Verdammt, warum habe ich das nicht bemerkt? War ich so abwesend ...?

        So long,
         Martin

    4. Hallo,

      hab noch eine zweite Frage. Um die Seitenzahlen anzuzeigen habe ich diesen Code:

      if ($amount > LIMIT) { 
            
           echo "<div class=\"pagination\">";
            for($i=1;$i<=$pages;$i++)
             {
             $active = "";
                 if ($_SERVER["QUERY_STRING"] == "page=".$i): $active = "active"; endif;
             echo '<a href="hersteller?page='.$i.'" class="page '.$active.'">'.$i.'</a>';
             } 
           echo "</div>";
          }
      

      Dieser kann ich nicht mit in die Funktion packen, denn meine Ausgabe gestallte ich so

      $hersteller = hersteller($mysqli);
      
      foreach($hersteller as $array){
       echo htmlspecialchars($array['h_titel']);
      }
      

      Jetzt erhalte ich natürlich weitere Fehlermeldungen: Notice: Use of undefined constant LIMIT - assumed 'LIMIT' in

      Das heißt ich sollte hier am besten komplett auf eine Funktion verzichten und den SQL Code direkt mit in die jeweilige PHP Datei schreiben?

      1. @@Jnnbo - Nicht angemeldet

        hab noch eine zweite Frage. Um die Seitenzahlen anzuzeigen habe ich diesen Code:

        if ($amount > LIMIT) { 
              
             echo "<div class=\"pagination\">";
              for($i=1;$i<=$pages;$i++)
               {
               $active = "";
                   if ($_SERVER["QUERY_STRING"] == "page=".$i): $active = "active"; endif;
               echo '<a href="hersteller?page='.$i.'" class="page '.$active.'">'.$i.'</a>';
               } 
             echo "</div>";
            }
        

        Ich hab eine dritte Frage: Warum ist der Code so unübersichtlich? Nicht HTML in PHP schachteln, sondern PHP in HTML.

        <?php if ($amount > LIMIT): ?>
          <div class="pagination">
          <?php for($i = 1; $i <= $pages; $i++): ?>
            <?php $active = ($_SERVER['QUERY_STRING'] == 'page='.$i) ? 'active' : ''; ?>
            <a href="hersteller?page=<?= $i ?>" class="page <?= $active ?>"><?= $i ?></a>
          <?php endfor; ?>
          </div>
        <?php endif; ?>
        

        oder gleich

        <?php if ($amount > LIMIT): ?>
          <div class="pagination">
          <?php for($i = 1; $i <= $pages; $i++): ?>
            <a href="hersteller?page=<?= $i ?>" class="page 
              <?php if ($_SERVER['QUERY_STRING'] == 'page='.$i): ?>
                active
              <?php endif; ?>
            "><?= $i ?></a>
          <?php endfor; ?>
          </div>
        <?php endif; ?>
        

        Ich glaub, ich weiß auch die Antwort: Weil du vollkommen beratungsresistent bist.

        Eine vierte Frage hätte ich aber auch noch: Warum ist die aktuelle Seite im Menü verlinkt?

        LLAP 🖖

        --
        Ist diese Antwort anstößig? Dann könnte sie nützlich sein.
        1. Hallo,

          Ich glaub, ich weiß auch die Antwort: Weil du vollkommen beratungsresistent bist.

          nein bin ich nicht. Warum sollte ich ständig PHP auf und wieder zu machen, wenn es erlaubt ist HTML in PHP auszugeben. Wenn du diesen Code unübersichtlich findest ist das OK, ich sehe keine Vor und Nachteile. Daher werde ich es weiter so umsetzten wie ICH es gelernt habe.

          Eine vierte Frage hätte ich aber auch noch: Warum ist die aktuelle Seite im Menü verlinkt?

          Warum nicht? Mein Menü wird an vielen Stellen ausgegeben, glaubst du ich prüfen zusätzlich mit PHP noch befindet sich der User (ich selber) auf der aktuellen Seite, dann entferne mit PHP den Link? Sorry in dieser Zeit kann ich viel wichtigeres umsetzten.

          1. Moin,

            Ich glaub, ich weiß auch die Antwort: Weil du vollkommen beratungsresistent bist.

            nein bin ich nicht. Warum sollte ich ständig PHP auf und wieder zu machen, wenn es erlaubt ist HTML in PHP auszugeben. Wenn du diesen Code unübersichtlich findest ist das OK, ich sehe keine Vor und Nachteile. Daher werde ich es weiter so umsetzten wie ICH es gelernt habe.

            das ist okay, und ehrlich gesagt finde ich es meistens(!) auch übersichtlicher, HTML mit PHP auszugeben - übersichtlicher jedenfalls als das, was Gunnar da vorschlägt.

            Klarer Nachteil allerdings: Man muss korrektes Escaping beachten. Für HTML-Passagen, die mehr als zwei, drei Zeilen umfassen, bietet sich auch noch die HEREDOC-Notation an.

            Eine vierte Frage hätte ich aber auch noch: Warum ist die aktuelle Seite im Menü verlinkt?

            Warum nicht? Mein Menü wird an vielen Stellen ausgegeben, glaubst du ich prüfen zusätzlich mit PHP noch befindet sich der User (ich selber) auf der aktuellen Seite, dann entferne mit PHP den Link? Sorry in dieser Zeit kann ich viel wichtigeres umsetzten.

            Schon recht. Geschmackssache. Das mit dem Nicht-Verlinken der aktuellen Seite bzw. die Meckerei in diesem Punkt ist bei Gunnar vermutlich eine Art Reflex, das muss man nicht so ernst nehmen.

            So long,
             Martin

          2. @@Jnnbo - Nicht angemeldet

            Daher werde ich es weiter so umsetzten wie ICH es gelernt habe.

            Du hast gelernt, mitten in geschweiften Klammern
            if ($_SERVER["QUERY_STRING"] == "page=".$i): $active = "active"; endif;
            zu schreiben?

            Eine vierte Frage hätte ich aber auch noch: Warum ist die aktuelle Seite im Menü verlinkt?

            Mein Menü wird an vielen Stellen ausgegeben, glaubst du ich prüfen zusätzlich mit PHP noch befindet sich der User (ich selber) auf der aktuellen Seite

            Tust du nicht genau das mit if ($_SERVER["QUERY_STRING"] == "page=".$i) schon?

            Anstelle eine Klasse "active" zu setzen oder auch nicht kannst du genauso gut href setzten oder nicht.

            dann entferne mit PHP den Link?

            Wie gesagt, das a-Element kann bleiben, auch ohne href-Attribut.

            Für die Barrierefreiheit wäre zu überlegen, ob man den Menüpunkt trotzdem vorlesen lässt (mit der Anmerkung, dass das die aktuelle Seite ist), also tabindex="1" aria-describedby="aktuelle Seite" setzt. [The Accessible Current Page Link Conundrum]

            LLAP 🖖

            --
            Ist diese Antwort anstößig? Dann könnte sie nützlich sein.
          3. @@Jnnbo - Nicht angemeldet

            Wenn du diesen Code unübersichtlich findest ist das OK, ich sehe keine Vor und Nachteile.

            Die Nachteile, die ich sehe, hatte ich oft genug verlinkt. Die Escape-Hölle wurde hier auch nochmal angesprochen.

            Ein weiterer Vorteil, bei der Ausgabe ausschließlich die alternative Schreibweise für Kontrollstrukturen zu verwenden, ist saubere Programmierung. Wenn man schon nicht MVC o.ä. macht, dann doch wenigstens EVA (Eingabe – Verarbeitung – Ausgabe).

            Und bei der Ausgabe darf keine Businesslogik mehr vorkommen. Das ist gewährleistet, wenn man sich dabei auf <?php echo;?> (d.h. meist <?php echo htmlspecialchars(); ?>) und Kontrollstrukturen (if, for u.dgl.) beschränkt, was dem Funktionsumfang einer Template-Sprache entspricht.

            Daher werde ich es weiter so umsetzten wie ICH es gelernt habe.

            Dann werde ich dir bei jedem Problem, mit dem du hier im Forum aufschlägst, aufs Neue sagen: mit vernünftigem Code wär das nicht passiert.

            LLAP 🖖

            --
            Ist diese Antwort anstößig? Dann könnte sie nützlich sein.
            1. Hallo,

              Dann werde ich dir bei jedem Problem, mit dem du hier im Forum aufschlägst, aufs Neue sagen: mit vernünftigem Code wär das nicht passiert.

              halten wir also fest, hätte ich DEINE Schreibweise genommen, hätte ich dieses Problem: http://forum.selfhtml.org/self/2015/aug/14/fatal-error-call-to-a-member-function-execute/1647982#m1647982 nicht? Halte ich zwar für ein Gerücht, aber ich werde gleich mal deine Schreibweise testen.

              1. halten wir also fest, hätte ich DEINE Schreibweise genommen, hätte ich dieses Problem: http://forum.selfhtml.org/self/2015/aug/14/fatal-error-call-to-a-member-function-execute/1647982#m1647982 nicht? Halte ich zwar für ein Gerücht, aber ich werde gleich mal deine Schreibweise testen.

                Das passiert also wenn man den gleichen Rechner verwendet NICHT eingeloggt ist und Microsoft Edge nutzt. Ich trage mein Namen ein und er nimmt den Namen meiner Freundin. Ganz klasse. Erst kann man sich nicht einloggen, weil Benutzername und oder Kennwort nicht stimmt dann übernimmt er irgendwelche Namen.

                1. Hallo Jnnbo,

                  Ich trage mein Namen ein und er nimmt den Namen meiner Freundin.

                  Nö, "er" (die Software) nimmt den Namen, den du dort eingetragen hast und keinen anderen.

                  Der Default-Wert ist allerdings der Name, der als letztes verwendet wurde.

                  Ganz klasse. Erst kann man sich nicht einloggen, weil Benutzername und oder Kennwort nicht stimmt dann übernimmt er irgendwelche Namen.

                  Wenn Benutzername oder Kennwort nicht stimmen, kannst du das Passwort zurücksetzen lassen.

                  LG,
                  CK