قم بإنشاء تطبيقات خفيفة الوزن وقابلة للتثبيت مكتوبة في HTML و CSS و JavaScript و PHP لأنظمة تشغيل سطح المكتب Windows و Mac و Linux.

ما يمكن إنشاؤه باستخدام خادم تطبيق PHP هو تطبيقات برامج حقيقية وقابلة للتثبيت تستغرق جزءًا من الوقت لإنشاءها عند مقارنتها بتطوير تطبيقات سطح المكتب التقليدية. انتقل من الفكرة/المفهوم إلى النشر الكامل في 1/10 الوقت ودعم كل نظام تشغيل سطح المكتب الرئيسي مع قاعدة رمز واحدة فقط.

PHP App Server هو خادم ويب تم توسيعه بالكامل وقابل للتمديد مكتوب في PHP مع ميزات مخصصة مصممة خصيصًا لاستخدامها في بيئة نظام تشغيل سطح المكتب التقليدي. عندما يقوم المستخدم بتشغيل البرنامج عبر قائمة START ، وقاذفة التطبيق ، وما إلى ذلك ، يبدأ البرنامج الخادم ثم يقوم بتشغيل متصفح الويب المفضل للمستخدم للوصول إلى التطبيق. تقوم PHP بتشغيل الواجهة الخلفية بينما يتعامل متصفح الويب مع جميع التفاصيل الدقيقة لعرض واجهة المستخدم. تبسط البرامج النصية للتثبيت الجاهزة عملية إنشاء حزم الإصدار النهائي للتسليم إلى أنظمة الكمبيوتر الخاصة بالمستخدم.
قم بتنزيل أو استنساخ أحدث إصدار للبرامج. عند الاستنساخ ، تأكد من استخدام شوكة وإنشاء فرع لتطبيقك قبل البدء في التطوير. يؤدي القيام بذلك إلى تجنب الكتابة فوق برنامجك عن طريق الخطأ كلما قمت بجلب تحديثات المنبع لخادم تطبيق PHP نفسه.
بالنسبة لبقية هذا الدليل ، يُفترض أن يتم تثبيت إصدار حديث من PHP. هناك العديد من الطرق لتحقيق ذلك.
من سطر الأوامر ، قم بتشغيل ما يلي للحصول على قائمة بخيارات سطر الأوامر:
php server.php -?
ابدأ خادم الويب على المنفذ 9002 عن طريق التشغيل:
php server.php -port=9002
هيكل دليل خادم تطبيق PHP كما يلي:
server.php للعمل. قم بإنشاء ملف index.php في دليل "www":
<?php
phpinfo ();اتصل بخادم التشغيل مع متصفح الويب الخاص بك على:
http://127.0.0.1:9002/
يتم عرض إخراج phpinfo() في المتصفح ويتم كتابة نتيجة الطلب إلى سطر الأوامر.
تغيير عنوان URL إلى:
http://127.0.0.1:9002/api/v1/account/info
يتم تشغيل نفس ملف index.php .
أعد تسمية أو نسخ ملف index.php إلى api.php وإعادة تحميل الصفحة. الآن api.php يتم استدعاؤه. ميزة الدليل الظاهري لخادم تطبيق PHP هي شيء قد تجده مفيدًا أثناء تطوير تطبيقك.
لا يمكن لتطبيقات البرامج المثبتة الكتابة إلى "www". عادة ما يتم تثبيت التطبيقات من قبل مستخدم متميز على النظام ، لكن الشخص الذي يقوم بتشغيل البرنامج لن يكون لديه عمومًا أذونات كافية للكتابة إلى دليل "www". هذا اعتبار مهم يجب وضعه في الاعتبار أثناء تطوير تطبيق برنامج باستخدام خادم تطبيق PHP. لحسن الحظ ، هناك حل لهذه المشكلة مدمجة بالفعل في الخادم: جذور المستند المزدوجة.
عندما يتم تنفيذ رمز PHP من دليل "www" للتطبيق ، فإنه يمكنه إمكانية الوصول إلى خمسة متغيرات $_SERVER التي يتم تمريرها بواسطة بيئة خادم تطبيق PHP وفريدة من نوعها:
DOCUMENT_ROOT_USER . يمكن أيضًا كتابتها ولكن لا يمكن الرجوع إليها بواسطة عناوين URL. مفيد لتخزين البيانات الخاصة للتطبيق (مثل قاعدة بيانات SQLite).server.php ). مفيد للوصول إلى الملفات في support الفرعي. عندما يتم تقديم طلب إلى خادم الويب ، يبدو خادم تطبيق PHP أولاً للملفات في دليل "www" للتطبيق. إذا لم يجد ملفًا هناك ، فسيتحقق من الملف في المسار المحدد بواسطة DOCUMENT_ROOT_USER .
يمكن أن تؤدي كتابة تطبيق خادم مضيف محلي يعتمد على متصفح الويب إلى انتهاكات خطيرة في أمن النظام التي تتراوح من فقدان التحكم في البيانات إلى إتلاف نظام ملفات المستخدم. طالما أن التطبيق مكتوب بشكل صحيح ، فإن سياسات متصفح الويب ستحمي المستخدم بشكل عام من مواقع الويب الضارة والمستخدمين الذين يحاولون الوصول إلى محتوى خادم تطبيق PHP.
ومع ذلك ، فيما يلي بعض العناصر المهمة التي تحدد الأمن التي يجب أن تدافع عنها جميع تطبيقات البرمجيات القائمة على خادم تطبيق PHP بنشاط (حسب الأهمية):
$_SERVER["PAS_USER_FILES"] أو موقع محدد من قبل المستخدم لتخزين بيانات المستخدم الحساسة بدلاً من $_SERVER["DOCUMENT_ROOT_USER"] . اسأل المستخدم دائمًا عما يجب فعله إذا كان قد يعتبرون شيئًا حساسًا (على سبيل المثال ، يمكن أن يكون السؤال بسيطًا مثل عرض مربع الاختيار للمستخدم). سيتحدث الأفراد المتمركزين في الخصوصية بشكل عام عن رأيهم.$_SERVER["PAS_SECRET"] مع حزمة مسؤول Counsoft أو أطر عمل أخرى تساعد في التعامل مع هذه المشكلة. تتطلب امتدادات الخادم أيضًا عمومًا رمز مصادقة استنادًا إلى $_SERVER["PAS_SECRET"] .هناك العديد من الاعتبارات الأمنية الأخرى الموجودة في قائمة OWASP Top 10 وقائمة هجمات OWASP التي تضعها في الاعتبار أيضًا ، ولكن هذه هي الكبار.
يتضمن خادم تطبيق PHP امتدادًا قويًا للخادم واثنين من SDKs لجعل البدء والإدارة ومراقبة العمليات طويلة الأجل سهلة وآمنة من كل من PHP و JavaScript. يتم تشغيل العمليات التي تم تشغيلها كمستخدم يتم تشغيل خادم تطبيق PHP كما لا يقتصر على المهلة أو حدود الذاكرة مثل طلبات CGI/FastCGI العادية. يمكن مراقبة عمليات التشغيل بنشاط وتفاعل معها من متصفح الويب عبر JavaScript SDK.

يجب تخزين البرامج النصية طويلة الأمد بشكل مثالي في دليل "دعم خادم تطبيق PHP الرئيسي" الدعم "دعم خادم تطبيق PHP الرئيسي". وبهذه الطريقة ، فهي بعيدة عن جذر الويب الرئيسي ولكن لا يزال بإمكان التطبيق العثور عليها عبر $_SERVER["PAS_ROOT"] .
فيما يلي مثال على بدء برنامج نصي PHP يسمى "test.php" باستخدام 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. " ;
?>يتم إعطاء كل عملية علامة ، والتي تسمح بتجميع عمليات تشغيل متعددة حسب العلامة. في المثال أعلاه ، تسمى العلامة "Demo". يمكن استخدام Javacsript SDK لاحقًا لإظهار العمليات التي تستخدم علامة محددة فقط:
<?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 بتبسيط انبعاث تبعيات CSS و Javscript اللازمة في HTML. يوضح الرمز أعلاه إعداد اتصال WebSocket بملحق خادم تطبيق PHP وتوصيله بمثيل TerminalManager لمراقبة العمليات باستخدام علامة "Demo". TerminalManager عبارة عن فئة JavaScript المضمنة تقوم تلقائيًا بإنشاء وتدير واحد أو أكثر من الأجزاء الخارجية (المدرجة أيضًا) بناءً على معايير الإدخال. في هذه الحالة ، ستعلق TerminalManager تلقائيًا بأي عملية تم إنشاؤها باستخدام علامة "تجريبية". يبدو أن هذا execterminal يلي:

كل ما يلفت الانتباه إلى مثيل محطة XterM.JS مع ميزات إضافية:
وأكثر.
لاحظ أن TerminalManager و execterminal غير مطلوبان لإدارة العمليات طويلة الأمد ولكنها تتعامل مع عدد قليل من السيناريوهات الشائعة. رمز المثال أعلاه فقط يخدش سطح ما يمكن القيام به.
فيما يلي القائمة الكاملة لخيارات TerminalManager:
توفر فئة Xterm PHP المضمّنة تحكمًا سلسًا ومبسطًا على الإخراج من برنامج نصي طويل الأمد إلى exectercinal المتوافق مع Xterm في المتصفح. لا حاجة لتذكر رموز الهروب أنسي. إليك نص مثال:
<?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" ;
?>أخيرًا ، إذا كنت تستخدم حزمة مسؤول Counsoft أو Flexforms لإنشاء تطبيقك ، فإن PHP SDK يتضمن تكامل Flexforms الأصلي (أي لا داعي لكتابة 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 );
?> تتطلب كتابة امتداد القليل من المعرفة حول كيفية عمل خادم تطبيق PHP: يتم تحميل الامتدادات في وقت مبكر أثناء بدء التشغيل حتى يتمكنوا من المشاركة في تسلسل بدء التشغيل إذا احتجت إلى ذلك (في الغالب فقط للملحقات المتعلقة بالأمان). بمجرد بدء تشغيل خادم الويب ، يسير كل طلب ويب عبر قائمة الإضافات ويسأل ، "هل يمكنك التعامل مع هذا الطلب؟" إذا استجابت تمديد بالإيجاب (أي إرجاع صحيح) ، يتم تمرير بقية الطلب إلى الامتداد للتعامل معها.
نظرًا لأن الامتدادات يتم تشغيلها مباشرة مع الخادم الأساسي ، فإنها تحصل على دفعة كبيرة في الأداء ويمكنها القيام بأشياء مثل الاستجابة عبر WebSocket أو بدء عمليات طويلة الأجل التي عادة ما يتم قتلها بعد 30 ثانية بواسطة مسار PHP العادي.
ومع ذلك ، فإن هذه الفوائد تأتي مع اثنين من العيوب الرئيسية. الأول هو أنه إذا رفع التمديد استثناء غير معطل أو يعطل بطريقة أخرى ، فإنه يتطلب خادم الويب بالكامل معه. والثاني هو أن إجراء تغييرات التعليمات البرمجية على امتداد يتطلب إعادة تشغيل خادم الويب لاختبار التغييرات ، والتي يمكن أن تكون قليلاً من المتاعب. بشكل عام ، يكون مسار "www" العادي كافيًا لمعظم الاحتياجات والتمديدات مخصصة للقطاعات العرضية من المنطق المتخصص.
يعد امتداد الرمز المميز للأمن المضمّن نقطة انطلاق ممتازة لبناء امتداد يمكنه التعامل مع الطلبات بشكل صحيح. امتداد الرمز المميز للأمان قصير إلى حد ما ، يعمل بشكل جيد ، ويعمل.
يفترض الخادم أن اسم الملف جزء من اسم الفصل. أيا كان ما تم تسمية ملف PHP ، فإن اسم الفئة داخل حذوه ، وإلا سيفشل خادم تطبيق PHP في تحميل الامتداد. يجب أن تبدأ أسماء الامتداد برقم ، مما يشير إلى الترتيب المتوقع للاتصال بالتمديد.
تتوفر المتغيرات المتاحة لنصوص PHP العادية أيضًا للتمديدات عبر متغير $baseenv العالمي (مثل $baseenv["DOCUMENT_ROOT_USER"] و $baseenv["PAS_USER_FILES"] ). يرجى عدم تغيير قيم $baseenv لأن ذلك سيؤثر سلبًا على بقية التطبيق.
استخدم دائمًا وظيفة ProcessHelper::StartProcess() عند بدء عمليات خارجية طويلة الأجل داخل التمديد. تم تصميم فئة ProcessHelper لبدء عمليات عدم الحظر في الخلفية عبر جميع المنصات. لاحظ أن الطريقة المفضلة لبدء العمليات طويلة الأجل هي استخدام امتداد العمليات طويلة المدى.
بالنسبة لبعض المهام ، من المهم إخبار خادم تطبيق PHP بالخروج. على سبيل المثال ، عند ترقية تطبيق خادم تطبيق PHP على Windows ، يجب تحديث PHP نفسه وبالتالي لا يمكن تشغيله أثناء الترقية. كما أنه من الجيد بشكل عام الخروج من تطبيق لم يمض وقت طويل بعد إغلاق علامة تبويب المتصفح الأخيرة.
هناك طريقتان متاحتان لتشغيل الإنهاء المبكر للخادم:
/exit-app/ وأرسل authtoken صالحًا delay في كائن JSON يحدد عدد الثواني للانتظار لإنهاء الخادم. بمجرد استخدامه ، يجب أن تتصل كل صفحة من التطبيقات بـ /exit-app/ للحفاظ على الخادم حيًا. يوصى بتأخير الحد الأدنى من 3 ثوان. تميل متصفحات الويب إلى إسقاط اتصالات WebSocket بمجرد مغادرتها الصفحة أو تم إغلاق علامة التبويب.X-Exit-App في استجابة نص PHP. قيمة الرأس هي رقم عدد صحيح من الثواني للانتظار لإنهاء الخادم. يوصى بتأخير الحد الأدنى من 3 ثوان. لا يتم تمرير هذا الرأس الخاص إلى متصفح الويب ولكنه يتم التعامل معه داخليًا.مثال رمز PHP لطريقة تمديد تطبيق الخروج:
<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>مثال رمز PHP لطريقة الرأس:
<?php
// User clicked an "Exit application" link or something.
header ( " X-Exit-App: 3 " );
?>الامتداد هو طريقة أكثر موثوقية لاكتشاف أن جميع علامات تبويب المتصفح قد تم إغلاقها. ومع ذلك ، إذا كان التطبيق غير قادر على دعم الامتداد لسبب ما ، فاستخدم طريقة الرأس بدلاً من ذلك. من الأفضل استخدام طريقة الرأس على الصفحات التي من المنطقي (على سبيل المثال صفحة تحتوي على معلومات ترقية).
قبل تشغيل البرامج النصية المختلفة التي تنشئ حزم المثبتات ، يجب إنشاء ملفات مختلفة وإعادة تسميتها و/أو تعديلها. يجب إعادة تسمية كل ملف يبدأ بـ "yourapp" إلى اسم التطبيق الخاص بك ، ويفضل أن يقتصر على جميع AZ و Hyphens الصغيرة. يجب القيام بذلك حتى لا تحديث التحديثات إلى البرنامج عن طريق الخطأ في كتابة عملك عن طريق الخطأ ، وبالتالي فإن أي مستخدمين فضوليين يتدفقون حول بنية الدليل يرون الاسم الفعلي للتطبيق بدلاً من "YouRapp".
ملف "yourapp.phpapp" هو ملف PHP يقوم بتنفيذ تسلسل بدء تشغيل التطبيق الفعلي لبدء تشغيل خادم الويب (server.php) ثم تشغيل متصفح الويب الخاص بالمستخدم. هناك مجموعة $options في الملف الذي يجب تعديله لاحتياجات طلبك:
الخيارات الثلاثة الأخيرة مخصصة لسيناريوهات متخصصة للغاية. قد يكون تغيير "المضيف" إلى شيء مثل "127.0.1.1" على ما يرام ولكن لا تستخدم "0.0.0.0" أو ":: 0" ، الذي يربط الخادم علنًا بواجهة الشبكة. قد يبدو الارتباط برقم "منفذ" معين فكرة جيدة حتى يبدأ المستخدمون في الشكوى من رسائل الخطأ عندما يحاولون إعادة تشغيل التطبيق.
خيار "quitdelay" مثير للاهتمام. سيتم الالتفاف على جزء الخادم من خادم تطبيق PHP حتى ينفصل العميل الأخير. يجب أن يرسل التطبيق طلب "Heartbeat" كل خمس دقائق لضمان أن خادم الويب لن ينهي نفسه قبل الانتهاء من المستخدم باستخدام التطبيق.
تحتوي كل أداة تغليف منصة على تعليماتها الخاصة:
xdg-utils (Gnome ، KDE ، XFCE ، إلخ على ما يرام).هناك بعض مشكلات التغليف المعروفة:
لدى المثبتات وبرنامج الخادم بعض القصص المثيرة للاهتمام وراءهم. ربما سأشارك هذه القصص يومًا ما. في الوقت الحالي ، استمتع ببناء تطبيقك التالي في خادم تطبيق PHP!