Texter mit x: Was ist der Rückgabewert von array_rand(array());?

Im Manuel steht nichts zum Rückgabewert von array_rand() falls das übergebene Array leer ist.

In PHP 5.2.10 ist der Rückgabewer NULL.

Meine Frage ist, kann man sich darauf verlassen oder sollte man immer vorher zusätzlich prüfen, ob das Array leer ist?

  1. Hi!

    Im Manuel steht nichts zum Rückgabewert von array_rand() falls das übergebene Array leer ist.

    Da ein leeres Array keine Schlüssel hat, kann die logische Konsequenz nur sein:

    In PHP 5.2.10 ist der Rückgabewer NULL.

    0 oder Leerstring wären gültige Keys und somit wäre das Ergebnis nicht mehr eindeutig. null hingegen ist kein gültiger Key. (Wenn man null beim Anlegen als Key verwendet, wird daraus ein Leerstring.)

    Meine Frage ist, kann man sich darauf verlassen oder sollte man immer vorher zusätzlich prüfen, ob das Array leer ist?

    Ich denk schon, dass man sich darauf verlassen kann. Änderungen im Verhalten künftiger Versionen stehen wie immer im Changelog.

    Lo!

    1. Da ein leeres Array keine Schlüssel hat, kann die logische Konsequenz nur sein:

      In PHP 5.2.10 ist der Rückgabewer NULL.

      0 oder Leerstring wären gültige Keys und somit wäre das Ergebnis nicht mehr eindeutig. null hingegen ist kein gültiger Key.

      Es gibt aber noch mehr mögliche Rückgabewerte die kein gültiger Key wären. Der Rückgabewert würde sich, so er nicht definiert ist, einfach aus den Gegebenheiten ergeben. Er könnte sich aber ändern, wenn an der Funktion, ohne, daß sich etwas von dem was definiert ist ändert, etwas geändert wird.

      Deshalb frage ich, der Rückgabewert könnte ja für oben genannten Fall doch definiert sein, ohne daß es im Manuel steht und jemand könnte das wissen.

      1. Hi!

        Da ein leeres Array keine Schlüssel hat, kann die logische Konsequenz nur sein:

        In PHP 5.2.10 ist der Rückgabewer NULL.

        0 oder Leerstring wären gültige Keys und somit wäre das Ergebnis nicht mehr eindeutig. null hingegen ist kein gültiger Key.

        Es gibt aber noch mehr mögliche Rückgabewerte die kein gültiger Key wären. Der Rückgabewert würde sich, so er nicht definiert ist, einfach aus den Gegebenheiten ergeben.

        Welche Gegebenheiten meinst du? Du übergibt entweder ein Array und bekommst einen oder mehrere Schlüssel oder du übergibst keins oder ein leeres und erhältst null. null steht für nicht vorhanden. Alles andere wäre nicht besonders sinvoll.

        Er könnte sich aber ändern, wenn an der Funktion, ohne, daß sich etwas von dem was definiert ist ändert, etwas geändert wird.
        Deshalb frage ich, der Rückgabewert könnte ja für oben genannten Fall doch definiert sein, ohne daß es im Manuel steht und jemand könnte das wissen.

        Der Quelltext von PHP ist öffentlich verfügbar. Derzeit gibt es null, wie du gesehen hast, und wenn sich was ändert steht es im Changelog.

        Obendrein ist ein

        if (!is_array($array))
            return von_dir_definierter_wert;

        schnell getippt, wenn dir das weniger Bauchschmerzen bereitet. :-)

        Lo!

        1. Hi!

          if (!is_array($array))

          Besser:

          if (empty($array))

          Lo!

          1. if (!is_array($array))

            Besser:

            if (empty($array))

            Denke ich auch, danke an alle Beteiligten.

        2. Welche Gegebenheiten meinst du?

          Den konkreten Code des Parsers, in dem der diskutierte Fall vielleicht nicht berücksichtigt wurde, der aber dennoch ein unauffälliges Ergebnis liefert. In der Folge könnte sich das Ergebnis bei Änderungen, vielleicht wiederum unauffällig, verändern.

          Der Quelltext von PHP ist öffentlich verfügbar. Derzeit gibt es null, wie du gesehen hast, und wenn sich was ändert steht es im Changelog.

          Ich kenne mich mit dem Prozedere nicht ansatzweise aus, wird wirklich jede Änderung dokumentiert, auch, wenn sie sich (vermeintlich) nicht nach außen auswirkt?

          1. Hi!

            Ich kenne mich mit dem Prozedere nicht ansatzweise aus, wird wirklich jede Änderung dokumentiert, auch, wenn sie sich (vermeintlich) nicht nach außen auswirkt?

            Zumindest findest du eine Referenz auf den Problemfall, der zu lösen gewesen ist. Was für ein Problem hättest du mit einer Änderung, die sich nicht nach außen auswirkt?

            Lo!

            1. Ich kenne mich mit dem Prozedere nicht ansatzweise aus, wird wirklich jede Änderung dokumentiert, auch, wenn sie sich (vermeintlich) nicht nach außen auswirkt?

              Zumindest findest du eine Referenz auf den Problemfall, der zu lösen gewesen ist. Was für ein Problem hättest du mit einer Änderung, die sich nicht nach außen auswirkt?

              Keins.

  2. Hello,

    Im Manuel steht nichts zum Rückgabewert von array_rand() falls das übergebene Array leer ist.

    In PHP 5.2.10 ist der Rückgabewer NULL.

    Meine Frage ist, kann man sich darauf verlassen oder sollte man immer vorher zusätzlich prüfen, ob das Array leer ist?

    Auf solche Verhaltensweisen würde ich mich bei PHP nur zu 99,51% verlassen, wenn sie definitv im Manual stehen. Wenn als Übergabeparameter ein Array verlangt wird, dann solltest Du auch eines liefern, solange es _nicht_ im Handbuch steht. Und sonst gehört für mich seit einiger Zeit eine umfangreiche Versions- und IstFunktionVorhanden-Kontolle zur Intallationsroutine meiner Lösungen.

    Array_Rand() hatte in den bisher von mir getesteten 32-Bit-Versionen von PHP außerdem noch ein "zu-wenig-Zufall-Problem"

    Da gibt es im Archiv einen Thread mit globe und mir, in dem dies offensichtlich wurde.

    Liebe Grüße aus dem schönen Oberharz

    Tom vom Berg

    --
    Nur selber lernen macht schlau
    http://bergpost.annerschbarrich.de
    1. Wenn als Übergabeparameter ein Array verlangt wird, dann solltest Du auch eines liefern, solange es _nicht_ im Handbuch steht.

      Ein leeres Array ist doch ein Array.

      Die Teilaufgabe ist, einem Array (es ist eine Art to-do-Liste) (anspruchslos) zufällig Schlüssel und Werte zu entnehmen und anschließend aus dem Array zu entfernen. Außerdem können "außer der Reihe" über den Schlüssel Paare entfernt werden. Irgendwann ist das Array dann leer. Deshalb würde sich der Rückgabewert zur Auswertung anbieten.

      Array_Rand() hatte in den bisher von mir getesteten 32-Bit-Versionen von PHP außerdem noch ein "zu-wenig-Zufall-Problem"

      Die schlechte Zufälligkeit mancher Zufallsfunktionen in PHP ist mir bekannt. In meinem Fall stellt das kein Problem dar.

      1. Moin!

        Die Teilaufgabe ist, einem Array (es ist eine Art to-do-Liste) (anspruchslos) zufällig Schlüssel und Werte zu entnehmen und anschließend aus dem Array zu entfernen. Außerdem können "außer der Reihe" über den Schlüssel Paare entfernt werden. Irgendwann ist das Array dann leer. Deshalb würde sich der Rückgabewert zur Auswertung anbieten.

        Da würde ich exakt EINMAL mit shuffle() das Array durchmischen und es danach mit foreach iterieren - schon hast du wunderbaren Zufall, ohne den Overhead des Entfernens von Arrayelementen oder der Prüfung, ob array_rand mit leeren Arrays kann oder nicht.

        - Sven Rautenberg

        1. Die Teilaufgabe ist, einem Array (es ist eine Art to-do-Liste) (anspruchslos) zufällig Schlüssel und Werte zu entnehmen und anschließend aus dem Array zu entfernen. Außerdem können "außer der Reihe" über den Schlüssel Paare entfernt werden. Irgendwann ist das Array dann leer. Deshalb würde sich der Rückgabewert zur Auswertung anbieten.

          Da würde ich exakt EINMAL mit shuffle() das Array durchmischen und es danach mit foreach iterieren - schon hast du wunderbaren Zufall, ohne den Overhead des Entfernens von Arrayelementen oder der Prüfung, ob array_rand mit leeren Arrays kann oder nicht.

          Gute Idee, das Array wird zwar auch mit neuen Werten aufgefüllt, dies allerdings nur ein mal. Die neuen Werte könnte man also vor dem Anfügen mischen. Foreach ohne Löschen fällt allerdings aus, da der Vorgang über mehrere Aufrufe läuft (Session). Ein manueller durchgeschleifter Index ginge auch, die Paare die außer der Reihe gelöscht werden muß ich aber auch dann wirklich löschen.

  3. Hi Texter mit x.

    Im Manuel steht nichts zum Rückgabewert von array_rand() falls das übergebene Array leer ist.

    In PHP 5.2.10 ist der Rückgabewer NULL.

    array_rand hat ja einen zweiten, optionalen Parameter, der die Anzahl der zurueckzugebenden Argumente angibt. Gibt man eine Anzahl an, die groesser als die Laange des Arrays ist, etwa

    array_rand(array(1,2), 3);

    gibt's ein Warning:
    Warning:  array_rand(): Second argument has to be between 1 and the number of elements in the array

    Der Aufruf
    array_rand(array(), 1);

    liefert das Warning auch. Lediglich

    array_rand(array());

    gibt kein Warning, obwohl 1 der Default-Wert des zweiten Parameters ist und daher der Aufruf aequivalent zu obigem sein muesste.

    Meine Frage ist, kann man sich darauf verlassen oder sollte man immer vorher zusätzlich prüfen, ob das Array leer ist?

    Ich wuerde in diesem Fall dazu neigen, mich auf gar nichts zu verlassen. Denn array_rand ist offenbar nicht dafuer gemacht, Deinen Fall kontrolliert zu behandeln. Zumindest riskierst Du, in zukuenftigen Versionen ein Warning um die Ohren geknallt zu kriegen, weil Du es wohl einem Bug zu verdanken hast, dass Du bisher keins kriegst.

    Viele Gruesse,
    der Bademeister

    1. Ich wuerde in diesem Fall dazu neigen, mich auf gar nichts zu verlassen. Denn array_rand ist offenbar nicht dafuer gemacht, Deinen Fall kontrolliert zu behandeln. Zumindest riskierst Du, in zukuenftigen Versionen ein Warning um die Ohren geknallt zu kriegen, weil Du es wohl einem Bug zu verdanken hast, dass Du bisher keins kriegst.

      Auf dem Standpunkt bin ich mittlerweile auch. Ich wollte nur so zweckmäßigen Code wie möglich schreiben, was in dem Fall also bedeutet den Fall mit einem zusätzlichen Befehl abzudecken.