Kotchasan Framework Documentation

Kotchasan Framework Documentation

Kotchasan\View

TH 06 Feb 2026 06:23

Kotchasan\View

View เป็นคลาสที่รับผิดชอบการจัดการ presentation layer ใน MVC pattern จัดการการสร้าง HTML และการจัดการ template

สารบัญ

  1. ภาพรวม
  2. การติดตั้งและเตรียมความพร้อม
  3. เมธอดหลัก
  4. ตัวอย่างการใช้งาน
  5. Best Practices
  6. ข้อผิดพลาดที่พบบ่อย
  7. คลาสที่เกี่ยวข้อง

ภาพรวม

View class เป็นส่วนประกอบสำคัญของ Kotchasan Framework ที่ทำหน้าที่:

  • Template Management: จัดการ HTML templates และการแทนที่เนื้อหาด้วย regex patterns
  • Asset Management: จัดการ CSS, JavaScript files และ meta tags
  • Content Rendering: สร้าง HTML output ที่สมบูรณ์จาก templates
  • Header Management: ควบคุม HTTP headers และ responses
  • Script Integration: เพิ่ม JavaScript files และ inline scripts

ใช้เมื่อไหร่:

  • เมื่อสร้างหน้า HTML ใน MVC controller
  • เมื่อสร้าง email templates
  • เมื่อสร้าง dynamic content ด้วย template placeholders
  • เมื่อจัดการ page assets (CSS/JS) แบบ programmatic

การติดตั้งและเตรียมความพร้อม

ความต้องการ

  • PHP 7.4 หรือสูงกว่า
  • Kotchasan Framework
  • HTML template files (.html)

การเตรียมพื้นฐาน

use Kotchasan\View;

// สร้าง view instance
$view = View::create();

View class จะตั้งค่าเริ่มต้นใน templates โดยอัตโนมัติ:

  • /{WEBTITLE}/ - ชื่อเว็บไซต์จาก configuration
  • /{WEBDESCRIPTION}/ - คำอธิบายเว็บไซต์จาก configuration
  • /{WEBURL}/ - URL พื้นฐานของเว็บไซต์
  • /{SKIN}/ - path ของ template/skin ปัจจุบัน

เมธอดหลัก

create()

สร้าง View instance ใหม่ (Factory method)

Signature:

public static function create(): static

Returns: View instance

ตัวอย่าง:

$view = View::create();

setContents()

ตั้งค่า content placeholders สำหรับ template replacement

Signature:

public function setContents(array $array): void

Parameters:

  • $array (array) - Key-value pairs โดย keys เป็น patterns (เช่น '/{NAME}/') และ values เป็น strings ที่จะแทนที่

ตัวอย่าง:

$view->setContents([
    '/{TITLE}/' => 'ชื่อหน้า',
    '/{CONTENT}/' => 'เนื้อหาของหน้า',
    '/{COPYRIGHT}/' => '© 2024 เว็บไซต์ของฉัน'
]);

setContentsAfter()

ตั้งค่า content ที่จะถูกแทนที่ AFTER ที่ template ถูก render แล้ว มีประโยชน์สำหรับการแก้ไขขั้นสุดท้าย

Signature:

public function setContentsAfter(array $array): void

Parameters:

  • $array (array) - Key-value pairs สำหรับการแทนที่หลัง rendering

ตัวอย่าง:

$view->setContentsAfter([
    '/{FINAL_SCRIPT}/' => '<script>console.log("Page loaded");</script>'
]);

addCSS()

เพิ่ม CSS file link ใน HTML head

Signature:

public function addCSS(string $url): void

Parameters:

  • $url (string) - URL หรือ path ของ CSS file

ตัวอย่าง:

$view->addCSS('/css/bootstrap.min.css');
$view->addCSS('/css/custom.css');

HTML ที่สร้างขึ้น:

<link rel="stylesheet" href="/css/bootstrap.min.css">
<link rel="stylesheet" href="/css/custom.css">

addJavascript()

เพิ่ม JavaScript file ใน HTML head

Signature:

public function addJavascript(string $url): void

Parameters:

  • $url (string) - URL หรือ path ของ JavaScript file

ตัวอย่าง:

$view->addJavascript('/js/jquery.min.js');
$view->addJavascript('/js/app.js');

HTML ที่สร้างขึ้น:

<script src="/js/jquery.min.js"></script>
<script src="/js/app.js"></script>

addScript()

เพิ่ม inline JavaScript code ที่จะแทรกใน head section

Signature:

public function addScript(string $script): void

Parameters:

  • $script (string) - JavaScript code (ไม่ต้องใส่ <script> tags)

ตัวอย่าง:

$view->addScript('
    $(document).ready(function() {
        console.log("Page ready");
    });
');

HTML ที่สร้างขึ้น:

<script>
    $(document).ready(function() {
        console.log("Page ready");
    });
</script>

setHeaders()

ตั้งค่า HTTP headers สำหรับ response

Signature:

public function setHeaders(array $array): void

Parameters:

  • $array (array) - Key-value pairs ของชื่อ header และค่า

ตัวอย่าง:

$view->setHeaders([
    'Content-Type' => 'text/html; charset=utf-8',
    'X-Frame-Options' => 'DENY',
    'X-Content-Type-Options' => 'nosniff'
]);

setMetas()

เพิ่ม custom meta tags ใน HTML head

Signature:

public function setMetas(array $array): void

Parameters:

  • $array (array) - Key-value pairs โดย values เป็น HTML ของ meta tag ทั้งหมด

ตัวอย่าง:

$view->setMetas([
    'description' => '<meta name="description" content="คำอธิบายเว็บไซต์">',
    'keywords' => '<meta name="keywords" content="คำค้น1, คำค้น2">',
    'og:title' => '<meta property="og:title" content="ชื่อหน้า">'
]);

renderHTML()

Render HTML output สุดท้ายโดยประมวลผล template ด้วย content ที่ตั้งค่าไว้ทั้งหมด

Signature:

public function renderHTML(?string $template = null): string

Parameters:

  • $template (string|null) - Template content หรือ null เพื่อใช้ 'index.html' จาก Template::load()

Returns: string - HTML ที่ render แล้ว

ตัวอย่าง:

// ใช้ template เริ่มต้น (index.html)
$html = $view->renderHTML();

// ใช้ custom template content
$template = '<html><head>{/TITLE/}</head><body>{/CONTENT/}</body></html>';
$html = $view->renderHTML($template);

output()

ส่ง HTTP headers และ output เนื้อหาไปยัง browser

Signature:

public function output(string $content): void

Parameters:

  • $content (string) - เนื้อหาที่จะ output

ตัวอย่าง:

$html = $view->renderHTML();
$view->output($html);

back()

สร้าง URL สำหรับการนำทาง โดยรักษา query string parameters จาก request ปัจจุบัน

Signature:

public static function back(array|string $f): string

Parameters:

  • $f (array|string) - Query string หรือการแก้ไข parameters

Returns: string - URL ที่แก้ไขแล้ว

หมายเหตุ: ต้องการ HTTP request context ที่ active (ต้องมีการ initialize Request object)

ตัวอย่าง:

// ใน controller ที่มี active request
$backUrl = View::back('module=home&action=index');
// Returns: URL ปัจจุบันพร้อม parameters ที่แก้ไข/เพิ่ม

array_value()

ดึงค่าจาก array อย่างปลอดภัยพร้อม default fallback

Signature:

public static function array_value(array $array, string $key, mixed $default = ''): mixed

Parameters:

  • $array (array) - Source array
  • $key (string) - Key ที่ต้องการดึง
  • $default (mixed) - ค่า default ถ้า key ไม่มี (default: '')

Returns: mixed - ค่าที่ได้หรือ default

ตัวอย่าง:

$data = ['name' => 'สมชาย', 'age' => 30];

$name = View::array_value($data, 'name', 'ไม่ระบุ'); // Returns: 'สมชาย'
$city = View::array_value($data, 'city', 'ไม่ทราบ');   // Returns: 'ไม่ทราบ'

object_value()

ดึงค่า property จาก object อย่างปลอดภัยพร้อม default fallback

Signature:

public static function object_value(object $source, string $key, mixed $default = ''): mixed

Parameters:

  • $source (object) - Source object
  • $key (string) - ชื่อ property ที่ต้องการดึง
  • $default (mixed) - ค่า default ถ้า property ไม่มี (default: '')

Returns: mixed - ค่า property หรือ default

ตัวอย่าง:

$user = (object)['name' => 'สมหญิง', 'email' => 'somying@example.com'];

$name = View::object_value($user, 'name', 'ไม่ระบุ');  // Returns: 'สมหญิง'
$phone = View::object_value($user, 'phone', 'ไม่มี');  // Returns: 'ไม่มี'

ตัวอย่างการใช้งาน

1. การ Render หน้าพื้นฐาน

use Kotchasan\View;

class HomeController
{
    public function index()
    {
        // สร้าง view
        $view = View::create();

        // ตั้งค่าเนื้อหาหน้า
        $view->setContents([
            '/{TITLE}/' => 'ยินดีต้อนรับสู่เว็บไซต์ของเรา',
            '/{HEADING}/' => 'ยินดีต้อนรับ!',
            '/{CONTENT}/' => 'นี่คือเนื้อหาของหน้าแรก',
            '/{YEAR}/' => date('Y') + 543  // ปี พ.ศ.
        ]);

        // เพิ่ม CSS
        $view->addCSS('/css/style.css');

        // เพิ่ม JavaScript
        $view->addJavascript('/js/main.js');

        // Render และ output
        $html = $view->renderHTML();
        $view->output($html);
    }
}

2. หน้ารายละเอียดสินค้า

use Kotchasan\View;

class ProductController
{
    public function show($id)
    {
        // ดึงข้อมูลสินค้า
        $product = $this->getProduct($id);

        // สร้าง view
        $view = View::create();

        // ตั้งค่าเนื้อหา
        $view->setContents([
            '/{TITLE}/' => $product->name . ' - ร้านค้าของเรา',
            '/{PRODUCT_NAME}/' => htmlspecialchars($product->name),
            '/{PRODUCT_PRICE}/' => number_format($product->price, 2),
            '/{PRODUCT_DESCRIPTION}/' => nl2br(htmlspecialchars($product->description)),
            '/{PRODUCT_IMAGE}/' => '<img src="'.$product->image.'" alt="'.htmlspecialchars($product->name).'">'
        ]);

        // เพิ่ม assets เฉพาะสินค้า
        $view->addCSS('/css/product.css');
        $view->addJavascript('/js/product-gallery.js');

        // เพิ่ม structured data สำหรับ SEO
        $view->addScript('
            var productData = {
                id: '.$product->id.',
                name: "'.addslashes($product->name).'",
                price: '.$product->price.'
            };
        ');

        return $view->renderHTML();
    }
}

3. หน้าที่ปรับ SEO

$view = View::create();

// ตั้งค่าเนื้อหาหน้า
$view->setContents([
    '/{TITLE}/' => 'สินค้ายอดนิยม 2024 - ดีลสุดคุ้ม',
    '/{CONTENT}/' => $pageContent
]);

// เพิ่ม SEO meta tags ที่ครบถ้วน
$view->setMetas([
    'description' => '<meta name="description" content="ค้นหาสินค้าคุณภาพด้วยดีลสุดพิเศษในปี 2024">',
    'keywords' => '<meta name="keywords" content="สินค้า, ดีล, 2024, ช้อปปิ้ง">',
    'og:title' => '<meta property="og:title" content="สินค้ายอดนิยม 2024">',
    'og:description' => '<meta property="og:description" content="ค้นหาสินค้าคุณภาพ">',
    'og:image' => '<meta property="og:image" content="https://example.com/image.jpg">',
    'og:url' => '<meta property="og:url" content="https://example.com/products">',
    'canonical' => '<link rel="canonical" href="https://example.com/products">'
]);

// เพิ่ม security headers
$view->setHeaders([
    'X-Frame-Options' => 'SAMEORIGIN',
    'X-Content-Type-Options' => 'nosniff',
    'X-XSS-Protection' => '1; mode=block'
]);

$html = $view->renderHTML();

4. Email Template

use Kotchasan\View;

class EmailService
{
    public function sendWelcomeEmail($user)
    {
        $view = View::create();

        // ตั้งค่าเนื้อหา email template
        $view->setContents([
            '/{USER_NAME}/' => htmlspecialchars($user->name),
            '/{USER_EMAIL}/' => htmlspecialchars($user->email),
            '/{ACTIVATION_LINK}/' => $this->generateActivationLink($user),
            '/{WEBSITE_NAME}/' => 'เว็บไซต์ของเรา',
            '/{WEBSITE_URL}/' => 'https://example.com',
            '/{SUPPORT_EMAIL}/' => 'support@example.com'
        ]);

        // โหลด email template
        $template = file_get_contents(ROOT_PATH.'templates/emails/welcome.html');
        $emailHTML = $view->renderHTML($template);

        // ส่งอีเมล
        mail($user->email, 'ยินดีต้อนรับ!', $emailHTML, 'Content-Type: text/html');
    }
}

5. AJAX JSON Response พร้อม HTML

use Kotchasan\View;

class CommentController
{
    public function add()
    {
        try {
            // บันทึกความคิดเห็น
            $comment = $this->saveComment($_POST);

            // สร้าง HTML สำหรับความคิดเห็นใหม่
            $view = View::create();
            $view->setContents([
                '/{COMMENT_ID}/' => $comment->id,
                '/{AUTHOR_NAME}/' => htmlspecialchars($comment->author_name),
                '/{COMMENT_TEXT}/' => nl2br(htmlspecialchars($comment->text)),
                '/{COMMENT_DATE}/' => date('d/m/Y H:i', strtotime($comment->created_at))
            ]);

            $template = file_get_contents(ROOT_PATH.'templates/comment-item.html');
            $commentHTML = $view->renderHTML($template);

            // ส่งกลับเป็น JSON พร้อม HTML
            header('Content-Type: application/json');
            echo json_encode([
                'success' => true,
                'html' => $commentHTML,
                'message' => 'เพิ่มความคิดเห็นสำเร็จ'
            ]);

        } catch (Exception $e) {
            header('Content-Type: application/json', true, 400);
            echo json_encode([
                'success' => false,
                'message' => $e->getMessage()
            ]);
        }
    }
}

Best Practices

1. การจัดระเบียบ Template

// จัดระเบียบ templates ตามวัตถุประสงค์
// templates/
//   ├── layouts/
//   │   ├── main.html
//   │   └── admin.html
//   ├── pages/
//   │   ├── home.html
//   │   └── about.html
//   ├── emails/
//   │   └── welcome.html
//   └── partials/
//       ├── header.html
//       └── footer.html

2. ความปลอดภัย: Escape User Input เสมอ

// ✅ ดี: Escape user input
$view->setContents([
    '/{USER_NAME}/' => htmlspecialchars($userName, ENT_QUOTES, 'UTF-8'),
    '/{SAFE_HTML}/' => $trustedContent // เฉพาะ trusted content เท่านั้น
]);

// ❌ ไม่ดี: ใช้ user input โดยตรง
$view->setContents([
    '/{USER_NAME}/' => $_POST['name'] // ช่องโหว่ XSS!
]);

3. ประสิทธิภาพ: ลด Assets

// ✅ ดี: ใช้ไฟล์ที่รวมและ minify แล้ว
$view->addCSS('/css/combined.min.css');
$view->addJavascript('/js/combined.min.js');

// ❌ ไม่ดี: ไฟล์แยกมากเกินไป
$view->addCSS('/css/bootstrap.css');
$view->addCSS('/css/font-awesome.css');
$view->addCSS('/css/custom.css');
$view->addCSS('/css/responsive.css');
// ... (HTTP requests มากเกินไป)

4. Asset Versioning สำหรับ Cache Busting

$version = '1.2.5'; // อัพเดตเมื่อไฟล์เปลี่ยน
$view->addCSS('/css/app.css?v=' . $version);
$view->addJavascript('/js/app.js?v=' . $version);

5. แยก Concerns

// ✅ ดี: Controller เตรียมข้อมูล, View render
class ProductController
{
    public function show($id)
    {
        // Business logic
        $product = $this->productService->getById($id);
        $relatedProducts = $this->productService->getRelated($id);

        // View rendering
        return $this->renderProductView($product, $relatedProducts);
    }

    private function renderProductView($product, $related)
    {
        $view = View::create();
        // ... set contents
        return $view->renderHTML();
    }
}

// ❌ ไม่ดี: Concerns ปะปน
class ProductController
{
    public function show($id)
    {
        $view = View::create();
        $product = DB::table('products')->find($id); // Business logic ใน view method
        $view->setContents(['/{NAME}/' => $product->name]);
        return $view->renderHTML();
    }
}

ข้อผิดพลาดที่พบบ่อย

❌ ข้อผิดพลาด 1: ไม่ Escape User Input

// ผิด - ช่องโหว่ XSS
$view->setContents([
    '/{COMMENT}/' => $_POST['comment']
]);

// ถูกต้อง
$view->setContents([
    '/{COMMENT}/' => htmlspecialchars($_POST['comment'], ENT_QUOTES, 'UTF-8')
]);

❌ ข้อผิดพลาด 2: รูปแบบ Pattern ผิด

// ผิด - ไม่มี regex delimiters
$view->setContents([
    '{TITLE}' => 'หัวข้อ'  // ใช้งานไม่ได้!
]);

// ถูกต้อง - ใช้รูปแบบ regex pattern
$view->setContents([
    '/{TITLE}/' => 'หัวข้อ'
]);

❌ ข้อผิดพลาด 3: ลืม Render

// ผิด - จะไม่มี output
$view = View::create();
$view->setContents(['/{TITLE}/' => 'ทดสอบ']);
// ขาด: $view->renderHTML()

// ถูกต้อง
$view = View::create();
$view->setContents(['/{TITLE}/' => 'ทดสอบ']);
$html = $view->renderHTML();
$view->output($html);

❌ ข้อผิดพลาด 4: ตั้ง Headers หลัง Output

// ผิด - ต้องตั้ง headers ก่อน output
echo "อะไรบางอย่าง";
$view->setHeaders(['Content-Type' => 'application/json']); // สายเกินไป!

// ถูกต้อง - ตั้ง headers ก่อน
$view = View::create();
$view->setHeaders(['Content-Type' => 'text/html; charset=utf-8']);
$html = $view->renderHTML();
$view->output($html);

คลาสที่เกี่ยวข้อง

  • Template - Template loading และ processing engine
  • Controller - MVC controller base class
  • Database - Database operations สำหรับ dynamic content

หมายเหตุเพิ่มเติม

💡 เคล็ดลับ: View class ใช้การแทนที่แบบ regex Patterns อย่าง /{NAME}/ ถูกแทนที่ด้วย preg_replace() ตรวจสอบให้แน่ใจว่า patterns เป็น regex patterns ที่ถูกต้อง

⚠️ คำเตือน: เมธอด back() ต้องการ HTTP request context ที่ active จะใช้งานไม่ได้ถ้าเรียกนอก web request (เช่น ใน CLI scripts)

ℹ️ หมายเหตุ: CSS และ JavaScript ทั้งหมดที่เพิ่มผ่าน addCSS() และ addJavascript() จะถูกแทรกโดยอัตโนมัติก่อน </head> tag ขณะ renderHTML()