Achot: function LIKE ?%

Hallo,

kann ich in einer Funktion kein LIKE ?% verwenden? Ich erhalte einen

Fatal error: Call to a member function bind_param() on a non-object

if ($filter == true) {

  $param  = $filter;

  $stmt = $mysqli->prepare($select . "WHERE locationname LIKE ?% ORDER by locationname ASC" );
  $stmt->bind_param("s", $param);

} else {
  $stmt = $mysqli->prepare($select . "ORDER by locationname ASC" );
}

EDIT: Komisch so geht es

if ($filter == true) {

$param = $filter.'%';

  $stmt = $mysqli->prepare($select . "WHERE locationname LIKE ? ORDER by locationname ASC" );
  $stmt->bind_param("s", $param);
}
else {
  $stmt = $mysqli->prepare($select . "ORDER by locationname ASC" );
        }

Aber warum muss ich den Umweg über ein zweite Variable gehen?

  1. Tach!

    kann ich in einer Funktion kein LIKE ?% verwenden? Ich erhalte einen

    Fatal error: Call to a member function bind_param() on a non-object

    Das ist ein Folgefehler. Das Prepare liefert false zurück. Du ignorierst das und versuchst das false wie ein Objekt zu verwenden. Das bringt dann die besagte PHP-Fehlermeldung. Die eigentliche Ursache wäre über $mysqli->error abrufbar.

    $stmt = $mysqli->prepare($select . "WHERE locationname LIKE ?% ORDER by locationname ASC" );

    Das ist eben ungültige MySQL-Syntax.

    EDIT: Komisch so geht es

    $param = $filter.'%';
    
      $stmt = $mysqli->prepare($select . "WHERE locationname LIKE ? ORDER by locationname ASC" );
    

    Aber warum muss ich den Umweg über ein zweite Variable gehen?

    Weil du nur so eine gültige Syntax erzeugst. Die Jokerzeichen müssen Bestandteil des Strings sein. Die Syntax ohne Prepared Statements wäre … LIKE 'foo%' …. Die Platzhalter in Prepared Statements ersetzen nur komplette Werte.

    dedlfix.

  2. Hallo Achot,

    das ist zwar abseits deines eigentlichen Problems, aber dennoch wichtig:

    if ($filter == true) {
      $param  = $filter;
      // …
    }
    

    Ich gehe mal stark davon aus, dass du überprüfen möchtest, ob die Variable $filter einen leeren String enthält, liege ich da richtig? Dann solltest du if(!empty($filter)) verwenden. – Bei $filter = "0"; würde er bei deiner derzeitigen Bedingung nicht ins if hinein gehen – Informationen zur impliziten Typumwandlung in PHP.

    Generell musst du auch nicht unbedingt if($var == true) schreiben, weil if($var) äquivalent und weniger Schreibarbeit ist.

    Ceterum Censeo: Umkopieren von Variablen ist unnötig.

    Gruß
    Julius

    --
    „Unterschätze niemals die Datenübertragungsrate eines mit Bändern vollgeladenen Kombis, der über die Autobahn rast.“
    Andrew S. Tanenbaum (Quelle)
    1. Tach!

      Dann solltest du if(!empty($filter)) verwenden. – Bei $filter = "0"; würde er bei deiner derzeitigen Bedingung nicht ins if hinein gehen

      Mit empty() aber auch nicht.

      dedlfix.

      1. Hallo dedlfix,

        Dann solltest du if(!empty($filter)) verwenden. – Bei $filter = "0"; würde er bei deiner derzeitigen Bedingung nicht ins if hinein gehen

        Mit empty() aber auch nicht.

        Mit einem $string != '' kann ich aber einen leeren String abfangen, oder hat auch das wieder seine Tücken?

        Gruß
        Julius

        --
        „Unterschätze niemals die Datenübertragungsrate eines mit Bändern vollgeladenen Kombis, der über die Autobahn rast.“
        Andrew S. Tanenbaum (Quelle)
        1. Tach!

          Mit empty() aber auch nicht.

          Mit einem $string != '' kann ich aber einen leeren String abfangen, oder hat auch das wieder seine Tücken?

          Der Link beantwortet diese Frage. Abseits davon gibt es keine versteckten Überraschungen damit.

          Du kannst ja mal in den Tabellen alles verdecken außer der Header-Zeile und -Spalte und dann die Antworten zu geben versuchen.

          dedlfix.

          1. Hallo dedlfix,

            Mit empty() aber auch nicht.

            Mit einem $string != '' kann ich aber einen leeren String abfangen, oder hat auch das wieder seine Tücken?

            Der Link beantwortet diese Frage.

            Ja: Nein, es funktioniert nicht.

            Du kannst ja mal in den Tabellen alles verdecken außer der Header-Zeile und -Spalte und dann die Antworten zu geben versuchen.

            Habe ich gemacht. empty() verhält sich anders als ich es urspringlich dachte, gut zu wissen. Danke!

            Gruß
            Julius

            --
            „Unterschätze niemals die Datenübertragungsrate eines mit Bändern vollgeladenen Kombis, der über die Autobahn rast.“
            Andrew S. Tanenbaum (Quelle)
        2. Hallo Julius,

          Mit einem $string != '' kann ich aber einen leeren String abfangen, oder hat auch das wieder seine Tücken?

          Bestimmt. 😉 PHP ist quasi die Tücke in Person. Mit $string !== '' solltest du auf der sichereren Seite sein.

          Bis demnächst
          Matthias

          --
          Rosen sind rot.
          1. Hallo Matthias,

            Mit einem $string != '' kann ich aber einen leeren String abfangen, oder hat auch das wieder seine Tücken?

            Bestimmt. 😉 PHP ist quasi die Tücke in Person.

            Mhhh, ich glaube langsam zu verstehen, warum einige (viele?) so auf das Typensystem und die -umwandlungen in PHP drauf hauen...

            Mit $string !== '' solltest du auf der sichereren Seite sein.

            Dann müsste ich aber zusätzlich noch null via is_null() mit ausschließen...

            Gruß
            Julius

            --
            „Unterschätze niemals die Datenübertragungsrate eines mit Bändern vollgeladenen Kombis, der über die Autobahn rast.“
            Andrew S. Tanenbaum (Quelle)
      2. Blödes Type Juggling in PHP... Und wie macht man's am richtigsten?

        function isFilledString($s) {
            return is_string($s) && strlen($s) > 0;
        }
        

        So? Ggf. noch mit einem trim() dabei?

        Zum Thema:

        Man könnte die PHP-seitige Stringverkettung auch im SQL durchführen.

        $stmt = $mysqli->prepare($select . "WHERE locationname LIKE CONCAT(?, '%') ORDER by locationname ASC" );
        

        Rolf

        1. Tach!

          Blödes Type Juggling in PHP... Und wie macht man's am richtigsten?

          Wenn es der Anwendungsfall hergibt, definiert man, dass '0' wie Leerstring zu den ungültigen Werten gehört und fertig. Das passt in vielen Situationen.

          Ansonsten geht jeder Ausdruck, für den die Wahrheitstabelle die passenden Ergebnisse liefert. Zum Beispiel !empty($_POST['key']) or $_POST['key'] == '0' Da es keine anderen Typen als Strings regulär im $_POST/$_GET-Array geben kann, muss man noch nicht mal typsicher vergleichen, weil alle anderen Fälle bereits vom empty() eindeutig entschieden werden.

          dedlfix.

    2. Hallo,

      Ceterum Censeo: Umkopieren von Variablen ist unnötig.

      wenn ich dieses so einfüge:

      $stmt = $mysqli->prepare($select . "WHERE locationname LIKE ? ORDER by locationname ASC" );
      $stmt->bind_param("s", $filter.'%');
      

      erhalte ich folgende Meldung

      Fatal error: Cannot pass parameter 2 by reference

      daher bin ich den Weg über

      $param = $filter.'%';
      

      gegangen.

      1. Hallo Achot,

        $stmt = $mysqli->prepare($select . "WHERE locationname LIKE ? ORDER by locationname ASC" );
        $stmt->bind_param("s", $filter.'%');
        

        erhalte ich folgende Meldung

        Fatal error: Cannot pass parameter 2 by reference

        Man muss bind_param() anscheinend eine Referenz (also eine Variable) übergeben und keinen konkreten Wert. Gut zu wissen, wieder was gelernt :-)

        Gruß
        Julius

        --
        „Unterschätze niemals die Datenübertragungsrate eines mit Bändern vollgeladenen Kombis, der über die Autobahn rast.“
        Andrew S. Tanenbaum (Quelle)
        1. Tach!

          Man muss bind_param() anscheinend eine Referenz (also eine Variable) übergeben und keinen konkreten Wert.

          Man muss da einen Container übergeben, der da gebunden werden soll. Und dem man für das nächste Execute einen neuen Wert zuweisen kann. Ein berechneter Ausdruck ist da nicht geeignet, es muss eine Variable sein. Das ist der Nachteil an mysqli, dass es da so strikt ist. PDO ist in der Hinsicht anwenderfreundlicher, dem kann man Werte auch als Literal oder berechneten Ausdruck übergeben.

          dedlfix.

        2. Genau. Das liegt daran, dass MySQLI es einem ersparen möchte, die Parameter ständig neu zu binden. Man macht einmal den Prepare, bind_param und ggf. bind_result, und kann dann in einer Schleife das Statement wiederholt ausführen, bzw. in einer Schleife den fetch laufen lassen. Die gebundenen Parameter werden bei jedem execute neu ausgelesen, bzw. bei jedem fetch neu gefüllt.

          Das geht nur mit Referenzen.

          Rolf