欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Symfony2框架學(xué)習(xí)筆記之表單用法詳解

 更新時(shí)間:2016年03月18日 09:44:22   作者:Seekr  
這篇文章主要介紹了Symfony2框架學(xué)習(xí)筆記之表單用法,結(jié)合實(shí)例形式詳細(xì)分析了Symfony2針對(duì)表單的創(chuàng)建,校驗(yàn),提交等各種常用技巧,需要的朋友可以參考下

本文實(shí)例講述了Symfony2框架表單用法。分享給大家供大家參考,具體如下:

對(duì)于一個(gè)Web開(kāi)發(fā)者來(lái)說(shuō),處理HTML表單是一個(gè)最為普通又具挑戰(zhàn)的任務(wù)。Symfony2集成了一個(gè)Form組件,讓處理表單變的容易起來(lái)。在這一節(jié)里,我們將

從基礎(chǔ)開(kāi)始創(chuàng)建一個(gè)復(fù)雜的表單,學(xué)習(xí)表單類(lèi)庫(kù)中最重要的內(nèi)容。

Symfony2 的Form組件是一個(gè)獨(dú)立的類(lèi)庫(kù),你可以在Symfony2項(xiàng)目之外使用它。

創(chuàng)建一個(gè)簡(jiǎn)單的表單:

假設(shè)你要?jiǎng)?chuàng)建一個(gè)應(yīng)用程序的todo列表,需要顯示一些任務(wù)。因?yàn)槟愕挠脩?hù)需要編輯和創(chuàng)建任務(wù),所以你需要?jiǎng)?chuàng)建一個(gè)表單。在你開(kāi)始之前,首先來(lái)看通用的Task類(lèi),用來(lái)表示和存儲(chǔ)一個(gè)單一任務(wù)的數(shù)據(jù):

// src/Acme/TaskBundle/Entity/Task.php
namespace Acme\TaskBundle\Entity;
class Task
{
  protected $task;
  protected $dueDate;
  public function getTask()
  {
    return $this->task;
  }
  public function setTask($task)
  {
    $this->task = $task;
  }
  public function getDueDate()
  {
    return $this->dueDate;
  }
  public function setDueDate(\DateTime $dueDate = null)
  {
    $this->dueDate = $dueDate;
  }
}

如果你是按照我們提供的示例編碼,那么你需要先創(chuàng)建一個(gè)AcmeTaskBundle:

$ php app/console generate:bundle --namespace=Acme/TaskBundle

該類(lèi)是一個(gè)普通的PHP對(duì)象類(lèi),因?yàn)樗麄儧](méi)有任何Symfony或者其它類(lèi)庫(kù)引用。非常簡(jiǎn)單的一個(gè)PHP對(duì)象類(lèi),它直接解決的是你程序中表現(xiàn)task的數(shù)據(jù)。當(dāng)然,在本節(jié)的最后,你將能夠通過(guò)HTML表單提交一個(gè)Task實(shí)例數(shù)據(jù),校驗(yàn)它的數(shù)值,并把它持久化到數(shù)據(jù)庫(kù)。

創(chuàng)建一個(gè)Form

現(xiàn)在已經(jīng)創(chuàng)建了一個(gè)Task類(lèi),下一步就是創(chuàng)建和渲染一個(gè)真正的HTML表單了。在symfony2中,它是通過(guò)創(chuàng)建一個(gè)表單對(duì)象并渲染到模板的?,F(xiàn)在,可以從controller內(nèi)部處理form。

//src/Acme/TaskBundle/Controller/DefaultController.php
namespace Acme\TaskBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Acme\TaskBundle\Entity\Task;
class DefaultController extends Controller
{
    //創(chuàng)建一個(gè)任務(wù)并給它一些假數(shù)據(jù)作為示例
    $task = new Task();
    $task->setTask('Write a blog post');
    $task->setDueDate(new \DateTime('tomorrow'));
    $form = $this->createFormBuilder($task)
       ->add('task','text')
       ->add('dueDate','date')
       ->getForm();
    return $this->render('AcmeTaskBundle:Default:new.html.twig',array(
        'form' =>$form->createView(),
    ));
}

上面的示例顯示了如何直接在Controller中創(chuàng)建一個(gè)表單,為了可以讓表單重用你完全可以在一個(gè)單獨(dú)的類(lèi)文件中創(chuàng)建表單。

因?yàn)镾ymfony2通過(guò)一個(gè)表單生成器“form builder"來(lái)創(chuàng)建表單對(duì)象,所以你可以使用很少的代碼就能完成創(chuàng)建表單任務(wù)。表單生成器的目的是讓你能編寫(xiě)簡(jiǎn)單的表單創(chuàng)建方法,讓它來(lái)負(fù)責(zé)繁重的創(chuàng)建任務(wù)。

在這個(gè)示例中,你已經(jīng)添加了兩個(gè)字段到你的表單,一個(gè)是task一個(gè)是dueDate。它們關(guān)聯(lián)到Task類(lèi)的task和dueDate屬性。你已經(jīng)為它們分別指定了類(lèi)型(比如,text,date等),由這些類(lèi)型來(lái)決定為這些字段生成什么樣的HTML表單標(biāo)簽。

Symfony2 擁有許多內(nèi)建的類(lèi)型,接下來(lái)我們將簡(jiǎn)單的介紹。

渲染一個(gè)表單

表單創(chuàng)建以后,下一步就是渲染它。這是通過(guò)傳遞一個(gè)特定的表單”view"對(duì)象(就是上例中的 $form->createView()返回的view對(duì)象)到你的模板并通過(guò)一些列的表單幫助函數(shù)來(lái)實(shí)現(xiàn)的。

Twig格式:

{# src/Acme/TaskBundle/Resources/views/Default/new.html.twig #}
<form action="{{ path('task_new') }}" method ="post" {{ form_enctype(form) }}>
  {{ form_widget(form) }}
   <input type="submit" />
</form>

PHP代碼格式:

<!-- src/Acme/TaskBundle/Resources/views/Default/new.html.php -->
<form action="<?php echo $view['router']->generate('task_new') ?>" method="post" <?php echo $view['form']->enctype($form) ?> >
   <?php echo $view['form']->widget($form) ?>
   <input type="submit" />
</form>

在這里假設(shè)你已經(jīng)創(chuàng)建了一個(gè)名叫task_new的路由指向AcmeTaskBundle:Default:new Controller。

就是這些了,通過(guò)打印form_widget(form),表單中的每個(gè)字段都會(huì)被渲染出來(lái)。同時(shí)還有一個(gè)文本標(biāo)簽和錯(cuò)誤信息。是不是很簡(jiǎn)單,不過(guò)現(xiàn)在它還不夠靈活。通常情況下,我們渴望單獨(dú)渲染表單中的每一個(gè)字段,這樣我們可以更好的控制表單的樣式。我們會(huì)在在模板中渲染表單一節(jié)介紹。

在繼續(xù)下去之前,我們注意到,為什么我們渲染出來(lái)的task輸入框中有一個(gè)來(lái)自$task對(duì)象的屬性值“Write a blog post"。這是表單的第一個(gè)工作:從一個(gè)對(duì)象中獲取數(shù)據(jù)并把它轉(zhuǎn)換為合適的格式渲染到一個(gè)HTML表單中。

注意,表單系統(tǒng)已經(jīng)足夠聰明,它們能夠通過(guò)像getTask()和setTask()方法來(lái)訪問(wèn)Task類(lèi)中受保護(hù)的屬性task。除非一個(gè)是公共屬性,否則必須有一個(gè)getter和setter方法被定義來(lái)用于表單組件從這些屬性中獲取和保持?jǐn)?shù)據(jù)。對(duì)于布爾型的屬性,你可以使用一個(gè)”isser"方法(比如 isPublished())替代getter方法(getPublished())。

處理表單提交

表單系統(tǒng)的第二個(gè)任務(wù)就是傳遞用戶(hù)提交的數(shù)據(jù)回到一個(gè)對(duì)象的屬性中。要做到這一點(diǎn),用戶(hù)提交的數(shù)據(jù)必須綁定到表單才行。添加如下代碼到你的Controller類(lèi):

//...
public function newAction(Request $request)
{
     //只是創(chuàng)建一個(gè)新的$task對(duì)象(不需要假數(shù)據(jù))
    $task = new Task();
    $form= $this->createFormBuilder($task)
       ->add('task','text')
       ->add('dueDate','date')
       ->getForm();
    if($request->getMethod() == "POST"){
       $form->bindRequest($request);
       if($form->isValid()){
           //執(zhí)行一些行為,比如保持task到數(shù)據(jù)庫(kù)
           return $this->redirect($this->generateUrl('task_success'));
       }
    }
    //...
}

現(xiàn)在,當(dāng)表單被提交時(shí),Controller可以綁定被提交的數(shù)據(jù)到表單,表單會(huì)把數(shù)據(jù)傳回$task對(duì)象的task和dueDate屬性。這些都在bindRequest()方法中完成。只要bindRequest()方法被調(diào)用,提交的數(shù)據(jù)就會(huì)立刻被傳輸?shù)降讓訉?duì)象。不管數(shù)據(jù)是否被真正的校驗(yàn)通過(guò)。

controller一般會(huì)遵循一個(gè)通用的模式來(lái)處理表單,它有三個(gè)可能的途徑:

1.當(dāng)在瀏覽器初始加載一個(gè)頁(yè)面時(shí),請(qǐng)求方法是GET,表單處理僅僅是創(chuàng)建和渲染。

2.當(dāng)用戶(hù)提交帶有不合法數(shù)據(jù)的表單(方法為POST)時(shí),表單會(huì)并綁定然后渲染,這時(shí)候顯示所有校驗(yàn)錯(cuò)誤。

3.當(dāng)用戶(hù)提交的表單帶有的數(shù)據(jù)均合法時(shí),表單綁定并且在頁(yè)面跳轉(zhuǎn)之前你有機(jī)會(huì)去使用數(shù)據(jù)去執(zhí)行一些業(yè)務(wù)邏輯活動(dòng),比如持久化它到數(shù)據(jù)庫(kù))。

表單校驗(yàn)

在前面我們提到了,如何提交一個(gè)帶有合法數(shù)據(jù)和非法數(shù)據(jù)的表單。在Symfony2中,校驗(yàn)是在底層對(duì)象上進(jìn)行的。換句話說(shuō),form表單合法與否不重要,主要看在表單提交數(shù)據(jù)以后,底層對(duì)象比如$task對(duì)象是否合法。調(diào)用$form->isvalid() 是一個(gè)詢(xún)問(wèn)底層對(duì)象是否獲得合法數(shù)據(jù)的快捷方式。

校驗(yàn)是通過(guò)添加一些列規(guī)則(約束)到一個(gè)類(lèi)來(lái)完成的。我們給Task類(lèi)添加規(guī)則和約束,使它的task屬性不能為空,duDate字段不能空并且是一個(gè)合法的DateTime對(duì)象。

YAML格式:

# Acme/TaskBundle/Resources/config/validation.yml
Acme\TaskBundle\Entity\Task:
  properties:
    task:
      - NotBlank: ~
    dueDate:
      - NotBlank: ~
      - Type: \DateTime

在Task類(lèi)中聲明格式:

// Acme/TaskBundle/Entity/Task.php
use Symfony\Component\Validator\Constraints as Assert;
class Task
{
  /**
   * @Assert\NotBlank()
   */
  public $task;
  /**
   * @Assert\NotBlank()
   * @Assert\Type("\DateTime")
   */
  protected $dueDate;
}

XML格式:

<!-- Acme/TaskBundle/Resources/config/validation.xml -->
<class name="Acme\TaskBundle\Entity\Task">
  <property name="task">
    <constraint name="NotBlank" />
  </property>
  <property name="dueDate">
    <constraint name="NotBlank" />
    <constraint name="Type">
      <value>\DateTime</value>
    </constraint>
  </property>
</class>

PHP代碼格式:

// Acme/TaskBundle/Entity/Task.php
use Symfony\Component\Validator\Mapping\ClassMetadata;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\Constraints\Type;
class Task
{
  // ...
  public static function loadValidatorMetadata(ClassMetadata $metadata)
  {
    $metadata->addPropertyConstraint('task', new NotBlank());
    $metadata->addPropertyConstraint('dueDate', new NotBlank());
    $metadata->addPropertyConstraint('dueDate', new Type('\DateTime'));
  }
}

就是這樣了,如果你現(xiàn)在再提交包含非法數(shù)據(jù)的表單,你將會(huì)看到相應(yīng)的錯(cuò)誤被打印在表單上。

HTML5 校驗(yàn)

作為HTML5,許多瀏覽器都加強(qiáng)了客戶(hù)端某些校驗(yàn)約束。最常用的校驗(yàn)活動(dòng)是在一個(gè)必須的字段上渲染一個(gè)required屬性。對(duì)于支持HTML5的瀏覽器來(lái)說(shuō),如果用戶(hù)此時(shí)提交一個(gè)空字段到表單時(shí),瀏覽器會(huì)顯示提示信息。生成的表單廣泛吸收了這些新內(nèi)容的優(yōu)點(diǎn),通過(guò)添加一些HTML屬性來(lái)監(jiān)控校驗(yàn)。客戶(hù)端校驗(yàn)可以通過(guò)添加novalidate屬性到form標(biāo)簽或者formnovalidate 到提交標(biāo)簽而關(guān)閉。這對(duì)你想檢查服務(wù)端校驗(yàn)規(guī)則時(shí)非常有用。

校驗(yàn)分組

如果你的對(duì)象想從校驗(yàn)組中受益,你需要指定你的表單使用哪個(gè)校驗(yàn)組。

$form = $this->createFormBuilder($users, array(
  'validation_groups' => array('registration'),
))->add(...)
;

如果你創(chuàng)建表單類(lèi),你需要添加羨慕的getDefaultOptions()方法:

public function getDefaultOptions(array $options)
{
  return array(
    'validation_groups' => array('registration')
  );
}

在這兩種情況下,只有registration 校驗(yàn)組將被用于校驗(yàn)底層對(duì)象。

內(nèi)建字段類(lèi)型

Symfony標(biāo)準(zhǔn)版含有大量的字段類(lèi)型,它們幾乎涵蓋了所有通用表單的字段和數(shù)據(jù)類(lèi)型。

文本字段:
text
textarea
email
integer
money
number
password
percent
search
url

選擇字段:
choice
entity
country
language
locale
timezone

日期和時(shí)間字段:
date
datetime
time
birthday

其它字段:
checkbox
file
radio

字段組:
collection
repeated

隱藏字段:
hidden
csrf

基礎(chǔ)字段:
field
form

當(dāng)然,你也可以定義自己的字段類(lèi)型。

字段類(lèi)型選項(xiàng)

每一個(gè)字段類(lèi)型都有一定數(shù)量的選項(xiàng)用于配置。比如,dueDate字段當(dāng)前被渲染成3個(gè)選擇框。而日期字段可以被配置渲染成一個(gè)單一的文本框,用戶(hù)可以輸入字符串作為日期。

->add('dueData','data', array('widget' = 'single_text'))

required選項(xiàng):

最常用到的選項(xiàng)是required選項(xiàng),它可以應(yīng)用于任何字段。默認(rèn)情況下它被設(shè)置為true。這就意味著支持HTML5的瀏覽器會(huì)使用客戶(hù)端校驗(yàn)來(lái)判斷字段是否為空。如果你不想讓它發(fā)生,或者把在你的字段上把required選項(xiàng)設(shè)置為false,或者關(guān)閉HTML5校驗(yàn)。設(shè)置required為true并不意味著服務(wù)端校驗(yàn)被應(yīng)用。換句話說(shuō),如果用戶(hù)提交一個(gè)空數(shù)值到該字段,它將接受這個(gè)控制除非你使用Symfony的NotBlank或者NotNull校驗(yàn)約束。也就是說(shuō),required選項(xiàng)是很好,但是服務(wù)端校驗(yàn)還是要繼續(xù)用。

label選項(xiàng):

表單字段可以使用label選項(xiàng)設(shè)置顯示字符標(biāo)簽,可以應(yīng)用于任何字段:

->add('dueDate', 'date',array(
  'widget' =>'single_text',
  'label' => 'Due Date',
))

字段類(lèi)型猜測(cè):

現(xiàn)在你已經(jīng)添加了校驗(yàn)元數(shù)據(jù)到Task類(lèi),Symfony早已經(jīng)了解一點(diǎn)關(guān)于你的字段了。如果你允許,Symfony可以猜到你的字段數(shù)據(jù)類(lèi)型并為你設(shè)置它。在下面的例子中,Symfony可以根據(jù)校驗(yàn)規(guī)則猜測(cè)到task字段是一個(gè)標(biāo)準(zhǔn)的text字段,dueDate是date字段。

public function newAction()
{
  $task = new Task();
  $form = $this->createFormBuilder($task)
    ->add('task')
    ->add('dueDate', null, array('widget' => 'single_text'))
    ->getForm();
}

當(dāng)你省略了add方法的第二個(gè)參數(shù)(或者你輸入null)時(shí),Symfony的猜測(cè)能力就起作用了。如果你輸入一個(gè)選項(xiàng)數(shù)組作為第三個(gè)參數(shù)(比如上面的dueDate),那么這些選項(xiàng)會(huì)成為Symfony猜測(cè)的依據(jù)。如果你的表單使用了指定的校驗(yàn)數(shù)組,字段類(lèi)型猜測(cè)器將還是要考慮所有的校驗(yàn)規(guī)則來(lái)綜合猜測(cè)你的字段類(lèi)型。

字段類(lèi)型可選項(xiàng)猜測(cè)

除了猜測(cè)字段類(lèi)型,Symfony還能是這猜測(cè)一些可選項(xiàng)字段值。當(dāng)這些可選項(xiàng)被設(shè)置時(shí),字段將會(huì)被渲染到特定HTML屬性中,讓HTML5客戶(hù)端來(lái)提供校驗(yàn)。

然而,它們不會(huì)在服務(wù)端生成相應(yīng)的校驗(yàn)規(guī)則。盡管你需要手動(dòng)的在服務(wù)端添加這些規(guī)則,但是這些字段類(lèi)型選項(xiàng)還是能根據(jù)這些信息猜測(cè)到。

required: required規(guī)則可以在校驗(yàn)規(guī)則或者Doctrine元數(shù)據(jù)的基礎(chǔ)上猜測(cè)到。這當(dāng)你的客戶(hù)端校驗(yàn)將自動(dòng)匹配你的校驗(yàn)規(guī)則時(shí)很有用。
max_length: 如果字段是一些列文本字段,那么max_length選項(xiàng)可以從校驗(yàn)規(guī)則或者Doctrine元數(shù)據(jù)中猜到。
如果你喜歡改變一個(gè)猜到的數(shù)值,你可以通過(guò)在可選項(xiàng)數(shù)組中傳遞該選項(xiàng)來(lái)重寫(xiě)它。

->add('task',null, array('max_length'=>4))

在模板中渲染表單

到目前為止,我們已經(jīng)看了一個(gè)完整的表單是如何通過(guò)一行代碼被渲染的。當(dāng)然,你通常需要更加靈活的渲染方式:

Twig格式:

{# src/Acme/TaskBundle/Resources/views/Default/new.html.twig #}
<form action="{{ path('task_new') }}" method="post" {{ form_enctype(form) }}>
  {{ form_errors(form) }}
  {{ form_row(form.task) }}
  {{ form_row(form.dueDate) }}
  {{ form_rest(form) }}
  <input type="submit" />
</form>

PHP代碼格式:

<!-- // src/Acme/TaskBundle/Resources/views/Default/newAction.html.php -->
<form action="<?php echo $view['router']->generate('task_new') ?>" method="post" <?php echo $view['form']->enctype($form) ?>>
  <?php echo $view['form']->errors($form) ?>
  <?php echo $view['form']->row($form['task']) ?>
  <?php echo $view['form']->row($form['dueDate']) ?>
  <?php echo $view['form']->rest($form) ?>
  <input type="submit" />
</form>

讓我們看看這組代碼的詳細(xì):

form_enctype(form) 只要有一個(gè)字段是文件上傳,那么它就會(huì)義務(wù)的設(shè)置為 enctype="multipart/form-data";
form_errors(form) 渲染任何整個(gè)form的任何錯(cuò)誤信息(特定字段的錯(cuò)誤,會(huì)顯示在每個(gè)字段的下面一行)。
form_row(form.dueDate) 默認(rèn)情況下,為給定的字段在一個(gè)div中渲染一個(gè)文本標(biāo)簽,任何錯(cuò)誤,和HTML表單部件。
form_rest(form) 渲染沒(méi)有指出的其余任何字段,通常在表單的末尾調(diào)用它防止遺忘或者渲染一些你不愿意手動(dòng)設(shè)置的隱藏字段。它同時(shí)還能為我們提供CSRF保護(hù)。

大部分工作是由form_row幫助方法類(lèi)完成的,它默認(rèn)在一個(gè)div中為每個(gè)字段渲染顯示標(biāo)簽,錯(cuò)誤信息和HTML表單部件。

注意,你可以通過(guò)form.vars.value 來(lái)訪問(wèn)你當(dāng)前是表當(dāng)數(shù)據(jù):

Twig格式:

{{ form.vars.value.task }}

PHP代碼格式:

<?php echo $view['form']->get('value')->getTask() ?>

手工渲染每一個(gè)表單字段

form_row幫助器能讓你很快的渲染你表單中的每一個(gè)字段,并且每一行可以被自定義化。但是生活不總是那么簡(jiǎn)單的,你也可能要手動(dòng)的渲染每一個(gè)字段。

Twig格式:

{{ form_errors(form) }}
<div>
  {{ form_label(form.task) }}
  {{ form_errors(form.task) }}
  {{ form_widget(form.task) }}
</div>
<div>
  {{ form_label(form.dueDate) }}
  {{ form_errors(form.dueDate) }}
  {{ form_widget(form.dueDate) }}
</div>
{{ form_rest(form) }}

PHP代碼格式:

<?php echo $view['form']->errors($form) ?>
<div>
  <?php echo $view['form']->label($form['task']) ?>
  <?php echo $view['form']->errors($form['task']) ?>
  <?php echo $view['form']->widget($form['task']) ?>
</div>
<div>
  <?php echo $view['form']->label($form['dueDate']) ?>
  <?php echo $view['form']->errors($form['dueDate']) ?>
  <?php echo $view['form']->widget($form['dueDate']) ?>
</div>
<?php echo $view['form']->rest($form) ?>

如果自動(dòng)生成顯示標(biāo)簽不準(zhǔn)確,那么你可以顯式的指定它:

Twig格式:

{{ form_label(form.task, 'Task Description') }}

PHP代碼格式:

<?php echo $view['form']->label($form['task'], 'Task Description') ?>

一些字段類(lèi)型有一些額外的渲染選項(xiàng)可以傳入widget,一個(gè)常用的選項(xiàng)為attr,它允許你修改表單元素的屬性。下面的示例將添加task_field class到渲染的文本輸入字段:

Twig格式:

{{ form_widget(form.task, {'attr': {'class':'task_field'} }) }}

PHP代碼格式:

<?php echo $view['form']->widget($form['task'], array(
'attr' => array('class' => 'task_field'),
)) ?>

如果你想手工渲染表單字段,你可以單獨(dú)訪問(wèn)每個(gè)字段的值,比如id,name和label,這里我們獲取id

Twig格式:

{{ form.task.vars.id }}

PHP代碼格式:

<?php echo $form['task']->get('id') ?>

需要獲取表單字段名稱(chēng)屬性你需要使用full_name值:

Twig格式:

{{ form.task.vars.full_name }}

PHP代碼格式:

<?php echo $form['task']->get('full_name') ?>

創(chuàng)建表單類(lèi)

正如你看到的,一個(gè)表單可以直接在controller類(lèi)中被創(chuàng)建和使用。然而,一個(gè)更好的做法是在一個(gè)單獨(dú)的PHP類(lèi)中創(chuàng)建表單。它可以被重用到你應(yīng)用程序的任何地方。創(chuàng)建一個(gè)新類(lèi)來(lái)保存生成task表單的邏輯:

// src/Acme/TaskBundle/Form/Type/TaskType.php
namespace Acme\TaskBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilder;
class TaskType extends AbstractType
{
  public function buildForm(FormBuilder $builder, array $options)
  {
    $builder->add('task');
    $builder->add('dueDate', null, array('widget' => 'single_text'));
  }
  public function getName()
  {
    return 'task';
  }
}

這個(gè)新類(lèi)包含了所有創(chuàng)建一個(gè)task表單所需要的內(nèi)容,注意getName()方法將返回一個(gè)該表單類(lèi)型的唯一標(biāo)識(shí),用于快速創(chuàng)建該表單。

// src/Acme/TaskBundle/Controller/DefaultController.php
// 在類(lèi)上添加這個(gè)新的引用語(yǔ)句
use Acme\TaskBundle\Form\Type\TaskType;
public function newAction()
{
    $task = // ...
    $form = $this->createForm(new TaskType(), $task);
    // ...
}

設(shè)置data_class

每個(gè)表單都需要知道它底層保存數(shù)據(jù)的類(lèi)名稱(chēng),(比如Acme\TaskBundle\Entity\Task)。通常情況下,是根據(jù)createForm方法的第二個(gè)參數(shù)來(lái)猜測(cè)的。以后,當(dāng)你開(kāi)始嵌入表單時(shí),這個(gè)可能就不怎么充分了,所以,通常一個(gè)好的方法是通過(guò)添加下面代碼到你的表單類(lèi)型類(lèi)來(lái)顯式的指定data_class 選項(xiàng)。

public function getDefaultOptions(array $options)
{
   return array(
        'data_class' => 'Acme\TaskBundle\Entity\Task',
   );
}

當(dāng)然,這種做法也不總是必須的。

當(dāng)你映射表單到一個(gè)對(duì)象是,所有的字段都被映射。 表單的任何字段如果在映射的對(duì)象上不存在那么就會(huì)造成拋出異常。在這種情況下,你需要在表單中獲取字段(比如,一個(gè)“你同意這些說(shuō)法嗎?”復(fù)選框)將不能映射到底層對(duì)象,那么你需要設(shè)置property_path為false以避免拋出異常。

public function buildForm(FormBuilder $builder, array $options)
{
     $builder->add('task');
     $builder->add('dueDate', null, array('property_path' => false));
}

另外,如果有任何的表單字段沒(méi)有被包含著提交的數(shù)據(jù)中,那么這些字段需要顯式的設(shè)置為null。

在controller類(lèi)中我們可以訪問(wèn)字段數(shù)據(jù):

$form->get('dueDate')->getData();

Forms和Doctrine

表單的目的是把數(shù)據(jù)從一個(gè)底層對(duì)象傳遞給一個(gè)HTML表單然后把用戶(hù)提交的數(shù)據(jù)傳回到原先的底層對(duì)象。因此,底層對(duì)象把數(shù)據(jù)持久化到數(shù)據(jù)庫(kù)就跟表單沒(méi)有任何的關(guān)系了。但是,如果你已經(jīng)配置了底層類(lèi)是通過(guò)Doctrine來(lái)持久化,(你已經(jīng)定義了映射元數(shù)據(jù)在底層類(lèi)),接下來(lái)當(dāng)表單提交數(shù)據(jù)后,當(dāng)表單合法后就可以持久化它了。

if ($form->isValid()) {
  $em = $this->getDoctrine()->getEntityManager();
  $em->persist($task);
  $em->flush();
  return $this->redirect($this->generateUrl('task_success'));
}

如果處于某種原因,你不想訪問(wèn)原有的$task對(duì)象,你可以從表單中直接獲取數(shù)據(jù):

$task = $form->getData();

在這里,關(guān)鍵要理解當(dāng)表單跟底層對(duì)象綁定后,用戶(hù)提交的數(shù)據(jù)會(huì)立刻傳遞給底層對(duì)象。如果你想持久化這些數(shù)據(jù),你只需要持久化對(duì)象本身即可。

嵌入式表單:(Embedded Forms)

通常,你可能想生成一個(gè)表單,它包含來(lái)自不同對(duì)象的字段。比如,一個(gè)注冊(cè)表單可能包含屬于User對(duì)象和Address對(duì)象的字段。幸運(yùn)的是,這些對(duì)于form組件來(lái)說(shuō)都是很容易很自然的事。嵌入一個(gè)單獨(dú)對(duì)象:假設(shè)每個(gè)Task屬于一個(gè)Category對(duì)象,首先創(chuàng)建這個(gè)Category對(duì)象:

// src/Acme/TaskBundle/Entity/Category.php
namespace Acme\TaskBundle\Entity;
use Symfony\Component\Validator\Constraints as Assert;
class Category
{
  /**
   * @Assert\NotBlank()
   */
  public $name;
}

接下來(lái),添加一個(gè)新的category屬性到Task類(lèi):

// ...
class Task
{
  // ...
  /**
   * @Assert\Type(type="Acme\TaskBundle\Entity\Category")
   */
  protected $category;
  // ...
  public function getCategory()
  {
    return $this->category;
  }
  public function setCategory(Category $category = null)
  {
    $this->category = $category;
  }
}

現(xiàn)在我們來(lái)相應(yīng)我們應(yīng)用程序的一個(gè)新需求,需要?jiǎng)?chuàng)建一個(gè) 表單可以讓用戶(hù)修改Category對(duì)象。

// src/Acme/TaskBundle/Form/Type/CategoryType.php
namespace Acme\TaskBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilder;
class CategoryType extends AbstractType
{
  public function buildForm(FormBuilder $builder, array $options)
  {
    $builder->add('name');
  }
  public function getDefaultOptions(array $options)
  {
    return array(
      'data_class' => 'Acme\TaskBundle\Entity\Category',
    );
  }
  public function getName()
  {
    return 'category';
  }
}

我們的最終目的是能夠讓用戶(hù)在Task表單中修改Category對(duì)象,所以,我們需要添加一個(gè)類(lèi)型為CategoryType表單類(lèi)的category字段到TaskType 表單類(lèi)。

public function buildForm(FormBuilder $builder, array $options)
{
  // ...
  $builder->add('category', new CategoryType());
}

這時(shí)我們可以在TaskType類(lèi)字段渲染的旁邊渲染CategoryType類(lèi)的字段了:
Twig格式:

{# ... #}
<h3>Category</h3>
<div class="category">
  {{ form_row(form.category.name) }}
</div>
{{ form_rest(form) }}
{# ... #}

PHP代碼格式:

<!-- ... -->
<h3>Category</h3>
<div class="category">
  <?php echo $view['form']->row($form['category']['name']) ?>
</div>
<?php echo $view['form']->rest($form) ?>
<!-- ... -->

當(dāng)用戶(hù)提交表單時(shí),提交的Category字段數(shù)據(jù)被用于創(chuàng)建一個(gè)Category實(shí)例,然后被設(shè)置到Task實(shí)例的category字段。該Category實(shí)例可以通過(guò)Task實(shí)例來(lái)訪問(wèn),同時(shí)也能被持久化到數(shù)據(jù)或者用作它用。

$task->getCategory()

嵌入一個(gè)表單集合

你也可以將一個(gè)表單集合嵌入到一個(gè)表單(想象一個(gè)Category 表單和許多Product子表單)。它是通過(guò)一個(gè)字段類(lèi)型集合類(lèi)實(shí)現(xiàn)的。

表單主題化

表單的每一部分渲染都是可以被自定義個(gè)性化的。你可以自由的改變每一個(gè)表單行的渲染,改變渲染錯(cuò)誤的標(biāo)志,更或者是textarea標(biāo)簽應(yīng)該怎樣顯示等。沒(méi)有任何限制,不同的個(gè)性化設(shè)置能用到不同的區(qū)域。

Symfony使用模板渲染每一個(gè)或者部分表單,比如label標(biāo)簽,input標(biāo)簽,錯(cuò)誤信息以及任何其它內(nèi)容。在Twig中,每個(gè)表單片段會(huì)被一個(gè)Twig block來(lái)渲染。要個(gè)性化渲染表單,你只需要重寫(xiě)相應(yīng)的block即可。在PHP模板中,它是通過(guò)單獨(dú)的模板文件來(lái)渲染表單片段的,所以你需要通過(guò)編寫(xiě)新的模板來(lái)替代舊的模板即可。在理解了它們是怎么工作的之后,讓我們來(lái)個(gè)性化form_row片段并添加一個(gè)class屬性到包裹每一表單行的div元素。首先創(chuàng)建一個(gè)新模板文件用于存放新的標(biāo)志:

Twig格式:

{# src/Acme/TaskBundle/Resources/views/Form/fields.html.twig #}
{% block field_row %}
{% spaceless %}
  <div class="form_row">
    {{ form_label(form) }}
    {{ form_errors(form) }}
    {{ form_widget(form) }}
  </div>
{% endspaceless %}
{% endblock field_row %}

PHP代碼格式:

<!-- src/Acme/TaskBundle/Resources/views/Form/field_row.html.php -->
<div class="form_row">
  <?php echo $view['form']->label($form, $label) ?>
  <?php echo $view['form']->errors($form) ?>
  <?php echo $view['form']->widget($form, $parameters) ?>
</div>

field_row表單片段會(huì)在通過(guò)form_row函數(shù)渲染大部分的表單字段時(shí)使用。 要告訴你的表單組件使用你的新的field_row片段,需要添加下面的內(nèi)容到你渲染該表單的模板頂部:

Twig格式:

{# src/Acme/TaskBundle/Resources/views/Default/new.html.twig #}
{% form_theme form 'AcmeTaskBundle:Form:fields.html.twig' %}
{% form_theme form 'AcmeTaskBundle:Form:fields.html.twig' 'AcmeTaskBundle:Form:fields2.html.twig' %}
<form ...>

PHP代碼格式:

<!-- src/Acme/TaskBundle/Resources/views/Default/new.html.php -->
<?php $view['form']->setTheme($form, array('AcmeTaskBundle:Form')) ?>
<?php $view['form']->setTheme($form, array('AcmeTaskBundle:Form', 'AcmeTaskBundle:Form')) ?>
<form ...>

其中的form_theme 標(biāo)簽導(dǎo)入前面定義的片段。換句話說(shuō),當(dāng)form_row函數(shù)在模板中被調(diào)用后,它將從你的自定義主題中使用field_row 塊(替代Symfony已有的field_row block)。你的個(gè)性化主題不必重寫(xiě)所有的塊。當(dāng)渲染一個(gè)你沒(méi)有重寫(xiě)過(guò)的塊時(shí),主題引起會(huì)找全局的主題(定義在bundle級(jí)的主題)使用。

在擁有多個(gè)個(gè)性化主題的情況下,它會(huì)在使用全局主題之前查找定制列表。要個(gè)性化你表單的任何部分,你只需要重寫(xiě)相關(guān)的片段即可。

表單片段命名

在symfony中,表單的每一部分都會(huì)被渲染,HTML表單元素,錯(cuò)誤消息,顯示標(biāo)簽等這些都是被定義在基礎(chǔ)主題里的。它組成了一個(gè)Twig的塊集合和一個(gè)PHP模板集合。

在Twig中,每個(gè)需要的塊都被定義到一個(gè)單獨(dú)的模板文件中(form_dive_layout.html.twig),它們被保存在Twig Bridge里。在這個(gè)文件中,你可以看到渲染一個(gè)表單多需要的每一個(gè)block和默認(rèn)的字段類(lèi)型。

在PHP模板中,片段是單獨(dú)的模板文件。 默認(rèn)情況下它們位于框架bundle的Resources/views/Form 目錄下。每個(gè)偏度名稱(chēng)都遵循相同的基本模式,用一個(gè)下劃線(_)分為兩部分,比如:

field_row 用于form_row渲染大部分的字段
textarea_widget 用于form_widget渲染一個(gè)textarea字段類(lèi)型
field_errors 用于form_errors渲染一個(gè)字段的錯(cuò)誤信息

每個(gè)片段都命名都遵循:type_part 模式。type部分對(duì)應(yīng)被渲染的字段類(lèi)型(比如textarea,checkbox,date等),而part部分對(duì)應(yīng)著是什么被渲染(比如label,widget,errors等)

默認(rèn)情況下,有4種可能的表單part被用來(lái)渲染:

label 渲染字段的標(biāo)簽 如field_label
widget 渲染字段的HTML表示 如field_widget
errors 渲染字段的錯(cuò)誤信息 如field_errors
row 渲染字段的整個(gè)行(包括label,widget和errors) 如 filed_row

還有其它3個(gè)part類(lèi)型,分別是rows,rest和enctype,不過(guò)這三個(gè)一般不會(huì)用到。

通過(guò)知道字段類(lèi)型(比如:textarea)和你想渲染那一部分(比如:widget),你可以創(chuàng)建一個(gè)你需要重寫(xiě)的片段名稱(chēng)(比如:textarea_widget).

模板片段繼承

在某些情況下,你個(gè)性化的片段可能會(huì)丟失。比如,在Symfony提供的默認(rèn)主題中沒(méi)有提供textarea_errors片段。那么如何來(lái)渲染一個(gè)textarea字段的錯(cuò)誤信息呢?

答案是通過(guò)field_errors片段。當(dāng)Symfony渲染一個(gè)textarea類(lèi)型的錯(cuò)誤時(shí),它首先查找一個(gè)textarea_errors片段,如果沒(méi)有找到則會(huì)回到field_errors片段。

每個(gè)field類(lèi)型有一個(gè)parenttype(textarea的父類(lèi)型為field),Symfony如果沒(méi)有發(fā)現(xiàn)本身的片段,就會(huì)轉(zhuǎn)而使用父類(lèi)片段。

所以,要重寫(xiě)textarea字段的errors,拷貝field_errors片段,重命名為textarea_errors并個(gè)性化它們。為所有字段重寫(xiě)默認(rèn)的error渲染,則需要直接拷貝和個(gè)性化field_errors片段。

全局表單主題

在上面的示例中,我們使用了form_theme helper來(lái)導(dǎo)入自定義個(gè)的表單片段到表單。你也可以告訴Symfony在全項(xiàng)目中導(dǎo)入自定義的form。

Twig

為了從所有之前創(chuàng)建的fileds.html.twig模板中自動(dòng)包含個(gè)性化的block,修改你的應(yīng)用程序配置文件:

YAML格式:

# app/config/config.yml
twig:
  form:
    resources:
      - 'AcmeTaskBundle:Form:fields.html.twig'
  # ...

XML格式:

<!-- app/config/config.xml -->
<twig:config ...>
    <twig:form>
      <resource>AcmeTaskBundle:Form:fields.html.twig</resource>
    </twig:form>
    <!-- ... -->
</twig:config>

PHP代碼格式:

// app/config/config.php
$container->loadFromExtension('twig', array(
  'form' => array('resources' => array(
    'AcmeTaskBundle:Form:fields.html.twig',
   ))
  // ...
));

現(xiàn)在在fields.html.twig模板中的任何塊都可以被廣泛的使用來(lái)定義表單輸出了。

自定義表單輸出到一個(gè)單一的Twig文件中

在Twig中,你也可以個(gè)性化一個(gè)表單塊在模板中

{% extends '::base.html.twig'%}
{# 導(dǎo)入"_self" 作為一個(gè)表單主題 #}
{% form_theme form _self %}
{# 個(gè)性化表單片段 #}
{% block field_row %}
    {# 自定義字段行輸出 #}
{% endblock field_row %}
{% block content %}
    {# ... #}
    {{ form_row(form.task) }}
{% endblock %}

這里{% form_theme form _self %}標(biāo)簽允許表單塊在使用那些自動(dòng)化內(nèi)容的模板中被直接自定義化。使用這個(gè)方法來(lái)快速的生成個(gè)性化輸出。

注意,{% form_theme form _self %}的功能只有在繼承自其它模板時(shí)才能起作用,如果不是繼承自其它模板,則需要指出form_theme 到單獨(dú)模板中。

PHP

從以前在所有模板中創(chuàng)建的Acme/TaskBundle/Resources/views/Form 目錄自動(dòng)導(dǎo)入個(gè)性化模板。修改你的配置文件:

YAML格式:

# app/config/config.yml
framework:
  templating:
    form:
      resources:
        - 'AcmeTaskBundle:Form'
# ...

XML格式:

<!-- app/config/config.xml -->
<framework:config ...>
  <framework:templating>
    <framework:form>
      <resource>AcmeTaskBundle:Form</resource>
    </framework:form>
  </framework:templating>
  <!-- ... -->
</framework:config>

PHP代碼格式:

// app/config/config.php
$container->loadFromExtension('framework', array(
  'templating' => array('form' =>
    array('resources' => array(
      'AcmeTaskBundle:Form',
   )))
  // ...
));

此時(shí)在Acme/TaskBundle/Resources/views/Form目錄中的任何片段都可以全局范圍內(nèi)定義表單輸出了。

CSRF 保護(hù)

CSRF--Cross-site request forgery,跨站偽造請(qǐng)求 是惡意攻擊者試圖讓你的合法用戶(hù)在不知不覺(jué)中提交他們本不想提交的數(shù)據(jù)的一種方法。

幸運(yùn)的是,CSRF攻擊可以通過(guò)在你的表單中使用CSRF 記號(hào)來(lái)阻止。

默認(rèn)情況下,Symfony自動(dòng)為你嵌入一個(gè)合法的CSRF令牌。這就意味著你不需要做任何事情就可以得到CSRF保護(hù)。CSRF保護(hù)是通過(guò)在你的表單中添加一個(gè)隱藏字段,默認(rèn)的名叫_token。它包含一個(gè)值,這個(gè)值只有你和你的用戶(hù)知道。這確保了是用戶(hù)而不是其它實(shí)體在提交數(shù)據(jù)。Symfony自動(dòng)校驗(yàn)該token是否存在以及其準(zhǔn)確性。

_token 字段是一個(gè)隱藏字段并且會(huì)自動(dòng)的渲染,只要你在你的模板中包含了form_rest()函數(shù)。它確保了沒(méi)有被渲染過(guò)的字段全部渲染出來(lái)。CSRF令牌可以按照表單來(lái)個(gè)性化,比如:

class TaskType extends AbstractType
{
   // ...
   public function getDefaultOptions(array $options)
   {
      return array(
          'data_class' => 'Acme\TaskBundle\Entity\Task',
          'csrf_protection' => true,
          'csrf_field_name' => '_token',
          // 一個(gè)唯一的鍵值來(lái)保證生成令牌
          'intention' => 'task_item',
      );
   }
   // ...
}

要關(guān)閉CSRF保護(hù),設(shè)置csrf_protection 選項(xiàng)為false。intentsion選項(xiàng)是可選的,但為不同的表單生成不同的令牌極大的加強(qiáng)了安全性。

使用一個(gè)無(wú)底層類(lèi)表單

大多數(shù)情況下,一個(gè)表單要綁定一個(gè)對(duì)象的,并且表單中所有的字段獲取或者保存它們的數(shù)據(jù)到該對(duì)象屬性。但有時(shí)候,你可能只想使用一個(gè)沒(méi)有類(lèi)的表單,返回一個(gè)提交數(shù)據(jù)的數(shù)組,這個(gè)非常容易實(shí)現(xiàn):

// 確認(rèn)你在類(lèi)上方導(dǎo)入了Request對(duì)象
use Symfony\Component\HttpFoundation\Request
// ...
public function contactAction(Request $request)
{
    $defaultData = array('message' => 'Type your message here');
    $form = $this->createFormBuilder($defaultData)
       ->add('name', 'text')
       ->add('email', 'email')
       ->add('message', 'textarea')
       ->getForm();
     if ($request->getMethod() == 'POST') {
        $form->bindRequest($request);
        // 數(shù)據(jù)是一個(gè)數(shù)組并包含 "name", "email", 和"message" 鍵
        $data = $form->getData();
     }
    // ... 渲染表單
}

默認(rèn)情況下,一個(gè)表單真的假設(shè)你想要一個(gè)數(shù)據(jù)數(shù)組而不是數(shù)據(jù)對(duì)象。

這里有兩種方式你可以改變它的行為并綁定一個(gè)對(duì)象;

1.當(dāng)創(chuàng)建表單時(shí)傳入一個(gè)對(duì)象(作為createFormBuilder的第一個(gè)參數(shù)或者createForm的第二個(gè)參數(shù))。

2.在你的表單中聲明data_class 選項(xiàng)

如果以上兩種方式都沒(méi)有,那么表單會(huì)返回一個(gè)數(shù)組數(shù)據(jù)。在這個(gè)示例中因?yàn)?defaultData不是一個(gè)對(duì)象,又沒(méi)有設(shè)置data_class選項(xiàng),則$form->getData()最終返回一個(gè)數(shù)組。

你也可以通過(guò)Request對(duì)象直接訪問(wèn)POST的值,

$this->get('request')->request->get('name');

注意,大多數(shù)的情況下我們使用getData()方法是更好一點(diǎn)的選擇。因?yàn)樗祷氐氖墙?jīng)過(guò)表單框架轉(zhuǎn)換過(guò)的數(shù)據(jù)。

添加校驗(yàn)規(guī)則

唯一遺漏的地方就是校驗(yàn)規(guī)則了,通常當(dāng)你調(diào)用$form->isvalid()時(shí),對(duì)象會(huì)調(diào)用你在類(lèi)東提供的校驗(yàn)規(guī)則進(jìn)行校驗(yàn)。但如果沒(méi)有類(lèi),你怎么來(lái)添加對(duì)你表單數(shù)據(jù)的約束規(guī)則呢?答案是自己創(chuàng)建約束,然后傳入到表單。

// 在controller類(lèi)前導(dǎo)入命名空間
use Symfony\Component\Validator\Constraints\Email;
use Symfony\Component\Validator\Constraints\MinLength;
use Symfony\Component\Validator\Constraints\Collection;
$collectionConstraint = new Collection(array(
      'name' => new MinLength(5),
      'email' => new Email(array('message' => 'Invalid email address')),
));
// 創(chuàng)建一個(gè)表單沒(méi)有默認(rèn)值,傳入約束選項(xiàng)。
$form = $this->createFormBuilder(null, array(
           'validation_constraint' => $collectionConstraint,
    ))->add('email', 'email')
// ...
;

現(xiàn)在,當(dāng)你調(diào)用$form->bindRequest($request)時(shí),約束就會(huì)被創(chuàng)建并作用于你的表單數(shù)據(jù)。如果你使用表單類(lèi),重寫(xiě)getDefaultOptions 方法來(lái)指定可選項(xiàng):

namespace Acme\TaskBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilder;
use Symfony\Component\Validator\Constraints\Email;
use Symfony\Component\Validator\Constraints\MinLength;
use Symfony\Component\Validator\Constraints\Collection;
class ContactType extends AbstractType
{
  // ...
  public function getDefaultOptions(array $options)
  {
    $collectionConstraint = new Collection(array(
      'name' => new MinLength(5),
      'email' => new Email(array('message' => 'Invalid email address')),
    ));
    return array('validation_constraint' => $collectionConstraint);
  }
}

這樣你有了足夠的靈活性來(lái)創(chuàng)建表單類(lèi)和約束了,它返回一個(gè)數(shù)據(jù)數(shù)組而不是一個(gè)對(duì)象。大多數(shù)情況下,這個(gè)是不錯(cuò)的,而綁定一個(gè)表單到一個(gè)對(duì)象,從某種程度上說(shuō)更加健壯。對(duì)于簡(jiǎn)單表單來(lái)說(shuō)是個(gè)不錯(cuò)的選擇。

總結(jié)思考

你現(xiàn)在已經(jīng)了解了所有建造復(fù)雜功能性的表單所需要的所有建造塊。當(dāng)生成表單時(shí),記住一個(gè)表單的首要目標(biāo)是從一個(gè)對(duì)象把數(shù)據(jù)傳遞給一個(gè)HTML表單以方便用戶(hù)修改它們。第二個(gè)目標(biāo)就是把用戶(hù)提交的數(shù)據(jù)重寫(xiě)提交回對(duì)象。

希望本文所述對(duì)大家基于Symfony框架的PHP程序設(shè)計(jì)有所幫助。

相關(guān)文章

  • thinkphp框架實(shí)現(xiàn)路由重定義簡(jiǎn)化url訪問(wèn)地址的方法分析

    thinkphp框架實(shí)現(xiàn)路由重定義簡(jiǎn)化url訪問(wèn)地址的方法分析

    這篇文章主要介紹了thinkphp框架實(shí)現(xiàn)路由重定義簡(jiǎn)化url訪問(wèn)地址的方法,結(jié)合實(shí)例形式分析了thinkphp路由重定義及url地址訪問(wèn)相關(guān)操作技巧與注意事項(xiàng),需要的朋友可以參考下
    2020-04-04
  • php實(shí)現(xiàn)當(dāng)前頁(yè)面點(diǎn)擊下載文件的實(shí)例代碼

    php實(shí)現(xiàn)當(dāng)前頁(yè)面點(diǎn)擊下載文件的實(shí)例代碼

    下面小編就為大家?guī)?lái)一篇php實(shí)現(xiàn)當(dāng)前頁(yè)面點(diǎn)擊下載文件的實(shí)例代碼。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2016-11-11
  • PHP使用遞歸生成文章樹(shù)

    PHP使用遞歸生成文章樹(shù)

    寫(xiě)遞歸函數(shù),可考慮緩存,定義一些靜態(tài)變量來(lái)存上一次運(yùn)行的結(jié)果,多程序運(yùn)行效率很有幫助.大概步驟如下:首先到數(shù)據(jù)庫(kù)取數(shù)據(jù),放到一個(gè)數(shù)組,然后把數(shù)據(jù)轉(zhuǎn)化為一個(gè)樹(shù)型狀的數(shù)組,最后把這個(gè)樹(shù)型狀的數(shù)組轉(zhuǎn)為html代碼。下面我們來(lái)看個(gè)實(shí)例
    2015-04-04
  • PHP四種基本排序算法示例

    PHP四種基本排序算法示例

    這篇文章主要介紹了PHP四種基本排序算法示例,本文用一個(gè)實(shí)例講解冒泡排序法、快速排序法、選擇排序法、插入排序法的使用,需要的朋友可以參考下
    2015-04-04
  • PHP自動(dòng)補(bǔ)全表單的兩種方法

    PHP自動(dòng)補(bǔ)全表單的兩種方法

    這篇文章主要介紹了PHP自動(dòng)補(bǔ)全表單的兩種方法,第一種從數(shù)據(jù)庫(kù)中檢索之后補(bǔ)全,第二種郵箱等純前端的補(bǔ)全,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2017-03-03
  • thinkPHP交易詳情查詢(xún)功能詳解

    thinkPHP交易詳情查詢(xún)功能詳解

    這篇文章主要介紹了thinkPHP交易詳情查詢(xún)功能,結(jié)合實(shí)例形式分析了thinkPHP數(shù)據(jù)庫(kù)查詢(xún)功能及視圖輸出相關(guān)操作技巧,需要的朋友可以參考下
    2016-12-12
  • Laravel中為什么不使用blpop取隊(duì)列詳析

    Laravel中為什么不使用blpop取隊(duì)列詳析

    這篇文章主要給大家介紹了關(guān)于Laravel中為什么不使用blpop取隊(duì)列的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2018-08-08
  • windows中為php安裝mongodb與memcache

    windows中為php安裝mongodb與memcache

    這篇文章主要介紹了windows中為php安裝mongodb與memcache的方法,十分的詳盡,需要的朋友可以參考下
    2015-01-01
  • PHP利用curl發(fā)送HTTP請(qǐng)求的實(shí)例代碼

    PHP利用curl發(fā)送HTTP請(qǐng)求的實(shí)例代碼

    這篇文章主要介紹了PHP利用curl發(fā)送HTTP請(qǐng)求的實(shí)例,文中示例代碼非常詳細(xì),幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-07-07
  • Smarty最簡(jiǎn)單實(shí)現(xiàn)列表奇偶變色的方法

    Smarty最簡(jiǎn)單實(shí)現(xiàn)列表奇偶變色的方法

    這篇文章主要介紹了Smarty最簡(jiǎn)單實(shí)現(xiàn)列表奇偶變色的方法,實(shí)例分析了Smarty屬性與方法的相關(guān)使用技巧,需要的朋友可以參考下
    2015-07-07

最新評(píng)論