2015-10-30 3 views
12

Wie kann ich das Haupt PHP-Skript Rückkehr false von innerhalb einer Klasse oder einer Funktion machen?Wie kann man von einem PHP-Skript innerhalb einer Klasse/Funktion false zurückgeben?

Warum: Das ist wegen des eingebauten Webserver:

Wenn eine PHP-Datei auf der Kommandozeile angegeben wird, wenn der Web-Server gestartet wird es als „Router“ Skript behandelt wird. Das Skript wird zu Beginn jeder HTTP-Anfrage ausgeführt. Wenn dieses Skript FALSE zurückgibt, wird die angeforderte Ressource unverändert zurückgegeben.

aus der Dokumentation über die PHP Built-in webserver

Mit anderen Worten: Sie kehren false in Ihrem Router-Skript, so dass die integrierten Webserver kann statische Dateien dienen. Beispiel aus der Dokumentation:

if (preg_match('/\.(?:png|jpg|jpeg|gif)$/', $_SERVER["REQUEST_URI"])) { 
    return false; // serve the requested resource as-is. 
} else { 
    echo "<p>Welcome</p>"; 
} 

Die Sache ist, dass ich dieses Verhalten zu einem Web-Framework hinzufügen bin versucht: Ich möchte nicht, dass in index.php schreiben. Ich würde diese Logik lieber in eine Klasse (Middleware) einkapseln, die die Ausführung des Skripts stoppt, wenn php_sapi_name() == 'cli-server' und ein statisches Asset gefragt wird.

Ich weiß jedoch nicht, wie ich das ganze PHP-Skript false aus einer Klasse oder Funktion zurückgeben kann, da return false offensichtlich von der aktuellen Methode/Funktion/Datei und nicht von der Hauptdatei zurückkommt.

Gibt es eine Möglichkeit, das gleiche Verhalten zum Beispiel mit exit() zu erreichen? Ich weiß, ich weiß nicht einmal, was return false in der Hauptdatei eigentlich bedeutet (ist das ein bestimmter Exit-Code?).

+0

@Terminus 'return false' hat eine besondere Bedeutung für PHP integrierten Server finden Sie in der Dokumentation I zitiert. –

Antwort

6

Sie sollten den Router die Klassenmethode aufrufen lassen und dann, wenn die Methode false zurückgibt, false aus Ihrer Routerdatei zurückgeben.

Natürlich kann es in Kopfschmerzen verwandeln. Es gibt im Grunde nur zwei Methoden, um das zu erreichen, was Sie erreichen wollen.

Es gibt einen schnelleren Weg, obwohl, können Sie Ausnahmen missbrauchen und eine spezielle Ausnahme für den Fall erstellen:

StaticFileException.php

<?php 
class StaticFileException extends Exception {} 

router.php

<?php 
try { 
    $c = new Controller(); 
    return $c->handleRequest(); 
} catch (StaticFileException $e) { 
    return false; 
} 

Sobald Sie diese Art haben, Code an Ort und Stelle, nur throw new StaticFileException und du bist fertig.

+0

danke für die Bearbeitung @self – tacone

+0

Vielen Dank für die Ideen. Ich suche idealerweise nach einem Äquivalent von 'return false' mit' exit() 'oder so ähnlich (wenn es überhaupt möglich ist ...). Wenn das nicht möglich ist, muss ich leider nach Lösungen suchen:/Aber ich halte die 'index.php' lieber so klein wie möglich. –

+0

Ich verstehe nicht, wie es kompliziert ist, die ganze Router-Datei in einen großen Try-Catch zu wickeln. Übrigens: Die einzige Möglichkeit, von verschachtelten Kontexten zurück zu springen, ist das Auslösen einer Ausnahme. – tacone

4

Wenn die Methode in Ihrer Klasse verarbeitet statische Vermögenswerte unter Verwendung exit dann kann die Lösung so einfach sein wie exit mit return false ersetzt ist und die Anrufer dieses Verfahrens einfach die Methode im globalen Bereich und zurück.

Also wenn Ihre Klasse so etwas aussieht ...

class Router 
{ 
    public function handleRequest($uri) 
    { 
     if (is_file($this->docRoot . $uri->path)) { 
      exit; // static file found 
     } else { 
      // handle as normal route 
     } 
    } 
} 

Gerade exit es ersetzen mit return false ...

  return false; // static file found 

Dann, wenn Ihr index.php so etwas wie das funktioniert ...

$router = new Router($docRoot); 
$router->handleRequest($_SERVER['REQUEST_URI']); 

einfach eine Rückkehr direkt vor dem handleRequest Methode hinzufügen wie so ....

nur aus dem Skript der globalen Bereich

Dies sollte nur minimale Nebenwirkungen auf Ihrem Rahmen-Design hat und wie Sie benötigt sehr wenig Code und Refactoring sehen können, weil die Rückkehr eine einzige Nebenwirkung in PHP hat (indem er den Wert wieder auf Skript Aufruf dh, wenn Sie verwendet include/require als Ausdruck in einer Zuweisung). In Ihrem Fall, wenn index.php das aufrufende Skript ist, dann müssen Sie sich hier keine Sorgen machen, indem Sie return vor dieser Methode hinzufügen.

Natürlich, wenn Sie den Rest des Skripts wird bestätigt, weiterhin so sicherstellen, dass es die letzte Anweisung in der index.php ist. Sie können sogar zuweisen nur den Rückgabewert auf einen temporären Wert und später zurück, wenn Sie für die Logik benötigt ....

$router = new Router($docRoot); 
if ($router->handleRequest($_SERVER['REQUEST_URI'])) { 
    /* if you need to do anything else here ... */ 
} else { 
    return false; // otherwise you can return false for static here 
} 

Generell würde ich sagen, dass exit aus dem Inneren einer Funktion/Methode aufrufen ist fast nie wünschenswert. Es macht Ihre Klasse schwieriger zu testen und zu debuggen und hat wirklich keinen den Kopf von den Alternativen wie eine Ausnahme zu werfen, oder einfach nur aus dem Verfahren zurückkehrt, und läßt den Anrufer die Fehlerszenarien behandelt anmutig.

+0

Das ist eine gute Idee. Ich möchte nur darauf hinweisen, dass ich heute 'exit()' überhaupt nicht verwende.Statische Dateien werden vom integrierten Server nicht unterstützt. Die einzige Sache, die es für mich schwierig macht, ist, dass das Framework auf [Middlewares] basiert (https://github.com/zendframework/zend-stratigility/blob/master/doc/book/middleware.md). Da eine Middleware ** ein 'ResponseInterface' -Objekt ** zurückliefern muss, kann ich' false' nicht zurückgeben (ich möchte, dass die Funktion "Statische Dateien" als Middleware implementiert wird, um ordnungsgemäß gekapselt zu werden). Wie auch immer, das ist Essen für Gedanken, danke. –

+0

In diesem Fall ist der Vorschlag, eine Ausnahme auszugeben und '' false '' aus dem globalen Bereich mit einem 'catch'-Block zurückzugeben, wahrscheinlich die beste Wahl. – Sherif

0

Ist es nicht möglich, mit register_shutdown_function oder mit auto_append_file-Einstellung zu spielen, um damit umzugehen? Nicht wirklich nett, aber vielleicht kann das den Job machen.

+0

Oh, ich mag die Art, wie du denkst: P Ich fürchte, 'register_shutdown_function' bedeutet, dass ich in einer Funktion bin. Wenn also false zurückgegeben wird, wird die Funktion und nicht das Skript beendet:/Und für' auto_append_file' ist es leider nicht möglich um es zur Laufzeit zu benutzen, konnte ich es nicht funktionieren lassen, selbst in einer dummen Testdatei (zusätzlich wäre es für die Benutzer so verwirrend, aber warum nicht). –

+0

Sie sprachen über "Exit" und auch über einen Framework-Kontext mit dem internen PHP-Webserver. Deshalb habe ich diese Zwecke gemacht. Ich stimme dir völlig zu: Beide sind nicht sehr nett. –

Verwandte Themen