* عند البدء في كتابة تطبيق ما مثلا (news) يجب عليك تحديد خصائص التطبيق مثلا (add, edit , view , index) وهذا يأعنى أن ستقوم ببنائ تطبيق أخبار يحتوى يمكن من خلاله اضافة , تعديل , عرض , قائمة خبر أو أخبار .
* بعد تحديد التطبيق وخصائص بشكل واضح بقي لنا الطريقة المثالية لكتابة كود هذا التطبيق وهي أن يكون هذا التطبيق في ملف news.php ويحتوى على صنف class بإسم news ويحتوى هذا الصنف على طرق/خصائص method بهذا الخصائص add, edit , view , index وبهذا الشكل لم يبقى لدينا سوى كتابة الكود البرمجي لكل خاصية... الان هذا هو شكل الملف news.php
كود PHP:
<?php class news { function index() {} // عرض قائمة بالاخبار function view($id=false) {} // عرض الخبر , نحتاج رقم الخبر لعرضه function add() {} // اضافة خبر function edit() {} // تحرير خبر } ?>
من النظره الأولى ستجد ان التطبيق واضح لك ولا يوجد أي صعوبه في فهمه او تتبع مشكله ما فيه .
* المتحكم controller وهو خطوة مهمة ... ويتولى مهمة تنفيذ وتشغيل هذا التطبيق الذي يأتي على شكل صنف class او اي برنامج آخر ... سوف نعمل صفحه index.php للاستدعاء التطبيق وتشغيله , تحتوى هذه الصفحه على متحكم صغير بنفس طريقة بيئات العمل تمام ولكنه بشكل مناسب لتطبيقاتك .
كود PHP:
<?php list(,$class, $method, $id) = explode('/',$_SERVER['PATH_INFO'],4); if(file_exists("$class.php")) { require_once("$class.php"); // استيراد news.php $object = new $class; // إنشاء كائن من صنف الاخبار news class if(method_exists($object, $method)) { // التأكد من الخاصية موجوده method exists call_user_func_array(array($object, $method), $id); // تنفيذ الخاصة وتمرير المتغيرات لها method } else { echo 'Error: Method not found.'; } } else { echo 'Error: Script not found'; } ?>
سيقوم المتحكم السابق بتنفيذ تلقائي حسب معطيات المرسله ... سيعمل استيراد للملف + انشاء الكائن + تنفيذ الداله المطلوبه مع تمرير المتغير لها ان وجد .
* أصبح لدينا الان المتحكم controller وهو index.php + التطبيق module وهو الاخبار news.php كل ما علينا الان هو اكمال التطبيق... مثال بسيط ل news.php
كود PHP:
<?php class news { function index() { echo 'news::index()'; } function view($id=null) { if($id) { echo 'News Number '.$id; } else { echo 'Error: No news ID'; } } function add() { echo 'news::add()'; } function edit() { echo 'news::edit()'; } } ?>
* الخلاصة: عليك من الان وصاعدا بناء تطبيقاتك على شكل أصناف class .
* الفائده: تنظيم التطبيق وسهولة نقله الى بيئات عمل او دمجه مع تطبيقات أخرى و القدره على التحكم بالتطبيق من خلال المتحكم وإضافة نظام صلاحيات بسهوله + سجل للعمليات + فلترة المدخلات ... الخ .
(لم اراجع الموضوع لغويا او املائيا)
مراجع: PHP: call_user_func_array - Manual PHP: method_exists - Manual
تم رفع وتثبيت الموضوع نظرا لأهميته للمبرمجين
__________________
ضيف الله العتيبي مبرمج حر و مهندس معتمد من زيند (ZCE)
الاتصال: daif@daif.net او جوال: 0556639884
الخدمات: تقديم استشارات برمجيه, تطوير بوابات/خدمات إلكترونيه للقطاع العام او الخاص .
جميل جدا ..
جزاك الله كل خير ..
هيكل البرنامج يبدو واضح وخاصة عندما تشرحه بتلك الطريقه
إقتباس:
<?php class news {
function index() {} // عرض قائمة بالاخبار function view($id=false) {} // عرض الخبر , نحتاج رقم الخبر لعرضه function add() {} // اضافة خبر function edit() {} // تحرير خبر } ?>
يطى صورة إجمالية أفضل بكثير لفكرة البرنامج
__________________ Mohamed Amin Ui & Web Designer graphic_designer2007#hotmail.com
الا تكفي الدوال (function)
عن استخدام الاصناف (class)
__________________
---[ كلمتان خفيفتان على اللسان ]---
---[ ثقيلتان في الميزان ]---
---[ حبيبتان الى الرحمن ]---
---[ سبحان الله وبحمده سبحان الله العظيم ]---
WaLeeD : لن يفرق كثيراً من حيث الكود في المشاريع البسيطة، أما إذا تقدم الكود أو أحببت عمل تفاصيل أكثر للمشروع فتستفيد بكود أقل وأكثر تنظيم من الكائنات
هذا أضافة إلى تنظيم فكرة عند التعامل مع الكلاس على أنه مكتبة للدوال على أقل تقديم
إقتباس:
* الفائده: تنظيم التطبيق وسهولة نقله الى بيئات عمل او دمجه مع تطبيقات أخرى و القدره على التحكم بالتطبيق من خلال المتحكم وإضافة نظام صلاحيات بسهوله + سجل للعمليات + فلترة المدخلات ... الخ .
WaLeeD : لن يفرق كثيراً من حيث الكود في المشاريع البسيطة، أما إذا تقدم الكود أو أحببت عمل تفاصيل أكثر للمشروع فتستفيد بكود أقل وأكثر تنظيم من الكائنات
هذا أضافة إلى تنظيم فكرة عند التعامل مع الكلاس على أنه مكتبة للدوال على أقل تقديم
كل الشكر يالغالي
بصراحه ارى ان الاصناف
مع اني عملت معها مجبرا في الجافا
لكن ارى السهول بالدوال
قد تكون المشاريع الكبيره جدا هي ماتتطلب class
لازلت اعمل بالدوال واراها تنفع كثيرا
كل الشكر مره اخرى
__________________
---[ كلمتان خفيفتان على اللسان ]---
---[ ثقيلتان في الميزان ]---
---[ حبيبتان الى الرحمن ]---
---[ سبحان الله وبحمده سبحان الله العظيم ]---
روعة روعة ^^،
جميل جداً هذا الأمر. الصراحة هذي الخطوات يجب أن نتعلمها وأعني بذلك عمل MVC، فأنت أعطيتنا الC والباقي علينا ^^،.
قالها مبرمج نسيت أسمه، لكن ما صدقت بكلامه فأول مرة. قال يجب أن تعمل إطار عملك الخاص ولو كان بسيطاً قبل أن تعمل بواحد جاهز! هذا يسهل عليك الإنتقال من فكرة البرمجة بدون oop إلى البرمجة كاملاً بواسطة oop خصوصاً في لغة مثل php حيث تتوفر لك أكثر من طريقة برمجة! حتى أنك أحياناً تستطيع القيام بعمل موقع كامل وبدون تعريف دالة واحدة!.
سأتابع مواضيعك يا ضيف، وصراحة ما تكتبه يدعم كلامك بعدم الحاجة لأطر العمل بغض النظر عن إن كان ذلك صحيحاً أم لا .
controller جميل جداً ، في الحقيقة منذ فترة وأنا أفكر في إنشاء اطار عمل خاص بي .. هذا الموضوع يعطي دافعاًَ كبيراً ورغبة في البدء في التطبيق .. ، سؤال .. لماذا قمت بتعيين قيمة false للمتغير id في وظيفة العرض ؟ نقطة أخرى هي أنني أفضل التعامل مع الروابط التي تكون بشكل استعلام ( query )
في الكود الذي وضعه ضيف اذا طلبنا الصفحة index.php سيطبع لنا هذه الرسالة
كود HTML:
Error: Script not found
ونحن لا نريد هذا في برنامجنا اذا يجب علينا اضافة كلاس مثلا اسمه index وسيطبع ما تريده ان يكون في الصفحة الرئيسة اذا لم يتم اختيار اي كلاس
سيكون شكل الكلاسات
classes/news.php ->كلاس المقالات
classes/index.php ->كلاس الصفحة الرئيسة
الكود هو
كود PHP:
<?php list(,$class, $method, $id) = explode('/',$_SERVER['PATH_INFO'],4); $modules="classes/"; if(file_exists($modules.$class.".php")) { require_once($modules.$class.".php"); // استيراد news.php $object = new $class; // إنشاء كائن من صنف الاخبار news class if(method_exists($object, $method)) { // التأكد من الخاصية موجوده method exists call_user_func_array(array($object, $method), $id); // تنفيذ الخاصة وتمرير المتغيرات لها method } else { echo 'Error: Method not found.'; } } else {
على فكرة بحثت في جوجل عن عدد المواقع التي تستخدم هذه الطريقة فوجدت اكثر من ست ملايين ونصف نتيجة
مما يدل على انتشار هذه الطريقة site:*.*/index.php/*/*/ - Google Search
$class = (isset($_GET['class']) == true) ? $_GET['class'] : 'home';
$method = (isset($_GET['method']) == true) ? $_GET['method'] : 'index';
foreach ($_GET as $key => $value) {
if (in_array($key, array('class', 'method')) == false) {
$parameters[] = $value;
}
}
// or: unset($_GET['class'], $_GET['method']); $parameters = $_GET;
$class_path = 'classes/'.$class.'.php';
if (file_exists($class_path) == true) {
require_once($class_path);
if (class_exists($class) == true) {
$object = new $class;
if (method_exists($object, $method) == true) {
if (is_callable(array($object, $method)) == true) {
// Warning: Missing argument (int) for object::method()
call_user_func_array(array($object, $method), $parameters);
} else {
die('method is can\'t be used..');
}
} else {
die('method is not found..');
}
} else {
die('class is not found..');
}
} else {
die('class file is not found..');
}
اعتقد ان هدفي واضح ، احاول جعل المتحكم يتعرف على المتغيرات بشكل تلقائي ، احاول الان ايجاد طريقة للتأكد من وجود عناصر الدالة المطلوبة في الرابط ، حاولت البحث في الدليل والطريقة الوحيدة التي وجدتها لابد من استخدامها في داخل الدالة نفسها ، هل من حلول ؟
لابد من منع اي ثغرات في الشفرة يمكن استغلالها من خلال الرابط ، هل من طرق اخرى لتحصين الشفرة الحالية؟
إقتباس:
سؤال .. لماذا قمت بتعيين قيمة false للمتغير id في وظيفة العرض ؟
لا اعلم لماذا قمت بطرح هذا السؤال ! من الواضح انك تريد استخدام الطريقة التالية ..
كود PHP:
if (!$id) { // ..
هذه ميزة من ميزات php ، التعرف التلقائي على نوع المتغير على عكس اللغة الام C ..
هنا أيضا متحكم مثالي صغير , يفي لجميع المشاريع بدون استثناء .
- الملف الاساسي tinycontroller.php يمكن تغييره الى index.php
- مجلد الأصناف او الوحدات modules يمكن تغيير اسمه في المتحكم
- اسم ملف الصنف الموجود في مجلد الأصناف يجب ان ينتهي ب _ + module يمكن تغييره أيضا من المتحكم.
- اسم الصنف نفسه يجب ان ينتهي ب _ + Module بالاضافه الى اول حرف سيكون كبير.
//Example = http://localhost/tinycontroller.php/module/method/id1/id2 //apply trim & strtolower to url @list(,$module, $method, $param) = array_map('strtolower', array_map('trim', explode('/',$_SERVER['PATH_INFO'],4))); //return array if $param is empty OR split $param with / $param = (empty($param) || trim($param)=='/') ? array():explode('/',$param); //Example = modules/example_module.php $mfile = $module_path.'/'.$module.$module_suffix;
if(file_exists($mfile)){ //check is file exists require_once($mfile); //required modules/example_module.php one time $class = ucfirst($module).$class_suffix; //Example_Module if(class_exists($class)){ //check is class exists $object = new $class; //create new object from Example_Module class if(method_exists($object,$method) && $method{0}!=='_'){ //check is method exists & not privte method call_user_func_array(array($object, $method), $param); //call method & pass parameters } else { //method exists print("<b>Error</b>: Method {$module}->{$method} is not exist"); //throw error message } } else { //class exists print("<b>Error</b>: Module class {$module} is not found"); //throw error message } } else { //file exists print("<b>Error</b>: Module {$module} is not exist"); //throw error message } ?>
شفرة مثال على ذلك news_module.php
كود PHP:
<?php class News_Module { function index() { echo 'news::index()'; } function view($id=null) { if($id) { echo 'News Number '.$id; } else { echo 'Error: No news ID'; } } function add() { echo 'news::add()'; } function edit() { echo 'news::edit()'; } } ?>
__________________
ضيف الله العتيبي مبرمج حر و مهندس معتمد من زيند (ZCE)
الاتصال: daif@daif.net او جوال: 0556639884
الخدمات: تقديم استشارات برمجيه, تطوير بوابات/خدمات إلكترونيه للقطاع العام او الخاص .
نعم هو متحكم كامل بالوحدات , لكن ينقصه خاصية العرض , اقصد بعد استقبال الطلب يتم انشاء الكائن ثم استدعاء الداله المطلوبه , يفترض ان يستدعي view الخاصة بهذه الداله او الصنف ويمرر اليها المتشغيرات العامه او نتيجة الداله.
بإضافة هذه الاسطر سيكون كامل الا انها تحتاج الى تنظيم أكثر .
كود PHP:
//After this line $mfile = $module_path.'/'.$module.$module_suffix; add
//Example = modules/example_module_view.php
$vfile = $module_path.'/'.$module.'_view'.$module_suffix;
//After this line call_user_func_array(array($object, $method), $param); //call method & pass parameters add
__________________
ضيف الله العتيبي مبرمج حر و مهندس معتمد من زيند (ZCE)
الاتصال: daif@daif.net او جوال: 0556639884
الخدمات: تقديم استشارات برمجيه, تطوير بوابات/خدمات إلكترونيه للقطاع العام او الخاص .
$_SERVER ليست داله, انما مصفوفوه تحتوى على عدة عناصر مثل PATH_INFO والذي يحتوى على مسار الصفحه الحالية .
__________________
ضيف الله العتيبي مبرمج حر و مهندس معتمد من زيند (ZCE)
الاتصال: daif@daif.net او جوال: 0556639884
الخدمات: تقديم استشارات برمجيه, تطوير بوابات/خدمات إلكترونيه للقطاع العام او الخاص .
فلا أعتقد أن هذه هي هالطريقة الصحيحة للتأكد من كون الـ method من النوع public ، الدالة is_callable تؤدي الغرض ..
كود PHP:
is_callable(array($object, $method)
لا أزال بإنتظار حل للمشكلة التي عرضتها في ردي السابق ، كيف يمكن ان نتحقق من وجود عناصر الدالة المطلوبة .. ، مثلاً عن استدعاء الدالة a فانني سامرر لها عناصر عددها b ، كيف يمكن ان أتأكد من ان b = عدد عناصر الدالة ؟ السبب في ذلك هو محاولة ايجاد رسالة خطأ تظهر عند عدم تحقق هذا الشرط ..
- متعارف في php ان اي داله تبدأ بعلامة _ تكون داله خاصه ولا يمكن مناداتها من الخارج , هذا ما فعلته هنا قد يكون لديك داله تستخدمها داخل الصنف ولا تريد ان يتم استدعائها عبر الموقع على شكل رابط مثل http://localhost/module/_method/id, اذا عليك ان تجعلها تبدأ بشرطه سفلية _ .
- استخدم set_error_handler لتتبع أخطاء البرنامج, وعرضها في وضع التطوير .
__________________
ضيف الله العتيبي مبرمج حر و مهندس معتمد من زيند (ZCE)
الاتصال: daif@daif.net او جوال: 0556639884
الخدمات: تقديم استشارات برمجيه, تطوير بوابات/خدمات إلكترونيه للقطاع العام او الخاص .
جزاك الله خيرا اخي
انا كان قصدي اني لو طلبة الكلاس كان بيكتب كده
وانا عملة ميزة التحكم في الصفحة الرئيسية يعني لو مافي اي كلاس في المتصفح يكون الصفحة الرئيسية الي انت
اخترته يكون
كان طلبي انة بيطبع الكلاس مع الدوال مثلا كده
كود PHP:
class test
{
function test()
{
echo("class test");
}
function anyfunction()
{
echo"anyfunction";
}
}
هنا لو انا طلبة من المتصفح كده
index.php/test
هيطبع
class test
صح طيب لو انا طلبة كده
index.php/test/anyfunction
المفروض يطبع
anyfunction
لكن لا بيطبع
class testanyfunction
في مش عارف اعمل ليها اية ؟؟
__________________
ســـــــبحان الله وبـــــــــحمده *سبـــــــــــحان الله العظيم
لطلب البرمجة فقط helal-egypt@hotmail.com