首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从zend framework 2中的另一个模块获取数据

问从zend framework 2中的另一个模块获取数据
EN

Stack Overflow用户
提问于 2014-01-08 01:34:43
回答 2查看 2.6K关注 0票数 2

我安装了SkeletonApplication,并从ZF2文档创建了默认的相册模块。http://framework.zend.com/manual/2.2/en/user-guide/modules.html

在那之后,我创建了分类模块,比如相册模块。下面是它的字段: category_id和category_name

然后为专辑表添加了额外的字段: cat_id,正如您所理解的,我正在尝试对专辑进行分类。

然后,我将这段代码添加到AlbumForm.php文件中,用于从选择框中选择字段集cat_id

代码语言:javascript
复制
$this->add(array(
    'type' => 'Zend\Form\Element\Select',
    'name' => 'cat_id',
    'options' => array(
            'value_options' => $selectOptions,
        'label' => 'Category',
     ),
)); 

现在,如何将category_name和category_id从另一个类别模块获取到专辑模块?

EN

回答 2

Stack Overflow用户

发布于 2014-01-08 05:29:45

如果我们能看到你的分类模块文件的代码,那就太好了。

首先,你应该考虑是否真的需要一个新的模块,因为它可能应该在同一个模块中,只是创建新的模型类和新的视图(如果有)。无论如何,在这一点上都无关紧要。

如果你在你的相册模块中使用SkeletonApplication,在Module.php中你会有这样的代码:

代码语言:javascript
复制
 public function getServiceConfig()
    {
        return array(
                'factories' => array(
                        'Album\Model\AlbumTable' =>  function($sm) {
                            $tableGateway = $sm->get('AlbumTableGateway');
                            $table = new AlbumTable($tableGateway);
                            return $table;
                        },
                        'AlbumTableGateway' => function ($sm) {
                            $dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
                            $resultSetPrototype = new ResultSet();
                            $resultSetPrototype->setArrayObjectPrototype(new Album());
                            return new TableGateway('album', $dbAdapter, null, $resultSetPrototype);
                        },
                ),
        );
    }

然后,您可能为您的类别表创建了类似的内容,例如

代码语言:javascript
复制
 public function getServiceConfig()
    {
        return array(
                'factories' => array(
                        'Category\Model\CategoryTable' =>  function($sm) {
                            $tableGateway = $sm->get('CategoryTableGateway');
                            $table = new CategoryTable($tableGateway);
                            return $table;
                        },
                        'CategoryTableGateway' => function ($sm) {
                            $dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
                            $resultSetPrototype = new ResultSet();
                            $resultSetPrototype->setArrayObjectPrototype(new Album());
                            return new TableGateway('category', $dbAdapter, null, $resultSetPrototype);
                        },
                ),
        );
    }

如果有很大的不同,请告诉我。

由于所有配置都已合并,因此无论您是否在其他模块中,您的服务管理器都可以在您的控制器中找到Category\Model\CategoryTable。

因此,您必须修改您的AlbumForm类,例如在构造函数中,您可以传递依赖项,例如servicemanager或‘Category\Model’,因此当您需要检索$selectOptions列表时,您可以访问它以进行任何查询。

此外,您可以从samsonasik查看更好的解决方案,但它可能更难理解。

和,你可以从jamescarr中查看这个blog post和code,以获得与你所需的大致相同的结果。它真的很容易理解,而且是一个很好的解决方案。

票数 2
EN

Stack Overflow用户

发布于 2014-01-08 08:45:28

事实上,你不必为你的分类模型创建一个新的模块,=>把它放到你的相册模块中:)

多个模块并不是一个好主意...每个表一个表太多了:D

在我的先例之后,我看到你仍然有麻烦,我写并注释了所有的代码,这样你就可以更好地理解:)

ServiceManager工厂是一个非常重要的概念,需要很好地理解!

因此,首先必须在module.php文件中进行工厂配置:

代码语言:javascript
复制
namespace Album;

use Zend\Db\ResultSet\ResultSet;
use Zend\Db\TableGateway\TableGateway;

use Album\Model\Album;
use Album\Model\AlbumTable;
use Album\Model\Category;
use Album\Model\CategoryTable;

class Module
{

    public function getServiceConfig()
    {
        return array (
            'factories' => array(
                //here already the AlbumTable config

                // here begin the categoryTable factory
                'Album\Model\CategoryTable' =>  function($sm)
                {
                    //get the tableGateway just below in his own factory
                    $tableGateway = $sm->get('CategoryTableGateway');
                    //inject the tableGateway in the Table
                    $table = new CategoryTable($tableGateway);
                    return $table;
                },
                //here is the tableGateway Factory for the category
                'CategoryTableGateway' => function($sm)
                {
                    //get adapter to donnect dataBase
                    $dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
                    // create a resultSet
                    $resultSetPrototype = new ResultSet();
                    //define the prototype of the resultSet 
                    // => what object will be cloned to get the results
                    $resultSetPrototype->setArrayObjectPrototype(new Category());
                    //here you define your database table (category) 
                    //when you return the tableGateway to the CategoryTable factory
                    return new TableGateway('category', $dbAdapter, null, $resultSetPrototype);
                },
            ),
        ),
    }
}

在模块/相册/源/相册/模型中创建Category.php文件:

代码语言:javascript
复制
namespace Album\Model;

class Category
{
    public $id;
    public $name;

    public function exchangeArray(){
        $this->id     = (isset($data['id'])) ? $data['id'] : null;
        $this->name = (isset($data['name'])) ? $data['name'] : null;
    }

}

在同一文件夹中创建CategoryTable.php文件(选择输入只需要fetchAll()方法,您只需要所有类别的列表)

代码语言:javascript
复制
namespace Album\Model;

use Zend\Db\TableGateway\TableGateway;

use Album\Model\Category;

class CategoryTable
{
    protected $tableGateway;

    public function __construct(TableGateway $tableGateway)
     {
         $this->tableGateway = $tableGateway;
     }

     public function fetchAll()
     {
         $resultSet = $this->tableGateway->select();
         return $resultSet;
     }


     public function getCategory($id){
        // ...
     }

    public function saveCategory(Category $category)
    {
       // ...
    }

     public function deleteCategory($id)
     {       
        // ...
     }
}

不要忘了在您的AlbumTable::saveAlbum()方法中添加新的cat_id字段;)

在相册/表单文件夹中创建表单和他的过滤器

代码语言:javascript
复制
namespace Album\Form;

class AlbumForm{
    public function __construct($cat_options){

        $this->add(array(
            'name' => 'id',
            'required' => false,
            'type' => 'hidden',
        ));

        $this->add(array(
            'name' => 'cat_id',
            'required' => true,
            'type' => 'Select',
            'options' => array(
                'value_options' => $cat_options,
                'label' => 'Category',
            )
            'attributes' => array(
                'value' => 3, // to select a default value
            )
        ));
        //and the rest of the form
         $this->add(array(
            'name' => 'submit',
            'type' => 'Submit',
            'attributes' => array(
                'id' => 'submitbutton',
                'value' => 'Go',
            ),
        ));
    }
}

请注意,我将过滤器放在一个特定的类中,即窗体所在的同一名称空间中。当你在一个模块中有很多表单和模型时,=>会更容易找到…=>我更喜欢这样,所以我重新注释它:D =>对于同一模型,您可以有几个表单,例如注册、登录和resetPassword表单,所有这些表单都用于相同的User类

代码语言:javascript
复制
namespace Album\Form;

use Zend\InputFilter\InputFilter;
use Zend\InputFilter\InputFilterAwareInterface;

class AlbumFilter implements InputFilterAwareInterface
{
    protected $inputFilter;

    public function setInputFilter(InputFilterInterface $inputFilter)
    {
        throw new \Exception("Not used");
    }

    public function getInputFilter()
    {
        if(!$this->inputFilter)
        {
            $inputFilter = new InputFilter();

            $inputFilter->add(array(
                'name'     => 'id',
                'required' => false,
                'filters'  => array(
                    array('name' => 'Int'),
                ),
            ));
            $inputFilter->add(array(
                'name'     => 'cat_id',
                'required' => true,
                'filters'  => array(
                    array('name' => 'Int'),
                ),
            ));

            $inputFilter->add(array(
                'name'     => 'artist',
                'required' => true,
                'filters'  => array(
                    array('name' => 'StripTags'),
                    array('name' => 'StringTrim'),
                ),
                'validators' => array(
                    array(
                        'name'    => 'StringLength',
                        'options' => array(
                            'encoding' => 'UTF-8',
                            'min'      => 1,
                            'max'      => 45,
                        ),
                    ),
                ),
            ));

            $inputFilter->add(array(
                'name'     => 'title',
                'required' => true,
                'filters'  => array(
                    array('name' => 'StripTags'),
                    array('name' => 'StringTrim'),
                ),
                'validators' => array(
                    array(
                        'name'    => 'StringLength',
                        'options' => array(
                            'encoding' => 'UTF-8',
                            'min'      => 1,
                            'max'      => 45,
                        ),
                    ),
                ),
            ));
            $this->inputFilter = $inputFilter;
        }
        return $this->inputFilter;
    }

}

现在一切都配置好了,让Controller :)

代码语言:javascript
复制
namespace Album\Controller;

use Zend\Mvc\Controller\AbstractActionController;
use Album\Model\Album;
use Album\Form\AlbumForm;

class MyControler extends AbstractActionController
{
    private $CategoryTable;

    public function getAlbumsTable(){
        if(!$this->Album){
            // get AlbumTable from the ServiceLocator factory (defined in Module.php)
            $this->Album = $this->getServiceLocator()
                ->get('Album\Model\AlbumTable'); 
        }
    }

    public function getCategoryTable(){
        if(!$this->CategoryTable){
            $this->CategoryTable = $this->getServiceLocator()
                ->get('Album\Model\CategoryTable');
        }
    }

    public function addAction(){
        //get the categories from the database
        $categories = $this->getCategoryTable()->fetchall();

        //make an array from the resultSet
            // you can do it as well in your controller
            //or in your form class like I did in my yersterday's answer
        $cat_options = array();
            foreach ($categories as $category) {
                $cat_options[$category->id]=$category->name;
            }

        //create your form with category list as parameter
        $form = new AlbumForm($cat_options);
        //here I recomend to create a specific class for you filters
        // and not put it in your Album class as describe in the zf tutorial

        // => so you can have several forms using the same Model
        // and it is more easy to find on the form folder ;)
        $filter = new AlbumFilter();
        //inject InputFilter in your form
        $form->setInputFilter($filter->getInputFilter());
        //inject data in form
        $form->setData($request->getPost());
        //check the form validity (data vs filters)
        if($form->isValid()){
            //create a new album
            $album = new Album();  
            //hydrate your Album
            $album->exchangeArray($form->getData());
            //ask the albumsTable to save album in the database
            $this->albumsTable->saveAlbum($album);

            //here you can redirect to the Album list
            $this->redirect()->toRoute('Album');
        }
        //call the viewModel if first time you see the page
        // or if validation errors of the form.
        return array('form' =>$form);
    }
}

然后你只需要让你的观点...我不会冒犯你把这段代码放在这里;)

如果您仍然需要在应用程序中创建多个模块,则可以使用getobjectTable()方法调用控制器中的任何表,使用工厂:正如卡洛斯所说,getServiceConfig()数组全部合并为一个,因此您可以从应用程序中的任何位置获取任何表:)

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20978141

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档