إطار الويب هو نقطة وسط بين كتابة مشروع من الصفر بهدف الحصول على أعلى أداء وأعلى تحكم ومرونة وبين استعمال نظام إدارة محتوى (مثل جملة أو دروبال) بهدف الحصول على أعلى إنتاجية وإعادة استعمال ما هو موجود أصلا.
إن الجزء الأكبر من كل المواقع الموجودة مشترك مثلا كلها فيها مستخدمين وفيها جلسات وقواعد بيانات و captcha وغيرها لذا يعتبر كتابة موقع من الصفر هدر حيث أن هناك الكثير من الأجزاء موجودة بالفعل وعلينا وإعادة استخدامها.
لكن نظم إدارة المحتوى دائما موجهة نحو عنوان ومتن ومعرض صور فقط وعندما تريد تركيب الإضافات لها تتحول إلى فيل ثقيل الظل!
أطر الويب الحديثة توفر الكثير من الميزات مثل:
يأتي اسمه من Yes it is وهي إجابة لسؤال هل يدعم الميزة الفلانية. إطارنا هذا هو إطار ويب عالي الأداء مقسم إلى مكونات كل منها وحدة منفصلة component based
بعكس أطر الويب الأخرى في لغة php فإن Yii يتطلب إصدار php رقم 5.1.0 فما فوق حتى يستفيد من المزايا الجديدة فيها.
هو نطم تصميم design pattern في هندسة البرمجيات يقسم الكود إلى 3 عناصر مستقلة بهدف تقسم العمل separation of concern
يعني Object-Relational Mapping التعامل مع قاعدة البيانات على شكل كائنات Objects مثلا عوضا عن كتاية عبارات SQL مثلا
INSERT INTO article (title, body) VALUES ($t, $b);
تصبح
$a=new Article(); $a->title=$t; $a->body=$b; $a->save();
هذا يحمينا من SQL injection ويسمح لنا بإضافة أشياء على مستوى php.
بعد تنزيل إطار الويب Yii من الموقع وفك ضغطه في مجلد ما ستجد بداخله مجلد yii بداخله framework بداخله أداة سطر الأوامر yiic (أو yiic.bat في ويندوز) التي نستخدمها لعمل الكثير من الأشياء والتي أهمها إنشاء المشروع في مسار مثل target/path وذلك بالأمر التالي
/yii/framework/yiic webapp target/path
مثلا
/yii/framework/yiic webapp ~/public_html/my_app
وستجد المشروع موجود في public_html مجلد اسمه my_app للوصول للأداة yiic فيما يتعلق بمشروعك عليك استعمال النسخة الموجودة في مشروعك وهي في مجلد protected الموجود داخل مجلد application داخل مجلد مشروعك.
داخل مجلد protected نجد مجلد اسمه config فيه ملف main.php نضع فيه نوع وطريقة الاتصال بقاعدة البيانات ونستهل فيه كافية المكونات componenets مثل الكاش وغيره.
جذر الوثائق DocumentRoot في خادم الويب هو مجلد application بعد إعداد الخادم بالشكل الصحيح يمكنك أن تفتح سكربت الدخول index.php كما في الصورة
لاحظ أن التنقل بين صفحات الموقع يكون عبر متغير r مثلا r=site/index و r=site/contact وهنا r تعني route
من بين مكونات التطبيق components هناك مكون اسمه urlManager نجد فيه صفة urlFormat قيمتها الأولى هي get قم بتغيرها إلى path
'components'=>array( // ... 'urlManager'=>array( 'class'=>'UrlManager', 'urlFormat'=>'path', 'showScriptName'=>false,
وحتى يعمل هذا الأخير نحن بحاجة لعمل .htaccess داخل مجلد application يحتوي
RewriteEngine on # if a directory or a file exists, use it directly RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d # otherwise forward it to index.php RewriteRule . index.php
التطبيق الأولي الذي عملناه يحتوي على صفحة “اتصل بنا” وقاعدة بيانات مستخدمين من أجل صفحة الدخول. علينا الآن إضافة جداول في قاعدة البيانات تتناسب والتطبيق الذي نريده مثلا جدول للمقالات يتحتوي العنوان والمتن وإشارة إلى رقم المؤلف.
قاعدة البيانات التي يشير لها التطبيق الأولي هي ملف sqlite3 موجودة في ملف data الموجود داخل مجلد protected. يمكنك تغيير الإعدادات كي تربط التطبيق بقاعدة بيانات Mysql لكن دعونا نتابع هكذا.
باستخدام أي عميل sqlite3 نفذ الأمر التالي لإنشاء جدول المقالة
CREATE TABLE tbl_article ( id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, author_id INTEGER, title VARCHAR(64), content TEXT, FOREIGN KEY(author_id) REFERENCES tbl_user(id) );
إن لم يكن عندك خبرة في SQL انظر بدهيات استعلامات SQL مع قواعد بيانات Sqlite.
يأتي إطار الويب Yii مع أداة رسومية تعمل عبر الويب تعمل على توليد الكود اللازم بضغظ زر يمكنك تخصيص الكود المولد كما تشاء بعد توليده.
يمكن تفعيل وحدة gii في قسم الوحدات modules من ملف الإعدادات main.php مع اشتراط كلمة سر وحصره في العنوان المحلي 127.0.0.1
'modules'=>array( // ... 'gii'=>array( 'class'=>'system.gii.GiiModule', 'password'=>'MyPASSW0RD', 'ipFilters'=>array('127.0.0.1'), ),
بعدها نزور العنوان http://localhost/gii
بعد إنشاء الجدول نعمل على إنشاء النموذج model الخاص به
حتى يتمكن Gii من حفظ الكود يجب أن يمتلك مستخدم خادم apache صلاحيات الوصول والكتابة في مجلد التطبيق.
هنا يمكنك إضافة الشروط للتحقق من سلامة المدخلات Validators مثل فحص الطول الأدنى أو الأقصى وهل من الآمن أن يدخلها المستخدم …إلخ.
توفر لنا Yii شروط لا تنفذ إلا في ظروف معينة تسمى scenario مثلا لا نريد أن نسمح للمستخدم أن يحدد قيمة حقل author_id لكن إن كان السياق هو البحث فإننا نسمح له بتمرير هذا الحقل
array('id, author_id, subject, content', 'safe', 'on'=>'search'),
لاحظ أن Gii حيث أنه اكتشف وجود علاقة BELONGS_TO بين جدول المقالة Article وجدول المستخدم User
لكن يمكنك إضافة العلاقات لتكون واحة من بين
عندما تكون العلاقات معرفة بالشكل الصحيح يمكنك الاستفادة منها هكذا
echo $article->author->first_name; foreach($article->tags as $t) { echo $t->name; }
لتوليد الكود اللازم لعمل واجهة الإدارة نطلب من Gii عمل CRUD
بعد حفظ الملفات المولدة قم بزيارة http://localhost/article/admin
داخل مجلد application/protected/controllers نجد ملف ArticleController.php
نجد فيه filters وهي أشياء تنفذ قبل أو بعد كل طلب ومنها التحقق من صلاحيات الوصول access control
public function filters() { return array( 'accessControl',
دالة فحص الوصول تقرأ من المصفوفة التي تعيدها accessRules حيث نحدد الإجراءات actions والمستخدمين المسموح لهم الوصول مثلا * تعني الكل أما @ فتعني كل المستخدمين الذين سجلوا الدخول
public function accessRules() { return array( array('allow', // allow all users to perform 'index' and 'view' actions 'actions' => array('index', 'view'), 'users' => array('*'), ),
كذلك يمكن تحديد مجموعة من المستخدمين الذين لديهم صلاحيات معينة role
array('allow', 'actions' => array('admin', 'delete', 'create', 'update'), 'roles' => array('admin'), ),
عند زيارة رابط مثل article/update فإن هذا يعني ArticleController ودالة actionUpdate
public function actionUpdate($id=null){
داخل دالة الإجراء action يكون المتغير $this يشير للمتحكم controller مثلا
$model = $this->loadModel(); $model->setScenario('update');
دالة loadModel تعمل على جلب النموذج من قاعدة البيانات هكذا
$this->_model = Article::model()->with(array('author'))->findbyPk($_GET['id']); return $this->_model;
ثم تمرر النموذج model إلى العرض view عبر
$this->render('update', array( 'model' => $model, ));
أول معامل وهو كلمة update يعني application/protected/views/article/update.php أو application/themes/mytheme/views/article/update.php
داخل ملف العرض المتغير $this يشير للمتحكم controller وكذلك هناك متغيرات باسم كل عناصر المصفوفة الممررة إلى render
داخل كل قالب عرض يمكنك استدعاء قالب جزئي آخر عبر renderPartial
$this->renderPartial('_sub');
الفرق بين render و renderPartial هو أن الأولى تعمل على تركيب layout حول المحتوى.
كما يظهر من الشكل عندما يطلب المستخدم صفحة ما فإن أول شيء ينفذ هو المدخل entry script وهو في حالتنا index.php تمكن مهمته في تحديد مسار yii ومسار ملف الإعدادات وتحميل الأول مع تمرير الثاني له.
require_once($yii); Yii::createWebApplication($config)->run();
هناك نوعان من التطبيقات في yii أولها هو تطبيق الويب وهو النوع الذي ينشؤه سكربت المدخل وثانيها تطبيق سطر الأوامر وهو ليس موضوع حديثنا الآن.
يمكن الوصول لكائن التطبيق عبر
$app=Yii::app();
يقوم التطبيق باستهلال كائن من نوع request يقدم معلومات عن العنوان المطلوب uri والكوكيز وغيرها. يمكن الوصول له عبر أي من السطرين
$r=Yii::app()->getRequest(); $r=Yii::app()->request;
ثم يتم تمرير كائن الطلب request إلى مدير العناوين urlManager وهو أحد مركبات إطار Yii ويمكنك تخصيصه في ملف الإعدادات. مهمة مدير العناوين تكمن في أمرين وهو تحديد الوجهة route أي المتحكم والإجراء controller/action بناءً على المعلومات الموجودة في كائن الطلب ويعرف هذا باسم parseUrl. الأمر الثاني عكس العملية السابقة وتسمى createUrl حيث نقدم الوجهة لنحصل على ما يقابلها من عنوان.
'components'=>array( // ... 'urlManager'=>array( 'class'=>'CUrlManager', 'urlFormat'=>'path', 'showScriptName'=>false, 'rules'=>array( // ... ROUTES GOES HERE '<controller:\w+>/<action:\w+>'=>'<controller>/<action>', ), ), ),
مثلا الوجهة التالية والتي تمثل نمط REGEX تطابق كلمة article متبوعة برقم (يتم حفظه في متغير id) ثم - ثم صفر أو أكثر من الحروف عدا / يتم حفظها في متغير title
'article/<id:\d+>-<title:[^/]*>'=>'article/view',
فإن تطابق يتم تشغيل الوجهة article/view