Zend Framework2-从数据库创建Select option选项几种方法

Zend\Form\Element\Select and Database Values

Mar 22

One of the most common questions currently is how one is able to populate a Zend\Form\Element\Select with data from the database. In this blog I am going to demonstrate to you guys how you can achieve this using three different ways. First will be the very barebone way using Zend\Db\Adapter\AdapterInterface, another way will be using the Zend\Db\TableGateway\TableGatewayInterface and the third option to make this possible using a Doctrine\Common\Persistence\ObjectManager.

Understanding Dependencies

Let’s start with trying to understand what we actually need. We are going to have one Zend\Form. This form, somehow needs to be inserted some data from a Database. Without this, the form is not functional. If i am going to express those facts using a different terminology it will be this:
The form is dependant on the database!

What we’re ultimately going to do is to inject a dependency into our form. This is pretty simple if you know how to do it. We have two options, Setter-Injection and Constructor-Injection. Given the circumstances that the form will not be usable without the dependency, hence the dependency is a requirement, I will choose Constructor-Injection.

Choose your method

This blog will cover three possible ways to achieve our goal. Please choose which method fits you the best.

All of the Methods follow a common Workflow.

  • Create a form with a database-dependency
  • Inject the dependency into the form
  • Query database for data
  • Fill data into form element

Please note: all of the examples require you to have correctly configured your DB connection. Namely those will be either the doctrine-adapter or Zend\Db\Adapter\Adapter. If those examples don’t work for you, please check ALL your Code and Configuration with the project over at my GitHub-Playground-Repository.

All code will be inside a Module called FormDependencies. If you try out the codes, make sure you adjust the namespace and the paths correctly!

Element\Select via Db\Adapter

Let’s start by taking a look at our Controller.

The highlighted lines show the interesting part. In line #6 we call the ServiceLocator and ask for the Zend\Db\Adapter\Adapter. This adapter will then be injected into our Form called DbAdapterForm using Constructor-Injection.

So let’s take now take a look at how to create our form.

As you can see we are overwriting the __construct() of Zend\Form to require a parameter compatible with the Zend\Db\Adapter\AdapterInterface. With this we can make sure that no matter what adapter you guys choose to use, the following code would work. Please create a setter- and getter-function for the protected $dbAdapter.

The next highlighted line would be where we assign the value_options. We call for a function which we yet have to define. This is where we will query the database and return a key-value paired array to populate the Zend\Form\Element\Select.

And this is all the magic. We fire a query to our database, we iterate through the result, push the data into an array and return it. That’s all!

Once again, if this is not working for you, please check in with my GitHub-Playground-Repository.

Element\Select via Db\TableGateway

The method to populate a Select-Element using the TableGateway-Pattern is very similar to the one above. Let’s once again take a look at our Controller first.

As you can see we get the TableGateway-Access from the ServiceLocator and inject this into the form. I will not explain how the TableGateway-Pattern functions here, but i’ll show you the configuration i have set up to make this work.

I will not show you guys the exact code for the SelectTable or SelectOption classes, as they are pretty common. You can however check the cover at my GitHub-Playground-Repository and read the relevant part of the official Zend Framework 2 Documentation about Database and Models.

Let’s now take a look at what’s happening inside our Form. I will first show you how the Form is constructed.

At line #11 you can see that we are overwriting the default __construct() of Zend\Form. With this we make sure that our form gets an injection of our TableGateway-Class called SelectTable.

Line #22 then shows you that we’re calling a function to populate the value_options. The functions task is to access the TableGateway and get the data that we want. So let’s take a look at how this is done.

The code is pretty similar to the DbAdapter-Example. Instead of writing a manual Query, we are using the fetchAll() function of the TableGateway. Next we are iterating through the ResultSet, push the data into an array, that we’re going to return in the end.

And that’s it. If there are any errors or some missing configuration, please check in with my GitHub-Playground-Module. I am only covering the critical points of this topic and leave out the documentation for configuration stuff.

Element\Select via Doctrine\ObjectManager

Now achieving the goal via DbAdapter or TableGateway was very similar. Using any implementation of Doctrines ObjectManager is similar as far as the Dependency-Injection goes, too, but since Doctrine ships with it’s own Form-Elements, we should be doing things the Doctrine-Way. But let’s first take a look at the Controller again.

This code is pretty much identical with the above two methods. We query the ServiceLocator for our DB-Dependency, which in this case is the Doctrine\ORM\EntityManager and then use Constructor-Injection to inject it into our form called DoctrineForm. That’s boring, so let’s first check in with the DoctrineForm

This Form looks a little different. We are implementing the ObjectManagerAwareInterface. This is not required, but it’s a good thing to do if ever other people will require certain features or want to use the form elsewhere. The important part to note is that we are injecting the ObjectManager. And we need this ObjectManager to use the Form-Elements that are shipped within DoctrineModule. Namely ObjectSelect, ObjectRadio and ObjectMultiCheckbox. In our example we will make use of ObjectSelect. So let’s implement it.

Now what’s that? First we define that this FormElement is of type ObjectSelect. The ObjectSelect requires some additional parameters to work. It requires the ObjectManager, it needs to know which Entity is represented by this Select-Element (in this case Entity\SelectOption) and it needs to know which property to display.

And this is all that is done here. In the Doctrine-Example we are not querying the database manually, that’s what the ObjectSelect is doing behind the scenes for us. All we have to make sure is that we are correctly adding the dependency to the form, inject it, and pass it over to the ObjectSelect Form-Element.

Final Words

With this code i hope to reach some people who are yet unable to do this kind of thing. There are other ways to inject the dependencies. Just to give an example, you can – and probably should – getch the whole form from the ServiceManager and inject the dependency in that process. It shouldn’t be the task of a Controller to handle the dependency. But for the sake of keeping this blogpost somewhat small and easy, i did it this way instead.

Furthermore i’ll say this again: the blogpost doesn’t cover all the configuration that are required, like setting up a database-connection or setting up doctrine the correct way. If you need help with this, please check in to my ZF2Playground as GitHub to see how it’s done.

Ultimately i hope this is of help to some of you guys. Feel free to ask me anything regarding this topic and I’m sure I’ll come up with an answer sooner or later ;

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值