Dynamische Array-Erstellung?

Martys

Erfahrenes Mitglied
Hallo zusammen,

ich stehe momenatn vor folgendem Problem:
Ich habe eine Einteilung von Postleizahlbereichen in verschiedene Gruppen.

Bsp.:
Gruppe1 = "67583-67587|67677-67829|68753|68794"
Gruppe2 = "98530-98749|99100|99189-99195|99428-99998"
usw.

Die Frage die ich mir stelle ist: "Wie kann ich mit diesem Konstrukten am sinnvollsten umgehen, wenn ich aus einem Formular eine bestimmte PLZ geliefert bekomme und nun prüfen will, zu welcher Gruppe die PLZ aus dem Formular gehört?"

Meine erste Überlegung war, mit den Stringfunktionen die Trennzeichen "|" zu finden und die einzelnen Blöcke weiter auf das nächste Trennzeichen "-" zu untersuchen. Bei Misserfolg von "-" wird der Wert in ein neu erstelltes Array (Ergebnisarray) geschrieben, bei vorhandensein von "-" wird wieder mittels Stringfunktion der "Anfangs-" und der "Endwert" bestimmt und mittels Schleife alle in diesem Bereich vorkommen Ganzzahlen in das Ergebnisarray geschrieben.
Nun müsste ich noch mit in_array die PLZ aus dem Formular in den einzelnen Ergebnisarrays suchen lassen.

Ich habe dies noch nicht geprüft bzw. getestet, da ich mir nicht sicher bin, ob dies eine sinnvolle Vorgehensweise ist oder nicht, zumal es auch meine erste Arbeit dieser Art ist. Habe zwar schon ein wenig mit PHP gearbeitet, dies beschränkte sich aber eher auf deutlich kleinere Applikationen.

Für Tipps und Anregungen, wie man soetwas sicher, schnell und ressourcenschonend bewerkstelligen kann wäre ich dankbar.
Martys
 
Ich weiss nicht genau, wie deine Applikation aufgebaut ist, aber anhand der vorliegenden Informationen dünkt es mich effizienter, wenn du anstatt alle Werte in einem Intervall zu bestimmen einfach die aus dem Formular übergebene PLZ nimmst und überprüfst, ob sie grösser gleich dem Anfangswert und kleiner gleich dem Endwert ist. Damit kannst du dir das ganze Array-Gefrickel ersparen, das enorm ressourcenhungrig ist.
 
Mal ungeachtet von Sinn und Zweck hier eine einfache Lösung für ein solches Problem.
PHP:
<?php
    $groups[1] = "67583-67587|67677-67829|68753|68794";
    $groups[2] = "98530-98749|99100|99189-99195|99428-99998";

    $plz=98535;
    
    foreach ($groups as $groupNr => $group){
         $areas = explode('|', $group);
         foreach($areas as  $area){
             $borders = explode('-', $area);
             $min = $borders[0];
             //Bei Einzelzahlen ist min und max gleich gross und der Array $borders hat die Grösse 1
             $max = (count($borders) == 1) ? $borders[0] : $borders[1];
             
             if ($min <= $plz && $plz <= $max){
                 $nr = $groupNr;
                 // beide foreach verlassen
                 break 2;
             }
         }   
    }

    echo $nr;
?>
 
Erstmal vielen Dank für eure Antworten.

@SilentWarrior:
Dein Vorschlag ist ja offensicht performanter, bin nur nicht auf die Prüfung < und > gekommen.

@yaslaw:
Leider bekomme ich die Postleitzahlen so gestellt und muss daher so damit weiterarbeiten.
Hoffe ich komme heute noch dazu, den geposteten Code auszuprobieren bzw. erstmal komplett nachzuvollziehen.

Martys
 
@yaslaw
Wobei man in die erste foreach-Schleife (Zeile 8) noch einen Abschnitt einfügen könnte, der den String auf die PLZ absucht und abbricht, wenn er sie findet. Ich weiß nicht was schneller ginge, aber man könnte zuerst alle Strings auf die PLZ absuchen, wenn sie nicht gefunden wurde, dann erst zerlegen.

holzmensch
 
Wenn du mit Session arbeitest oder diese Funktion mehrfach verwenden musst, dann lohnt es sich das ganze mit Klassen zu lösen. Damit werden die sxplode() nicht bei jedem Aufruf ausgeführt

PHP:
$groups = new PlzGroups();
$groups->add(1, "67583-67587|67677-67829|68753|68794");
$groups->add(2, "98530-98749|99100|99189-99195|99428-99998");
echo $groups->check(67587)."<br />";
echo $groups->check(99100)."<br />";
echo $groups->check(11111)."<br />";
echo $groups->check(99998)."<br />";

/**
 * Klasse für die Gruppenbestimmung 
 */
class PlzGroups{
    private $groupNodes = array();
    
    /**
     * Gruppendefinition hinzufügen 
     */
    public function add($groupNr, $string){
         foreach(explode('|', $string) as  $area){
             $this->groupNodes[] = new PlzGroupNode($groupNr, $area);
         }   
    }
    
    /**
     * Postleitzahl prüfen 
     */
    public function check($plz){
        foreach ($this->groupNodes as $node){
            if (false != $groupNr = $node->check($plz)) break;
        }
        return $groupNr;
    }
    
}
/**
 * Klasse mit allen Bereichen der Gruppen
 */
class PlzGroupNode{
    private $min;
    private $max;
    private $groupNr;
    /**
     * Bereich erstellen 
     */
    public function __construct($groupNr, $area){
        $this->groupNr = $groupNr;
        $borders = explode('-', $area);
        $this->min = $borders[0];
        $this->max = (count($borders) == 1) ? $this->min : $borders[1];
    }
    /**
     * Postleitzahl prüfen 
     */
     public function check($plz){      
        return ($this->min <= $plz && $plz <= $this->max) ? $this->groupNr : false;
    }    
}

Nachtrag:
@holzmensch
Bei der Version ohne Klassen -> ja.
Mit Klassen ist mMn schöner und besser wenn man es nicht nur einmal braucht.
 
@yaslaw:
DANKE, funktioniert super.
Habe noch nicht mit Klassen gearbeitet, werde dies aber als nächstes angehen und am Wochenende erstmal den von dir geposteten Code versuchen komplett nachzuvollziehen.

Martys
 
Zurück