PHP Symfony Code Review Best Practice — คู่มือฉบับสมบูรณ์ 2026 | SiamCafe Blog

PHP Symfony Code Review Best Practice — คืออะไร?
การรีวิวโค้ด (Code Review) ในระบบที่ใช้ PHP กับ Symfony Framework ไม่ใช่แค่ขั้นตอนสุดท้ายของการพัฒนา แต่คือหัวใจสำคัญของการสร้างซอฟต์แวร์ที่มีคุณภาพ
ยั่งยืน และสามารถขยายต่อยอดได้ในอนาคตข้างหน้า ด้วยประสบการณ์การเทรด Forex ที่ยาวนานกว่า 13 ปี ซึ่งต้องอาศัยการวิเคราะห์เชิงลึก การตัดสินใจอย่างแม่นยำ และการบริหารความเสี่ยงอยู่ตลอดเวลา อ.บอมเข้าใจดีว่า “ความผิดพลาดเล็กๆ อาจทำให้เสียทั้งพอร์ต” — ซึ่งก็เหมือนกับโค้ดที่ผิดเพียงบรรทัดเดียวอาจทำให้ระบบล่มในช่วงเวลาสำคัญได้ ดังนั้น คู่มือฉบับนี้จึงไม่ได้เขียนเพื่อทฤษฎี แต่สร้างขึ้นจากประสบการณ์จริงจากการพัฒนาโปรเจกต์หลายร้อยโปรเจกต์ ตั้งแต่เว็บไซต์ร้านค้าออนไลน์ขนาดเล็ก ไปจนถึงระบบจัดการธุรกรรมระดับองค์กรที่ต้องรองรับผู้ใช้หลายแสนรายใน 5 กันยายน 2026 ที่ผ่านมา ทุกแนวทางที่นำเสนอถูกทดสอบในสภาพแวดล้อมจริง ไม่ว่าจะเป็นการใช้ Symfony 5, 6 หรือ 7 ที่มีการอัปเดตโครงสร้างอย่างต่อเนื่อง
ในยุคที่การพัฒนาซอฟต์แวร์ต้องแข่งขันกับเวลาและคุณภาพอย่างต่อเนื่อง ความแม่นยำในการเขียนโค้ดไม่ใช่แค่เรื่องของ “เขียนได้” แต่คือเรื่องของ “เขียนถูกต้อง ปลอดภัย และขยายต่อยอดได้” โดยเฉพาะในระบบที่ใช้ PHP กับ Symfony Framework ซึ่งเป็นโครงสร้างพื้นฐานของแอปพลิเคชันระดับองค์กรหลายตัว ทั้งในไทยและต่างประเทศ การรีวิวโค้ดจึงไม่ใช่แค่ขั้นตอนสุดท้าย แต่คือหัวใจสำคัญของการพัฒนาที่ยั่งยืน ด้วยประสบการณ์การเทรด Forex ที่ยาวนานกว่า 13 ปี ซึ่งต้องอาศัยการวิเคราะห์เชิงลึก การตัดสินใจอย่างแม่นยำ และการบริหารความเสี่ยงอยู่ตลอดเวลา อ.บอมเข้าใจดีว่า “ความผิดพลาดเล็กๆ อาจทำให้เสียทั้งพอร์ต” — ซึ่งก็เหมือนกับโค้ดที่ผิดเพียงบรรทัดเดียวอาจทำให้ระบบล่มในช่วงเวลาสำคัญได้ ดังนั้น คู่มือฉบับนี้จึงไม่ได้เขียนเพื่อทฤษฎี แต่สร้างขึ้นจากประสบการณ์จริงจากการพัฒนาโปรเจกต์หลายร้อยโปรเจกต์ ตั้งแต่เว็บไซต์ร้านค้าออนไลน์ขนาดเล็ก ไปจนถึงระบบจัดการธุรกรรมระดับองค์กรที่ต้องรองรับผู้ใช้หลายแสนรายใน 5 กันยายน 2026 ที่ผ่านมา ทุกแนวทางที่นำเสนอถูกทดสอบในสภาพแวดล้อมจริง ไม่ว่าจะเป็นการใช้ Symfony 5, 6 หรือ 7 ที่มีการอัปเดตโครงสร้างอย่างต่อเนื่อง การรีวิวโค้ดที่ดี จึงต้องเริ่มจากการเข้าใจว่า “โค้ดที่ดี” คืออะไร และต้องมีกรอบการทำงานที่ชัดเจน เพื่อให้ทีมพัฒนาทุกคน “เห็นตรงกัน” ไม่ใช่แค่ “ชอบ” หรือ “ไม่ชอบ” แต่ต้อง “เห็นว่ามันถูกต้องตามหลักวิชาการ” ซึ่งจะถูกอธิบายในหัวข้อถัดไปอย่างละเอียด
โค้ดที่ดีใน Symfony ไม่ได้วัดแค่ “ทำงานได้” แต่ต้องผ่านเกณฑ์หลายมิติ เช่น โครงสร้างที่ชัดเจน ความปลอดภัยสูง ประสิทธิภาพดี และสามารถบำรุงรักษาได้ในระยะยาว หนึ่งในหลักการพื้นฐานที่ควรตั้งไว้ตั้งแต่ต้น คือ “โค้ดที่ดีต้องอ่านง่าย แก้ไขง่าย และขยายได้ง่าย” ซึ่งในบริบทของ Symfony นั้นหมายถึงการใช้โครงสร้าง MVC อย่างถูกต้อง การแยกส่วนอย่างชัดเจนระหว่าง Controller, Service, Repository และ Template ไม่ควรให้ Business Logic ไปปนกับ Controller หรือ Template อย่างเด็ดขาด เพราะจะทำให้ระบบยุ่งเหยิงและเสี่ยงต่อข้อผิดพลาดในอนาคต ตัวอย่างเช่น หากมีการเขียนโค้ดที่ดึงข้อมูลจากฐานข้อมูล แล้วแปลงข้อมูลใน Controller โดยตรง ก็ถือว่าผิดหลักการ เพราะควรย้ายกระบวนการนี้ไปไว้ใน Service หรือ Repository แทน เพื่อให้สามารถนำกลับมาใช้ใหม่ได้ในที่อื่นได้ง่ายขึ้น อีกประเด็นสำคัญคือการใช้ Dependency Injection อย่างถูกต้อง โดยเฉพาะใน Symfony ที่มีระบบ Dependency Injection Container ที่ทรงพลัง ควรหลีกเลี่ยงการสร้างออบเจกต์โดยตรงด้วย `new` แต่ควรใช้ Dependency Injection ผ่าน Constructor หรือ Setter เพื่อให้ระบบยืดหยุ่นและสามารถทดสอบได้ง่ายขึ้น ทั้งนี้ การรีวิวโค้ดควรตรวจสอบว่ามีการใช้ Interface หรือ Abstract Class ในการกำหนด contract หรือไม่ ซึ่งช่วยให้สามารถเปลี่ยน implementation ได้โดยไม่กระทบกับส่วนอื่นของระบบ และยังสอดคล้องกับหลักการ Dependency Inversion ของ SOLID ที่สำคัญมากในระบบขนาดใหญ่
การรีวิวโค้ดที่มีประสิทธิภาพใน Symfony ต้องอาศัยกระบวนการที่เป็นระบบ ไม่ใช่แค่ “ดูแล้วรู้สึกไม่โอเค” แต่ต้องมีเกณฑ์ชัดเจนในการประเมิน
หนึ่งในแนวทางที่ใช้ได้ผลดีที่สุดคือการใช้ Checklists หรือ Template สำหรับการรีวิว ซึ่งควรครอบคลุมทั้งด้านโค้ด ความปลอดภัย และการทดสอบ ตัวอย่างเช่น ควรตรวจสอบว่า:
การรีวิวโค้ดที่มีประสิทธิภาพใน Symfony ต้องอาศัยกระบวนการที่เป็นระบบ ไม่ใช่แค่ “ดูแล้วรู้สึกไม่โอเค” แต่ต้องมีเกณฑ์ชัดเจนในการประเมิน หนึ่งในแนวทางที่ใช้ได้ผลดีที่สุดคือการใช้ Checklists หรือ Template สำหรับการรีวิว ซึ่งควรครอบคลุมทั้งด้านโค้ด ความปลอดภัย และการทดสอบ ตัวอย่างเช่น ควรตรวจสอบว่า:
- มีการใช้ Doctrine อย่างถูกต้องหรือไม่ (เช่น ใช้ Query Builder แทน Raw SQL ถ้าเป็นไปได้)
- มีการป้องกัน SQL Injection หรือ XSS หรือไม่
- มีการใช้ CSRF Token ในฟอร์มหรือไม่
- มีการจัดการ Session อย่างปลอดภัยหรือไม่
- มีการใช้ Environment Variables สำหรับค่าต่างๆ แทนการเขียนค่าคงที่ในโค้ด
- มีการใช้ Logging อย่างเหมาะสมหรือไม่
- มีการจัดการข้อผิดพลาดด้วย Exception ที่เฉพาะเจาะจงหรือไม่
- มีการใช้ HTTP Status Code อย่างเหมาะสม (404, 403, 500) หรือไม่
- มีการตรวจสอบสิทธิ์ (Authorization) หรือไม่
- มีการใช้ DTO หรือ Serializer สำหรับการส่งข้อมูลหรือไม่
การใช้ checklist เหล่านี้ช่วยให้การรีวิวไม่ตกหล่นประเด็นสำคัญ และทำให้ทีมพัฒนา “เห็นภาพ” ได้ชัดเจนขึ้น โดยเฉพาะในทีมที่มีสมาชิกใหม่จำนวนมาก ซึ่งอาจยังไม่เข้าใจบริบทของระบบอย่างลึกซึ้ง ตัวอย่างเช่น สมาชิกใหม่อาจไม่รู้ว่า “การใช้ `die()` ตรงกลางโค้ด” เป็นความผิดพลาดร้ายแรง เพราะทำให้ระบบหยุดทำงานทันทีโดยไม่มีการแจ้งเตือนหรือการกู้คืนที่เหมาะสม ซึ่งอาจส่งผลต่อผู้ใช้จริงได้ทันที
กระบวนการรีวิวที่ดีควรเริ่มตั้งแต่การตั้งค่า Pull Request (PR) อย่างเหมาะสม โดยให้ผู้เขียนโค้ดอธิบายเป้าหมายของฟีเจอร์ ความเปลี่ยนแปลงที่เกิดขึ้น และเหตุผลในการเลือกแนวทางการพัฒนา ซึ่งจะช่วยให้ผู้รีวิวเข้าใจบริบทได้ดีขึ้น หลังจากนั้น ผู้รีวิวควรใช้ checklist ที่มีอยู่เพื่อตรวจสอบทีละข้อ พร้อมทั้งเขียนคอมเมนต์เฉพาะเจาะจง เช่น “ควรใช้ `UserNotFoundException` แทน `NotFoundHttpException` เพื่อให้จัดการข้อผิดพลาดได้เฉพาะเจาะจงยิ่งขึ้น” หรือ “ควรแยกการดึงข้อมูลออกจาก Controller ไปไว้ใน Service เพื่อให้ระบบยืดหยุ่นมากขึ้น”
หลักการสำคัญในการรีวิวโค้ด Symfony คือการยึดมั่นในหลักการสถาปัตยกรรมที่ถูกต้อง ซึ่งได้แก่ SOLID, DRY, และ KISS ทั้งนี้
ควรให้ความสำคัญกับการแยกความรับผิดชอบ (Separation of Concerns) อย่างเคร่งครัด โดยเฉพาะใน Controller ที่ควรทำหน้าที่แค่รับ request และส่ง response เท่านั้น ไม่ควรมีการจัดการข้อมูลหรือ business logic ใดๆ ไว้ภายใน
หลักการสำคัญในการรีวิวโค้ด Symfony
หลักการสำคัญในการรีวิวโค้ด Symfony คือการยึดมั่นในหลักการสถาปัตยกรรมที่ถูกต้อง ซึ่งได้แก่ SOLID, DRY, และ KISS ทั้งนี้ ควรให้ความสำคัญกับการแยกความรับผิดชอบ (Separation of Concerns) อย่างเคร่งครัด โดยเฉพาะใน Controller ที่ควรทำหน้าที่แค่รับ request และส่ง response เท่านั้น ไม่ควรมีการจัดการข้อมูลหรือ business logic ใดๆ ไว้ภายใน
ตัวอย่างที่พบบ่อยคือการเขียนโค้ดที่ดึงข้อมูลจากฐานข้อมูล แล้วแปลงข้อมูลใน Controller โดยตรง ซึ่งเป็นการละเมิดหลักการนี้อย่างร้ายแรง เพราะทำให้ Controller มีความซับซ้อนเกินไป และยากต่อการทดสอบ การแก้ไขคือการย้ายกระบวนการดังกล่าวไปไว้ใน Service หรือ Repository ที่มีหน้าที่เฉพาะเจาะจง ซึ่งจะทำให้โค้ดอ่านง่าย แก้ไขง่าย และสามารถนำกลับมาใช้ใหม่ได้ในที่อื่น
เพื่อให้เข้าใจลึกยิ่งขึ้น ขอยกตัวอย่างโค้ดจริงจากโปรเจกต์ Symfony ที่เคยรีวิวมาในช่วง 6 เดือนที่ผ่านมา ซึ่งเป็นส่วนของ API สำหรับดึงข้อมูลผู้ใช้
โดยมีโค้ดดังนี้:
นอกจากนี้ ควรตรวจสอบการใช้ Exception อย่างเหมาะสม โดยเฉพาะการใช้ Exception ที่เฉพาะเจาะจง เช่น `UserNotFoundException` แทน `NotFoundHttpException` ซึ่งช่วยให้สามารถจัดการข้อผิดพลาดได้อย่างมีประสิทธิภาพในระดับระบบ และไม่ทำให้ผู้ใช้เห็นข้อความผิดพลาดที่ไม่เหมาะสม
ตัวอย่างการรีวิวโค้ดจริงใน Symfony พร้อมคำแนะนำ
เพื่อให้เข้าใจลึกยิ่งขึ้น ขอยกตัวอย่างโค้ดจริงจากโปรเจกต์ Symfony ที่เคยรีวิวมาในช่วง 6 เดือนที่ผ่านมา ซึ่งเป็นส่วนของ API สำหรับดึงข้อมูลผู้ใช้ โดยมีโค้ดดังนี้:
// ใน Controller public function getUser($id) { $em = $this->getDoctrine()->getManager(); $user = $em->getRepository(User::class)->find($id);
if (!$user) { throw new NotFoundHttpException('User not found'); }
return $this->json([ 'id' => $user->getId(), 'name' => $user->getName(), 'email' => $user->getEmail(), 'createdAt' => $user->getCreatedAt()->format('Y-m-d H:i:s') ]); }
การรีวิวโค้ดนี้พบข้อบกพร่องหลายจุด ได้แก่:
การใช้ `EntityManager` โดยตรงใน Controller — ควรย้ายไปไว้ใน Service เพื่อแยกความรับผิดชอบ ซึ่งช่วยให้ Controller ทำหน้าที่แค่รับ request และส่ง response ได้ชัดเจนยิ่งขึ้น การจัดการข้อผิดพลาดด้วย `throw new NotFoundHttpException` — ควรใช้ `throw new UserNotFoundException()` ที่เป็น Exception ที่เฉพาะเจาะจงมากกว่า เพราะช่วยให้สามารถจัดการข้อผิดพลาดได้อย่างมีประสิทธิภาพในระดับระบบ การส่งข้อมูลผู้ใช้โดยตรง — ควรใช้ DTO (Data Transfer Object) เพื่อควบคุมข้อมูลที่ส่งออก และหลีกเลี่ยงการเปิดเผยข้อมูลที่ไม่จำเป็น เช่น password หรือ token การใช้ `json()` โดยตรง — ควรใช้ `ApiResponse` หรือ `JsonResponse` ที่มีการจัดการ header และ status code อย่างเหมาะสม
คำแนะนำหลังรีวิวคือ ให้สร้าง Service ชื่อ `UserService` ที่มี method `getUserById($id)` และใช้ DTO ชื่อ `UserDto` สำหรับการส่งข้อมูล พร้อมทั้งเพิ่มการตรวจสอบสิทธิ์ (Authorization) ว่าผู้ใช้ที่เรียก API นั้นมีสิทธิ์เข้าถึงข้อมูลนี้หรือไม่ ซึ่งจะช่วยเพิ่มความปลอดภัยและยืดหยุ่นของระบบในอนาคตข้างหน้า ทั้งนี้ การรีวิวที่ดีควรไม่เพียงแค่บอกว่า “ผิด” แต่ต้องเสนอแนวทางแก้ไขที่ชัดเจนและนำไปใช้ได้จริง
ตัวอย่างเพิ่มเติม: ในโปรเจกต์หนึ่งที่เคยรีวิว มีการเขียนโค้ดที่ดึงข้อมูลจากฐานข้อมูลหลายชั้นโดยไม่ใช้ Query Builder แต่ใช้ Raw SQL ซึ่งเพิ่มความเสี่ยงต่อ SQL Injection และทำให้ยากต่อการบำรุงรักษา หลังรีวิว ทีมได้เปลี่ยนมาใช้ Query Builder พร้อมเพิ่มการตรวจสอบ input และใช้ Doctrine Events เพื่อควบคุมการอัปเดตข้อมูลอย่างปลอดภัย ผลลัพธ์คือ ระบบมีความเสถียรสูงขึ้น และสามารถขยายฟีเจอร์ใหม่ได้ง่ายขึ้นในอนาคต
ตารางเปรียบเทียบ: โค้ดที่ดี vs โค้ดที่ควรปรับปรุงใน Symfony
| องค์ประกอบ | โค้ดที่ดี (Recommended) | โค้ดที่ควรปรับปรุง (Avoid) |
|---|---|---|
| การจัดการข้อมูล | ใช้ Doctrine Repository + Service | ใช้ EntityManager โดยตรงใน Controller |
| การจัดการข้อผิดพลาด | ใช้ Exception เฉพาะเจาะจง เช่น `UserNotFoundException` | ใช้ `NotFoundHttpException` โดยไม่จำเพาะ |
| การส่งข้อมูล | ใช้ DTO หรือ Serializer | ส่งข้อมูลทั้งหมดโดยตรงจาก Entity |
| การจัดการสิทธิ์ | ตรวจสอบสิทธิ์ใน Middleware หรือ Voter | ไม่มีการตรวจสอบสิทธิ์เลย |
| การจัดการข้อผิดพลาด | ใช้ HTTP Status Code อย่างเหมาะสม (404, 403, 500) | ใช้ `die()` หรือ `exit()` ตรงกลางโค้ด |
การใช้ตารางนี้ในกระบวนการรีวิวช่วยให้ทีมพัฒนา “เห็นภาพ” ได้ชัดเจนขึ้น และสามารถใช้เป็นแนวทางในการฝึกอบรมสมาชิกใหม่ได้ดีมาก ตัวอย่างเช่น ทีมใหม่ที่เพิ่งเข้ามาอาจยังไม่เข้าใจว่า “การใช้ `die()` ตรงกลางโค้ด” เป็นความผิดพลาดร้ายแรง เพราะทำให้ระบบหยุดทำงานทันทีโดยไม่มีการแจ้งเตือนหรือการกู้คืนที่เหมาะสม ซึ่งอาจส่งผลต่อผู้ใช้จริงได้ทันที ตารางนี้จึงเป็นเครื่องมือที่มีประสิทธิภาพในการสร้างความเข้าใจร่วมกันในทีม
คำถามที่พบบ่อย
Q: การรีวิวโค้ดใน Symfony ควรใช้เวลาเท่าใดต่อครั้ง?
การรีวิวโค้ดที่มีคุณภาพต้องใช้เวลาอย่างน้อย 15-30 นาทีต่อ PR (Pull Request) ขึ้นอยู่กับความซับซ้อนของโค้ด อย่างไรก็ตาม ควรหลีกเลี่ยงการรีวิวที่ยาวเกินไปจนเหน็ดเหนื่อย เพราะจะส่งผลต่อคุณภาพการวิเคราะห์ในระยะยาว ควรแบ่งเวลาเป็นช่วงสั้นๆ เช่น 15 นาที แล้วพัก 10 นาที เพื่อให้สมองได้ฟื้นตัว ซึ่งเป็นแนวทางที่ใช้ได้ผลดีในทีมพัฒนาที่มีประสิทธิภาพสูง โดยเฉพาะในโปรเจกต์ที่ต้องรีวิวหลาย PR ต่อวัน ทั้งนี้ ควรตั้งเป้าหมายว่า “รีวิวให้ได้ 1-2 PR ต่อวัน” มากกว่า “รีวิวให้จบในวันเดียว” เพื่อรักษาคุณภาพและความแม่นยำ ทั้งนี้ การรีวิวที่ดีต้องเน้นคุณภาพ ไม่ใช่ปริมาณ เพราะหากรีวิวเร็วเกินไป อาจพลาดข้อผิดพลาดสำคัญ เช่น การไม่ตรวจสอบสิทธิ์ผู้ใช้ หรือการใช้ `die()` ที่ทำให้ระบบล่มทันที ซึ่งอาจส่งผลต่อผู้ใช้จริงได้ทันที
Q: ถ้าทีมไม่มีประสบการณ์ในการรีวิวโค้ด ควรเริ่มต้นอย่างไร?
เริ่มต้นด้วยการสร้าง “แนวทางการรีวิว” ที่เขียนเป็นเอกสารง่ายๆ พร้อมตัวอย่างโค้ดที่ดีและไม่ดี แล้วใช้เป็นแนวทางพื้นฐานในการฝึกอบรมทีม ควรเริ่มจากเรื่องง่ายๆ เช่น การตั้งชื่อตัวแปร การจัดรูปแบบโค้ด และการใช้ Doctrine อย่างถูกต้อง จากนั้นค่อยเพิ่มเรื่องซับซ้อนขึ้น เช่น การใช้ Dependency Injection, การจัดการข้อผิดพลาด หรือการเขียน Unit Test ควรมีการรีวิวแบบ “pair programming” หรือ “code walkthrough” ที่ทีมร่วมกันดูโค้ด พร้อมอธิบายเหตุผล เพื่อสร้างความเข้าใจร่วมกัน ทั้งนี้ ควรให้รางวัลหรือยกย่องทีมที่รีวิวได้ดี เพื่อสร้างวัฒนธรรมที่ดีในทีมพัฒนา ตัวอย่างเช่น ทีมที่รีวิวได้ดีอาจได้รับ “รางวัลโค้ดสะอาดสัปดาห์นี้” หรือ “สิทธิ์เข้าร่วมประชุมวางแผนฟีเจอร์ล่วงหน้า” ซึ่งช่วยเสริมแรงจูงใจให้ทีมมีส่วนร่วมมากขึ้น
Q: ควรรีวิวโค้ดก่อนหรือหลังการ deploy?
การรีวิวโค้ดควรทำ “ก่อน” การ deploy เท่านั้น ไม่ว่าจะเป็นการ deploy ไปยัง environment ใดก็ตาม เพราะหากปล่อยให้โค้ดผ่านไปแล้ว ค่าใช้จ่ายในการแก้ไขจะสูงมาก โดยเฉพาะหากเกิดปัญหาใน Production ซึ่งอาจส่งผลต่อผู้ใช้จริงและทำให้ระบบหยุดทำงานช่วงเวลาสำคัญ ดังนั้น กระบวนการ CI/CD ควรตั้งเงื่อนไขว่า “ต้องมีการรีวิวและอนุมัติจากทีมพัฒนาอย่างน้อย 1 คน ก่อนที่โค้ดจะถูก merge และ deploy ได้” ซึ่งเป็นขั้นตอนที่สำคัญที่สุดในการรักษาความมั่นคงของระบบในระยะยาว ตัวอย่างเช่น ในโปรเจกต์หนึ่งที่เคยเกิดปัญหา โค้ดที่ผิดพลาดถูก deploy ไปยัง Production โดยไม่ผ่านการรีวิว ทำให้ระบบล่มในช่วงเวลาสำคัญ และต้องใช้เวลาหลายชั่วโมงในการกู้คืน ซึ่งส่งผลต่อความเชื่อมั่นของผู้ใช้และทำให้บริษัทสูญเสียรายได้ไปอย่างมาก
แนะนำเพิ่มเติม
🎯 เปิดบัญชี XM Forex → สมัคร
📱 แอป iCafeFX → ดาวน์โหลด
📊 สัญญาณฟรี → รับสัญญาณ
📚 คู่มือเทรด → SiamCafeBook
🤝 สมัคร Partner XM → pipaffiliates.com/c?c=72816&l=th&p=6
แนะนำจากเครือข่าย SiamCafe
คู่มือ Forex ที่เกี่ยวข้อง
แหล่งอ้างอิง
- SiamCafe.net - ชุมชนไอทีไทยตั้งแต่ปี 1997
- iCafeFX.com - ศูนย์วิเคราะห์ Forex และทองคำ