2012-10-13 7 views
12

Ich implementiere eine Ajax-Dateiupload für meine PHP-Anwendung (mit CodeIgniter).PHP Warnung demoliert JSON Antwort

Ich erkenne, ob die hochgeladenen POST-Daten zu groß sind (> post_max_size) nach http://andrewcurioso.com/2010/06/detecting-file-size-overflow-in-php/ und versuche, eine entsprechende JSON-codierte Fehlerantwort zu senden.

Aber die entsprechende php Warnung in der Ausgabe zerstört vollständig meine JSON Antwort!

<br /> 
<b>Warning</b>: POST Content-Length of 105906405 bytes exceeds the limit of 8388608 bytes in <b>Unknown</b> on line <b>0</b><br /> 
[{"error":"Posted data is too large. 105906405 bytes exceeds the maximum size of 8388608 bytes."}] 

Ich will nicht die Warnung heraus auf Client-Seite zu analysieren und zu filtern, das scheint hässlich. Und alle Php-Warnungen global deaktivieren scheint unpassend.

Kann ich bestimmte PHP-Warnungen im Zusammenhang mit einer PHP-Funktion deaktivieren? Oder wickle es innerhalb einer gültigen JSON-Antwort ein?

+3

Sie sollten Fehler in Ihrer Produktionsumgebung sowieso deaktiviert haben ... – lonesomeday

+1

@lonesomeday Ich stimme zu, aber das angegebene Verhalten "Feedback an den Benutzer geben, wenn er versucht, zu große Dateien hochzuladen" sollte in der Produktion und sein Entwicklungs-/Testumgebung. Ich bin kein Fan von "Ja, aber im Produktionsmodus funktioniert es!" ;) –

+1

Normalerweise Fehler in Zeile 0 sind Startup-Fehler, Hinzufügen von 'php_flag display_startup_errors off' zu Ihrem .htaccess sollte es deaktivieren ... hinzugefügt, dass zu meiner Antwort. – xception

Antwort

12

Auf Produktionsserver: Deaktivieren Sie immer PHP-Warnungen.

Auf Entwicklungsmaschine: Deaktivieren Sie alle Warnungen für die Seite zum Zwecke der Prüfung und wieder aktivieren, nachdem der Test abgeschlossen ist und die Funktionalität als Arbeits bestätigt.

Hinweis: Ich bevorzuge eine Variable global gesetzt und je nachdem aktivieren oder deaktivieren Sie alle PHP und Datenbank Warnmeldungen. Sie könnten das zum Beispiel in .htaccess setzen, wenn Sie Apache verwenden. Ich habe dies in .htaccess:

  • Produktion: SetEnv DEVELOPMENT Off
  • Entwicklung: SetEnv DEVELOPMENT On

Und im PHP-Code:

if(strtolower(getenv('DEVELOPMENT')) == "on") { 
     ini_set("display_errors",2); 
     ini_set('error_reporting', E_ALL | E_STRICT); 
} 

Um alle Fehler aus .htaccess Verwendung zu deaktivieren

php_flag display_startup_errors off 
php_flag display_errors off 
php_flag html_errors off 
php_value docref_root 0 
php_value docref_ext 0 

Wenn Sie wirklich schwierig bekommen Sie einen Scheck wie könnte hinzufügen:

if(error_get_last() !== null) 

und legen Sie einen HTTP-Header und prüfen, ob von javascript sowohl für json Ausgabe und wenn Ihre Seite zu laden und einen Blick auf die nehmen Fehlerprotokoll oder Anzeige des Fehlers auf dem Bildschirm, wenn Sie das bevorzugen, ich empfehle immer noch, dass Sie den Fehler deaktivieren, der Code in der Produktionsumgebung zeigt.

Für weitere eingehende Diskussion über dieses Thema werfen Sie einen Blick auf this article.

+0

stimme ich völlig zu, aber der Code sollte schließlich gut funktionieren mit 'display_errors' auf 'on' gesetzt. Und in diesem speziellen Fall scheint das nicht möglich zu sein. –

+0

@BartFriederichs Fehlerberichte von php.ini oder .htaccess deaktivieren. Das muss funktionieren. Code dafür in meiner Antwort hinzugefügt. – xception

+0

@BartFriederichs Eine der 2 Möglichkeiten, die ich vorgeschlagen habe, sollte funktionieren, überprüfen Sie den letzten Teil meiner Antwort für eine Möglichkeit, beide eine Art von Fehlerberichterstattung zu haben, und es betrifft nicht direkt Ihre Ausgabe! – xception

2

Sie können einstellen, eine benutzerdefinierte Fehlerbehandlung: http://www.php.net/manual/en/function.set-error-handler.php

Sie können auch die Ausgabe-Pufferung Funktionen verwenden, um sie zu wickeln. ob_start, ob_end_flush und andere.

Es ist jedoch immer am besten, wenn PHP error_reporting in Produktionssystemen auf false gesetzt ist, dann fangen Sie Fehler und wickeln sie in Ihrem JSON ein.

+0

Ich möchte einen benutzerdefinierten Ereignishandler verwenden, aber die Dokumentation Ihrer geposteten Links lautet: > Wenn Fehler auftreten, bevor das Skript ausgeführt wird (z. B. bei Dateiuploads), kann der benutzerdefinierte Fehlerhandler nicht aufgerufen werden, da er nicht registriert ist diese Zeit. –

+0

Gute Eins. Ihr spezifisches Problem scheint eher ein serverzentriertes als ein Skriptproblem zu sein. Die einzige schnelle Sache, an die ich jetzt denken kann, ist, Warnungen im Skript zu deaktivieren. –

0

Oder Sie können einfach die Größe Post max auf php.ini ändern:

post_max_size = 10M //change this line to whatever fits your needs 

Aber je nachdem, was der Benutzer das Hochladen werden soll, sollten Sie auch versuchen, die Dateigröße der Dateien überprüft, die sie‘ erneut hochladen.

+2

Das hindert Benutzer jedoch nicht, Dateien mit einer Größe von "post_max_size + 1" zu senden –

2

Ich hatte gerade das gleiche Problem, ein Upload-Skript zu implementieren, das die Kommunikation zurück zum aufrufenden Skript erfordert. Einige PHP-Warnungen korrumpierten die Ausgabeantwort.

Ich habe auf die PHP-Pufferung Funktionen zurückgegriffen. Dies ist, wie ich die Warnung Ausgang Nachrichten losgeworden bin:

ob_start(); // start output buffering (we are at the beginning of the script) 

[ ... ] // the script actual functionality is unchanged 

ob_end_clean(); // this clears any potential unwanted output 

exit($my_json_encoded_response); // and this just outputs my intended response 

Dies löste mein Problem.