# PHP-Skript "richtig" abbrechen



## Alice (19. Februar 2012)

Hallo. 

Wie die meisten hier im PHP-Unterforum wissen, arbeite ich schon seit längerem an einem PHP-Skript. Nun habe ich mal wieder ein Problem und komme nicht weiter.

Wenn es z.B. im Skript einen Fehler gibt, mache ich das immer so das ich wichtige Variablen lösche (Unset() und so das Skript abbrechen lasse.

Denn in der Mitte des Skripts ist eine Preg_Match Abfrage und wenn die wichtigen Variablen nicht gesetzt sind, bricht das Skript ab.

Das Problem ist nun alles was nach der Preg_Match Abfrage kommt, lässt sich nicht Fehlerfrei abbrechen.

Beispiel:
Kurz vor Skript Ende kommt es zu einem Berechnungsfehler (nicht wirklich Fehler), weil der User eine Kombination aus Optionen gewählt hat, die ich aber nicht zulasse.


```
$img = getimagesize($new_image);

if ($img[0] > 7580) {
   echo 'ERROR!';
}
```

Ok jetzt habe ich "ERROR!" ausgegeben aber das Skript läuft trotzdem weiter und versucht weitere Grafiken zu erstellen usw.

Ein "Break" bringt mir glaube ich auch nichts, weil das letzte Stück Code im Skript teilweise das aussehen der Webseite darstellt. Ein "reload" wäre sehr unprofessional finde ich.

Hat jemand eine Idee wie man das lösen könnte?

Gibt es evtl. eine Funktion oder so in PHP wo man z.B. den restlichen Code überspringen kann bis zu einem bestimmten Punkt? Oder gäbe es die Möglichkeit an der Stelle wo der Fehler aufgetreten ist, die Variablen neu zu "gestalten" und das Skript fängt dann automatisch von vorne an.


```
$img = getimagesize($new_image);

if ($img[0] > 7580) {
   echo 'ERROR!';
   $font_typ = 'normal'; // nehmen wir an der Eintrag "bold" hat zu diesem Fehler geführt.
}

NEW START des Skripts!?
```


----------



## timestamp (19. Februar 2012)

Abbrechen geht mit exit()  oder die().
Ein "neustart", bzw das Springen, wäre mit goto; möglich.


----------



## Alice (19. Februar 2012)

Hi. 

Goto funktioniert bei mir nicht. Hab ich schon ausprobiert.

Geht wahrscheinlich NUR mit PHP 5.3.0.

Edit:

Bei meinem Hoster kann ich wohl PHP 5.3.0 nutzen in dem ich das in die .htaccess Datei eintrage. Aber ob das dann "richtiges" PHP 5.3.0 ist?


----------



## timestamp (19. Februar 2012)

Wenn du nur nach unten springen willst, geht das auch mit if.
Um nach oben zu springen, müsstest du die Teile in Funktionen auslagern.


```
//Nach unten
$jump = false;

$a = 4;
$b = 5;
if( $a < $b ){
  //goto bla; können wir nicht nutzen, weil php version zu alt
  $jump = true;
}

if( !$jump ){
  //Code der normalerweise ausgeführt wird
  echo 'Blablablabla';
}

//Code zu dem dann gesprungen wird
echo 'Blablabla2';
```



```
//nach oben

function do_something(){
  //Dein Code, der eventuell ein 2tes mal ausgeführt werden soll
  echo 'Blablablbalabla';
}

//bla:
do_something();

$a = 4;
$b = 5;

if( $a < $b ){
 //goto bla;
  do_something();
}
```


----------



## Alice (19. Februar 2012)

So ich habe mal eben PHP 5.3.0 aktiviert.


```
AddHandler php53-cgi .php
```

Kurze Frage dazu:
- Ist das eine "richtige PHP 5.3.0" Version?
- Ich habe es aktuell in meinem Root-Verzeichnis (.htaccess). Kann ich es auch nur im Ordner des PHP-Skriptes "aktivieren"? Denn ohne diesen Eintrag habe ich PHP 5.2.1 oder so ähnlich.

Kann man mit Goto auch nach oben springen?


----------



## timestamp (19. Februar 2012)

Kleiner Tipp: Anstatt immer zu fragen ob etwas möglich ist, einfach eine neue Datei test.php erstellen und prüfen ob's geht, das Resultat siehst du ja  Schlimmsten falls gibt's eine Fehlermeldung oder eine Endlosschleife.
Goto kann nach oben SPringen, du musst allerdings dort auf eine Endlosschleife aufpassen:


```
$i = 0;
foo: 
echo 'foo ';
$i++;

if( $i < 2 )
	goto foo;
echo 'bar ';
```
Das gibt "foo foo bar" aus.


----------



## Napofis (20. Februar 2012)

Ein Skript sollte man überhaupt nicht abbrechen, Fehler sollten entsprechende behandelt werden. Von der GOTO Anweisung sollte man *nie* Gebrauch machen! Ich kann mich noch an die Proteste erinnern als das wieder eingeführt wurde. Diese Anweisung führt zu einen völlig unübersichtlichen und unwartbaren Code.

*die()* und *exit()* verwendet man maximal zu Debug zwecken.


----------



## Parantatatam (20. Februar 2012)

Na na na, _goto_ gerne, aber nur bei Assemblersprachen  Ansonsten sollte man die() und exit() auch nie nutzen, sondern sich mal eher um eine sinnvolle Ausnahmenbehandlung kümmern.

Nachtrag:

```
class ImageException extends Exception {}

try {
  $img = getimagesize($new_image);

  if($img[0] > 7580) { 
    throw new ImageException('unexpected image size');
  }
} catch(ImageException $e) {
  echo 'exception: ' . $e->getMessage();
}
```


----------



## Alice (20. Februar 2012)

```
//nach oben

function do_something(){
  //Dein Code, der eventuell ein 2tes mal ausgeführt werden soll
  echo 'Blablablbalabla';
}

//bla:
do_something();

$a = 4;
$b = 5;

if( $a < $b ){
 //goto bla;
  do_something();
}
```

Funktioniert leider nicht. Zwar wird der Code ausgeführt (echo) aber die veränderten Variablen werden nicht übernommen.


----------



## timestamp (20. Februar 2012)

Zeige mal bitte deinen Code.


----------



## Alice (20. Februar 2012)

Ich habe diesen Code so weit wie möglich oben eingebaut. Rein "logisch" sollte das Skript dann statt "$var = Usereingabe" diesen Code ausführen.


```
function do_something() {
   $var1 = 'ERROR';
   $var2 = 'NR';
   $var3 = '1';
echo 'Error! Bitte Eingaben prüfen!';
}
```

Ziehmlich unten im Skript habe ich das dann so eingebaut.


```
if ($img[0] < 8000) {
   do_something();
}
```

Und das "Echo" wird auch ausgegeben hat aber leider keine Auswirkung auf die ganzen Variablen und berechnungen. Das Echo wird übrigens sogar als erstes ausgegeben. Wird also quasi wie ein verspätetes Echo behandelt. Aber die Variablen ändern sich dadurch nicht.

Ich dachte ich kann damit ein "Neustart" einleiten.


----------



## Parantatatam (20. Februar 2012)

Neustart? Ne, dass geht so nicht. Du könntest höchstens per HTTP-Location erneut auf dieses Skript verweisen. Das hätte aber als Folge, dass die Daten, die per POST verschickt wurden, nicht mehr vorhanden sind.


----------



## Alice (20. Februar 2012)

Das ist das Problem. Echt Schade dass das nicht so geht.

Denn in meinem Skript werden alleine in über 35 Zeilen reinste Berechnungen durchgeführt.

Im ersten Teil theoretische Berechnung und später dann die richtigen Berechnungen und es gibt dann keine Möglichkeit mehr das Skript Fehlerfrei in einen absichtlichen Fehler umzuleiten. Jedenfalls gibt es keine Professionelle möglichkeit.


----------



## Parantatatam (20. Februar 2012)

Deshalb: erst prüfen, dann rechnen.


----------



## timestamp (20. Februar 2012)

Doch, auch das geht, Stichwort Exceptions:

```
try{
  $a = 5;
  $b = 4;
  if( $b < $a ){
    throw new Exception('b ist kleiner als a');
  }
}
catch(Exception $e){
  echo 'Upps, da ging was schief: '.$e->getMessage();
}
```


----------



## Parantatatam (20. Februar 2012)

Ich fühl' mich gerade mal wieder ignoriert, weil ich das, was *timestamp* eben geschrieben hat, bereits vorher erwähnt habe, und das nicht das erste Mal ist. Vielleicht solltest du, *bl5000*, die Beiträge mal genauer durchlesen und ausprobieren, bevor du sagst, dass etwas nicht geht. Wie gesagt: das ist nicht das erste Mal bei dir.


----------



## Alice (20. Februar 2012)

He? Das ist doch fast das selbe wie ein nomales Echo. Hat nichts mit meinem Problem zutun?


----------



## Alice (20. Februar 2012)

einfach nur crack hat gesagt.:


> Ich fühl' mich gerade mal wieder ignoriert, weil ich das, was *timestamp* eben geschrieben hat, bereits vorher erwähnt habe, und das nicht das erste Mal ist. Vielleicht solltest du, *bl5000*, die Beiträge mal genauer durchlesen und ausprobieren, bevor du sagst, dass etwas nicht geht. Wie gesagt: das ist nicht das erste Mal bei dir.



Wieso ignoriert? Was soll ich denn zu deinen Beitrag noch sagen?

Wenn es nicht geht, geht es halt nicht.


----------



## Parantatatam (20. Februar 2012)

Was willst du denn eigentlich? Willst du, dass dein Skript, wenn es denn einmal läuft, nicht mehr abgebrochen wird? Das geht nicht! Oder willst du, dass du deinen Skriptteil mit den rechenintensiven Operationen erst dann ausgeführt wird, wenn alle Daten korrekt sind? Dann musst du das eben alles vorher überprüfen. Oder willst du, dass dein Skript, wenn ein Fehler auftritt, sofort abbricht? Dann schau dir bitte Exceptions an.


----------



## timestamp (20. Februar 2012)

Das tut mir leid einfach nur crack, ich hatte das jetzt irgendwie übersehen.

bl5000 ich stimme ihm da zu, du hast hier jetzt praktische sämtliche Lösungswege für jedes Problem aber scheinbar passt da keins zu deinem? Werde dir doch bitte erst einmal darüber im klaren was du wirklich willst.


----------



## Alice (20. Februar 2012)

Sobald alles Berechnet ist, kann ich nichts mehr machen und das Skript läuft weiter und erzeugt eine inkorrekte Grafik.

Ich habe diese Exceptions-Funktion ausprobiert und das Skript läuft trotzdem weiter. Es generiert sogar die Grafik.



timestamp hat gesagt.:


> Das tut mir leid einfach nur crack, ich hatte das jetzt irgendwie übersehen.
> 
> bl5000 ich stimme ihm da zu, du hast hier jetzt praktische sämtliche Lösungswege für jedes Problem aber scheinbar passt da keins zu deinem? Werde dir doch bitte erst einmal darüber im klaren was du wirklich willst.



Ich habe alle Vorschläge ausprobiert.

Was ich möchte ist, bei einem Fehler den ich feststelle (durch eine einfache IF-Abfrage) zurück nach oben und die Eingaben des Benutzer (die im laufe des Skriptes "erweitert" werden) zu ändern.


----------



## Parantatatam (20. Februar 2012)

Magst du uns vielleicht dein komplettes Skript zeigen? Denn so etwas kenne ich in PHP nur bei Sockets, die du hier ohne Zweifel nicht verwenden wirst.


----------



## timestamp (20. Februar 2012)

Du willst die Eingaben des Benutzers ändern? Selbstständig? Dann überschreibe einfach die Variablen.
Prüfe *VORHER* ob diese gültig sind, nicht während der Berechnung, das wäre große Schlamperei.
Der User soll neue angeben? Dann lade die Seite per header('Location: meineseite.php'); neu.

"Exceptions sind doch fast dasselbe wie ein normales echo"? Ganz weit daneben gegriffen!


----------



## Alice (20. Februar 2012)

einfach nur crack hat gesagt.:


> Magst du uns vielleicht dein komplettes Skript zeigen? Denn so etwas kenne ich in PHP nur bei Sockets, die du hier ohne Zweifel nicht verwenden wirst.



Nein. Das hat aber ganz verschiedene Gründe. Ich denke auch nicht das man das Skript mal eben so verstehen würde.



timestamp hat gesagt.:


> Du willst die Eingaben des Benutzers ändern? Selbstständig? Dann überschreibe einfach die Variablen.
> Prüfe *VORHER* ob diese gültig sind, nicht während der Berechnung, das wäre große Schlamperei.
> Der User soll neue angeben? Dann lade die Seite per header('Location: meineseite.php'); neu.
> 
> "Exceptions sind doch fast dasselbe wie ein normales echo"? Ganz weit daneben gegriffen!



Nein eigentlich möchte ich nicht die Eingabes des Users verändern. Ich möchte auch nicht das der User die eingaben von neu eingeben muss.

In meinem Skript habe ich ziehmlich weit oben eine Kategorie mit "Grundeinstellungen" und "User-Einstellungen" erstellt.

Ganz blödes Beispiel:

```
//Grundeinstellungen
$ausgabe = 'png';
$leerzeichen = '35' // in px

//User-Einstellungen
$font_size = '20'; // Kann auch 40 oder 60 sein
```

Wenn nun später im Skript berechnet wird, das die Grafik zu groß ist, möchte ich z.B. $font_size ändern.

Ich möchte also von der IF-Abfrage wo der Fehler festgestellt wurde, wieder zurück bis zu den "User-Einstellungen", die Variable verändern und von dort aus das Skript quasi neu rechnen lassen.


----------



## Parantatatam (20. Februar 2012)

Punkt 1: somit sind deine Grundeinstellungen sinnlos. Punkt 2: dann verändere diese eine blöde Variable doch bitte, wenn die anderen Variablen unangetastet bleiben.


----------

