首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

Agavi MVC 框架實戰 (二-1):表單處理、驗證器與聯絡我們頁面實作

     編輯:PHP 綜合知識

本章目標

  • 建立聯絡表單 Action (Input/Success/Error 三種 View)
  • 使用內建驗證器進行伺服器端驗證
  • 理解 `ContactInputView` 的特殊角色 (首次顯示表單)
  • 路由配置與模板綁定

產生 Action 與 View

./bin/agavi action-wizard
# Module: Default
# Action: Contact
# Views: Input Error Success

產生:`ContactAction`、`ContactInputView`、`ContactErrorView`、`ContactSuccessView` + 對應模板。

路由設定 (app/config/routing.xml)

<route name="contact" pattern="^/contact$" module="Default" action="Contact" />

Action 實作

<?php
// app/modules/Default/actions/ContactAction.class.php
class Default_ContactAction extends AgaviAction
{
    public function execute(AgaviRequestDataHolder $rd)
    {
        // 1. 表單已送出 (POST)
        if ($rd->getParameter('submit')) {
            // 驗證在 validate() 自動執行,若通過這裡即為合法資料
            $data = [
                'name'    => $rd->getParameter('name'),
                'email'   => $rd->getParameter('email'),
                'subject' => $rd->getParameter('subject'),
                'message' => $rd->getParameter('message'),
            ];

            // 2. 業務邏輯:發送郵件、寫入資料庫等
            $this->getContext()->getMailer()->sendContactMail($data);

            // 3. 設定成功訊息
            $this->setAttribute('data', $data);
            return 'Success';
        }

        // 3. 首次 GET 請求 → 顯示空白表單
        return 'Input';
    }

    public function validate(AgaviValidator $validator)
    {
        // 必填
        $validator->addRule('name', new AgaviRequiredValidator());
        $validator->addRule('email', new AgaviRequiredValidator());
        $validator->addRule('subject', new AgaviRequiredValidator());
        $validator->addRule('message', new AgaviRequiredValidator());

        // 格式
        $validator->addRule('email', new AgaviEmailValidator());
        $validator->addRule('name', new AgaviStringValidator(['max_length' => 100]));
        $validator->addRule('subject', new AgaviStringValidator(['max_length' => 150]));
        $validator->addRule('message', new AgaviStringValidator(['min_length' => 10, 'max_length' => 5000]));

        // CSRF 保護 (需在表單加入 csrfToken() ?>)
        $validator->addRule('csrf_token', new AgaviCsrfValidator());
    }

    // 可選:驗證失敗時自訂錯誤處理
    public function handleError($errors)
    {
        // 將錯誤傳給 Error View
        $this->setAttribute('errors', $errors);
        return 'Error';
    }
}

Input View (首次顯示表單)

<?php
// app/modules/Default/views/ContactInputView.class.php
class Default_ContactInputView extends AgaviHtmlView
{
    public function setupHtml()
    {
        $this->setLayout('Master');
    }
}

Input 模板 (含驗證錯誤回顯)

<?php // app/modules/Default/templates/ContactInput.php ?>
<h1>聯絡我們</h1>

<?php if ($t->hasAttribute('errors')): ?>
  <div class="alert alert-danger">
    <ul>
      <?php foreach ($t->getAttribute('errors') as $field => $msgs): ?>
        <?php foreach ($msgs as $msg): ?>
          <li><strong><?= ucfirst($field) ?>:</strong> <?= $msg ?></li>
        <?php endforeach; ?>
      <?php endforeach; ?>
    </ul>
  </div>
<?php endif; ?>

<form method="POST" action="<?= $ro->gen('contact') ?>">
  <input type="hidden" name="csrf_token" value="<?= $ro->csrfToken() ?>">

  <div class="form-group">
    <label>姓名</label>
    <input type="text" name="name" value="<?= $t->getAttribute('name', '') ?>" class="form-control" required>
  </div>

  <div class="form-group">
    <label>Email</label>
    <input type="email" name="email" value="<?= $t->getAttribute('email', '') ?>" class="form-control" required>
  </div>

  <div class="form-group">
    <label>主旨</label>
    <input type="text" name="subject" value="<?= $t->getAttribute('subject', '') ?>" class="form-control" required>
  </div>

  <div class="form-group">
    <label>內容</label>
    <textarea name="message" class="form-control" rows="6" required><?= $t->getAttribute('message', '') ?></textarea>
  </div>

  <button type="submit" name="submit" value="1" class="btn btn-primary">送出</button>
</form>

Success View 範例

<?php // app/modules/Default/templates/ContactSuccess.php ?>
<div class="alert alert-success">
  <h2>感謝您的來信!</h2>
  <p>我們已收到您的訊息,將盡快回覆。</p>
  <dl class="dl-horizontal">
    <dt>姓名</dt><dd><?= $t->getAttribute('data.name') ?></dd>
    <dt>Email</dt><dd><?= $t->getAttribute('data.email') ?></dd>
    <dt>主旨</dt><dd><?= $t->getAttribute('data.subject') ?></dd>
  </dl>
  <p><a href="<?= $ro->gen('default.index') ?>" class="btn btn-link">返回首頁</a></p>
</div>

關鍵概念總結

概念說明
Input View專門處理 **GET 請求顯示空白/預填表單**,驗證失敗時也會導向此 View (透過 `handleError`)。
Error View若 `handleError` 返回 `'Error'`,則渲染 `ContactErrorView`,適合 API 回傳 JSON 錯誤。
驗證器鏈`addRule` 可同一欄位疊加多個驗證器,依序執行,任一失敗即停止並收集錯誤訊息。
CSRF Token`$ro->csrfToken()` 產生並存入 Session,`AgaviCsrfValidator` 自動比對,防止跨站請求偽造。
資料回填`$t->getAttribute('field', '')` 安全輸出用戶輸入,避免 XSS。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved