Өөрийн фраймворкоо Symfony2 -ын компонент дээр үүсгэе (хэсэг 3)

За уншигч, хөгжүүлэгч нартаа энэ өдрийн мэнд хүргэе.

Энэхүү цуварлууд маань хугацааны хувьд бага зэрэг хоцорсон ч, ерөнхий агуулгын хувьд хуучраагүй тул нэгэнт эхлүүлсэн ажилаа дуусгахаар шийдээд өнөөдрөөс эхлэн 12 цувралыг гүйцэт орчуулан дуусгахаар шийдлээ.
За эхэлцгээе. Урагшаа!

Тэмдэглэл:
Энэхүү нийтлэл нь “Өөрийн фраймворкоо Symfony2 -ын компонент дээр үүсгэе” цувралын нэг хэсэг юм.

Бидний өдий хүртэл хөгжүүлсэн аппликэйшн нь маань зөвхөн нэг л хуудас юм. Ялимгүй сайжруулаад цөмөөрөө “Баяртай” гэж харуулдаг дахин нэг хуудас нэмцгээе:


<!--?php

// framework/bye.php

require_once __DIR__.’/autoload.php’;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

$request = Request::createFromGlobals();

$response = new Response(‘Goodbye!’);
$response->send();

Таны харж байгаачлан, ихэнх код маань бидний өмнө нэг дэх хуудсанд бичсэн кодтой бараг ижил байна. Бүх хуудснуудад ашиглагдаж болох тийм ижил кодыг ялган авъя. “Дахин ашиглагдах код&#8221; өөрсдийн фраймворкоо үүсгэхэд хэрэг болохоор сайхан л сонсогдож байна.

PHP -ийн хувьд дахин тодорхойлох нь магадгүй include файл үүсгэх байх:


<!--?php

// framework/init.php

require_once __DIR__.’/autoload.php’;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

$request = Request::createFromGlobals();
$response = new Response();

Өөрсдийн жишээн дээр үзэцгээе:


<!--?php

// framework/index.php

require_once __DIR__.’/init.php’;

$input = $request->get(‘name’, ‘World’);

$response->setContent(sprintf('Hello %s', htmlspecialchars($input, ENT_QUOTES, 'UTF-8')));
$response->send();

</code>

“Баяртай&#8221; хуудсын хувьд:


<!--?php

// framework/bye.php

require_once __DIR__.’/init.php’;

$response->setContent('Goodbye!');
$response->send();

Үнэндээ бид өөрсдийн дахин ашиглагдаж болох ихэнх кодуудаа нэг хэсэгт төвлөрүүлчлээ, харин энэ нэг л тийм сайн төсөөлөл болсонгүй, үгүй гэж үү? Нэгдүгээрт бид бүх хуудснууддаа send method -тай байна, мөн бидний хуудсууд темплэйт шиг харагдахгүй байгаас гадна кодоо бид зарчмын дагуу зөв тест хийж мөн л чадахгүй байна.

Мөн түүнчлэн, шинээр хуудас нэмнэ гэдэг нь: бид шинэ PHP скрипт үүсгэх ба тэр нь хэрэглэгчдэд дараах маягаар харагдах болно. (http://example.com/bye.php)

Хүсэлтүүд шууд веб серверээр зохицуулагдаж байгаа болохоор, PHP скрипт болон хэрэглэгчийн URL -ийн хооронд шууд холбоо байдаг. Энэ зохицуулалтыг өөрсдийн кодоороо дамжуулан гүйцэтгэвэл хамаагүй дээр болох болов уу. Үүнийг амарханаар шийдвэл, бүх хэрэглэгчийн хүсэлтийг өөрсдийн нэг хуудас руу заахаар тохируулна.

Чимэг:
Хэрэглэгч рүү буцаан илгээх хариуг нэг PHP скриптээр зохицуулахыг “front controller&#8221; гэдэг загварчлал гэж нэрлэдэг.

Тийм скрипт магадгүй дараах шиг харагдах байх:


<!--?php

// framework/front.php

require_once __DIR__.’/autoload.php’;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

$request = Request::createFromGlobals();
$response = new Response();

$map = array(
‘/hello’ => __DIR__.’/hello.php’,
‘/bye’ => __DIR__.’/bye.php’,
);

$path = $request->getPathInfo();
if (isset($map[$path])) {
require $map[$path];
} else {
$response->setStatusCode(404);
$response->setContent(‘Not Found’);
}

$response->send();

`hello.php` -ын хувьд:


<!--?php

// framework/hello.php

$input = $request->get('name', 'World');
$response->setContent(sprintf('Hello %s', htmlspecialchars($input, ENT_QUOTES, 'UTF-8')));

`front.php` скриптэн дээр `$map` хэрэглэгчийн `URL` холбоосууд болон холбогдох PHP скриптийн зам байна.

Үүн дээр нэмээд бид `map`-аар тодорхойлогдоогүй холбоосыг хэрэглэгч асуувал, 404 хуудсыг буцааж болно. Одоо вэб хуудас тань таны удирлаган доор орлоо.

Хуудастайгаа холбогдохын тулд, одоо та `front.php`скриптыг ашиглах ёстой:

http://example.com/front.php/hello?name=Fabien
http://example.com/front.php/bye

`/hello` болон `/bye` -ууд нь холбогдох хуудсын замууд.

Зөвлөгөө:
Apache, nginx зэрэг ихэнх вэб серверүүд хэрэглэгчээс ирэх URL-уудыг дахин бичиж (rewrite) `front controller` скриптгүйгээр хэрэглэгч хандах боломжийг олгодог. Жишээ нь: http://example.com/hello?name=Fabien энэ нь хамаагүй дээр харагдаж байна.

Тэгэхээр яах вэ гэвэл `Request::getPathInfo()` method нь хэрэглэгчийн хүсэлтээс front controller скриптыг устгаад үлдэж буй хойшхи замуудыг буцаадаг. (Шаардлагатай бол дээрх зөвлөгөөг харна уу)

Зөвлөгөө:
Шалгахын тулд та заавал вэб сервер суулгахын шаардлагагүй. Үүний оронд, `$request = Request::createFromGlobals();` гэсэн хүсэлтийг `$request = Request::create(‘/hello?name=Fabien’);` -ээр солиод URL байрлах хэсэгт өөрийн хуудсын замыг оруулж өгнө.

Одоо бидний бүх хуудсуудыг вэб сервер зөвхөн нэг ижил скриптээр (front.php) дамжуулан хандах боллоо. Өөрсдийн кодоо илүү нууцлалтай болгохын тулд бүх PHP кодуудаа вэб-ийн эх хавтасаас гадагш нь байршуулъя:

example.com
??? composer.json
? src
? ??? autoload.php
? ??? pages
? ??? hello.php
? ??? bye.php
??? vendor
??? web
??? front.php

Одоо та өөрийн вэб серверийн эх хавтсыг заагч замыг өөрчлөн `/web` руу заах хэрэгтэй, ингэснээр бусад файлууд хэрэглэгчээс хандах боломжгүй болж байна.

Тэмдэглэл: Энэхүү шинэ бүтцийг ажилладаг болгохын тулд та хэд хэдэн PHP файлуудын замыг өөрчлөх шаардлагатай болох байх, энэ ажлыг таньд үлдээе.

Бүх хуудсуудад давтагдаж байгаа хамгийн сүүлийн зүйл нь `setContent()` хандалт байна. Бид хуудсуудаа бүгдийг нь `templates` рүү хөрвүүлээд, агуулгыг нь echo хийгээд, front controller скриптээс `setContent()` method-р дуудаж ажиллуулах боломжтой.


<!--?php

// example.com/web/front.php

// …

$path = $request->getPathInfo();
if (isset($map[$path])) {
ob_start();
include $map[$path];
$response->setContent(ob_get_clean());
} else {
$response->setStatusCode(404);
$response->setContent('Not Found');
}

// …

Одоо `hello.php` скриптийг мөн хөрвүүлж болно.

<!-- example.com/src/pages/hello.php -->

<?php $name = $request->get(‘name’, ‘World’) ?>

Hello <?php echo htmlspecialchars($name, ENT_QUOTES, ‘UTF-8’) ?>

За өнөөдрийн ажлын үр дүнгээр бидний фрэймворк маань ийм боллоо.


<!--?php

// example.com/web/front.php

require_once __DIR__.’/../src/autoload.php’;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

$request = Request::createFromGlobals();
$response = new Response();

$map = array(
‘/hello’ => __DIR__.’/../src/pages/hello.php’,
‘/bye’ => __DIR__.’/../src/pages/bye.php’,
);

$path = $request->getPathInfo();
if (isset($map[$path])) {
ob_start();
include $map[$path];
$response->setContent(ob_get_clean());
} else {
$response->setStatusCode(404);
$response->setContent(‘Not Found’);
}

$response->send();

Шинээр хуудас нэмэх нь хоёр алхамтай процесс: map -д шинээр оролт нэмж, шинэ PHP темплэйтийг `src/pages/` хавтасд үүсгэнэ. Тэмплэйтээс хүсэлт (Request) -ийн өгөгдлүүд `$request` хувьсагчаар ханддагдах ба Хариулт толгой өгөгдлүүд (Response headers) `$response` хувьсагчаар хандагдана.

Тэмдэглэл:
Хэрэв та энэ хүрээд болих гэж байгаа бол, холбоосуудын хаягжилтуудаа (URL map) тохиргооны файл руу ялган авч сайжруулах хэрэгтэй болох байх.

Advertisements

Хариулт үлдээх

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Өөрчлөх )

Twitter picture

You are commenting using your Twitter account. Log Out / Өөрчлөх )

Facebook photo

You are commenting using your Facebook account. Log Out / Өөрчлөх )

Google+ photo

You are commenting using your Google+ account. Log Out / Өөрчлөх )

Connecting to %s