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

Zend Framework 1.x 建立表單 (Zend_Form) 完整實戰:從類定義到視圖渲染

     編輯:PHP 相關知識

Zend_Form 提供強大的表單定義、驗證、過濾、裝飾器渲染功能。本文完整演示:**自動加載配置 → 表單類定義 (元素、驗證器、過濾器、CSRF) → 控制器處理 (POST 驗證、保存) → 視圖渲染**,附最佳實踐與常見坑點。

第一步:自動加載與目錄配置

<?php
// public/index.php 或 Bootstrap.php
require_once 'Zend/Loader/Autoloader.php';
$loader = Zend_Loader_Autoloader::getInstance();
$loader->registerNamespace('Application_'); // 表單類前綴

// include_path 包含 forms 目錄
set_include_path(implode(PATH_SEPARATOR, [
    realpath(APPLICATION_PATH . '/../library'),
    realpath(APPLICATION_PATH . '/forms/'), // 關鍵!
    get_include_path(),
]));
?>

第二步:表單類定義 (application/forms/Guestbook.php)

<?php
class Application_Form_Guestbook extends Zend_Form
{
    public function init()
    {
        $this->setMethod('post')
             ->setAttrib('id', 'guestbook-form')
             ->setAttrib('class', 'form-horizontal');

        // 1. Email 元素
        $this->addElement('text', 'email', [
            'label'      => '您的郵箱:',
            'required'   => true,
            'filters'    => ['StringTrim', 'StringToLower'],
            'validators' => [
                ['EmailAddress', true, ['messages' => ['emailAddressInvalidFormat' => '郵箱格式不正確']]],
                ['StringLength', false, [3, 254, 'messages' => ['stringLengthTooShort' => '郵箱過短']]],
            ],
            'decorators' => $this->getDefaultElementDecorators(), // 統一裝飾器
        ]);

        // 2. 留言內容 (textarea)
        $this->addElement('textarea', 'comment', [
            'label'      => '留言內容:',
            'required'   => true,
            'filters'    => ['StringTrim'],
            'validators' => [
                ['StringLength', true, [1, 500, 'messages' => ['stringLengthTooLong' => '留言不能超過 500 字']]],
            ],
            'attribs'    => ['rows' => 5, 'cols' => 50],
        ]);

        // 3. 驗證碼
        $this->addElement('captcha', 'captcha', [
            'label'      => '請輸入右側驗證碼:',
            'required'   => true,
            'captcha'    => [
                'captcha' => 'Figlet', // 或 'Image' (需 GD)
                'wordLen' => 5,
                'timeout' => 300,
                'font'    => APPLICATION_PATH . '/../data/fonts/figlet.flf', // Figlet 字體
            ],
        ]);

        // 4. 提交按鈕
        $this->addElement('submit', 'submit', [
            'ignore' => true, // 不參與驗證/獲取值
            'label'  => '提交留言',
            'attribs' => ['class' => 'btn btn-primary'],
        ]);

        // 5. CSRF 保護 (隱藏字段)
        $this->addElement('hash', 'csrf', [
            'ignore' => true,
        ]);

        // 統一設置元素裝飾器 (可選,簡化輸出)
        $this->setElementDecorators([
            'ViewHelper',
            'Errors',
            ['Description', ['tag' => 'span', 'class' => 'help-text']],
            ['HtmlTag', ['tag' => 'div', 'class' => 'form-group']],
            ['Label', ['tag' => 'label', 'class' => 'control-label']],
        ]);
        $this->setDecorators([
            'FormElements',
            ['HtmlTag', ['tag' => 'fieldset', 'class' => 'form-fieldset']],
            'Form',
        ]);
    }
}
?>

第三步:控制器處理 (application/controllers/GuestbookController.php)

<?php
class GuestbookController extends Zend_Controller_Action
{
    public function signAction()
    {
        $request = $this->getRequest();
        $form    = new Application_Form_Guestbook();

        if ($request->isPost()) {
            if ($form->isValid($request->getPost())) {
                // 驗證通過,獲取過濾後的數據
                $data = $form->getValues();
                // 保存模型 (示例)
                $comment = new Application_Model_Guestbook($data);
                $mapper  = new Application_Model_GuestbookMapper();
                $mapper->save($comment);

                // 重定向防重複提交 (PRG 模式)
                return $this->_helper->redirector('index');
            }
            // 驗證失敗:表單會自動填回用戶輸入並顯示錯誤信息
        }

        // 分配給視圖
        $this->view->form = $form;
    }
}
?>

第四步:視圖腳本渲染 (application/views/scripts/guestbook/sign.phtml)

<h2>給我們留言</h2>
<?php
// 設置表單提交地址 (當前 URL)
$this->form->setAction($this->url());
// 直接輸出表單 (使用裝飾器渲染)
echo $this->form;
?>

輸出將包含完整 `

`、字段、標籤、錯誤提示、CSRF 隱藏字段、提交按鈕,樣式由裝飾器控制。

進階:自定義裝飾器輸出 Bootstrap 5 風格

<?php
// 在表單類 init() 中
$this->setElementDecorators([
    'ViewHelper',
    'Errors',
    ['Description', ['tag' => 'div', 'class' => 'form-text']],
    ['HtmlTag', ['tag' => 'div', 'class' => 'form-floating mb-3']],
    ['Label', ['tag' => 'label', 'class' => 'form-label']],
]);
// 需配合 HTML 結構調整,建議參考 Zend_Form_Decorator 文檔深度定制
?>

常見坑點與最佳實踐

問題解決
表單不顯示 / 空白視圖中未 `echo $this->form`;或裝飾器配置導致無輸出
驗證器不生效檢查 `required => true`、`validators` 陣列結構;`isValid()` 傳入的數組鍵名需與元素名一致
CSRF 失效確保 Session 已啟動 (`Zend_Session::start()`),`hash` 元素 `ignore => true`
Figlet 驗證碼不顯示需安裝 `php-gd` 並提供 `.flf` 字體文件路徑;或改用 `Image` 驗證碼
文件上傳元素用 `$this->addElement('file', 'avatar', [...])`,控制器中 `$form->getFileInfo('avatar')` 處理

現代化建議

ZF1 已停止維護。新項目建議使用 **Laminas\Form** (ZF 繼承者、PSR-7/15 兼容) 或 **Symfony Form Component**、**Laravel Form Request**,配合 Composer 自動加載,獲得更好生態支持。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved