In this chapter, we will discuss regarding the various models and the database of the Zend Framework.
A Model defines the logical data representation of the application. For example, in a shopping cart application – Product, Customer, Cart and Orders are models. They define the properties of the entity it holds. Some of the concepts of models are as follows −
Controllers communicate with models and ask them to retrieve information they need. This retrieved information is then passed by the controller to the View. Finally, View will render the model as user consumable presentational data.
It is very rare that a model directly interacts with a view, but sometimes it may happen.
Models can talk with each other and aren't self-contained. They have relationships with each other. These relationships make it easier and quicker for a controller to get information, since it doesn't have to interact with different models; the models can do that themselves.
Let us take a look at a simple model – MyModel
<?php namespace Tutorial\Model; class Book { public $id; public $author; public $title; }
Zend framework provides a simple and feature-rich class, Zend\Db\TableGateway\TableGateway to find, insert, update and delete data from a database table.
Let us see how to connect the MySqlservice via PHP's PDO driver in Zend framework through the following steps.
Create database tutorials in the local MySQL server. We can use phpmyadmin or any other MySQL GUI tools for this purpose. Let us use the MySQL client in the command prompt. Connect to the mysql server and run the following command to create the tutorial database.
create database tutorials
Let us now create a database book in the tutorials db using the following SQL command.
use tutorials; CREATE TABLE book ( id int(11) NOT NULL auto_increment, author varchar(100) NOT NULL, title varchar(100) NOT NULL, PRIMARY KEY (id) );
Populate the book table with sample data. Use the following SQL command.
INSERT INTO book (author, title) VALUES ('Dennis Ritchie', 'C Programming'); INSERT INTO book (author, title) VALUES ('James gosling', 'Java Programming'); INSERT INTO book (author, title) VALUES ('Rasmus Lerdorf', 'Programming PHP');
Update the global configuration file, which is – myapp/config/autoload/global.php with the necessary database drive information.
<?php return array( 'db' => array( 'driver' => 'Pdo', 'dsn' => 'mysql:dbname = tutorials;host = localhost', 'driver_options' => array( PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\'' ), ), 'service_manager' => array( 'factories' => array( 'Zend\Db\Adapter\Adapter' => 'Zend\Db\Adapter\AdapterServiceFactory', ), ), );
Update the database credentials in the local configuration file, which is – myapp/config/autoload/local.php. In this way, we can separate the local and live database connection credentials.
<?php return array( 'db' => array( 'username' => '<user_name>', 'password' => '<password>', ), );
Let us create a Model, Book in our module src directory. Generally, models are grouped under the Model folder – /myapp/module/Tutorial/src/Model/Book.php.
<?php namespace Tutorial\Model; class Book { public $id; public $author; public $title; }
The TableGateway interacts with a model through the exchangeArray function. The standard argument of the exchangeArray function is the database result set stored as the PHP array. Using the exchangeArrayfunction, a model's property can be easily synced with the corresponding database table.
Update the model, Book as shown below −
<?php namespace Tutorial\Model; class Book { public $id; public $author; public $title; public function exchangeArray($data) { $this->id = (!empty($data['id'])) ? $data['id'] : null; $this->Author = (!empty($data['author'])) ? $data['author'] : null; $this->Title = (!empty($data['title'])) ? $data['title'] : null; } }
Create a class, BookTable to fetch book information from the database. Create the class, BookTable in the Model folder itself.
<?php namespace Tutorial\Model; use Zend\Db\TableGateway\TableGatewayInterface; class BookTable { protected $tableGateway; public function __construct(TableGatewayInterface $tableGateway) { $this->tableGateway = $tableGateway; } public function fetchAll() { $resultSet = $this->tableGateway->select(); return $resultSet; } }
We have used select() method of the TableGateway class to fetch the book information from the database. But, we have not used any reference to the table – book in the code. The TableGateway is generic in nature and it can fetch data from any table by using certain configuration. Usually, these configurations are done in the module.config.php file, which we will discuss in the subsequent steps.
Update the tutorial module, Module.php with the getServiceConfig() method.
<?php namespace Tutorial; use Zend\Db\Adapter\AdapterInterface; use Zend\Db\ResultSet\ResultSet; use Zend\Db\TableGateway\TableGateway; use Zend\ModuleManager\Feature\ConfigProviderInterface; class Module implements ConfigProviderInterface { public function getConfig() { return include __DIR__ . '/../config/module.config.php'; } public function getServiceConfig() { return [ 'factories' => [ Model\BookTable::class => function ($container) { $tableGateway = $container->get(Model\BookTableGateway::class); $table = new Model\BookTable($tableGateway); return $table; }, Model\BookTableGateway::class => function ($container) { $dbAdapter = $container->get(AdapterInterface::class); $resultSetPrototype = new ResultSet(); $resultSetPrototype->setArrayObjectPrototype(new Model\Book()); return new TableGateway('book', $dbAdapter, null, $resultSetPrototype); }, ], ]; } }
Here, we have registered the BookTable class using the service manager. The BookTable class is used to fetch the book information and by registering it, we can access it wherever needed. Since, the registered services are shared, they increase performance, reduce the memory consumption, etc.
Another item, Model\BookTableGateway::class is the TableGateway object specialized for the Book model and is a dependency of the BookTable.
We need the BookTable service in the tutorial controller to fetch the book information. To get the BookTable service, register it as constructor dependency in the TutorialController.
This Constructor dependency helps to get the BookTable service while the controller itself is in the initialization stage. Update the controller section of the tutorial module configuration, module.config.php as shown below.
'controllers' => [ 'factories' => [ Controller\TutorialController::class => function($container) { return new Controller\TutorialController( $container->get(Model\BookTable::class) ); }, ], ],
This is done by adhering to the following three steps.
private $table; public function __construct(BookTable $table) { $this->table = $table; }
Fetch book information using the BookTable's fetchAll() method and register it into the view.
public function indexAction() { $view = new ViewModel([ 'data' => $this->table->fetchAll(), ]); return $view; }
Display the book information in the view script.
<table class = "table"> <tr> <th>Author</th> <th>Title</th> <th> </th> </tr> <?php foreach ($data as $sampledata) : ?> <tr> <td><?php echo $this->escapeHtml($data->author);?></td> <td><?php echo $this->escapeHtml($data->title);?></td> </tr> <?php endforeach ?> </table>
Check the application by running − http://localhost:8080/tutorial.