intro
This article illustrates how to implement relations using Zend_Db_Table. You can download the source code of this article from here.
1.Create bootstrap.php and config.in
Create the file
Create the file
Please modify
In this article, we will use the following sql.
application/bootstrap.php
with the following content.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
<?php set_include_path('../library' . PATH_SEPARATOR . get_include_path()); define('APP_BASE', '../application'); define('CONFIG_PATH', APP_BASE . '/config.ini'); require_once 'Zend/Controller/Front.php'; require_once 'Zend/Layout.php'; require_once 'Zend/Db.php'; require_once 'Zend/Config/Ini.php'; require_once 'Zend/Db/Table/Abstract.php'; $layout = Zend_Layout::startMvc(); //$layout->getView()->baseUrl = '/yourBaseUrl'; $config = new Zend_Config_Ini(CONFIG_PATH, 'staging'); $params = $config->database->params->toArray(); $params['options'][Zend_Db::CASE_FOLDING] = Zend_Db::CASE_LOWER; $dbAdapter = Zend_Db::factory($config->database->adapter, $params); Zend_Db_Table_Abstract::setDefaultAdapter($dbAdapter); Zend_Controller_Front::run(APP_BASE . '/controllers'); |
Create the file
application/config.ini
with the following content.Please modify
database.params.*
properly.
1 2 3 4 5 6 |
[staging] database.adapter = pdo_mysql database.params.host = localhost database.params.username = db_user database.params.password = db_password database.params.dbname = db_name |
In this article, we will use the following sql.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
CREATE TABLE users ( id integer auto_increment NOT NULL PRIMARY KEY, username varchar(20) NOT NULL, password varchar(20) NOT NULL ); CREATE TABLE profiles ( id integer auto_increment NOT NULL PRIMARY KEY, user_id integer NOT NULL, first_name varchar(100) NOT NULL, last_name varchar(100) NOT NULL, email varchar(200) NOT NULL, url varchar(200) NOT NULL ); INSERT INTO users (username, password) values ('testuser', 'testpassword'); INSERT INTO profiles (user_id, first_name, last_name, email, url) values (1, 'Myfirstname', 'Mylastname', 'my@emailaddress', 'http://myurl/my/page'); |
2.Create Models
Create the file
The property
Create the file
The property
Each value is also an associative array, with the following keys:
application/models/Users.php
with the following content.
1 2 3 4 5 6 7 8 |
<?php require_once 'Zend/Db/Table/Abstract.php'; class Users extends Zend_Db_Table_Abstract { protected $_name = 'users'; protected $_dependentTables = array('Profiles'); } |
The property
$_dependentTables
is array of class names of tables that are children of current table.Create the file
application/models/Profiles.php
with the following content.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<?php require_once 'Zend/Db/Table/Abstract.php'; class Profiles extends Zend_Db_Table_Abstract { protected $_name = 'profiles'; protected $_referenceMap = array( 'Account' => array( 'columns' => 'user_id', 'refTableClass' => 'Users', 'refColumns' => 'id' ) ); } |
The property
$_referenceMap
is an array of reference rules. Each key is a name for one reference rule.Each value is also an associative array, with the following keys:
Key | Description |
---|---|
columns | name(s) of column(s) in the child table |
refTableClass | class name of the parent table |
refColumns | name(s) of column(s) in the parent table |
onDelete | 'cascade' or self::CASCADE means that a delete in the parent table also causes a delete of referencing rows in the child table.Default is not cascade. |
onUpdate | 'cascade' or self::CASCADE that an update of primary key values in the parent table also causes an update of referencing rows in the child table.Default is not cascade. |
3.Create Controller
Create the file
The code
Or you can fetch the row of parent table from the row of child table. The following is about it.
application/constorllers/IndexController.php
with the following content.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
<?php require_once 'Zend/Controller/Action.php'; require_once APP_BASE . '/models/Users.php'; require_once APP_BASE . '/models/Profiles.php'; class IndexController extends Zend_Controller_Action { protected $_user_id = 1; public function indexAction() { $users = new Users(); $user = $users->find($this->_user_id)->current(); if ($user) { $profile = $user->findProfiles()->current(); if ($profile) { $this->view->profile = $profile->toArray(); } $this->view->user = $user->toArray(); } } } |
The code
$user->findProfiles()
returns the rows of Profiles
. The following is an alternative code.
1 |
$user->findDependentRowset('Profiles') |
Or you can fetch the row of parent table from the row of child table. The following is about it.
1 2 3 4 |
$profile->findParentUsers() $profile->findParentUsersByAccount() $profile->findParentRow('Users') $profile->findParentRow('Users', 'Account') |
4.Create View
Create the file
application/views/scripts/index/index.phtml
with the following content.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
<h1><?= $this->translate('Table Relation Sample') ?></h1> <h2><?= $this->translate('Your User Account') ?></h2> <?php if (!$this->user) : ?> <span><?= $this->translate('No User Account Found') ?></span> <?php else : ?> <dl> <?php foreach($this->user as $key => $value) : ?> <dt><?= $this->translate($key) ?></dt> <dd><?= $this->escape($value) ?></dd> <?php endforeach; ?> </dl> <?php endif; ?> <h2><?= $this->translate('Your Profile') ?></h2> <?php if (!$this->profile) : ?> <span><?= $this->translate('No Profile Found') ?></span> <?php else : ?> <dl> <?php foreach($this->profile as $key => $value) : ?> <dt><?= $this->translate($key) ?></dt> <dd><?= $this->escape($value) ?></dd> <?php endforeach; ?> </dl> <?php endif; ?> |
5.Check
Access the web server and check the rows of Users and Profiles
Hi, Thank you for your informative Zend Framework articles. I am new to Zend Framework and just learning how to do many things.
I would like to do something similar to what you have done with the multiselect. I have a many-to-many table similar to you. Could you explain how the values in the multiselect are highlighted, based on database data, when on the project/update page? In other words, how do the database values populate and select the members in the multiselect.
I have downloaded the db_rel_table file and am looking at the code. But I am too new to figure it out. Thank you for helping.
Tim
Hello. Thank you for your comment and sorry for late.
The values populate in the function
_executeFind
inapplication/controllers/ProjectControllers.php
.And to display the form, I used the following 2 forms(one is sub form).
application/models/forms/ProjectForms.php
application/models/forms/ProjectMemberSubForm.php
Please point it out, if this comment is irrelevant.
Thank you.
PS: this comment is about the article Using Relation Table with Zend Framework.
That is helpful, thank you. And I have been working my way through that. I’m studying your outputFilter now. It looks like that is how the project numbers determine the project names. But usage of outputFilter is not clear to me yet.
Tim
Hello.
Output Filter is just for converting values(ex. converting values of select element to corresponding labels).
It uses Zend_Input_Filter. The following document is about it.
Programmer’s Reference Guide(14.5. Zend_Filter_Input)
And Output Filter is used in views. Like the following file:
application/views/scripts/project/detail.phtml
(line:3-4)Thank you.
There are alot of hurtles to jump over for a newbee, either that or I’m slow. I’ve very slowly working my was through each problem I encounter along the way. My current problem is with the ArrayValue plugin. I’m getting this message:
Opps! An error occurred!Plugin by name ArrayValue was not found in the registry.
#0 /home/mssapps/ZendFramework-1.5.2/library/Zend/Filter/Input.php(908): Zend_Loader_PluginLoader->load(‘ArrayValue’)
#1 /home/mssapps/ZendFramework-1.5.2/library/Zend/Filter/Input.php(880): Zend_Filter_Input->_getFilterOrValidator(‘filter’, Array)
#2 /home/mssapps/ZendFramework-1.5.2/library/Zend/Filter/Input.php(576): Zend_Filter_Input->_getFilter(Array)
#3 /home/mssapps/ZendFramework-1.5.2/library/Zend/Filter/Input.php(658): Zend_Filter_Input->_filter()
#4 /home/mssapps/ZendFramework-1.5.2/library/Zend/Filter/Input.php(331): Zend_Filter_Input->_process()
#5 /var/www/application/views/scripts/san/show.phtml(26): Zend_Filter_Input->getEscaped()
#6 /home/mssapps/ZendFramework-1.5.2/library/Zend/View.php(46): include(‘/var/www/applic…’)
#7 /home/mssapps/ZendFramework-1.5.2/library/Zend/View/Abstract.php(769): Zend_View->_run(‘../../applicati…’)
#8 /home/mssapps/ZendFramework-1.5.2/library/Zend/Controller/Action/Helper/ViewRenderer.php(895): Zend_View_Abstract->render(‘san/show.phtml’)
#9 /home/mssapps/ZendFramework-1.5.2/library/Zend/Controller/Action/Helper/ViewRenderer.php(916): Zend_Controller_Action_Helper_ViewRenderer->renderScript(‘san/show.phtml’, NULL)
#10 /home/mssapps/ZendFramework-1.5.2/library/Zend/Controller/Action/Helper/ViewRenderer.php(955): Zend_Controller_Action_Helper_ViewRenderer->render()
#11 /home/mssapps/ZendFramework-1.5.2/library/Zend/Controller/Action/HelperBroker.php(161): Zend_Controller_Action_Helper_ViewRenderer->postDispatch()
#12 /home/mssapps/ZendFramework-1.5.2/library/Zend/Controller/Action.php(512): Zend_Controller_Action_HelperBroker->notifyPostDispatch()
#13 /home/mssapps/ZendFramework-1.5.2/library/Zend/Controller/Dispatcher/Standard.php(293): Zend_Controller_Action->dispatch(‘showAction’)
#14 /home/mssapps/ZendFramework-1.5.2/library/Zend/Controller/Front.php(914): Zend_Controller_Dispatcher_Standard->dispatch(Object(Zend_Controller_Request_Http), Object(Zend_Controller_Response_Http))
#15 /var/www/html/sandb/index.php(53): Zend_Controller_Front->dispatch()
#16 {main}
How do I register ArrayValue?
Thank you,
Tim
Hello.
You can register ArrayValue plugin using the method
addFilterPrefixPath
ofZend_Input_Filter
. The following file shows an example.application/models/Projects.php(line:23)
Please make sure that the file
ArrayValue.php
is in your library directory({your_library}/My/Filter/ArrayValue.php).Thank you.