[PHP] Undefined offset

Goltergaul

Well-known member
ID: 17553
L
26 April 2006
480
7
Hi ich habe hier ne kleine schleife:
PHP:
foreach($data as $key => $value) {
     $array_troops[$key]=$array_troops[$key]+$value;
}

und bekomme nen notice: "undefined offset" weil es $array_troops[$key] nicht gibt. Ok den Offset gibt es ja auch nicht und soll deswegen angelegt werden.... Aber wie zum Henker bekomm ich jetzt die Notice weg?
 
Entweder mit isset() checken, ob das Element gesetzt is oder einfach n @ davor ;)
 
theHacker schrieb:
Entweder mit isset() checken, ob das Element gesetzt is oder einfach n @ davor ;)
Wie sieht das denn aus? Wenn ichs mit if checke und dann feststelle das es nicht gesetzt ist, was mache ich dann?^^ @ mag ich nicht benutzen
 
z.B.
PHP:
foreach($data as $key => $value)
  $array_troops[$key]=(isset($array_troops[$key])) ? $array_troops[$key]+$value : $value;
Die Alternative wäre einfach
PHP:
foreach($data as $key => $value)
  $array_troops[$key]=@$array_troops[$key]+$value;
 
@ ist keine alternative... das ist quatsch. entweder das error reporting soweit runterfahren wie nötig (bzw abfangen), oder die variablen entsprechend initialiseren.
 
Ich finde auch dass es quatsch ist. Entweder man macht notice ganz aus und schert sich nicht drum oder man machts richtig. Denn mit dem @ wird einem dann auch kein Fehler (z.b. undefinierte Variable) mehr angezeigt, und zum Debuggen is das dann wirklich unschön ;)
Warnung

Zum gegenwärtigen Zeitpunkt deaktiviert der "@" Fehler-Kontrolloperator die Fehlermeldungen selbst bei kritischen Fehlern, die die Ausführung eines Skripts beenden. Unter anderem bedeutet das, wenn Sie "@" einer bestimmten Funktion voranstellen, diese aber nicht zur Verfügung steht oder falsch geschrieben wurde, Ihr PHP-Skript einfach beendet wird, ohne Hinweis auf die Ursache.

Außerdem habe ich gehört dass solche @'s die Performance drücken können

edit: danke funzt übrigens ;)
 
Zuletzt bearbeitet:
theHacker schrieb:
Wieso ned ? :hö: Bei mir funktionierts. Es unterdrückt die Ausgabe einer jeden Warnung oder Fehlermeldung.

funktionieren ja... aber willst du vor jeder zuweisung jetzt nen @ setzen? entweder man machts richtig oder man lässts lieber gleich sein...

und das @ wirkt sich auch auf die geschwindigkeit aus... soll in manchen fällen das ganze um den faktor 10 verlagsamen. (find die seite aber nicht mehr, wo ich das gelesen hab)
 
ZeroCCC schrieb:
funktionieren ja... aber willst du vor jeder zuweisung jetzt nen @ setzen? entweder man machts richtig oder man lässts lieber gleich sein...
Nicht vor jede, nur vor welche, wo ich weiß, dass es ein Notice geben könnte, ich das aber vernachlässigen kann.
ZeroCCC schrieb:
und das @ wirkt sich auch auf die geschwindigkeit aus... soll in manchen fällen das ganze um den faktor 10 verlagsamen. (find die seite aber nicht mehr, wo ich das gelesen hab)
Das is natürlich ein Argument.
Ich werd mal suchen, ob ich was dazu finde :)
 
theHacker schrieb:
Ich werd mal suchen, ob ich was dazu finde :)
Gefunden hab ich nix, aber ich hab mal selbst getestet und das Ergebnis spricht für sich:
PHP:
<?php

error_reporting(E_ALL);
header("content-type: text/plain");
set_time_limit(210);

function microtimediff($a,$b)
{
  list($a_dec,$a_sec)=explode(" ",$a);
  list($b_dec,$b_sec)=explode(" ",$b);
  return $b_sec-$a_sec+$b_dec-$a_dec;
}

test(10);
test(1000);
test(100000);
test(10000000);

function test($max)
{
    echo sprintf("Anzahl Durchläufe: %lu\n",$max);
    
    $arr=array();
    $s=microtime();
    for($i=0;$i<$max;$i++)
    {
        $x=@$arr['undefined'];
    }
    $e=microtime();
    echo sprintf("Fehler-Kontroll-Operator: %3.2f ms\n",microtimediff($s,$e)*1000);
    
    
    $arr=array();
    $s=microtime();
    for($i=0;$i<$max;$i++)
    {
      if(isset($arr['undefined']))
        $x=$arr['undefined'];
      else
        $x=0;
    }
    $e=microtime();
    echo sprintf("  if(isset()) - if-Block: %3.2f ms\n",microtimediff($s,$e)*1000);
    
    
    $arr=array();
    $s=microtime();
    for($i=0;$i<$max;$i++)
    {
        $x=(isset($arr['undefined'])) ? $arr['undefined'] : 0;
    }
    $e=microtime();
    echo sprintf(" if(isset()) - Inline-If: %3.2f ms\n",microtimediff($s,$e)*1000);
    echo "\n";
}

?>
Anzahl Durchläufe: 10
Fehler-Kontroll-Operator: 0.11 ms
if(isset()) - if-Block: 0.02 ms
if(isset()) - Inline-If: 0.02 ms

Anzahl Durchläufe: 1000
Fehler-Kontroll-Operator: 4.13 ms
if(isset()) - if-Block: 1.11 ms
if(isset()) - Inline-If: 1.16 ms

Anzahl Durchläufe: 100000
Fehler-Kontroll-Operator: 496.52 ms
if(isset()) - if-Block: 138.33 ms
if(isset()) - Inline-If: 134.02 ms

Anzahl Durchläufe: 10000000
Fehler-Kontroll-Operator: 49871.72 ms
if(isset()) - if-Block: 13074.33 ms
if(isset()) - Inline-If: 13270.98 ms
Fazit:
Der Fehler-Kontoll-Operator verlangsamt mit den Faktor ~3,5x und sollte deshalb dann besser nicht verwenden werden, sondern eine isset()-Abfrage vorgeschaltet werden.

@ZeroCCC:
Man lernt doch nie aus :D