االخطوات
1 انشاء جدول السيارات بقاعدة البيانات
2 ننشيء الـ controller + model التي تدير بيانات السيارات
3 تعريف مسار الكونترولر cars بمدير المسارات ليتعرف عليه ال API
4 توجيه التطبيق نحو API لجلب البيانات
تنفيد الخطوات .
1. ننشيء جدول السيارات بقاعدة البيانات
CREATE TABLE IF NOT EXISTS `cars` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`reference` varchar(30) NOT NULL,
`brand` varchar(30) NOT NULL,
`price` int(11) NOT NULL,
`image` text NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
بيانات السيارات
INSERT INTO `cars` (`id`, `reference`, `brand`, `price`, `image`) VALUES
(1, 'IBIZA', 'Seat', 250, 'assets/images/image1.jpg'),
(2, 'Sandero', 'DACIA', 150, 'assets/images/image2.jpg'),
(3, 'Symbol', 'Renault', 180, 'assets/images/image3.jpg'),
(4, '307', 'Peugeot', 200, 'assets/images/image4.jpg');
2. ننشيء model جديد ونسميه Cars.php
بالمسار api/modules/v1/models
<?php
namespace api\modules\v1\models;
use Yii;
use yii\db\ActiveRecord;
class Cars extends ActiveRecord{
public static function tableName(){
return 'cars'; // اسم الجدول
}
public function rules(){ // القيود حيث توضع الشروط وتعريف اعمد الجداول
return [
[['brand', 'reference', 'price', 'image'], 'safe']
];
}
}
3. انشاء CarsController.php بالمسار api/modules/v1/controllers
<?php
namespace api\modules\v1\controllers;
use Yii;
use yii\rest\ActiveController;
class CarsController extends ActiveController{
public $modelClass = 'api\modules\v1\models\Cars'; // ربط الكونترولر بالموديل
public function behaviors(){
$behaviors = parent::behaviors();
// نأمر الخادم بأن يسمح لجميع المصادر بطلب بيانات هده الصفحة
$behaviors['corsFilter' ] = [
'class' => \yii\filters\Cors::className(),
'cors' => [
'Origin' => ['*'], //paths allowed
],
];
// JSON نأمر الخادم بأن يرجع البيانات على شكل
$behaviors['contentNegotiator'] = [
'class' => \yii\filters\ContentNegotiator::className(),
'formats' => [
'application/json' => \yii\web\Response::FORMAT_JSON,
],
];
return $behaviors;
}
public function actionOptions($id){
return true;
}
}
شرح محتوى الـ behaviors
// نأمر الخادم بأن يسمح لجميع المصادر بطلب بيانات هده الصفحة
$behaviors['corsFilter' ] = [
'class' => \yii\filters\Cors::className(),
'cors' => [
'Origin' => ['*'], //paths allowed
],
];
هده المصفوفة في Yii سوف يتم ترجمتها في لغة php الى هدا الأمر
<?php
header('Access-Control-Allow-Origin: *');
?>
عندما يحاول موقع"أ" جلب محتوى من الموقع "ب" ، يمكن لموقع "ب" إرسال عنوان استجابة لإخبار المتصفح بأن محتوى هذه الصفحة يمكن الوصول إليها أو لا
يمكن الوصول إلى صفحات الموقع ب لأي مصدر آخر ادا كانت القيمة (*) ويقصد بها السماح لجميع المصادر بالوصول لمحتوى الموقع "ب" باستخدام هده التعليمة
حيث يمكن ان نمرر مصفوفة تحتوي على عدة مسارات لتقييد الوصول الى المحتوى . مثلا لو مررنا ['http://localhost:8100']
$behaviors['corsFilter' ] = [
'class' => \yii\filters\Cors::className(),
'cors' => [
'Origin' => ['http://localhost:8100'], //paths allowed
],
];
والتي نقصد بها في php
<?php
header('Access-Control-Allow-Origin: http://localhost:8100');
?>
هنا قمنا بتقييد الخادم بالسماح لهدا المصدر فقط بالوصول لبيانات الصفحة .وادا لم يجد الخادم ان الطلب لم يأتي من هدا العنوان فسوف يقوم بتعليق المعالجة وعدم الاستجابة لطلب المستخدم لانه اتى من مصدر غير مسموح به
في الوقت الحالي سوف نكتفي باستخدام (*) والسماح لجميع المسارات بالوصول الى البيانات لاننا سنحول المشروع الى تطبيق android وليس متصفح على بورت http://localhost:8100
4. الخطوة التالية هي تعريف المسار cars في مدير المسارات بالـ api حتى يتم ربط CarsConroller هده الخطوة لايجب نسيانها لان غيابها يعني عدم تعرف الـ api على وجود الكونترولر الدي تم انشاءه
نتوجه الى الملف api/config/main.php
ونضيف في خانة rules التالي
'urlManager' => [
'enablePrettyUrl' => true,
'enableStrictParsing' => true,
'showScriptName' => false,
'rules' => [
[
'class' => 'yii\rest\UrlRule',
'controller' => 'v1/cars', // مسار الكونترولر
'pluralize' => false, // اتركها بهده القيمة
'tokens' => [
'{id}' => '<id:\\w+>',
],
'extraPatterns' => [
'OPTIONS {id}' => 'options', // اضف دالة actionOptions($id)
]
]
],
],
5. بعد عمل هده الخطوات ينبغي أن يعمل معك مسار api على المتصفح دون أخطاء
http://localhost/yii-application/api/v1/cars
يفترض ان تلاحظ نتائج JSON عند تنفيد الرابط بالمتصفح
[
{
"id": 1,
"reference": "IBIZA",
"brand": "Seat",
"price": 250,
"image": "assets/images/image1.jpg"
},
{
"id": 2,
"reference": "Sandero",
"brand": "DACIA",
"price": 150,
"image": "assets/images/image2.jpg"
},
{
"id": 3,
"reference": "Symbol",
"brand": "Renault",
"price": 180,
"image": "assets/images/image3.jpg"
},
{
"id": 4,
"reference": "307",
"brand": "Peugeot",
"price": 200,
"image": "assets/images/image4.jpg"
}
]
الان سنتحول الى تطبيق ionic فيتوجب علينا توجيه مسار البيانات بملف الخدمة نحو http://localhost/yii-application/api/v1/cars
فنجلب البيانات من api وليس من ملف json
حيث سنتوجه الى دالة getCars الموجودة بملف src/providers/car/car.ts
ونقوم باستبدال هده المسارات
let url:string='assets/data/cars.json';
الى
let url:string='http://localhost/yii-application/api/v1/cars';
ليصبح الدالة أكثر ديماكيية بهدا الشكل
public baseUrl = 'http://localhost/yii-application';
constructor(public http: HttpClient) {
}
getCars(){
let url:string = this.baseUrl+'/api/v1/cars';
return this.http.get(url)
.pipe(
map(res => res)
);
}
بعد حفظ الكود يفترض ان يعمل بشكل جيد دون مشاكل