Frage von Plueschtier94, 53

PHP Experte Gesucht. Foreach Datenverarbeitung nach der Schleife?

Hallo liebe Community,

ich stehe aktuell auf dem Schlauch, ich bin eigentlich nicht blöd, aber mittlerweile bezweifel ich auch das.

Ich habe folgenden Code

    foreach ($result as $ausgabe){
        $nachlieferung[$menge][rechnungsnr] = $ausgabe->Rechnungsnr;
        $nachlieferung[$menge][id] = $ausgabe->id;
        $nachlieferung[$menge][lagernr] = $ausgabe->lagernr;
        $menge++;
        if(isset($ausgabe)){
            $nachlieferung[menge] = $menge;
        }
    }

http://pastebin.com/x0anBwDN Hier nochmal übersichtlicher als GF das macht.

Nun zum Code

Ich möchte mir nach der Schleife die Variable $nachlieferung[menge] ausgeben lassen.

Die ist aber immer leer. Wenn ich mir innerhalb der Schleife die Variable ausgeben lasse, ist die gefüllt, nur danach nicht mehr. Es erfolgt ein Schleifendurchlauf (in meinem Test) , dennoch ist die variable leer, obwohl sie vorher noch gesetzt war.

Ich bin ratlos, kann mir hier jemand helfen?

Hilfreichste Antwort - ausgezeichnet vom Fragesteller
von FabianHolmes, 20

Dein Code macht wenig Sinn. Wieso machst Du das:

$nachlieferung[$menge][rechnungsnr] = ...

$menge ist eine Variable und er wird hochgezählt, dann hast du mehrere davon wie:

$nachlieferung = [
  1 => [rechnungsnr => ..., id => ..., lagernr => ...],
  2 => [rechnungsnr => ..., id => ..., lagernr => ...],
  ...
];

Genau das möchtest Du doch nicht. Du kannst dir das Ergebnis nach der Schleife ausgeben und prüfen mit:

var_dump($nachlieferung);

Du kannst dann die Struktur vom $nachlieferung komplett ausgeben lassen. 

Ich würde das sauber implementieren:

<?php

class Ausgabe {
  protected $id;
  protected $rechnungsnr;
  protected $lagernr;
  protected $produktId;

  public function __construct($id, $rechnungsnr, $lagernr, $produktId) {
    $this->id = $id;
    $this->rechnungsnr = $rechnungsnr;
    $this->lagernr = $lagernr;
    $this->produktId = $produktId;
  }

  public function getId() { 
    return $this->id; 
  }

  public function getRechnungsnr() {
    return $this->rechnungsnr; 
  }

  public function getLagernr() {
    return $this->lagernr;
  }

  public function getProduktId() {
    return $this->produktId;
  }
}

$ausgabe1 = new Ausgabe(1, "RN-0001", "L-0001", "P-001");
$ausgabe2 = new Ausgabe(2, "RN-0002", "L-0001", "P-001");
$ausgabe3 = new Ausgabe(3, "RN-0003", "L-0002", "P-002");
$ausgabe4 = new Ausgabe(4, "RN-0004", "L-0003", "P-003");

$ausgaben = [$ausgabe1, $ausgabe2, $ausgabe3, $ausgabe4];
$nachlieferung = [];

foreach ($ausgaben as $ausgabe) {
  if (!isset($nachlieferung[$ausgabe->getProduktId()])) {
    $nachlieferung[$ausgabe->getProduktId()] = [
      "menge" => 0,
      "rechnungsnummern" => []
    ];
  }

  $nachlieferung[$ausgabe->getProduktId()]["menge"]++;
  $nachlieferung[$ausgabe->getProduktId()]["rechnungsnummern"][] = $ausgabe->getRechnungsnr();
}

var_dump($nachlieferung);

Das Ergebnis von var_dump() Ausgabe sieht dann so aus:

array(3) {
'P-001' =>
array(2) {
'menge' =>
int(2)
'rechnungsnummern' =>
array(2) {
[0] =>
string(7) "RN-0001"
[1] =>
string(7) "RN-0002"
}
}
'P-002' =>
array(2) {
'menge' =>
int(1)
'rechnungsnummern' =>
array(1) {
[0] =>
string(7) "RN-0003"
}
}
'P-003' =>
array(2) {
'menge' =>
int(1)
'rechnungsnummern' =>
array(1) {
[0] =>
string(7) "RN-0004"
}
}
}

So kannst Du das array sinnvoll weiterverarbeiten.

Schöner ist es dann, wenn die Nachlieferung schön in einer Klasse gekapselt wird:

class Ausgaben {
public function __construct(array $ausgaben) {
$this->ausgaben = $ausgaben;
}

public function erhalteNachlieferungen() {
$nachlieferungen = [];

foreach ($this->ausgaben as $ausgabe) {
if (!isset($nachlieferungen[$ausgabe->getProduktId()])) {
$nachlieferungen[$ausgabe->getProduktId()] = [
"menge" => 0,
"rechnungsnummern" => []
];
}

$nachlieferungen[$ausgabe->getProduktId()]["menge"]++;
$nachlieferungen[$ausgabe->getProduktId()]["rechnungsnummern"][] = $ausgabe->getRechnungsnr();
}

return $nachlieferungen;
}
}

$ausgabe1 = new Ausgabe(1, "RN-0001", "L-0001", "P-001");
$ausgabe2 = new Ausgabe(2, "RN-0002", "L-0001", "P-001");
$ausgabe3 = new Ausgabe(3, "RN-0003", "L-0002", "P-002");
$ausgabe4 = new Ausgabe(4, "RN-0004", "L-0003", "P-003");

$ausgaben = new Ausgaben([$ausgabe1, $ausgabe2, $ausgabe3, $ausgabe4]);
var_dump($ausgaben->erhalteNachlieferungen());

Viel Spass!

Kommentar von MonkeyKing ,

Super Antwort aber er hat vermutlich noch nie etwas von OOP gehört, also verwirrt das mehr. ;)

Kommentar von Plueschtier94 ,

Antwort ist gut. OOP kann ich lieber Vorredner ;) 
das einfache Problem ist, dass bisher das ganze Projekt von meinem kollegen ohne OOP programmiert wurde. 

Soll sich mit der neu Programmierung ändern, demnach lohnt es sich einfach nicht hier für eine Sache damit anzufangen. 
Das das schöner ist, keine Frage brauchen wir nicht drüber zu diskutieren. 

Aber danke für die Top Antwort.! 

Antwort
von mastema666, 23

Also was zunächst mal auffällt, du benutzt $menge das erste Mal bevor die Variable überhaupt gesetzt wurde, kA mit welchem Wert die starten soll, aber den solltest du auf jeden Fall auch vorher setzen.

Außerdem benutzt du Arrays falsch: 

$nachlieferung[$menge][rechnungsnr] =...

"rechnugnsnr" soll ja vermute ich mal keine Konstante sein, daher solltest du das in '' setzen, also so:

$nachlieferung[$menge]['rechnungsnr'] = ...

Das gleiche gilt natürlich auch für die 3 anderen.

$nachlieferung[menge]

Müsstest du übrigens gar nicht so umständlich setzen, bzw musst du nicht nochmal prüfen, ob $ausgabe gesetzt ist, denn sonst kämst du ja gar nicht an diese Stelle. 

Und meinst du auch wirklich 

$nachlieferung['menge']

und nicht

$nachlieferung[$menge]

?

Ist etwas verwirrend mit solchen fast gleich lautenden Variablen / Keys, besser immer eindeutige verwenden.

Ich hab das mal, was mir so aufgefallen ist, auf die schnelle versucht bisl auszubessern, kann natürlich nichts testen, da ich dein $result ja nicht habe ;)

http://hastebin.com/aboqehehuj.coffee

Wobei mir irgendwie der Sinn hinter der Sache mit der Menge fehlt, aber ich habs halt mal so versucht wie du es anscheinend haben wolltest, sag wenn ichs falsch verstanden hab.

Kommentar von Plueschtier94 ,

Danke für die schnelle Antwort. 

1. $menge war natürlich gesetzt vorher, hatte ich nur nicht mitkopiert. 
2. Dies ist nur der Code meines Kollegen der aktuell im Urlaub ist aber Fehler aufwirft. Der hat diese Art bisher immer so benutzt also ohne Anführungszeichen. Ich weiß nicht ob es an WordPress liegt, aber ich kenne es eigentlich auch nur nach deiner Variante. 
Habe deine Änderungen komplett übernommen, gibt genau das selbe aus, wie vorher. 

print_r auf $nachlieferung kommt folgendes immer bei rum, ob alter bzw neuer code, nach der Schleife



Array
(
[0] => Array
(
[rechnungsnr] => 201454546
[id] => 15
[lagernr] => 312
)

[menge] => 1
)


So wie ich den weiteren code meines Kollegen verstehe, muss die "menge" aber im Key 0 Array rein. 

Kommentar von Plueschtier94 ,

So konnte das Problem lösen. 

Jetzt aber folgendes was ich wiederrum nicht verstehen

printr($nachlieferung);
return $nachlieferung;

Der vorherige Code ist in einer function,
hier in der Function im printr zeigt er mir das array noch so an:

Array
(
[0] => Array
(
[rechnungsnr] => 201454546
[id] => 15
[lagernr] => 312
[menge] => 1
)

)

 Wenn ich jetzt aber an die Stelle gehe, die die Funktion aufruft und mir da den return ansehen möchte, ist diese komplett leer. 
Das ist der Funktionsaufruf

$nachlieferung = get_nachlieferungen($id);

ich verstehe die welt einfach nicht mehr :D

Kommentar von mastema666 ,

Ohne die komplette Funktion zu kennen natürlich schwer zu sagen, aber vielleicht wird die Variable vor dem return irgendwo nochmal resetted?

Also wenn ein print_r() direkt nach der Schleife den richtigen Array ausgibt, sollte das genauso auch in der zurückgegebenen Variablen stehen (wenn man die dort returned, wo man auch print_r() genutzt hat, wenn dazwischen noch was anderes passiert kann das ja noch einiges ändern).

Bzgl der Sache mit den Anführungszeichen, so lange man sich nicht mit Konstanten überschneidet mag das auch ohne "funktionieren", unsauberer Stil ist es aber in jedem Fall (an Wordpress liegts nicht, die machen das in der Regel schon richtig^^).

Antwort
von Suboptimierer, 25
$nachlieferung[menge] = $menge;

Muss das nicht so lauten?:

$nachlieferung[$menge] = $menge;
Kommentar von Plueschtier94 ,

macht leider keinen unterschied

Keine passende Antwort gefunden?

Fragen Sie die Community

Weitere Fragen mit Antworten