2014-01-07 47 views
2

我安装了SkeletonApplication并从ZF2 Docs创建了默认相册模块。 http://framework.zend.com/manual/2.2/en/user-guide/modules.html从zend框架中的另一个模块获取数据2

之后,我创建了类似模块的专辑模块。 这是它的领域:category_id和category_name

然后添加额外的专辑表字段:cat_id 正如你明白我想分类专辑。

然后我说这个代码AlbumForm.php文件字​​段集可供选择选择框

$this->add(array(
    'type' => 'Zend\Form\Element\Select', 
    'name' => 'cat_id', 
    'options' => array(
      'value_options' => $selectOptions, 
     'label' => 'Category', 
    ), 
)); 

现在CAT_ID,我怎么能得到CATEGORY_NAME和CATEGORY_ID从另一个类模块专辑模块?

+0

我建议我的博文[Zend \ Form \ Element \ Select and Database Values](http://samminds.com/2013/03/zendformelementselect-and-database-值/) – Sam

回答

2

如果我们能够看到类别模块文件的代码,那将会很好。

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

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

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); 
         }, 
       ), 
     ); 
    } 

然后可能创建您的分类表类似的东西,像

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 \ CategoryTable',因此当您需要检索$ selectOptions列表时,您可以访问它来进行任何查询。

此外,你可以看看samsonasik这样的更好的解决方案,但它可能更难理解。

并且也您可以检查此blog post和jamescarr code实现或多或少相同的,你需要的。 这很容易理解,而且是一个很好的解决方案。

+1

就像你说我的相册模块的Module.php和类别模块的Module.php完全一样。我检查了samsonasik的链接,但像你说的我不明白。我会检查你的新链接并回到这里。 – ibrahim

+0

如果你没有得到另一个例子,生病给你提供了更多的代码,我自己的方法很容易理解 –

+0

http://blog.james-carr.org/2012/09/16/using-select-in-zend-framework- 2 /这是一个理解如何做到这一点的好教程,但它与数据库没有关系。所以我没有得到很好。 :( – ibrahim

2

逸岸,你不必为你的等级创建一个新的模块型号 =>把它放在你的相册模块:)

它不是多样信息模块个好主意......每一个表是很过分:d

正如我看你还是有麻烦我的先例aswer后,我写了评论和所有的代码,这样就可以更好地理解:)

该工厂的ServiceManager是一个概念非常重要非常了解!

所以,你首先必须使你的module.php文件出厂配置:

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); 
       }, 
      ), 
     ), 
    } 
} 

创建模块/专辑/ src目录/专辑/型号您Category.php文件:

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()需要选择输入法,你只是想所有类别的列表)

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;)

创建表单和他的专辑/表夹筛选

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', 
      ), 
     )); 
    } 
} 

注意,我把在与Form相同的命名空间中的特定类中的筛选器。 =>当你在一个模块中有很多表单和模型时,更容易找到... =>我喜欢这样,所以我推荐它:D =>您可以为同一个模型注册,登录和resetPassword形式,例如,所有使用相同的用户类

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; 
    } 

} 

而现在,一切都被配置,使控制器:)

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()方法中调用控制器中的任何objectTable:如Carlos所说,getServiceConfig()数组全部合并为一个,所以你可以从应用程序的任何地方得到任何表格:)

+0

我做了你所说的一切,但添加专辑页面出现此错误:致命错误:调用成员函数fetchall()在C:\ xampp \ htdocs \ tasarim \ module \ Album \ src \ Album \ Controller \ AlbumController.php在第39行 – ibrahim