Verwendung von return innerhalb einer rekursiven Funktion in PHP

Lesezeit: 5 Minuten

Benutzer-Avatar
Codefreak

Hier ist meine Frage: Ich versuche, einen zufälligen Barcode für meine Anwendung zu erstellen. Ich möchte überprüfen, ob dieser Code bereits in der Spalte enthalten ist, und dann eine neue Nummer generieren. Überprüfen Sie es erneut. Wenn es eindeutig ist, geben Sie es an den Aufrufer zurück, sonst generieren Sie es erneut.

Ich verwende zu diesem Zweck eine rekursive Funktion. Ich habe die Nummern 1,2,3,4 in meiner Datenbank hinzugefügt, also jedes Mal, wenn es läuft. Es muss mir 5,6,7,8,9 oder 10 anzeigen.

Hier meine Funktion:

function generate_barcode(){
    $barcode = rand(1,10);
    $bquery = mysql_num_rows(mysql_query("SELECT * FROM stock_item WHERE barcode="$barcode""));
    if($bquery==1){
        generate_barcode();
    }else{
        return $barcode;    
    }
 }

Und ich habe es gerade so getestet:

 $a = generate_barcode();
 if(isset($a))
 {
   echo $a;
 }
 else
 {
  echo 'Not Set';
 }  

Das Problem ist also, dass es mir manchmal “Not Set” anzeigt, aber ich möchte, dass es immer eine eindeutige Nummer generiert. Ich füge die Daten nicht ein, daher ist es kein Problem, dass alle Nummern reserviert sind.

Jemand führt mich einfach und lässt mich wissen, was mit dem Code nicht stimmt. Ich kann dafür andere Ansätze verwenden, aber ich muss wissen, was mit dem bereitgestellten Code falsch ist.

  • Veraltetes mysql* Bitte verwenden Sie keine mysql_*-Funktionen in neuem Code. Sie werden nicht mehr gepflegt und sind offiziell veraltet. Verwenden Sie mysqli oder PDO

    – PHPhil

    25. Juli 2015 um 8:03 Uhr


  • @PHPhil verwendet Shared Hosting, das nur mysql unterstützt

    – Codefreak

    25. Juli 2015 um 8:05 Uhr

  • Auf die kannst du sowieso verzichten if($bquery==1) Weil if($bquery) ist ein klein wenig besser.

    – Künstlerischer Phönix

    25. Juli 2015 um 8:24 Uhr

  • Dies ist kein rekursiver Algorithmus, es ist ein iterativer Algorithmus, der vergewaltigt wird, um wie eine Rekursion auszusehen. Außerdem endet es in einer Endlosschleife, sobald 10 Barcodes generiert wurden.

    – hek2mgl

    25. Juli 2015 um 8:39 Uhr


  • Diese Frage (und ihre akzeptierte Antwort) wird auf Meta diskutiert.

    – Ouflak

    23. Mai um 10:17 Uhr


Benutzer-Avatar
Carsten Maßmann

Sie müssen auch die generierte Nummer von Ihrem rekursiven Aufruf zurückgeben, wie zum Beispiel:

function generate_barcode() {
  $barcode = rand(1, 10);
  $bquery = mysql_num_rows(mysql_query("SELECT * FROM stock_item WHERE barcode="$barcode""));
  if ($bquery == 1) {
    return generate_barcode(); // changed!
  }
  else {
    return $barcode;
  }
}

(Sie sollten eine Art Exit für den Fall einbauen, dass alle Zahlen ‘besetzt’ sind. Diese aktuelle Version ruft sich selbst rekursiv auf, bis das PHP-Rekursionslimit erreicht ist, und wirft dann einen Fehler aus.)

  • Das ist Blödsinn! Wie ist das ein rekursiver Algorithmus? Ersetzen Sie es durch eine While-Schleife, das war’s. Und wenn Sie es durch eine While-Schleife ersetzt haben, werden Sie vielleicht bemerken, dass der Code zu einer Endlosschleife führt, nachdem 10 Barcodes generiert wurden.

    – hek2mgl

    25. Juli 2015 um 8:43 Uhr


  • Hey @hek2mgl, OP hat bereits zugegeben, dass der gewählte Ansatz „nicht der beste“ war und da hat Es wurde bereits darüber diskutiert, dass dies rekursiv ist – siehe oben. Er wollte einfach wissen, warum sein Code nicht funktionierte. Es gibt also keinen Grund, hier missbräuchlich zu werden.

    – Carsten Massmann

    25. Juli 2015 um 9:08 Uhr

  • Tatsächlich kann jeder rekursive Algorithmus durch einen iterativen ersetzt werden – was auch bedeutet, dass jeder iterative Algorithmus durch einen rekursiven ersetzt werden kann. Also wenn ich sage dies ist kein rekursiver Algorithmus Ich war nicht ganz richtig. Natürlich können Sie es mit einem rekursiven Algorithmus lösen – wie Sie gezeigt haben. Beim Lesen der Frage war ich jedoch verwirrt, warum das OP versucht, das Problem rekursiv zu lösen. Das macht meiner Meinung nach keinen Sinn und ist kontraproduktiv. Abgesehen davon ist es offensichtlich, dass dieser Algorithmus, unabhängig davon, ob er rekursiv oder iterativ geschrieben ist, das Problem nicht lösen würde.

    – hek2mgl

    25. Juli 2015 um 11:37 Uhr


Eine return-Anweisung übergibt einen Wert zurück an den unmittelbaren Aufrufer des Aufrufrahmens der aktuellen Funktion. Im Falle einer Rekursion kann dieser unmittelbare Aufrufer ein weiterer Aufruf derselben Funktion sein.

Sie können dem entgegenwirken, indem Sie Folgendes tun:

Veränderung:

generate_barcode();

zu:

return generate_barcode();

Benutzer-Avatar
KünstlerischPhoenix

Mach es so:

$hash = md5( microtime().rand(0, 1000) );

Das Hinzufügen einer Zeitkomponente bedeutet, dass dies der Fall ist ja schon einzigartig sein. Es sei denn, Sie haben 32^32 davon.

Wenn es nur Zahlen sein müssen, verwenden Sie einfach den pkey und fügen Sie für Aussehen etwa 10000 hinzu. oder so.

Nach sorgfältiger Analyse – daran ist nichts auszusetzen, aber:

$a = generate_barcode();
if(isset($a))  <<< this bit

Sehen Sie, wie Sie den eindeutigen Wert zurückgeben, und dann sagen Sie es isset mein einzigartiger Wert, und $a wird immer gesetzt, denn wenn nicht, rekursivieren Sie die Funktion, bis sie es ist, und geben sie dann zurück. Daher ist es immer eingestellt…

  • Ich habe erwähnt, dass ich viele andere Ansätze habe, um dies zu erreichen, möchte aber wissen, was an meinem Code falsch ist.

    – Codefreak

    25. Juli 2015 um 8:09 Uhr

  • wie ist das rekursiv? du führst es einmal aus

    – Künstlerischer Phönix

    25. Juli 2015 um 8:10 Uhr

  • Ist das nicht Rekursion? if($bquery==1) { generate_barcode(); }

    – Codefreak

    25. Juli 2015 um 8:12 Uhr


  • nein das nennt es einmal. Rekursiv bedeutet, dass es sich selbst in einem Schleifenstil aufruft, bis Sie es zum Beenden ausgeben. en.wikipedia.org/wiki/Recursion

    – Künstlerischer Phönix

    25. Juli 2015 um 8:15 Uhr


  • Nein, auf den zweiten Blick ist es das, aber ich musste es nicht formatieren, weil ich Code mit } in der nächsten Zeile und ohne Tabulatoren nicht lesen kann, funktioniert einfach nicht für mich. lol . mal sehen, wie viel besser das aussieht

    – Künstlerischer Phönix

    25. Juli 2015 um 8:20 Uhr


Benutzer-Avatar
hek2mgl

Sie versuchen Folgendes zu tun:

while(true) {
    $barcode = rand(1,10);
    $bquery = mysql_num_rows(mysql_query("SELECT * FROM stock_item WHERE barcode="$barcode""));
    if($bquery===0){
        break;
    }
}

echo $barcode;

Allerdings funktioniert das natürlich nur bei 10 Barcodes und führt danach zu einer Endlosschleife – es ist also nicht der richtige Ansatz, eine große Anzahl von Barcodes zu erstellen.

Stattdessen würde ich vorschlagen, ein zu verwenden auto_increment um den Barcode zu generieren.

Übrigens, die mysql Erweiterung ist veraltet. Verwenden mysqli oder PDO für neuen Code.

1015430cookie-checkVerwendung von return innerhalb einer rekursiven Funktion in PHP

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy