جدول المحتويات

, , , , , ,

بدهيات إطار الويب Yii

قيد الإنجاز

مقدمة

لماذا نستخدم إطار الويب

إطار الويب هو نقطة وسط بين كتابة مشروع من الصفر بهدف الحصول على أعلى أداء وأعلى تحكم ومرونة وبين استعمال نظام إدارة محتوى (مثل جملة أو دروبال) بهدف الحصول على أعلى إنتاجية وإعادة استعمال ما هو موجود أصلا.

إن الجزء الأكبر من كل المواقع الموجودة مشترك مثلا كلها فيها مستخدمين وفيها جلسات وقواعد بيانات و captcha وغيرها لذا يعتبر كتابة موقع من الصفر هدر حيث أن هناك الكثير من الأجزاء موجودة بالفعل وعلينا وإعادة استخدامها.

لكن نظم إدارة المحتوى دائما موجهة نحو عنوان ومتن ومعرض صور فقط وعندما تريد تركيب الإضافات لها تتحول إلى فيل ثقيل الظل!

أطر الويب الحديثة توفر الكثير من الميزات مثل:

لماذا إطار الويب Yii

يأتي اسمه من Yes it is وهي إجابة لسؤال هل يدعم الميزة الفلانية. إطارنا هذا هو إطار ويب عالي الأداء مقسم إلى مكونات كل منها وحدة منفصلة component based

بعكس أطر الويب الأخرى في لغة php فإن Yii يتطلب إصدار php رقم 5.1.0 فما فوق حتى يستفيد من المزايا الجديدة فيها.

ما معنى MVC

هو نطم تصميم design pattern في هندسة البرمجيات يقسم الكود إلى 3 عناصر مستقلة بهدف تقسم العمل separation of concern

مخطط MVC

ما معنى ORM

يعني 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.

أداة توليد الكود الرسومية Gii

يأتي إطار الويب 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

مولد الكود الرسومي Gii

إنشاء النموذج Model المقابل للجدول

بعد إنشاء الجدول نعمل على إنشاء النموذج model الخاص به

إنشاء النموذج

حتى يتمكن Gii من حفظ الكود يجب أن يمتلك مستخدم خادم apache صلاحيات الوصول والكتابة في مجلد التطبيق.

الكود النتاتج

التعديلات التي قد تحتاجها على النموذج

بيان الشروط Rules

هنا يمكنك إضافة الشروط للتحقق من سلامة المدخلات 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;
}

إنشاء واجهة الويب CRUD

لتوليد الكود اللازم لعمل واجهة الإدارة نطلب من Gii عمل CRUD

توليد 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 حول المحتوى.

المخطط الكامل للتطبيق

مخطط Yii

المدخل Entry Script

كما يظهر من الشكل عندما يطلب المستخدم صفحة ما فإن أول شيء ينفذ هو المدخل entry script وهو في حالتنا index.php تمكن مهمته في تحديد مسار yii ومسار ملف الإعدادات وتحميل الأول مع تمرير الثاني له.

require_once($yii);
Yii::createWebApplication($config)->run();
في بيئة التطوير يمكنك إزالة علامة التعليق عن الأسطر التي تفعل التمحيص debug.
يمكن جعل المتغير $yii يشير إلى yiilite.php عوضا عن yii.php لمزيد من السرعة.

التطبيق

هناك نوعان من التطبيقات في yii أولها هو تطبيق الويب وهو النوع الذي ينشؤه سكربت المدخل وثانيها تطبيق سطر الأوامر وهو ليس موضوع حديثنا الآن.

يمكن الوصول لكائن التطبيق عبر

$app=Yii::app();

يقوم التطبيق باستهلال كائن من نوع request يقدم معلومات عن العنوان المطلوب uri والكوكيز وغيرها. يمكن الوصول له عبر أي من السطرين

$r=Yii::app()->getRequest();
$r=Yii::app()->request;
عند تعريف أي دالة تبدأ ب get فإن ما بعدها تصبح صفة والدالة تصبح جالبة لها attribute getter

ثم يتم تمرير كائن الطلب 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