Zend_Db_Table
, designed to search, insert, update and delete records in a database table.Zend_Db_Table
, you will need to tell him which database, what username and password he will use. Taking into account that this information is preferably not to be hammered into the code, we will use the configuration file for its storage.Zend_Config
class, which provides flexible object-oriented access to configuration files in INI and XML formats. Stop your choice on the ini file:zf-tutorial/application/config.ini:
[general] db.adapter = PDO_MYSQL db.config.host = localhost db.config.username = rob db.config.password = 123456 db.config.dbname = zftest
Zend_Config
will be very simple: $config = new Zend_Config_Ini('config.ini', 'section');
Zend_Config_Ini
loads one section from the INI file (in the same way, if necessary, you can load any other section). The possibility of naming sections is implemented so that unnecessary data is not needlessly loaded. Zend_Config_Ini
uses a dot in the parameter names as a hierarchical separator, making it possible to group related parameters. In our config.ini
file, the host
, username
, password
and dbname
parameters will be grouped in the $config->db->config
object.index.php
):zf-tutorial/index.php:
... Zend_Loader::loadClass('Zend_Controller_Front'); Zend_Loader::loadClass('Zend_Config_Ini'); Zend_Loader::loadClass('Zend_Registry'); // load configuration $config = new Zend_Config_Ini('./application/config.ini', 'general'); $registry = Zend_Registry::getInstance(); $registry->set('config', $config); // setup controller ...
Zend_Config_Ini
and Zend_Registry
), a section of the application/config.ini
configuration file is loaded into the $config
object under the name general
. Next, the $config
object is included in the registry, which provides access to it from the entire application.$config
in the registry. This is done as an example of the operation of a “real” application, in the configuration file of which you may have to store something more than the database access parameters. When using the registry, also note that the data in it is available at the global level, and that if used carelessly, this can cause potential conflict situations within the application.Zend_Db_Table
class, we will need to pass into it the database access parameter that was just loaded. To do this, you need to create a Zend_Db
object and register it with the Zend_Db_Table::setDefaultAdapter()
function. Below is the corresponding code snippet in the primary boot file:zf-tutorial/index.php:
... Zend_Loader::loadClass('Zend_Controller_Front'); Zend_Loader::loadClass('Zend_Config_Ini'); Zend_Loader::loadClass('Zend_Registry'); <b>Zend_Loader::loadClass('Zend_Db'); Zend_Loader::loadClass('Zend_Db_Table');</b> // load configuration $config = new Zend_Config_Ini('./application/config.ini', 'general'); $registry = Zend_Registry::getInstance(); $registry->set('config', $config); <b>// setup database $db = Zend_Db::factory($config->db->adapter, $config->db->config->toArray()); Zend_Db_Table::setDefaultAdapter($db);</b> // setup controller ...
CREATE TABLE album ( id int(11) NOT NULL auto_increment, artist varchar(100) NOT NULL, title varchar(100) NOT NULL, PRIMARY KEY (id) );
INSERT INTO album (artist, title) VALUES ('James Morrison', 'Undiscovered'), ('Snow Patrol', 'Eyes Open');
Zend_Db_Table
is an abstract class, so on its basis it is necessary to create a heir class specialized in our task. The name of a new class does not matter in principle, but such classes should be called like the corresponding DB tables (this will increase the level of self-documenting of the code). Thus, for our album
table, the class name will be Album
.Zend_Db_Table
name of the table that it will manage, you must assign this value to the protected property of the $_name
class. It should be noted that in the Zend_Db_Table
class, by default, a key auto-increment table field with the name id
always used. If necessary, the value of the name of this field can also be changed.Album
class will be stored in the model directory.zf-tutorial/application/models/Album.php:
<?php class Album extends Zend_Db_Table { protected $_name = 'album'; }
Zend_Db_Table
will be enough to fully satisfy them. If, in your tasks, you need to implement more complex operations of interaction with the database, then the class of the model is exactly the place where the corresponding code should be placed.IndexController
class. Each action function inside IndexController
interacts with the album
table through the class Album
. Therefore, it makes sense to load it when the controller is initialized inside the init()
function.zf-tutorial/application/controllers/IndexController.php:
... function init() { $this->view->baseUrl = $this->_request->getBaseUrl(); Zend_Loader::loadClass('Album'); } ...
Zend_Loader::loadClass()
method to load non-standard classes. This works, because the model directory (in which the loadable Albums
class is stored) was added by us to include_path
.indexAction()
:zf-tutorial/application/controllers/IndexController.php:
... function indexAction() { $this->view->title = "My Albums"; $album = new Album(); $this->view->albums = $album->fetchAll(); } ...
fetchAll()
function returns a Zend_Db_Table_Rowset
object, which will allow us to generate a list of all the records in a template file of the form:zf-tutorial/application/views/scripts/index/index.phtml:
<?php echo $this->render('header.phtml'); ?> <h1><?php echo $this->escape($this->title); ?></h1> <p><a href="<?php echo $this->baseUrl; ?>/index/add">Add new album</a></p> <table> <tr> <th>Title</th> <th>Artist</th> <th> </th> </tr> <?php foreach($this->albums as $album) : ?> <tr> <td><?php echo $this->escape($album->title);?></td> <td><?php echo $this->escape($album->artist);?></td> <td> <a href="<?php echo $this->baseUrl; ?>/index/edit/id/<?php echo $album->id;?>">Edit</a> <a href="<?php echo $this->baseUrl; ?>/index/delete/id/<?php echo $album->id;?>">Delete</a> </td> </tr> <?php endforeach; ?> </table> <?php echo $this->render('footer.phtml'); ?>
localhost/zf-tutorial
localhost/zf-tutorial
should now display a list of our two albums.addAction()
action addAction()
:zf-tutorial/application/controllers/IndexController.php:
... function addAction() { $this->view->title = "Add New Album"; if ($this->_request->isPost()) { Zend_Loader::loadClass('Zend_Filter_StripTags'); $filter = new Zend_Filter_StripTags(); $artist = $filter->filter($this->_request->getPost('artist')); $artist = trim($artist); $title = trim($filter->filter($this->_request->getPost('title'))); if ($artist != '' && $title != '') { $data = array( 'artist' => $artist, 'title' => $title, ); $album = new Album(); $album->insert($data); $this->_ redirect('/'); return; } } // set up an "empty" album $this->view->album = new stdClass(); $this->view->album->id = null; $this->view->album->artist = ''; $this->view->album->title = ''; // additional view fields required by form $this->view->action = 'add'; $this->view->buttonText = 'Add';</b> } ...
artist
and title
values, and process them with the HTML tag filter Zend_Filter_StripTags
. Further, if the rows have a non-empty value, we use the Album()
class to add a new record to the database table. After adding an album, the user is redirected back to the main page using the _redirect()
controller method._form.html
), which will be used in add.phtml
and edit.phtml
:zf-tutorial/application/views/scripts/index/add.phtml:
<?php echo $this->render('header.phtml'); ?> <h1><?php echo $this->escape($this->title); ?></h1> <?php echo $this->render('index/_form.phtml'); ?> <?php echo $this->render('footer.phtml'); ?>
zf-tutorial/application/views/scripts/index/_form.phtml:
<form action="<?php echo $this->baseUrl ?>/index/<?php echo $this->action; ?>" method="post"> <div> <label for="artist">Artist</label> <input type="text" name="artist" value="<?php echo $this->escape(trim($this->album->artist));?>"/> </div> <div> <label for="title">Title</label> <input type="text" name="title" value="<?php echo $this->escape($this->album->title);?>"/> </div> <div id="formbutton"> <input type="hidden" name="id" value="<?php echo $this->album->id; ?>" /> <input type="submit" name="add" value="<?php echo $this->escape($this->buttonText); ?>" /> </div> </form>
_form.phtml
also when editing records, we use the $this->action
variable instead of hard-coding the name of the necessary action. In the same way, the variable is set to the inscription on the button to transfer data from the form.zf-tutorial/application/controllers/IndexController.php:
... function editAction() { $this->view->title = "Edit Album"; $album = new Album(); if ($this->_request->isPost()) { Zend_Loader::loadClass('Zend_Filter_StripTags'); $filter = new Zend_Filter_StripTags(); $id = (int)$this->_request->getPost('id'); $artist = $filter->filter($this->_request->getPost('artist')); $artist = trim($artist); $title = trim($filter->filter($this->_request->getPost('title'))); if ($id !== false) { if ($artist != '' && $title != '') { $data = array( 'artist' => $artist, 'title' => $title, ); $where = 'id = ' . $id; $album->update($data, $where); $this->_redirect('/'); return; } else { $this->view->album = $album->fetchRow('id='.$id); } } } else { // album id should be $params['id'] $id = (int)$this->_request->getParam('id', 0); if ($id > 0) { $this->view->album = $album->fetchRow('id='.$id); } } // additional view fields required by form $this->view->action = 'edit'; $this->view->buttonText = 'Update'; } ...
id
parameter from the params
property of the Request
object using the getParam()
method.zf-tutorial/application/views/scripts/index/edit.phtml:
<?php echo $this->render('header.phtml'); ?> <h1><?php echo $this->escape($this->title); ?></h1> <?php echo $this->render('index/_form.phtml'); ?> <?php echo $this->render('footer.phtml'); ?>
addAction()
and editAction()
very similar, and the templates for adding and editing records are generally identical. It is logical to assume the need for code refactoring. Solve this problem on your own, as an additional practical exercise.zf-tutorial/application/controllers/IndexController.php:
... function deleteAction() { $this->view->title = "Delete Album"; $album = new Album(); if ($this->_request->isPost()) { Zend_Loader::loadClass('Zend_Filter_Alpha'); $filter = new Zend_Filter_Alpha(); $id = (int)$this->_request->getPost('id'); $del = $filter->filter($this->_request->getPost('del')); if ($del == 'Yes' && $id > 0) { $where = 'id = ' . $id; $rows_affected = $album->delete($where); } } else { $id = (int)$this->_request->getParam('id'); if ($id > 0) { // only render if we have an id and can find the album. $this->view->album = $album->fetchRow('id='.$id); if ($this->view->album->id > 0) { // render template automatically return; } } } // redirect back to the album list unless we have rendered the view $this->_redirect('/'); } ...
Zend_Db_Table
using the delete()
method. At the end of the function, a user is redirected to a page with a list of albums. Thus, if one of the parameter _redirect()
checks fails, it returns to the original page without the help of repeated access to _redirect()
inside the function.zf-tutorial/application/views/scripts/index/delete.phtml:
<?php echo $this->render('header.phtml'); ?> <h1><?php echo $this->escape($this->title); ?></h1> <b><?php if ($this->album) :?> <form action="<?php echo $this->baseUrl ?>/index/delete" method="post"> <p>Are you sure that you want to delete '<?php echo $this->escape($this->album->title); ?>' by '<?php echo $this->escape($this->album->artist); ?>'? </p> <div> <input type="hidden" name="id" value="<?php echo $this->album->id; ?>" /> <input type="submit" name="del" value="Yes" /> <input type="submit" name="del" value="No" /> </div> </form> <?php else: ?> <p>Cannot find album.</p> <?php endif;?></b> <?php echo $this->render('footer.phtml'); ?>
index
/ index
, most likely the reason is that the class router cannot correctly determine which directory your website is in. This situation may occur if the URL of the site does not match the path to its directory relative to the root directory opened for access from the network.$baseURL
variable to the correct value for your server:zf-tutorial/index.php:
... // setup controller $frontController = Zend_Controller_Front::getInstance(); $frontController->throwExceptions(true); $frontController->setBaseUrl('/mysubdir/zf-tutorial'); $frontController->setControllerDirectory('./application/controllers'); ...
/mysubdir/zf-tutorial/
will need to be replaced with the actual path to the index.php
file. For example, if your URL to index.php
looks like localhost/~ralle/zf-tutorial/index.php
localhost/~ralle/zf-tutorial/index.php
, the correct value for the $baseUrl
variable is /~ralle/zf-tutorial/
.Source: https://habr.com/ru/post/31173/
All Articles