Erstellen Sie leichte, installierbare Anwendungen, die in HTML, CSS, JavaScript und PHP für die Betriebssysteme Windows, Mac und Linux Desktop geschrieben wurden.

Was mit PHP App Server erstellt werden kann, sind reale, installierbare Softwareanwendungen, die im Vergleich zur herkömmlichen Entwicklung von Desktop -Anwendungen einen Bruchteil der Zeit zum Erstellen benötigen. Gehen Sie von Idea/Konzept zur vollständigen Bereitstellung in 1/10 der Zeit und unterstützen Sie jedes große Desktop -Betriebssystem mit nur einer Codebasis.

PHP App Server ist ein vollwertiger und erweiterbarer Webserver in PHP mit benutzerdefinierten Funktionen, die speziell für die Verwendung in einer herkömmlichen Desktop-Betriebssystemumgebung entwickelt wurden. Wenn der Benutzer die Software über das Startmenü, den Anwendungslauncher usw. ausführt, startet die Software den Server und startet dann den bevorzugten Webbrowser des Benutzers, um auf die Anwendung zuzugreifen. PHP betreibt das Backend, während der Webbrowser alle Details zur Anzeige der Benutzeroberfläche übernimmt. Die vorgefertigten Installationskripte vereinfachen den Prozess des Erstellens endgültiger Release-Pakete für die Lieferung an die Computersysteme Ihres Benutzers.
Laden Sie die neueste Software -Version herunter oder klonen Sie. Verwenden Sie beim Klonen eine Gabel und erstellen Sie eine Zweigstelle für Ihre App, bevor Sie mit der Entwicklung beginnen. Wenn Sie dies tun, werden Ihre Software versehentlich überschrieben, wenn Sie Upstream -Updates für PHP App Server selbst abrufen.
Für den Rest dieses Handbuchs wird angenommen, dass eine kürzlich durchgeführte Version von PHP installiert wird. Es gibt viele Möglichkeiten, dies zu erreichen.
Führen Sie aus einer Befehlszeile Folgendes aus, um eine Liste der Befehlszeilenoptionen zu erhalten:
php server.php -?
Starten Sie einen Webserver auf Port 9002, indem Sie ausführen:
php server.php -port=9002
Die Verzeichnisstruktur des PHP -App -Servers lautet wie folgt:
server.php benötigt werden sollen, um zu arbeiten. Erstellen Sie eine index.php -Datei im Verzeichnis "www":
<?php
phpinfo ();Stellen Sie mit Ihrem Webbrowser eine Verbindung zum laufenden Server an:
http://127.0.0.1:9002/
Die Ausgabe von phpinfo() wird im Browser angezeigt und das Ergebnis der Anforderung wird in die Befehlszeile geschrieben.
Ändern Sie die URL in:
http://127.0.0.1:9002/api/v1/account/info
Die gleiche index.php -Datei wird ausgeführt.
Benennen oder kopieren Sie die Datei index.php in api.php und laden Sie die Seite neu. Jetzt wird api.php genannt. Die Funktion Virtual Directory von PHP App Server ist etwas, das Sie bei der Entwicklung Ihrer Anwendung möglicherweise nützlich finden.
Installierte Softwareanwendungen können nicht an 'www' schreiben. Anwendungen werden normalerweise von einem privilegierten Benutzer im System installiert, aber die Person, die die Software ausführt, verfügt im Allgemeinen nicht über ausreichende Berechtigungen, um in das Verzeichnis "www" zu schreiben. Dies ist eine wichtige Überlegung, die Sie bei der Entwicklung einer Softwareanwendung über den PHP -App -Server berücksichtigen können. Glücklicherweise gibt es eine Lösung für dieses Problem, das bereits in den Server integriert ist: Dual -Dokument -Wurzeln.
Wenn der PHP -Code aus dem "WWW" -Verzeichnis der Anwendung ausgestellt wird, hat er Zugriff auf fünf $_SERVER -Variablen, die in der Umgebung von PHP App Server übergeben werden und einzigartig sind:
DOCUMENT_ROOT_USER . Kann auch an geschrieben werden, kann aber nicht von URLs verwiesen werden. Nützlich zum Speichern privater Daten für die Anwendung (z. B. eine SQLite -Datenbank).server.php liegt). Nützlich zum Zugriff auf Dateien im support -Unterverzeichnis. Wenn eine Anfrage an den Webserver gestellt wird, sucht PHP App Server zuerst nach Dateien im 'WWW' Verzeichnis der Anwendung. Wenn es dort keine Datei findet, prüft sie die Datei im von DOCUMENT_ROOT_USER angegebenen Pfad.
Das Schreiben einer Localhost Server -Anwendung, die sich auf einen Webbrowser stützt, kann zu schweren Verstößen gegen die Systemsicherheit führen, die vom Verlust der Datenregelung bis zur Beschädigung des Dateisystems des Benutzers reichen. Solange die Anwendung korrekt geschrieben ist, schützt die Richtlinien des Webbrowsers den Benutzer im Allgemeinen vor böswilligen Websites und Benutzern, die versuchen, auf PHP App -Server kontrollierte Inhalte zuzugreifen.
Hier sind jedoch einige wichtige, ausgewählte Sicherheitselemente ausgewählt, gegen die alle PHP -App -serverbasierten Softwareanwendungen aktiv verteidigen müssen (in der Reihenfolge von Bedeutung):
$_SERVER["PAS_USER_FILES"] oder einen benutzerdefinierten Ort, um sensible Benutzerdaten anstelle von $_SERVER["DOCUMENT_ROOT_USER"] zu speichern. Fragen Sie den Benutzer immer, was zu tun ist, wenn er etwas als sensibel angesehen wird (z. B. die Frage könnte so einfach sein wie das Anzeigen eines Kontrollkästchens für den Benutzer). Privatsphäre zentrierte Personen werden im Allgemeinen ihre Meinung sagen.$_SERVER["PAS_SECRET"] kombiniert mit Cubiclesoft Admin Pack oder anderen Anwendungs -Frameworks helfen bei der Behandlung dieses Problems. Server -Erweiterungen erfordern im Allgemeinen auch ein Authentifizierungs -Token, das auf $_SERVER["PAS_SECRET"] basiert.Es gibt viele andere Sicherheitsüberlegungen, die sich in der OWASP Top 10 -Liste und der OWASP -Angriffsliste befinden, um ebenfalls zu im Auge, aber das sind die großen.
PHP App Server enthält eine leistungsstarke Servererweiterung und zwei SDKs, um langlebige Prozesse sowohl von PHP als auch von JavaScript zu starten, zu verwalten und zu überwachen. Beginnende Prozesse werden als Benutzer ausgeführt, dass der PHP -App -Server ausgeführt wird, aber nicht durch Zeitüberschreitungen oder Speicherlimits wie regelmäßige CGI/FastCGI -Anforderungen nicht begrenzt ist. Ausführende Prozesse können aktiv überwacht und sogar über das mitgelieferte JavaScript SDK aus dem Webbrowser interagiert werden.

Langlebige Skripte sollten idealerweise in einem Subverzeichnis "Skripte" vom Hauptverzeichnis "Haupt-PHP App Server" gespeichert werden. Auf diese Weise sind sie vom Haupt -Web -Root weg, aber die Anwendung kann sie weiterhin über $_SERVER["PAS_ROOT"] finden.
Hier ist ein Beispiel für das Starten eines PHP -Skripts namens "test.php" mit dem PHP SDK:
<?php
$ rootpath = str_replace ( "\" , " / " , dirname ( __FILE__ ));
// Load the PHP App Server common functions.
require_once $ _SERVER [ " PAS_ROOT " ] . " /support/process_helper.php " ;
require_once $ _SERVER [ " PAS_ROOT " ] . " /support/pas_functions.php " ;
$ cmd = escapeshellarg ( PAS_GetPHPBinary ());
$ cmd .= " " . escapeshellarg ( realpath ( $ _SERVER [ " PAS_ROOT " ] . " /support/scripts/test.php " ));
$ options = array (
// "rules" => array(
// "start" => time() + 5,
// "maxqueued" => 3
// ),
// "stdin" => false,
// "dir" => $_SERVER["PAS_ROOT"] . "/support/scripts/",
// "env" => ProcessHelper::GetCleanEnvironment(),
// "extraenv" => array("PASSWORD" => "supersecret"),
// "extra" => array(
// "title" => "Custom window title",
// "inputmode" => "readline"
// )
);
// Start the process.
require_once $ rootpath . " /support/pas_run_process_sdk.php " ;
$ rp = new PAS_RunProcessSDK ();
$ result = $ rp -> StartProcess ( " demo " , $ cmd , $ options );
if (! $ result [ " success " ]) echo " An error occurred while starting a long-running process. " ;
echo " Done. " ;
?>Jeder Prozess erhält ein Tag, mit dem mehrere laufende Prozesse nach Tag gruppiert werden können. Im obigen Beispiel heißt das Tag "Demo". Mit dem Javacsript SDK können später nur Prozesse angezeigt werden, die ein bestimmtes Tag verwenden:
<?php
header ( " Content-Type: text/html; charset=UTF8 " );
?>
<!DOCTYPE html>
<html>
<body>
<?php
$ rootpath = str_replace ( "\" , " / " , dirname ( __FILE__ ));
require_once $ rootpath . " /support/pas_run_process_sdk.php " ;
PAS_RunProcessSDK:: OutputCSS ();
PAS_RunProcessSDK:: OutputJS ();
?>
<div id="terminal-manager"></div>
<script type="text/javascript">
// NOTE: Always put Javascript RunProcesSDK and TerminalManager class instances in a Javascript closure like this one to limit the XSRF attack surface.
(function() {
// Establish a new connection with a compatible WebSocket server.
var runproc = new RunProcessSDK(' <?= PAS_RunProcessSDK:: GetURL () ?> ', false, ' <?= PAS_RunProcessSDK:: GetAuthToken () ?> ');
// Debugging mode dumps incoming and outgoing packets to the web browser's debug console.
runproc.debug = true;
// Establish a new terminal manager instance.
var elem = document.getElementById('terminal-manager');
// Automatically attach to all channels with the 'demo' tag.
var options = {
tag: 'demo'
};
var tm = new TerminalManager(runproc, elem, options);
})();
</script>
</body>
</html>Das PHP SDK vereinfacht die Ausgabe der erforderlichen CSS- und Javscript -Abhängigkeiten in die HTML. Der obige Code zeigt, dass das Einrichten einer WebSocket -Verbindung zur Erweiterung der PHP -App -Server eingerichtet und mit einer TerminalManager -Instanz verbunden ist, um die Prozesse mit dem Tag "Demo" zu überwachen. TerminalManager ist eine eingeschlossene JavaScript -Klasse, die automatisch einen oder mehrere Execterminals (auch enthalten) basierend auf den Eingabekriterien erstellt und verwaltet. In diesem Fall wird TerminalManager automatisch an einen Prozess angeschlossen, der mit einem "Demo" -Tag erstellt wurde. Ein exekativer Aussehen sieht so aus:

Jede extreme TERTERNIMINISCHE MACHTE EINE XTERM.JS -ANTERINAL -Instanz mit zusätzlichen Funktionen:
Und mehr.
Beachten Sie, dass TerminalManager und Execterminal für die Verwaltung langer Laufprozesse nicht erforderlich sind, aber einige gemeinsame Szenarien behandeln. Der obige Beispielcode kratzt nur die Oberfläche dessen, was getan werden kann.
Hier ist die vollständige Liste der Terminalmanager -Optionen:
Die mitgelieferte Xterm-PHP-Klasse bietet eine nahtlose und vereinfachte Kontrolle über die Ausgabe von einem langjährigen Skript bis zum Xterm-kompatiblen EXECERNAL im Browser. Sie müssen sich keine Ansi -Fluchtcodes erinnern. Hier ist ein Beispielskript:
<?php
if (! isset ( $ _SERVER [ " argc " ]) || ! $ _SERVER [ " argc " ])
{
echo " This file is intended to be run from the command-line. " ;
exit ();
}
$ rootpath = str_replace ( "\" , " / " , dirname ( __FILE__ ));
require_once $ rootpath . " /../xterm.php " ;
for ( $ x = 0 ; $ x < 5 ; $ x ++)
{
echo " Test: " . ( $ x + 1 ) . "n" ;
sleep ( 1 );
}
echo " That's boring. Let's... " ;
sleep ( 1 );
XTerm:: SetItalic ();
echo " spice it up! n" ;
XTerm:: SetItalic ( false );
sleep ( 1 );
$ palette = XTerm:: GetBlackOptimizedColorPalette ();
for ( $ x = 5 ; $ x < 10 ; $ x ++)
{
$ num = mt_rand ( 17 , 231 );
XTerm:: SetForegroundColor ( $ palette [ $ num ]);
echo " Test: " . ( $ x + 1 ) . " (Color " . $ palette [ $ num ] . " ) n" ;
sleep ( 1 );
}
XTerm:: SetForegroundColor ( false );
XTerm:: SetTitle ( " Changing the title... " );
usleep ( 250000 );
XTerm:: SetTitle ( " Changing the title...like " );
usleep ( 250000 );
XTerm:: SetTitle ( " Changing the title...like a " );
usleep ( 250000 );
XTerm:: SetTitle ( " Changing the title...like a BOSS! " );
usleep ( 500000 );
echo "n" ;
echo " Enter some text: " ;
$ line = rtrim ( fgets ( STDIN ));
XTerm:: SetBold ();
echo " Here's what you wrote: " . $ line . "nn" ;
XTerm:: SetBold ( false );
echo " [Switching to 'readline_secure' mode] nn" ;
XTerm:: SetCustomInputMode ( ' readline_secure ' );
echo " Enter some more text: " ;
XTerm:: SetColors ( 0 , 0 );
$ line = rtrim ( fgets ( STDIN ));
XTerm:: SetColors ( false , false );
XTerm:: SetCustomInputMode ( ' readline ' );
XTerm:: SetBold ();
echo " Here's what you wrote: " . $ line . "nn" ;
XTerm:: SetBold ( false );
echo " Done. n" ;
?>Wenn Sie Cubiclesoft Admin Pack oder FlexForms verwenden, um Ihre Anwendung zu erstellen, enthält das PHP SDK native FlexForms -Integration (dh keine Notwendigkeit, JavaScript/HTML zu schreiben):
<?php
// Admin Pack and FlexForms integration.
require_once " support/pas_run_process_sdk.php " ;
$ contentopts = array (
" desc " => " Showing all long-running processes with the 'demo' tag. " ,
" fields " => array (
array (
" type " => " pas_run_process " ,
// "debug" => true,
" options " => array (
" tag " => " demo "
)
)
)
);
BB_GeneratePage ( " Process Demo " , $ menuopts , $ contentopts );
?> Das Schreiben einer Erweiterung erfordert ein wenig Wissen darüber, wie PHP-App-Server funktioniert: Während des Starts werden die Erweiterungen frühzeitig geladen, damit sie bei Bedarf in die Start-Sequenz eintauchen können (hauptsächlich nur für Sicherheitsrate im Zusammenhang mit Erweiterungen). Sobald der Webserver begonnen hat, geht jede Webanforderung die Liste der Erweiterungen durch und fragt: "Können Sie diese Anfrage bearbeiten?" Wenn eine Verlängerung in der Bejahung reagiert (dh zurücksetzt), wird der Rest der Anfrage an die Verlängerung zur Handlung weitergegeben.
Da Erweiterungen direkt mit dem Kernserver eingeleitet werden, erhalten sie einen erheblichen Leistungssteiger und können Dinge wie auf Websocket reagieren oder langjährige Prozesse starten, die normalerweise nach 30 Sekunden vom normalen PHP-Pfad nach 30 Sekunden getötet werden.
Diese Vorteile sind jedoch mit zwei Hauptnachteilen verbunden. Das erste ist, dass, wenn eine Erweiterung eine ungewöhnliche Ausnahme ansteigt oder auf andere Weise abstürzt, der gesamte Webserver mitnimmt. Das zweite ist, dass das Voraussetzen von Codeänderungen in einer Erweiterung den Webserver neu gestartet werden muss, um die Änderungen zu testen, was ein wenig problematisch sein kann. Im Allgemeinen reicht der normale WWW -Weg für die meisten Bedürfnisse aus, und die Verlängerungen sind gelegentliche Segmente spezialisierter Logik.
Die mitgelieferte Verlängerung der Sicherheitspflichten ist ein hervorragender Ausgangspunkt für den Erstellen einer Erweiterung, mit der Anforderungen ordnungsgemäß behandelt werden können. Die Sicherheits-Token-Erweiterung ist ziemlich kurz, gut gefördert und funktioniert.
Der Server geht davon aus, dass der Dateiname Teil des Klassennamens ist. Unabhängig von der PHP -Datei muss der Klassenname in diesem Beispiel folgen, andernfalls kann der PHP -App -Server die Erweiterung nicht laden. Erweiterungsnamen sollten mit einer Nummer beginnen, die die erwartete Reihenfolge angibt, in der die Erweiterung aufgerufen werden soll.
Die Variablen, die normalen PHP -Skripten verfügbar sind, sind auch Erweiterungen über die globale $baseenv -Variable (z. B. $baseenv["DOCUMENT_ROOT_USER"] und $baseenv["PAS_USER_FILES"] ) verfügbar. Bitte ändern Sie nicht die $baseenv -Werte, da dies den Rest der Anwendung negativ beeinflusst.
Verwenden Sie immer die statische Funktion ProcessHelper::StartProcess() , wenn Sie externe, langlebige Prozesse in einer Erweiterung starten. Die Processhelper-Klasse ist so konzipiert, dass sie nicht blockierende Prozesse im Hintergrund auf allen Plattformen starten. Beachten Sie, dass die bevorzugte Methode, um langlebige Prozesse zu beginnen, darin besteht, die langjährige Prozesse zu verwenden.
Für bestimmte Aufgaben ist es wichtig, den PHP -App -Server zu beenden. Wenn beispielsweise eine PHP -App -Serveranwendung unter Windows aktualisiert wird, muss PHP selbst aktualisiert werden und kann daher während des Upgrades nicht ausgeführt werden. Es ist auch im Allgemeinen ein gutes Verhalten, eine Anwendung nicht zu lange nach dem letzten Browser -Registerkarte zu beenden.
Es stehen zwei verfügbare Methoden zur Auslösung der frühen Beendigung des Servers:
/exit-app/ und senden Sie eine gültige authtoken und eine delay in einem JSON-Objekt, das die Anzahl der Sekunden angibt, um zu warten, um den Server zu beenden. Nach der Verwendung muss jede Seite der App eine Verbindung zu /exit-app/ den Server am Leben erhalten. Eine Mindestverzögerung von 3 Sekunden wird empfohlen. Webbrowser neigen dazu, WebSocket -Verbindungen zu löschen, sobald sie die Seite verlassen oder die Registerkarte geschlossen ist.X-Exit-App Header in der Antwort eines PHP-Skripts. Der Wert des Headers ist die ganzzahlige Anzahl von Sekunden, die darauf warten, den Server zu beenden. Eine Mindestverzögerung von 3 Sekunden wird empfohlen. Dieser spezielle Header wird nicht an den Webbrowser übergeben, sondern intern behandelt.Beispiel -PHP -Code für die Erweiterungsmethode der Exit App:
<script type="text/javascript">
// NOTE: Always put WebSocket class instances in a Javascript closure like this one to limit the XSRF attack surface.
( function () {
function InitExitApp ()
{
var ws = new WebSocket ((window.location.protocol === ' https: ' ? ' wss:// ' : ' ws:// ' ) + window.location.host + ' /exit-app/ ' );
ws. addEventListener ( ' open ' , function ( e ) {
var msg = {
authtoken: ' <?=hash_hmac("sha256", "/exit-app/", $_SERVER["PAS_SECRET"])?> ' ,
delay: 3
};
ws. send ( JSON . stringify (msg));
});
ws. addEventListener ( ' close ' , function ( e ) {
setTimeout (InitExitApp, 500 );
});
}
InitExitApp ();
})();
</script>Beispiel -PHP -Code für die Header -Methode:
<?php
// User clicked an "Exit application" link or something.
header ( " X-Exit-App: 3 " );
?>Die Erweiterung ist eine zuverlässigere Methode zum Erkennen, dass alle Browser -Registerkarten der Anwendung geschlossen wurden. Wenn die Anwendung die Erweiterung jedoch aus irgendeinem Grund nicht unterstützen kann, verwenden Sie stattdessen die Header -Methode. Die Header -Methode wird am besten auf Seiten verwendet, auf denen sie sinnvoll ist (z. B. eine Seite mit Upgrade -Informationen).
Bevor Sie die verschiedenen Skripte ausführen, die Installationspakete generieren, müssen verschiedene Dateien erstellt, umbenannt und/oder geändert werden. Jede Datei, die mit "YourApp" beginnt, muss in Ihrem Anwendungsnamen umbenannt werden, vorzugsweise auf alle Kleinbuchstaben und Bindestriche beschränkt. Dies muss durchgeführt werden, damit Updates an der Software Ihre Arbeit nicht versehentlich überschrieben und so dass alle neugierigen Benutzer, die die Verzeichnisstruktur stöbern, den tatsächlichen Namen der Anwendung anstelle von "yourApp" sehen.
Die Datei 'yourApp.phpapp' ist eine PHP -Datei, die die tatsächliche Anwendungsstartsequenz des Starts des Webservers (Server.php) und dann den Webbrowser des Benutzers ausführt. In der Datei befindet sich ein Array $options , das für die Anforderungen Ihrer Anwendung geändert werden sollte:
Die letzten drei Optionen sind für hochspezialisierte Szenarien vorgesehen. Das Ändern von 'Host' in so etwas wie "127.0.1.1" mag in Ordnung sein, aber verwenden Sie nicht "0.0.0.0" oder ":: 0", der den Server öffentlich an die Netzwerkschnittstelle bindet. Die Bindung an eine bestimmte "Port" -Nummer scheint eine gute Idee zu sein, bis sich Benutzer über Fehlermeldungen beschweren, wenn sie versuchen, die Anwendung neu zu starten.
Die Option "Quitdelay" ist interessant. Der Serverabschnitt des PHP -App -Servers bleibt bis 'Quitdelay' Minuten nach dem letzten Client die Verbindung. Die Anwendung sollte alle fünf Minuten eine "Heartbeat" -Anforderung senden, um sicherzustellen, dass der Webserver sich nicht beendet, bevor der Benutzer mit der Anwendung fertig ist.
Jedes Plattform -Verpackungstool hat seine eigenen Anweisungen:
xdg-utils unterstützt (Gnome, KDE, XFCE usw. sind alles in Ordnung).Es gibt einige Probleme mit der Verpackung:
Die Installateure und die Serversoftware haben einige interessante Geschichten dahinter. Vielleicht werde ich diese Geschichten eines Tages teilen. Genießen Sie es vorerst, Ihre nächste Anwendung auf dem PHP -App -Server zu erstellen!