สร้างและรันโปรเจกต์ Symfony
ServBay เป็นสภาพแวดล้อมการพัฒนาเว็บในเครื่องที่ออกแบบมาสำหรับ macOS และ Windows โดยรวม PHP, Node.js, Python, Go, Java และฐานข้อมูลต่างๆ เช่น MySQL, PostgreSQL, MongoDB, Redis พร้อมสนับสนุนเซิร์ฟเวอร์ Apache และ Caddy คู่มือนี้จะอธิบายวิธีการใช้งาน ServBay ในการสร้างและรันโปรเจกต์ Symfony บน macOS และ Windows อย่างละเอียด
Symfony คืออะไร?
Symfony คือเฟรมเวิร์ค PHP เว็บโอเพ่นซอร์สที่พัฒนาโดย SensioLabs ตั้งใจให้นักพัฒนามีเครื่องมือที่มีประสิทธิภาพ, ยืดหยุ่น และฟีเจอร์มากมายสำหรับสร้างเว็บแอปยุคใหม่และ API โดยปฏิบัติตามแนวทางปฏิบัติมาตรฐานของเว็บและประกอบไปด้วยองค์ประกอบหลากหลาย เช่น ระบบกำหนดเส้นทาง, เทมเพลต (Twig), การจัดการฟอร์ม, การรับรองตัวตน, Dependency Injection และอื่นๆ ที่ช่วยลดความซับซ้อนสำหรับงานเว็บทั่วไป
คุณสมบัติเด่นและข้อดีของ Symfony
- การออกแบบแบบโมดูลาร์: Symfony ใช้คอมโพเนนต์ที่นำกลับมาใช้ซ้ำได้ นักพัฒนาสามารถเลือกใช้งานเฉพาะส่วนตามต้องการ เหมาะกับโปรเจกต์เล็กถึงใหญ่
- ประสิทธิภาพสูง: สถาปัตยกรรมที่ถูกปรับแต่ง, กลไกแคชที่มีประสิทธิภาพ และรองรับฟีเจอร์ใหม่ของ PHP ทำให้ Symfony มี performance ที่ยอดเยี่ยม
- ชุมชนสนับสนุนใหญ่: รองรับโดยนักพัฒนาอย่างกว้างขวาง, มี bundle (ปลั๊กอิน) หลากหลาย และเอกสารครบครัน จึงง่ายต่อการแก้ปัญหาต่างๆ
- ยืดหยุ่น: ง่ายต่อการผสานไลบรารีและส่วนขยายจาก third-party เหมาะกับงานหลากหลายรูปแบบและขนาดโปรเจกต์
- เสถียรและดูแลรักษาง่าย: ปฏิบัติตามแนวทางการเขียนโค้ดและ design pattern ที่ดี ทำให้ application ทดสอบง่าย ดูแลรักษาสะดวกและขยายได้
Symfony เหมาะสำหรับสร้างโปรเจกต์เว็บตั้งแต่ API ขนาดเล็กจนถึงระบบองค์กรขนาดใหญ่
สร้างและรันโปรเจกต์ Symfony ด้วย ServBay
ServBay เตรียมสภาพแวดล้อมที่สมบูรณ์สำหรับการใช้งาน Symfony ทั้งเวอร์ชัน PHP ที่ต้องการ, Composer, Web server, ฐานข้อมูลและแคชต่างๆ ส่วนนี้จะแนะนำการสร้างโปรเจกต์ Symfony ใหม่และการตั้งค่าด้วยฟีเจอร์ของ ServBay
ข้อกำหนดเบื้องต้น
ก่อนเริ่ม ให้ตรวจสอบว่าได้เตรียมสิ่งต่อไปนี้ไว้แล้ว:
- ติดตั้ง ServBay แล้ว: ServBay ถูกติดตั้งและเปิดใช้งานใน macOS ถ้ายังไม่ติดตั้ง ดู คู่มือการติดตั้ง ServBay
- ServBay ทำงานปกติ: core service ของ ServBay (Caddy หรือ Apache, ฐานข้อมูลที่ต้องการใช้) ยังทำงานอยู่
- พื้นฐานความรู้: เข้าใจพื้นฐานเกี่ยวกับ PHP, Composer และ Symfony แล้ว
สร้างโปรเจกต์ Symfony ใหม่
ServBay แนะนำให้เก็บโปรเจกต์เว็บไซต์ไว้ในโฟลเดอร์ /Applications/ServBay/www
จะช่วยให้ ServBay ตรวจจับและจัดการได้สะดวก
ตรวจสอบว่า Composer ใช้งานได้
ServBay ได้ติดตั้ง Composer พร้อมเซ็ต environment variable ให้เรียบร้อยโดยอัตโนมัติ ไม่จำเป็นต้องลงเพิ่ม ตรวจสอบโดยใช้คำสั่ง
composer --version
ใน Terminalสร้างโฟลเดอร์โปรเจกต์
สร้างโฟลเดอร์ใหม่เพื่อเก็บโปรเจกต์ Symfony:
bashcd /Applications/ServBay/www mkdir servbay-symfony-app
1
2ใช้ Composer สร้างโปรเจกต์ Symfony
เข้าโฟลเดอร์ที่สร้างไว้ ใช้ Composer สร้างโปรเจกต์ Symfony ด้วย skeleton
website-skeleton
ที่ลง dependencies พื้นฐานสำหรับ web app ทั่วไป:bashcd /Applications/ServBay/www/servbay-symfony-app composer create-project symfony/website-skeleton .
1
2จะดาวน์โหลดไฟล์ Symfony และ dependencies ทั้งหมดลงในโฟลเดอร์นี้
ตั้งค่าพื้นฐาน
การตั้งค่าหลักของโปรเจกต์ Symfony จะจัดการผ่าน environment variable ที่บันทึกไว้ในไฟล์ .env
ใน root directory
กำหนดค่า Environment Variable (
.env
)เปิดไฟล์
.env
ใน root directory ของโปรเจกต์ ที่นั่นเก็บข้อมูลสำคัญ เช่น การเชื่อมต่อฐานข้อมูล, application key ปรับ, เพิ่มหรือแก้ไขค่าตามความต้องการตรวจสอบให้แน่ใจว่ามีการตั้งค่าสำคัญถูกต้องหรือปรับตามสภาพแวดล้อม ServBay ของคุณ:
dotenv# ตัวอย่างไฟล์ .env APP_ENV=dev # สภาพแวดล้อมสำหรับพัฒนา APP_SECRET=your_secret_key # เปลี่ยนเป็นสตริงสุ่มที่ไม่ซ้ำเพื่อความปลอดภัย # ข้อมูลเชื่อมต่อฐานข้อมูล (ตัวอย่างใช้ MySQL, จะอธิบายต่อไป) # DATABASE_URL="mysql://db_user:db_password@127.0.0.1:3306/db_name?serverVersion=8.0&charset=utf8mb4" # DATABASE_URL="postgresql://db_user:db_password@127.0.0.1:5432/db_name?serverVersion=13&charset=utf8" # DATABASE_URL="sqlite:///%kernel.project_dir%/var/data.db"
1
2
3
4
5
6
7
8เปลี่ยน
your_secret_key
เป็นสตริงแบบสุ่มที่ปลอดภัย สำหรับข้อมูลเชื่อมต่อ MySQL/PGSQL โดยทั่วไป ServBay กำหนด username เป็นroot
password เป็นpassword
(ขอแนะนำให้เปลี่ยนใน production) ตัวอย่างในคู่มือใช้ชื่อ database ว่าservbay_symfony_app
กำหนดค่า Web Server (ServBay เว็บไซต์)
เพื่อเข้าใช้งานจาก browser ต้องใช้ฟีเจอร์ “เว็บไซต์” ของ ServBay ตั้งค่า virtual host ในเครื่อง โดย root directory ของเว็บสำหรับ Symfony จะอยู่ในโฟลเดอร์ public/
ของโปรเจกต์
เปิด ServBay control panel ไปที่หน้า “เว็บไซต์” (หรือ “โฮสต์” สำหรับ version เก่า) แล้วเพิ่มเว็บไซต์ใหม่:
- ชื่อ (Name): ตั้งชื่อเว็บไซต์ให้จำง่าย เช่น
My Symfony Dev Site
- โดเมน (Domain): กำหนดโดเมนท้องถิ่น เช่น
servbay-symfony-test.local
(ServBay จะทำ mapping ให้โดยอัตโนมัติ) - ประเภทเว็บไซต์ (Website Type): เลือก
PHP
- เวอร์ชัน PHP (PHP Version): เลือกที่เข้ากันกับ Symfony (แนะนำเวอร์ชันล่าสุด เช่น
8.3
) - Root Directory เว็บไซต์ (Website Root): ต้องชี้ไปที่โฟลเดอร์
public/
ของโปรเจกต์ ให้เลือก/Applications/ServBay/www/servbay-symfony-app/public
บันทึกและใช้งาน ServBay จะ config web server ให้อัตโนมัติ โดยทั่วไปจะเลือกใช้ Caddy หรือ Apache พร้อมออกแบบ SSL cert ให้อัตโนมัติสำหรับโดเมนท้องถิ่น สามารถเข้า HTTPS ได้ทันที
ดูรายละเอียดการตั้งค่าได้ที่ ServBay เพิ่มเว็บไซต์แรก
เพิ่มตัวอย่างโค้ดเบื้องต้น
เพื่อทดสอบว่ายัง config เว็บไซต์ถูกต้องหรือไม่ ให้เพิ่ม route และ controller ง่ายๆ ไว้ใน root path
กำหนด route (
config/routes.yaml
)แก้ไขไฟล์
config/routes.yaml
เพิ่ม config สำหรับ root path/
โดยชี้ไปยังเมธอด controller ชื่อindex
:yaml# config/routes.yaml index: path: / controller: App\Controller\DefaultController::index
1
2
3
4สร้าง Controller (
src/Controller/DefaultController.php
)สร้างไฟล์ใหม่ชื่อ
DefaultController.php
ในโฟลเดอร์src/Controller/
ตามโค้ดข้างล่างนี้:php<?php // src/Controller/DefaultController.php namespace App\Controller; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Annotation\Route; class DefaultController { /** * @Route("/", name="index") */ public function index(): Response { // ส่ง response HTTP อย่างง่าย return new Response('Hello ServBay and Symfony!'); } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18โค้ดนี้สร้าง controller ชื่อ
DefaultController
ฟังก์ชันindex
เชื่อมโยงกับ path/
(ผ่าน annotation@Route("/")
) จะคืนข้อความ "Hello ServBay and Symfony!" เมื่อเข้า root path
เข้าถึงเว็บไซต์
เปิด browser เข้าโดเมนที่ตั้งค่าไว้ https://servbay-symfony-test.local
หากทุกอย่างถูกต้องจะเห็นหน้าเว็บแสดงว่า:
Hello ServBay and Symfony!
1
แสดงว่าโปรเจกต์ Symfony รันผ่าน web server ของ ServBay สำเร็จแล้ว (ควรใช้ https://
สำหรับการเชื่อมต่อแบบปลอดภัย)
ตัวอย่างการใช้งานฐานข้อมูลและแคช
Symfony มักใช้ Doctrine ORM จัดการฐานข้อมูล และใช้ Symfony Cache สำหรับแคชหรือ NoSQL ServBay มีบริการฐานข้อมูลและ PHP extension หลายตัวพร้อมใช้งานในโปรเจกต์ Symfony
ฐานข้อมูลแบบสัมพันธ์ (Doctrine ORM)
ServBay รองรับทั้ง MySQL และ PostgreSQL ตัวอย่างนี้จะแนะนำการกำหนดค่าและใช้งานทั้งสองแบบ
ตั้งค่าการเชื่อมต่อฐานข้อมูล
ในไฟล์
.env
ให้เปิด (uncomment) และแก้ไขค่าDATABASE_URL
ให้ตรงกับฐานข้อมูลที่ใช้- MySQL: User เริ่มต้นของ MySQL คือ
root
, password เป็นpassword
, port3306
(ขึ้นกับ config ใน ServBay)dotenv# .env DATABASE_URL="mysql://root:password@127.0.0.1:3306/servbay_symfony_app?serverVersion=8.0&charset=utf8mb4"
1
2 - PostgreSQL: User คือ
root
, password เป็นpassword
, port5432
(ขึ้นกับ config)dotenv# .env DATABASE_URL="postgresql://root:password@127.0.0.1:5432/servbay_symfony_app?serverVersion=13&charset=utf8"
1
2
ตรวจสอบว่าฐานข้อมูลที่ต้องการใช้งานเปิดอยู่ใน ServBay control panel
- MySQL: User เริ่มต้นของ MySQL คือ
สร้างฐานข้อมูล
หาก
servbay_symfony_app
ยังไม่มี สามารถสร้างผ่านเครื่องมือจัดการของ ServBay เช่น phpMyAdmin หรือ pgAdmin (เข้าถึงได้ทาง control panel) หรือใช้คำสั่ง Symfonybashphp bin/console doctrine:database:create
1สร้าง Entity และไฟล์ migration
Entity Doctrine แทนตารางฐานข้อมูล ใช้ Maker Bundle ช่วยสร้าง Entity และ migration
- สร้าง Entity (ตัวอย่าง
User
):bashใส่ field เช่นphp bin/console make:entity User
1name
(string),email
(string, unique=yes) ตามคำแนะนำ - สร้างไฟล์ migration สร้างไฟล์ migration ตามการเปลี่ยนแปลง Entity:bashไฟล์ migration จะอยู่ใน
php bin/console make:migration
1src/Migrations
พร้อม SQL สร้างตารางusers
- สร้าง Entity (ตัวอย่าง
รัน migration
ดำเนินการ migration เอาโครงสร้าง DB ไปปลูกในฐานข้อมูล:
bashphp bin/console doctrine:migrations:migrate
1เพิ่มตัวอย่างโค้ดฐานข้อมูล
แก้ไข
src/Controller/DefaultController.php
เพื่อเพิ่ม route และ method สำหรับเขียน/อ่านข้อมูล ผ่าน Doctrine โดย injectionEntityManagerInterface
เพิ่ม constructor inject
EntityManagerInterface
:php<?php // src/Controller/DefaultController.php namespace App\Controller; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Annotation\Route; use Doctrine\ORM\EntityManagerInterface; // import use App\Entity\User; // import use Symfony\Component\HttpFoundation\JsonResponse; // สำหรับ JSON class DefaultController { private $entityManager; // inject EntityManagerInterface public function __construct(EntityManagerInterface $entityManager) { $this->entityManager = $entityManager; } /** * @Route("/", name="app_index") */ public function index(): Response { return new Response('Hello ServBay and Symfony!'); } // ... method อื่นๆ ... }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30เพิ่ม route สำหรับฐานข้อมูลใน
config/routes.yaml
:yaml# config/routes.yaml # ... อื่นๆ ... mysql_add_user: path: /mysql-add-user # หรือ /pgsql-add-user สำหรับ pgsql controller: App\Controller\DefaultController::addUser mysql_get_users: path: /mysql-users # หรือ /pgsql-users controller: App\Controller\DefaultController::getUsers
1
2
3
4
5
6
7
8เพิ่ม method ใน
src/Controller/DefaultController.php
:php<?php // src/Controller/DefaultController.php namespace App\Controller; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Annotation\Route; use Doctrine\ORM\EntityManagerInterface; use App\Entity\User; use Symfony\Component\HttpFoundation\JsonResponse; // import class DefaultController { private $entityManager; public function __construct(EntityManagerInterface $entityManager) { $this->entityManager = $entityManager; } /** * @Route("/", name="app_index") */ public function index(): Response { return new Response('Hello ServBay and Symfony!'); } /** * @Route("/add-user", name="app_add_user") */ public function addUser(): Response { $user = new User(); // ตัวอย่างข้อมูลสำหรับแบรนด์ ServBay $user->setName('ServBay Demo User'); $user->setEmail('demo-user@servbay.test'); // บันทึก entity ไว้ $this->entityManager->persist($user); // เขียนลง DB จริง $this->entityManager->flush(); return new Response('User added successfully!'); } /** * @Route("/get-users", name="app_get_users") */ public function getUsers(): JsonResponse { // ดึงทุก User entity จาก DB $users = $this->entityManager->getRepository(User::class)->findAll(); // แปลงเป็น array สำหรับ JSON $usersArray = []; foreach ($users as $user) { $usersArray[] = [ 'id' => $user->getId(), 'name' => $user->getName(), 'email' => $user->getEmail(), ]; } // ส่ง JSON response return new JsonResponse($usersArray); } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67ทดสอบตัวอย่าง
- เข้า
https://servbay-symfony-test.local/add-user
เพื่อเพิ่มผู้ใช้ - เข้า
https://servbay-symfony-test.local/get-users
เพื่อดูรายชื่อผู้ใช้แบบ JSON
- เข้า
ตัวอย่างการใช้งาน Cache และฐานข้อมูล NoSQL (Symfony Cache)
ServBay มี Redis และ Memcached พร้อม extension PHP ให้ใช้ Symfony Cache library กับบริการพวกนี้ได้ทันที
กำหนดการเชื่อมต่อ Cache
ตั้งค่าเชื่อมต่อ cache ในไฟล์
.env
- Memcached: Port เริ่มต้นของ Memcached คือ
11211
dotenvเช็คว่า Memcached เปิดอยู่ใน ServBay control panel# .env # ... อื่นๆ ... CACHE_DSN=memcached://127.0.0.1:11211
1
2
3 - Redis: Port ของ Redis คือ
6379
dotenvตรวจสอบ Redis เปิดใช้งานใน ServBay control panel# .env # ... อื่นๆ ... CACHE_DSN=redis://127.0.0.1:6379 # หาก Redis มี password (ค่าปกติใน ServBay ไม่มี), ตัวอย่าง: # CACHE_DSN=redis://:your_password@127.0.0.1:6379
1
2
3
4
5
- Memcached: Port เริ่มต้นของ Memcached คือ
เพิ่มตัวอย่างโค้ดการใช้แคช
แก้ไข
src/Controller/DefaultController.php
เพิ่ม constructor injectCacheInterface
และ route + method ตัวอย่าง:เพิ่มใน constructor:
php<?php // src/Controller/DefaultController.php namespace App\Controller; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Annotation\Route; use Doctrine\ORM\EntityManagerInterface; use App\Entity\User; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Contracts\Cache\CacheInterface; // import class DefaultController { private $entityManager; private $cache; // เพิ่ม cache property public function __construct(EntityManagerInterface $entityManager, CacheInterface $cache) { $this->entityManager = $entityManager; $this->cache = $cache; // เซ็ต cache } // ... method อื่นๆ ... }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24เพิ่ม route ใน
config/routes.yaml
:yaml# config/routes.yaml # ... อื่นๆ ... cache_example: path: /cache-example controller: App\Controller\DefaultController::cacheExample
1
2
3
4
5เพิ่ม method ใน controller:
php<?php // src/Controller/DefaultController.php namespace App\Controller; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Annotation\Route; use Doctrine\ORM\EntityManagerInterface; use App\Entity\User; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Contracts\Cache\CacheInterface; use Symfony\Component\Cache\Item\ItemInterface; // import class DefaultController { private $entityManager; private $cache; public function __construct(EntityManagerInterface $entityManager, CacheInterface $cache) { $this->entityManager = $entityManager; $this->cache = $cache; } // ... method อื่นๆ ... /** * @Route("/cache-example", name="app_cache_example") */ public function cacheExample(): Response { // พยายามดึงค่าจาก cache $cacheItem = $this->cache->get('my_symfony_cache_key', function (ItemInterface $item) { // หาก cache ไม่เจอ ให้สร้างใหม่ใน callback นี้ $item->expiresAfter(3600); // หมดอายุใน 1 ชั่วโมง // จำลองการประมวลผลที่ใช้เวลานาน เช่น query ข้อมูลอันซับซ้อน $data = "Data generated at " . date('Y-m-d H:i:s'); // คืนค่าที่จะ cache return $data; }); // $cacheItem คือค่าที่ cache ได้ หรือเพิ่งสร้างใหม่ $output = "From Cache: " . $cacheItem; return new Response($output); } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48ทดสอบ
- เข้า
https://servbay-symfony-test.local/cache-example
ครั้งแรกจะสร้าง cache ใหม่ ครั้งถัดไปจะใช้ข้อมูลจาก cache ถ้ายังไม่หมดอายุ
- เข้า
คำถามที่พบบ่อย (FAQ)
ถาม: เข้า https://servbay-symfony-test.local
แล้วเจอหน้าว่างหรือ error 500 ต้องทำอย่างไร?
ตอบ: เช็คสิ่งต่อไปนี้
- ServBay เปิดทำงานอยู่ และ website service (Caddy หรือ Apache) ยังทำงาน
- ค่าโดเมน
servbay-symfony-test.local
ใน ServBay ถูกต้อง และ root directory ตั้งไว้เป็น/Applications/ServBay/www/servbay-symfony-app/public
- ตรวจสอบไฟล์ log ของ Symfony ใน
var/log/dev.log
เพื่อดูรายละเอียด error - รัน
composer install
ใน root directory เพื่อให้ dependencies ถูกติดตั้งครบ - เช็คว่ารุ่น PHP ที่ตั้งค่าสอดคล้องกับ Symfony ที่ใช้งาน
ถาม: เชื่อมต่อฐานข้อมูลไม่ได้?
ตอบ: ตรวจสอบสิ่งเหล่านี้
- ฐานข้อมูล (MySQL หรือ PostgreSQL) เปิดอยู่ใน ServBay control panel
- ไฟล์
.env
กำหนดค่าDATABASE_URL
ถูกต้อง (username, password, host, port database name) - รหัสผ่านและชื่อผู้ใช้ database ตรงกับที่ตั้งไว้ (ค่า default หรือที่เปลี่ยนเอง)
- มีฐานข้อมูลชื่อ
servbay_symfony_app
อยู่ในระบบแล้ว
ถาม: ใช้คำสั่ง php bin/console
ไม่ได้?
ตอบ: ให้แน่ใจว่า Terminal อยู่ที่โฟลเดอร์ /Applications/ServBay/www/servbay-symfony-app
และ PHP จาก ServBay ถูกเพิ่มใน PATH (ตั้งให้โดยอัตโนมัติอยู่แล้ว) ใช้ which php
เพื่อเช็คว่ามาจาก ServBay
สรุป
จากคู่มือฉบับนี้ คุณสามารถใช้ ServBay สร้าง กำหนดค่า และรันโปรเจกต์ Symfony บน macOS ได้ครบสมบูรณ์ ServBay เตรียมทุกอย่างที่จำเป็นสำหรับนักพัฒนา Symfony (PHP, Composer, web server, ฐานข้อมูล, แคช) และลดขั้นตอน configuration ที่ยุ่งยาก ให้คุณเริ่มเขียนเว็บแอปได้รวดเร็วทันใจ พร้อมศึกษาส่วนต่างๆ เพิ่มเติมและเลือกใช้ software/service เพิ่มจาก ServBay ได้อีกมากมาย