Buat aplikasi ringan dan dapat diinstal yang ditulis dalam HTML, CSS, JavaScript, dan PHP untuk sistem operasi desktop Windows, Mac, dan Linux.

Apa yang dapat dibuat dengan server aplikasi PHP adalah aplikasi perangkat lunak yang nyata dan dapat diinstal yang membutuhkan sebagian kecil waktu untuk membuat jika dibandingkan dengan pengembangan aplikasi desktop tradisional. Pergi dari ide/konsep ke penyebaran penuh dalam 1/10 waktu dan mendukung setiap OS desktop utama dengan hanya satu basis kode.

PHP App Server adalah server web lengkap dan dapat diperluas yang ditulis dalam PHP dengan fitur khusus yang dirancang khusus untuk digunakan dalam lingkungan OS desktop tradisional. Ketika pengguna menjalankan perangkat lunak melalui menu mulai, peluncur aplikasi, dll., Perangkat lunak memulai server dan kemudian meluncurkan browser web yang disukai pengguna untuk mengakses aplikasi. PHP memberi daya pada backend sementara browser web menangani semua detail seluk-beluk dari menampilkan antarmuka pengguna. Skrip installer siap pakai menyederhanakan proses membuat paket rilis akhir untuk pengiriman ke sistem komputer pengguna Anda.
Unduh atau klon rilis perangkat lunak terbaru. Saat mengkloning, pastikan untuk menggunakan garpu dan membuat cabang untuk aplikasi Anda sebelum memulai pengembangan. Melakukannya menghindari secara tidak sengaja menimpa perangkat lunak Anda setiap kali Anda mengambil pembaruan hulu untuk server aplikasi PHP itu sendiri.
Untuk sisa panduan ini, versi PHP baru -baru ini diasumsikan dipasang. Ada banyak cara untuk mewujudkannya.
Dari baris perintah, jalankan yang berikut untuk mendapatkan daftar opsi baris perintah:
php server.php -?
Mulai server web di port 9002 dengan menjalankan:
php server.php -port=9002
Struktur Direktori Server Aplikasi PHP adalah sebagai berikut:
server.php untuk beroperasi. Buat file index.php di direktori 'www':
<?php
phpinfo ();Sambungkan ke server yang sedang berjalan dengan browser web Anda di:
http://127.0.0.1:9002/
Output phpinfo() ditampilkan di browser dan hasil permintaan ditulis ke baris perintah.
Ubah URL menjadi:
http://127.0.0.1:9002/api/v1/account/info
File index.php yang sama berjalan.
Ganti nama atau salin file index.php ke api.php dan muat ulang halaman. Sekarang api.php dipanggil. Fitur Direktori Virtual dari PHP App Server adalah sesuatu yang mungkin Anda temukan bermanfaat saat Anda mengembangkan aplikasi Anda.
Aplikasi perangkat lunak yang diinstal tidak dapat menulis ke 'www'. Aplikasi biasanya diinstal oleh pengguna istimewa pada sistem tetapi orang yang menjalankan perangkat lunak umumnya tidak akan memiliki izin yang cukup untuk menulis ke direktori 'www'. Ini adalah pertimbangan penting untuk diingat saat mengembangkan aplikasi perangkat lunak menggunakan server aplikasi PHP. Untungnya, ada solusi untuk masalah ini yang sudah dibangun ke dalam server: akar dokumen ganda.
Ketika kode PHP dieksekusi dari direktori 'www' aplikasi, ia memiliki akses ke lima variabel $_SERVER yang dilewati oleh dan unik untuk lingkungan server aplikasi PHP:
DOCUMENT_ROOT_USER . Juga dapat ditulis tetapi tidak dapat dirujuk oleh URL. Berguna untuk menyimpan data pribadi untuk aplikasi (misalnya database SQLITE).server.php berada). Berguna untuk mengakses file di subdirektori support . Ketika permintaan dibuat ke server web, server aplikasi PHP mencari file pertama di direktori 'www' aplikasi. Jika tidak menemukan file di sana, maka periksa file di jalur yang ditentukan oleh DOCUMENT_ROOT_USER .
Menulis aplikasi server LocalHost yang bergantung pada browser web dapat mengakibatkan pelanggaran keamanan sistem yang serius mulai dari hilangnya kontrol data hingga merusak sistem file pengguna. Selama aplikasi ditulis dengan benar, kebijakan browser web umumnya akan melindungi pengguna dari situs web berbahaya dan pengguna yang mencoba mengakses konten yang dikendalikan oleh server aplikasi PHP.
Namun, berikut adalah beberapa item terkait keamanan yang penting yang harus dipertahankan oleh semua aplikasi perangkat lunak berbasis server PHP Aplikasi secara aktif (dalam urutan kepentingan):
$_SERVER["PAS_USER_FILES"] atau lokasi yang ditentukan pengguna untuk menyimpan data pengguna yang sensitif alih -alih $_SERVER["DOCUMENT_ROOT_USER"] . Selalu tanyakan kepada pengguna apa yang harus dilakukan jika mereka dapat menganggap sesuatu sebagai sensitif (misalnya bertanya bisa sesederhana menampilkan kotak centang kepada pengguna). Individu privasi-sentris umumnya akan mengutarakan pikiran mereka.$_SERVER["PAS_SECRET"] Dikombinasikan dengan paket admin Cubiclesoft atau kerangka kerja aplikasi lainnya membantu menangani masalah ini. Ekstensi server juga umumnya memerlukan token otentikasi berdasarkan $_SERVER["PAS_SECRET"] .Ada banyak pertimbangan keamanan lain yang ada dalam daftar 10 teratas OWASP dan daftar serangan OWASP juga diingat, tetapi itu adalah yang besar.
PHP App Server mencakup ekstensi server yang kuat dan dua SDK untuk membuat awal, mengelola, dan memantau proses jangka panjang mudah dan aman dari PHP dan JavaScript. Mulai proses berjalan sebagai pengguna yang dijalankan server aplikasi PHP tetapi tidak dibatasi oleh batas waktu atau batas memori seperti permintaan CGI/FastCGI biasa. Proses berjalan dapat dipantau secara aktif dan bahkan berinteraksi dengan dari browser web melalui SDK JavaScript yang disertakan.

Script yang sudah berjalan lama idealnya harus disimpan dalam subdirektori 'skrip' dari direktori server aplikasi php 'dukungan'. Dengan begitu mereka jauh dari root web utama tetapi aplikasi masih dapat menemukannya melalui $_SERVER["PAS_ROOT"] .
Berikut adalah contoh memulai skrip PHP yang disebut 'test.php' menggunakan 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. " ;
?>Setiap proses diberikan tag, yang memungkinkan beberapa proses berjalan dikelompokkan berdasarkan tag. Dalam contoh di atas, tag disebut "demo". Javacsript SDK nanti dapat digunakan untuk menampilkan hanya proses yang menggunakan tag tertentu:
<?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>PHP SDK menyederhanakan pemancaran dependensi CSS dan Javscript yang diperlukan ke dalam HTML. Kode di atas menunjukkan pengaturan koneksi WebSocket ke ekstensi server aplikasi PHP dan menghubungkannya ke instance TerminalManager untuk memantau proses dengan tag "demo". TerminalManager adalah kelas JavaScript yang disertakan yang secara otomatis membuat dan mengelola satu atau lebih eksekutif (juga disertakan) berdasarkan kriteria input. Dalam hal ini, TerminalManager akan secara otomatis melekat pada proses apa pun yang dibuat dengan tag "demo". Seorang eksekutif terlihat seperti ini:

Setiap eksekutif membungkus instance terminal xterm.js dengan fitur tambahan:
Dan lebih banyak lagi.
Perhatikan bahwa TerminalManager dan Execterminal tidak diperlukan untuk mengelola proses yang sudah berjalan lama tetapi mereka menangani beberapa skenario umum. Kode contoh di atas hanya menggaruk permukaan apa yang bisa dilakukan.
Berikut adalah daftar lengkap Opsi TerminalManager:
Kelas Xterm PHP yang disertakan menawarkan kontrol yang mulus dan disederhanakan atas output dari skrip jangka panjang ke eksekutif yang kompatibel dengan Xterm di browser. Tidak perlu mengingat kode pelarian ANSI. Inilah contoh skrip:
<?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" ;
?>Akhirnya, jika Anda menggunakan paket admin Cubiclesoft atau FlexForms untuk membangun aplikasi Anda, PHP SDK mencakup integrasi FlexForms asli (yaitu tidak perlu menulis JavaScript/HTML):
<?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 );
?> Menulis ekstensi membutuhkan sedikit pengetahuan tentang cara kerja server aplikasi PHP: ekstensi dimuat sejak awal selama startup sehingga mereka dapat terlibat dalam urutan startup jika mereka perlu (kebanyakan hanya untuk ekstensi terkait keamanan). Setelah server web dimulai, setiap permintaan web berjalan melalui daftar ekstensi dan bertanya, "Bisakah Anda menangani permintaan ini?" Jika suatu perpanjangan merespons dalam afirmatif (yaitu mengembalikan true), maka sisa permintaan diturunkan ke ekstensi untuk ditangani.
Karena ekstensi dijalankan secara langsung sesuai dengan server inti, mereka mendapatkan peningkatan kinerja yang signifikan dan dapat melakukan hal-hal seperti merespons atas WebSocket atau memulai proses jangka panjang yang biasanya akan terbunuh setelah 30 detik dengan jalur PHP normal.
Namun, manfaat itu datang dengan dua kelemahan utama. Yang pertama adalah bahwa jika suatu ekstensi menimbulkan pengecualian yang tidak tertutup atau crash, ia membawa seluruh server web dengannya. Yang kedua adalah bahwa membuat perubahan kode ke ekstensi membutuhkan restart server web untuk menguji perubahan, yang bisa sedikit merepotkan. Secara umum, jalur 'www' normal sudah cukup untuk sebagian besar kebutuhan dan ekstensi adalah untuk segmen sesekali logika khusus.
Ekstensi token keamanan yang disertakan adalah titik awal yang sangat baik untuk membangun ekstensi yang dapat menangani permintaan dengan benar. Perpanjangan token keamanan cukup pendek, terommentasi dengan baik, dan berhasil.
Server mengasumsikan bahwa nama file adalah bagian dari nama kelas. Apa pun namanya file PHP, nama kelas di dalam harus mengikuti, jika tidak, server aplikasi PHP akan gagal memuat ekstensi. Nama ekstensi harus dimulai dengan nomor, yang menunjukkan urutan yang diharapkan untuk memanggil ekstensi.
Variabel yang tersedia untuk skrip PHP normal juga tersedia untuk ekstensi melalui variabel $baseenv global (misalnya $baseenv["DOCUMENT_ROOT_USER"] dan $baseenv["PAS_USER_FILES"] ). Harap jangan mengubah nilai $baseenv karena itu akan berdampak negatif pada sisa aplikasi.
Selalu gunakan fungsi statis ProcessHelper::StartProcess() saat memulai proses eksternal, jangka panjang di dalam ekstensi. Kelas ProcessHelper dirancang untuk memulai proses non-blocking di latar belakang di semua platform. Perhatikan bahwa cara yang lebih disukai untuk memulai proses jangka panjang adalah dengan menggunakan ekstensi proses jangka panjang.
Untuk tugas -tugas tertentu, penting untuk memberi tahu server aplikasi PHP untuk keluar. Misalnya, saat meningkatkan aplikasi server aplikasi PHP di Windows, PHP itu sendiri perlu diperbarui dan karenanya tidak dapat berjalan selama peningkatan. Umumnya juga perilaku yang baik untuk keluar dari aplikasi tidak terlalu lama setelah tab browser terakhir ditutup.
Ada dua metode yang tersedia untuk memicu penghentian awal server:
/exit-app/ dan mengirim authtoken yang valid dan delay dalam objek JSON yang menentukan jumlah detik untuk menunggu untuk mengakhiri server. Setelah digunakan, setiap halaman aplikasi harus terhubung ke /exit-app/ untuk menjaga server tetap hidup. Direkomendasikan penundaan minimum 3 detik. Browser web cenderung menjatuhkan koneksi WebSocket segera setelah mereka meninggalkan halaman atau tab ditutup.X-Exit-App dalam respons skrip PHP. Nilai header adalah jumlah integer detik untuk menunggu untuk mengakhiri server. Direkomendasikan penundaan minimum 3 detik. Header khusus ini tidak diteruskan ke browser web tetapi ditangani secara internal.Contoh kode PHP untuk metode ekstensi aplikasi keluar:
<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>Contoh kode PHP untuk metode header:
<?php
// User clicked an "Exit application" link or something.
header ( " X-Exit-App: 3 " );
?>Ekstensi adalah metode yang lebih andal untuk mendeteksi bahwa semua tab browser ke aplikasi telah ditutup. Namun, jika aplikasi tidak dapat mendukung ekstensi karena beberapa alasan, maka gunakan metode header sebagai gantinya. Metode header paling baik digunakan pada halaman yang masuk akal (misalnya halaman dengan informasi peningkatan).
Sebelum menjalankan berbagai skrip yang menghasilkan paket penginstal, berbagai file perlu dibuat, diganti namanya, dan/atau dimodifikasi. Setiap file yang dimulai dengan "YourApp" perlu diganti namanya menjadi nama aplikasi Anda, lebih disukai terbatas pada semua AZ dan tanda hubung kecil. Ini perlu dilakukan agar pembaruan pada perangkat lunak tidak secara tidak sengaja menimpa pekerjaan Anda dan sehingga setiap pengguna usil menyodok di sekitar struktur direktori melihat nama sebenarnya aplikasi alih -alih "YourApp".
File 'YourApp.phpapp' adalah file PHP yang melakukan urutan startup aplikasi yang sebenarnya untuk memulai server web (server.php) dan kemudian meluncurkan browser web pengguna. Ada array $options dalam file yang harus dimodifikasi untuk kebutuhan aplikasi Anda:
Tiga opsi terakhir dimaksudkan untuk skenario yang sangat khusus. Mengubah 'host' menjadi sesuatu seperti "127.0.1.1" mungkin baik -baik saja tetapi jangan gunakan "0.0.0.0" atau ":: 0", yang mengikat server secara publik ke antarmuka jaringan. Mengikat ke nomor 'port' spesifik mungkin tampak seperti ide yang bagus sampai pengguna mulai mengeluh tentang pesan kesalahan ketika mereka mencoba memulai kembali aplikasi.
Opsi 'QuitDelay' menarik. Bagian server dari server aplikasi PHP akan bertahan sampai 'QuitDelay' beberapa menit setelah klien terakhir terputus. Aplikasi harus mengirim permintaan "detak jantung" setiap lima menit untuk menjamin bahwa server web tidak akan mengakhiri dirinya sendiri sebelum pengguna selesai menggunakan aplikasi.
Setiap alat pengemasan platform memiliki instruksi sendiri:
xdg-utils (Gnome, KDE, XFCE, dll. Semuanya baik-baik saja).Ada beberapa masalah kemasan yang diketahui:
Installer dan perangkat lunak server memiliki beberapa kisah menarik di belakangnya. Mungkin saya akan berbagi cerita itu suatu hari nanti. Untuk saat ini, nikmati membangun aplikasi Anda berikutnya di server aplikasi PHP!