Practical symfony 5 дахь өдөр

DAY5

The Routing

Хэрэв та 4 дэхь өдрийг дуусгацан бол та MVC загварчлалын талаар нилээд мэдлэгтэй болсон бөгөөд кодчлолын ухагдахууныг илүү мэдэрч байгаа байх. Дахин багахан цагийг өнгрөөснөөр та дахин эргэж харахгүй болно. Өчигдөр дадлагаар бид Jobeet хуудсуудыг өөрчилж, мөн layout, helper, slot зэрэг хэд хэдэн symfony-ын ойлголтуудтай танилцсан.
Өнөөдөр бид гайхамшигт symfony routing framework-той танилцана.
URLs

Хэрэв та Jobeet-ын нүүр хуудсан дээр даралт хийвэл url нь дараах байдлаар харагдана: /job/show/id/1..  Хэрэв та өмнө ньPHP дээр вэбсайт хөгжүүлж байсан бол та /job.php?id=1URL-тэй байгаад дассан байх.  Яаж symfony ингэж ажиллуулж байна вэ?Яаж symfonyURL дээрх утгаар action-г тодорхойлж байна вэ? Яагаад job-ын id нь $request->getParameter(‘id’) –аар авагддаг вэ? Өнөөдөр бид эдгээр асуултуудад хариулт авах болно.
Эхлээд Url яг юу болох тухай ярилцацгаая.  Вэб-д URL бол вэб-ийн нөөцийн цорын ганц ялгагч.  Та URL-аар явахад браузераасURL-аас ялгагдах нөөцийг авахыг асууна. Тиймээс URL вэб сайт хэрэглэгч хоёрын хоорондох интерфэйс болохоор өөртөө нөөцийн тухай зарим олгомжгүй мэдээллийг хавсаргадаг.  “Уламжлалт” URL нөөцийн тухай мэдээллийг агуулдаггүй, тэдapplication-ны дотоод бүтцийг илэрхийлдэг. Хэрэглэгчдэд тухайн вэб сайт PHP хэл дээр хийгдсэн мөн ажлын байр бүр баазад өөрийн гэсэн ялгагчтай эсэх нь хамаагүй байдаг. Хамгаалалтын хувьд application-ны дотоод бүтцийг ил гаргах нь муу үр дүнтэй байдаг: Хэрэглэгч холбогдох шаардлагүй нөөцийн URL-ыг таах гэж оролдвол яах вэ? Мэдээж, хөгжүүлэгч тэдгээрийг тохиромжтой хэлбэрээр нууцлах ёстой ба нарийн мэдээллийг нуух нь гарцаагүй.
URL symfony-д маш чухал бөгөөд тэдгээрийн менежментэд зориулсан өөрийн гэсэн бүхэл бүтэн framework-оос бүрдэнэ:routing framework.Routing дотоод URI-ууд болонгадаад URL-уудыг зохицуулдаг. Хүсэлт ирэхэд routingURL-ыг задлан ялгаж дотоод URI-руу хөрвүүлдэг.
Та showSuccess.php template-ээс job хуудсындотоод URI-г харсан байх.
‘job/show?id=’.$job->getId()
url_for helper дотоод URI-ыг зохимжтой URL рүү хөрвүүлдэг.
/job/show/id/1
ДОтоод URI хэд хэдэн хэсгээс тогтдог: job бол модуль, show бол action мөнquery –ын action руу дамжуулах параметрууд.  Дотоод URI-ын ерөнхий хэлбэр нь:
MODULE/ACTION?key=value&key_1=value_1&…
Symfony routing нь 2 замт процесс учираас та дотоод хэрэгжилтийг өөрчлөхгүйгээр URL-ыг өөрчлөх боломжтой байдаг.
Routing тохиргоо
Дотоод URI болон гадаад URL-ын хоорондын зурагжилт ньrouting тохиргооны файлд тодорхойлогддог.
# apps/frontend/config/routing.yml
homepage:
url: /
param: { module: default, action: index }
default_index:
url: /:module
param: { action: index }
default:
url: /:module/:action/*

routing.yml файл route(зам, чиглэл)-үүдийг тодорхойлдог. Route- нь нэр (homepage) , хэв загвар (/:module/:action/*),зарим параметртэй (param түлхүүр үгний доор байрших) байдаг.
Хүсэлт ирэхэд routing өгөгдсөн URL –ыг хэв загвараас хайж тохируулахыг оролддог. Хамгийн түрүүнд тохирсон хэв загвар нь биелэгддэг болохоор routing.yml- д дэс дараалал нь маш чухал байдаг. Хэрхэн ажилдгыг илүү ойлгохын тулд зарим нэг жишээнээс үзэцгээе.
Та /job гэсэн URL –тэй Jobeet нүүр хуудсыг дуудахад хамгийн эхний тохирох хэв загвар нь default_index байна. Хэв загварт, (:)хоёр цэгээр эхэлсэн үг болгон хувьсагч, тиймээс :/module гэсэн загвар нь / тэгээд ямар нэгэн зүйл гэсэнтэй тохирно.  Бидний жишээнд moduleхувьсагч job гэсэн утгатай байна. Энэ утга ньaction хэсгээс $request->getParameter(‘module’) гэж дуудагдана.  Энэ route(хэв загвар)action хувьсагчын default утгыг мөн тодорхойлно. Тиймээс энэ загварт тохирох бүх URL-уудын хувьд хүсэлт бүр index гэх утгатай action параметр-тэй байна гэсэн үг.
Хэрэв та /job/show/id/1гэсэн хүсэлт илгээвэл, symfony /:module/
:action/*гэх хамгийн сүүлийн загвартай тохируулна. Загварт од (*)нь ташуу зураасаар (/) –аар тусгаарлагдах олон хувьсагчын утгуудын нэгдэлтэй тохирно:
Хүсэлтын параметр Утга
module                                job
action                                   show
id                                            1
module ба action хувьсагчууд symfony-д дуудагдахдаа аль action-г гүйцэтгэхийг тодорхойлдог болохоор онцгой төрөлд багтдаг.
/job/show/id/1URL template хэсгээс дараах url_for helper-ээр дуудагдажүүсдэг:
url_for(‘job/show?id=’.$job->getId())
Та мөн @-ээр эхлүүлж загварын нэрийг мөн ашиглаж болно:
url_for(‘@default?module=job&action=show&id=’.$job->getId())
Дээрх хоёр дуудалт хоёул ижил боловч сүүлийнх хамгийн сайн тохирохыг нь олохын тулд бүх загваруудыг ялгах шаардлагагүй учир илүү хурдан ба гүйцэтгэл нь хамаагүй бага байна (module ба action –ын нэр нь дотоод URI-д өгөгдөөгүй).
Route Customizations

Яг одоо та / URL-р браузерт хүсэлт илгээвэл default баярын мэнд гэсэн symfony-ын хуудас гарч ирнэ.  Энэ нь URL ньhomepage загвартай тохирсон гэсэн үг. Гэсэн ч Jobeet нүүр хуудас гарч ирдэгээр өөрчилж болно. Өөрчлөхийн тулдhomepage загварын module хувьсагчыг job болгон өөрчилнө.
# apps/frontend/config/routing.yml
homepage:
url: /
param: { module: job, action: index }
Одоо бид Jobeet  лого-ны холбоосыг homepage загвар руу заахаар болгоё.
<!– apps/frontend/templates/layout.php –>
<h1>
<a href=&#8221;<?php echo url_for(‘@homepage’) ?>&#8221;>
<img src=&#8221;http://www.symfony-project.org/images/logo.jpg&#8221; alt=&#8221;Jobeet
Job Board&#8221; />
</a>
</h1>

Маш амархан байлаа.
Routing тохиргооны файлд өөрчлөлт оруулсны дараа өөрчлөлт нь зөвхөнDevelopment орчны үед л шууд идэвхжих бөгөөд хэрэв та production орчны үед ажиллуулахыг хүсвэл  cache:clear командаар cache-г цэвэрлэх хэрэгтэй.
Илүү өөрийн болгохын тулд job хуудсын URL-ыг илүү утгатай болгон өөрчилье.
/job/sensio-labs/paris-france/1/web-developer
Jobeet-ын талаар юуч мэдэхгүй , хуудсыг хараагүй байсан ч та URL-с Sensio Labs –ыхан Францын Парис-д  Вэб хөгжүүлэгч хайж байгааг мэдэх боломжтой байна.
Цэвэрхэн URL хэрэглэгчдэд мэдээлэл өгөх учираас маш чухал. Мөн энэ нь та email- д copy and paste хийхэд эсвэл хайлтын системд илүү өртөхын тулд илүү хэрэгтэй байдаг.
Дараах загвар тэр URL-д тохирно.
/job/:company/:location/:id/:position
Routing.yml файлыг Edit хийж файлын эхэнд job_show_user загварыг нэм.
job_show_user:
url: /job/:company/:location/:id/:position
param: { module: job, action: show }
Хэрэв та одоо нүүр хуудсыг refresh хийж сэргээвэл, job-ын холбоос өөрчлөгдөөгүй байгаа. Яагаад гэвэл route боловсруулагдахын тулд, та шаардлагатай бүх хувьсагчаар хангах хэрэгтэй болно. Тиймээс одооindexSuccess.php файл дахь url_for()helper-ыг өөрчлөх хэрэгтэй.
url_for(‘job/show?id=’.$job->getId().’&company=’.$job->getCompany().
‘&location=’.$job->getLocation().’&position=’.$job->getPosition())
Дотоод URI мөн массиваар илэрхийлэгдэж болдог.
url_for(array(
‘module’ => ‘job’,
‘action’ => ‘show’,
‘id’ => $job->getId(),
‘company’ => $job->getCompany(),
‘location’ => $job->getLocation(),
‘position’ => $job->getPosition(),
))
Requirements(Шаардлагууд)

Хичээлийн эхний өдөр бид алдааны баталгаажуулалт ба боловсруулалт нь сайн зүйлийн талаар ярьцгаасан.
Route систем нь баталгаажуулалттайгаар хийгдсэнээрээ давуу талтай.  Route (Загвар) хувьсагчбүр route-ын тодорхойлолтынrequirementsгэсэн түлхүүр үгэнд ашиглагдах илэрхийллийн дагуу баталгаажуулагддаг:
job_show_user:
url: /job/:company/:location/:id/:position
param: { module: job, action: show }
requirements:
id: \d+
Дээрх requirements оролт нь id –г заавал тоон утгатай байх ёстойг илэрхийлнэ. Хэрэв үгүй бол route тохирохгүй.
Route Class

Routing.yml –д тодорхойлогдох route бүр sfRoute/http://www.symfony-project.org/api/1_4/sfRoute/классын объект болон хөрвүүлэгддэг.
Энэ класс нь route-ын тодорхойлолтонд class оролтыг оруулж өгсөнөөр өөрчлөгдөж болдог. Хэрэв та HTTP протокол-ын талаар ойлголттой бол, та GET, POST, ~HEAD|HEAD (HTTP Method)~, DELETE, PUTгэх зэрэг хэдэн “аргууд” байдгыг мэднэ. Эхний 3-г нь бүх браузерууд дэмждэг ба харин нөгөө 2-ыг нь дэмждэггүй.
Route-ыг тодорхой хэдэн аргуудаар хязгаарлахыг хүсвэл таroute –ын class-г sfRequestRoute/http://www.symfony-project.org/api/1_4/sfRequestRoute/ болгон өөрчилж мөн requirements-дээр sf_method хувьсагчыг нэмж өгч болно:
job_show_user:
url: /job/:company/:location/:id/:position
class: sfRequestRoute
param: { module: job, action: show }
requirements:
id: \d+
sf_method: [get]
route-д зөвхөн зарим HTTP аргуудыг тохирдог болгох нь action- хэсгээсsfWebRequest::isMethod() –г ашиглахтай бүрэн ижил биш юм. Энэ нь яагаад гэвэл routing нь арга нь таарахгүй байгаа route-ээс цааш мөн үргэлжлүүлж хайдаг учираас тэр юм.
Object Route Class

Job-ын шинэ дотоод URI нь нилээн урт ба бичихэд ядаргаатай байна (url_for(‘job/show?id=’.$job->getId().’&company=’.$job->getCompany().’&location=’.$job->getLocation().’&position=’.$job-
>getPosition())),гэвч бид өмнөх хэсгээс сурсанчлан route классыг өөрчлөх боломжтой. job_show_user route-ын хувьдsfDoctrineRoute/http://www.symfony-project.org/api/1_4/sfDoctrineRoute /-г ашиглах нь Doctrine объект эсвэл Doctrine объектын цуглуулгыг төлөөлж сайжруулагдсан класс учираас илүү дээр:
job_show_user:
url: /job/:company/:location/:id/:position
class: sfDoctrineRoute
options: { model: JobeetJob, type: object }
param: { module: job, action: show }
requirements:
id: \d+
sf_method: [get]
options оролт нь route-ын төлөвыг өөрийн хүссэнээр болгодог. modelсонголт нь route –тэй холбоотой Doctrine model класс (JobeetJob)–ыг тодорхойлдог, мөн type нь энэ route нэг объект-г илэрхийлж байна (та мөн цуглуулга объектыг төлөөлөх routelist–ыг ашиглах боломжтой).
Одоо job_show_user route JobeetJob-той холбоотойгоо мэдэх бөгөөд бид url_for() дуудалтыг хялбаруулж дуудна:
url_for(array(‘sf_route’ => ‘job_show_user’, ‘sf_subject’ => $job))
эсвэл:
url_for(‘job_show_user’, $job)
Эхний жишээ нь та ганц оъектоос илүүтэйгээр олон аргумент дамжуулах үед илүү хэрэгцээтэй байдаг.
Дээрх route дэхь бүх хувьсагч JobeetJob класс дахь тухайн хамаарахaccessor-уудтай учираас хэвийн ажиллана (тухайлбал, company routeхувьсагч getCompany() утгаар загварлагдана).
Хэрэв та хөрвүүлэгдэх URL-ыг харвал, яг бидний хүссэн хэлбэрээр биш байгааг харна.
Web+Developer
Бидэнд бүх ASCII бүх тэмдэгт бүрийг – ээр засах “slugify” багана хэрэгтэй. JobeetJob файлыг нээгээд класс-д дараах method-ыг нэм.
// lib/model/doctrine/JobeetJob.class.php
public function getCompanySlug()
{
return Jobeet::slugify($this->getCompany());
}
public function getPositionSlug()
{
return Jobeet::slugify($this->getPosition());
}
public function getLocationSlug()
{
return Jobeet::slugify($this->getLocation());
}
Тэгээд, lib/Jobeet.class.phpфайлыг үүсгээддотор нь slugify method-г нэм.
// lib/Jobeet.class.php
class Jobeet
{
static public function slugify($text)
{
// replace all non letters or digits by –
$text = preg_replace(‘/\W+/’, ‘-‘, $text);
// trim and lowercase
$text = strtolower(trim($text, ‘-‘));
return $text;
}
}
Энэ хичээлийн турш бид <?php гэсэн нээлтийн мөрийг кодын жишээ-нд үзүүлээгүй ба зөвхөн цэвэр PHP код болон хоорондын зай, мөн догол мөрүүдийг үзүүлсэн.  Та шинэ PHP файл үүсгэх болгондоо үүнийг санан нэмж өгөх хэрэгтэй. Харин template файлуудад бол хэрэггүй гэдгийг санах хэрэгтэй.
Бид getCompanySlug(), getPositionSlug(),getLocationSlug() гэх гурван “virtual” accessor-уудыг тодорхойллоо. Эдгээрүүд одооslugify()method (функц) -ыг дуудсаны дараа хамаатай баганын утгыг буцаана.  Одоо, та job_show_user route дахь жинхэнэ баганын нэрүүдийг дээрх “virtual” – утгуудаар солих боломжтой:
job_show_user:
url: /job/:company_slug/:location_slug/:id/:position_slug
class: sfDoctrineRoute
options: { model: JobeetJob, type: object }
param: { module: job, action: show }
requirements:
id: \d+
sf_method: [get]
Одоо та хүссэж байсан URL-тай боллоо.
Гэвч энэ нь түүхийн зөвхөн тал нь. Route объект дээр тулгуурлан URL-ыг боловсруулж чадна, харин өгөгдсөн URL-ын дагуу мөн объектыг олж бас чадна.  Хамаарах объект нь route объектын getObject()method-оор дуудагдаж болдог. Ирэх хүсэлтийг хөрвүүлвэл action-д ашиглагдах route-д тохирох обектыг өөртөө агуулсан байдаг.  Тиймээс,  executeShow()method-ыгөөрчилж Jobeet объектыг дуудах route объектыг ашиглая.
class jobActions extends sfActions
{
public function executeShow(sfWebRequest $request)
{
$this->job = $this->getRoute()->getObject();
$this->forward404Unless($this->job);
}
// …
}
Хэрэв та мэдэхгүй id-гаар job-г дуудахыг оролдвол 404 алдааны хуудсыг харна. Харин алдааны мэдээлэл нь өөрчлөгдсөн байна.
Энэ нь getRoute()method-ээс тань руу автоматаар 404 алдааг шидэж байгаа учираас тэр юм. Тиймээс бид executeShowmethod-ыг бүр хялбаршуулж болно.
class jobActions extends sfActions
{
public function executeShow(sfWebRequest $request)
{
$this->job = $this->getRoute()->getObject();
}
// …
}
Хэрэв та route 404 алдааг харуулахыг хүсэхгүй бол routingoption-д allow_empty –г тодорхойлж өгөх боломжтой.
Route-тэй хамааралтай объект нь удаан дуудагддаг. Хэрэв таgetRoute() method –ыг дуудсан бол энэ зөвхөн өгөгдлийн баазаас утгыг дууддаг.
Action болон template дэхь routing

Template-д url_for() helper дотоод URI –г гадаад URL рүү хөрвүүлдэг. Бусад зарим symfony helper мөн дотоод URI-ыг аргументаараа авдаг жишээ нь a tag-ыг боловсруулдагlink_to()helper :
<?php echo link_to($job->getPosition(), ‘job_show_user’, $job) ?>
Энэ нь дараах HTML кодыг боловсруулдаг:
<a href=&#8221;/job/sensio-labs/paris-france/1/web-developer&#8221;>Web Developer</a>
url_for() болонlink_to()хоёул бүрэн URL-ыг боловсруулах боломжтой.
url_for(‘job_show_user’, $job, true);
link_to($job->getPosition(), ‘job_show_user’, $job, true);
Хэрэв та action-аас URL-ыг боловсруулахыг хүсвэл generateUrl()method-ыг ашиглах боломжтой.
$this->redirect(‘job_show_user’, $job);
redirect” method-ын төрөл зүйл
Өчигдрийн хичэлээр бид “forward” method-ын тухай ярьцгаасан. Тэдгээрmethod-ууд нь тухайн хүсэлтийг браузераар тойрч аялалгүйгээр өөр actionруу forward хийдэг.
“redirect” method-ууд хэрэглэгчийг өөр URL рүү redirect(чиглүүлдэг) хийдэг. Яг forward шиг, та мөн redirect()эсвэл redirectIf()болон redirectUnless() shortcut method-уудыг ашиглах боломжтой.
Collection Route Class

Job модулын хувьд бид show action-ын route-г өөрийн болгож өөрчилсөн, гэвч бусад method-уудын URL –ууд default (index, new,edit, create, update, delete)route-ээрээ байгаа:
default:
url: /:module/:action/*
default route бол дөнгөж эхлэн код бичиж байгаа хүмүүст хэтэрхий ихroute бичихгүйгээр ашиглах хамгийн сайн арга. Гэвч route “catch-all”(бусдаасаа ялгагдах) –аар байх үед тусгай тохиргоо тохиргоо хийлгээгүйгээр ашиглагдах боломжтой байдаг.
Бүх jobaction-ууд JobeetJobmodel класс-тай холбоотой бол бидsfDoctrineRoute route-г show action-д тодорхойлсон шиг нэг бүрт нь хялбараар тодорхойлж өгч болно. Харин job модуль model –д боломжтой классик 7 action-уудыг тодохойлох бол, бид мөнsfDoctrineRouteCollection / http://www.symfony-project.org/api/1_4/sfDoctrineRouteCollection / классыг ашиглаж болно. routing.yml файлыг нээгээд доорх шиг болгон өөрчил.
# apps/frontend/config/routing.yml
job:
class: sfDoctrineRouteCollection
options: { model: JobeetJob }
job_show_user:
url: /job/:company_slug/:location_slug/:id/:position_slug
class: sfDoctrineRoute
options: { model: JobeetJob, type: object }
param: { module: job, action: show }
requirements:
id: \d+
sf_method: [get]
# default rules
homepage:
url: /
param: { module: job, action: index }
default_index:
url: /:module
param: { action: index }
default:
url: /:module/:action/*
дээрх jobroute бол дараах sfDoctrineRoute 7 route-үүдыг боловсруулах кодын shortcut нь:
job:
url: /job.:sf_format
class: sfDoctrineRoute
options: { model: JobeetJob, type: list }
param: { module: job, action: index, sf_format: html }
requirements: { sf_method: get }
job_new:
url: /job/new.:sf_format
class: sfDoctrineRoute
options: { model: JobeetJob, type: object }
param: { module: job, action: new, sf_format: html }
requirements: { sf_method: get }
job_create:
url: /job.:sf_format
class: sfDoctrineRoute
options: { model: JobeetJob, type: object }
param: { module: job, action: create, sf_format: html }
requirements: { sf_method: post }
job_edit:
url: /job/:id/edit.:sf_format
class: sfDoctrineRoute
options: { model: JobeetJob, type: object }
param: { module: job, action: edit, sf_format: html }
requirements: { sf_method: get }
job_update:
url: /job/:id.:sf_format
class: sfDoctrineRoute
options: { model: JobeetJob, type: object }
param: { module: job, action: update, sf_format: html }
requirements: { sf_method: put }
job_delete:
url: /job/:id.:sf_format
class: sfDoctrineRoute
options: { model: JobeetJob, type: object }
param: { module: job, action: delete, sf_format: html }
requirements: { sf_method: delete }
job_show:
url: /job/:id.:sf_format
class: sfDoctrineRoute
options: { model: JobeetJob, type: object }
param: { module: job, action: show, sf_format: html }
requirements: { sf_method: get }

sfDoctrineRouteCollection –аар боловсруулагдах зарим route нь ижил URLбайдаг. Route бүр өөр өөр HTTP аргуудын шаардлагуудтай болохоор тэдгээрийг ашиглах бүрэн боломжтой.
job_delete баjob_updateroute-үүд браузер дэмждэггүй HTTPаргачлалыг(DELETE ба PUT). шаарддаг. Symfony тэдгээрийг ялгадаг учираас хэвийн ажиллана. _form.php template –ыг нээ жишээ харж болно:
// apps/frontend/modules/job/templates/_form.php
<form action=&#8221;…&#8221; …>
<?php if (!$form->getObject()->isNew()): ?>
<input type=&#8221;hidden&#8221; name=&#8221;sf_method&#8221; value=&#8221;PUT&#8221; />
<?php endif; ?>
<?php echo link_to(
‘Delete’,
‘job/delete?id=’.$form->getObject()->getId(),
array(‘method’ => ‘delete’, ‘confirm’ => ‘Are you sure?’)
) ?>

Бүх symfony helper-үүд таны хүссэн HTTP аргыг тусгайsf_method параметрыг дамжуулснаар ялган таньдаг.
Symfony sf_ гэсэн угтвараар эхэлсэн өөр онцгой параметрүүдтэй тухайлбал sf_method. Дээрх route-үүдээс та өөрsf_format-ыг харж болно. Ирэх өдрүүдэд үүнийг тайлбарлана.
Route Debugging

Та route-үүдийн цуглуулгыг хэрэглэж байгаа бол заримдаа route-үүдийн жагсаалтыг боловсруулах нь илүү хэрэгцээтэй байдаг.
app:routes команд нь өгөгдсөн application-ны бүхroute-үүдийг гаргадаг:
$ php symfony app:routes frontend
Та мөн route-ын нэрийг нэмэлт аргументаар өгснөөр тухайн route-ын алдааны хэрэгцээт мэдээллийг мөн авах боломжтой.
$ php symfony app:routes frontend job_edit
Default Routes
Бүх URL бүр route тодорхойлж өгөх нь сайн. Jobeetapplication-д тодорхойлогдох бүх шаардлагатай route-үүд jobroute-д тодорхойлогдож байгаа учираас routing.yml тохиргооны файлаас defaultroute-үүдыг устгах юмуу санамж болго.
# apps/frontend/config/routing.yml
#default_index:
# url: /:module
# param: { action: index }
#
#default:
# url: /:module/:action/*

Jobeet application урьдых шиг хэвийн ажиллах ёстой.
Маргааш болтол баяртай

Өнөөдөрт маш олон шинэ мэдээлэл багтлаа. Та symfony –ынrouting framework-ыг хэрхэн яаж ашиглах талаар мөн хэрхэн тусгайлсан зориулалтаар өөрийн URL-г ашиглах талаар сурлаа.
Маргааш бид шинэ ойлголттой танилцахгүй ба харин илүүтэйгээр өдий хүртэл юу мэдэж авсан талаараа гүнзгий судлахад илүү цаг зарцуулна.

Published by

Think!

Web developer. Open source enthusiast.

5 thoughts on “Practical symfony 5 дахь өдөр”

  1. Notice:
    Дээр бичигдсэн routing-үүдийг шууд copy хийж ашиглах бол хоорондын зайг нь анхаараарай. Миний блогт routing нь орохдоо хоорондох зай нь алдагдсан байгаа шүү.

Leave a reply to Батаа Хариулт болиулах