Php 在Zend Framework 2中创建下拉列表

Php 在Zend Framework 2中创建下拉列表,php,drop-down-menu,zend-framework2,Php,Drop Down Menu,Zend Framework2,我知道这听起来更基本,但我还是想发布我的问题,因为它与Zend Framework 2有关。我从Zend示例模块中了解此表单 namespace Album\Form; use Zend\Form\Form; class AlbumForm extends Form { public function __construct($name = null) { // we want to ignore the name passed parent:

我知道这听起来更基本,但我还是想发布我的问题,因为它与Zend Framework 2有关。我从Zend示例模块中了解此表单

namespace Album\Form;

use Zend\Form\Form;

class AlbumForm extends Form
{
    public function __construct($name = null)
    {
        // we want to ignore the name passed
        parent::__construct('album');
        $this->setAttribute('method', 'post');
        $this->add(array(
            'name' => 'id',
            'attributes' => array(
                'type'  => 'hidden',
            ),
        ));
        $this->add(array(
            'name' => 'artist',
            'attributes' => array(
                'type'  => 'text',
            ),
            'options' => array(
                'label' => 'Artist',
            ),
        ));
        $this->add(array(
            'name' => 'title',
            'attributes' => array(
                'type'  => 'text',
            ),
            'options' => array(
                'label' => 'Title',
            ),
        ));
        $this->add(array(
            'name' => 'submit',
            'attributes' => array(
                'type'  => 'submit',
                'value' => 'Go',
                'id' => 'submitbutton',
            ),
        ));
    }
}
这就是所谓的这种方式

<?php
$form = $this->form;
$form->setAttribute('action', $this->url('album', array('action' => 'add')));
$form->prepare();

echo $this->form()->openTag($form);
echo $this->formHidden($form->get('id'));
echo $this->formRow($form->get('title'));
echo $this->formRow($form->get('artist'));
echo $this->formSubmit($form->get('submit'));
echo $this->form()->closeTag();

这是为静态选项执行此操作的一种方法

被警告……

由于您是在构造函数中创建表单,因此您将无权访问ServiceManager。如果要从数据库填充,这可能会导致问题

让我们试试像

但那不太好,重新考虑一下……

扩展表单以便创建表单并不完全正确。我们不是在创建一种新的表单,我们只是在设置一种表单。这需要一个工厂。此外,在这里使用工厂的优点是,我们可以通过使用服务管理器为其提供服务的方式来设置工厂,这样服务管理器可以注入自身,而不是我们从控制器手动注入。另一个优点是,只要有服务管理器,我们就可以调用此表单

另一点值得一提的是,在有意义的地方,我认为最好将代码从控制器中取出。控制器不是一个脚本转储,所以让对象自己照顾自己很好。我想说的是,向一个对象注入它需要的对象是好的,但是仅仅从控制器向它传递数据是不行的,因为它会产生太多的依赖性不要用勺子从控制器中喂入对象,注射勺子。

不管怎样,太多的代码

class MySpankingFormService implements FactoryInterface
{
    public function createService(ServiceLocatorInterface $serviceManager )
    {
        $mySpankingNewForm = new Form;

        // build that form baby,
        // you have a service manager,
        // inject it if you need to,
        // otherwise just use it.

        return $mySpankingNewForm;
    }
}
控制器

<?php

class FooController
{
    ...
    protected function getForm()
    {
        if ( is_null($this->form) ) {
            $this->form =
                $this->getServiceManager()->get('MySpankingFormService');
        }
        return $this->form;
    }
    ...
}

通过在controllerZF2表单中分配选项解决了此问题。ZF2表单比ZF1@Elzo-对我来说,这是掌握DI和运行时配置。我已经在一个使用ZF2的项目上全职工作了9周,现在我才刚刚开始工作。有点。@tomerre,感谢您提供了这么一个详细的示例,但正如Elzo所说,ZF2表单更容易混淆,对于像我这样的人来说,将来一定会访问这篇文章来追求ZF2,以防他们能在标准专辑示例中调整相同的代码。我的意思是你的解释很好,你能告诉我们如何在标准相册模块中使用同样的模块,特别是在servicemanager中。也许我们要求的太多了,但是作为初学者,很容易按照Album模块的示例来解释您的精彩解释,即将接受:)注入服务管理器的方式与注入其他任何内容的方式完全相同,只是从对象外部调用公共setter。然而,这并不好,因为你必须像一个不受欢迎的孤儿一样不断地传递它。在这个例子中,它看起来不太麻烦,但很快就会失去控制。我坚持我之前所说的,在构造函数中放置工厂很方便,但这不是一个好的模式,当然也不适合ZF2。至少在我的经验中,现在没有足够的时间来调整这张专辑的答案,但是如果有足够的兴趣的话,我会考虑在博客中列举一个例子。
public function initFormOptions()
{
    $this->get('number')->setAttribute('options', $this->getNumberOptions());
}

protected function getNumberOptions()
{
    // or however you want to load the data in
    $mapper = $this->getServiceManager()->get('NumberMapper');
    return $mapper->getList();
}

public function getServiceManager()
{
    if ( is_null($this->serviceManager) ) {
        throw new Exception('The ServiceManager has not been set.');
    }

    return $this->serviceManager;
}

public function setServiceManager(ServiceManager $serviceManager)
{
    $this->serviceManager = $serviceManager;
}
class MySpankingFormService implements FactoryInterface
{
    public function createService(ServiceLocatorInterface $serviceManager )
    {
        $mySpankingNewForm = new Form;

        // build that form baby,
        // you have a service manager,
        // inject it if you need to,
        // otherwise just use it.

        return $mySpankingNewForm;
    }
}
<?php

class FooController
{
    ...
    protected function getForm()
    {
        if ( is_null($this->form) ) {
            $this->form =
                $this->getServiceManager()->get('MySpankingFormService');
        }
        return $this->form;
    }
    ...
}
...
'service_manager' => array (
        'factories' => array (
            ...
            'MySpankingFormService'
                => 'MyNameSpacing\Foo\MySpankingFormService',
            ...