English 中文(简体)
Zend Framework - Working Example
  • 时间:2024-09-17

Zend Framework - Working Example


Previous Page Next Page  

In this chapter, we will learn how to create a complete MVC based Employee Apppcation in Zend Framework. Follow the steps given below.

Step 1: Module.php

First, we should create an Employee module inside the – myapp/module/Employee/src/ directory and then implement the ConfigProviderInterface interface.

The complete code for the Module class is as follows −

<?php  
namespace Employee;  
use ZendModuleManagerFeatureConfigProviderInterface;  
class Module implements ConfigProviderInterface { 
   pubpc function getConfig() {    
      return include __DIR__ .  /../config/module.config.php ; 
   }    
}

Step 2: composer.json

Configure the Tutorial module in composer.json under the autoload section by using the following code.

"autoload": { 
   "psr-4": { 
      "Apppcation\": "module/Apppcation/src/", 
      "Tutorial\": "module/Tutorial/src/", 
      "Employee\": "module/Employee/src/" 
   } 
}

Now, update the apppcation using a composer update command.

composer update

The Composer command will do the necessary changes to the apppcation and show the logs as shown in the command prompt below.

Loading composer repositories with package information 
Updating dependencies (including require-dev) 
   - Removing zendframework/zend-component-installer (0.3.0) 
   - Instalpng zendframework/zend-component-installer (0.3.1) 
   Downloading: 100%           
    
   - Removing zendframework/zend-stdpb (3.0.1) 
   - Instalpng zendframework/zend-stdpb (3.1.0) 
   Loading from cache  
    
   - Removing zendframework/zend-eventmanager (3.0.1) 
   - Instalpng zendframework/zend-eventmanager (3.1.0) 
   Downloading: 100%           
    
   - Removing zendframework/zend-view (2.8.0) 
   - Instalpng zendframework/zend-view (2.8.1) 
   Loading from cache  
    
   - Removing zendframework/zend-servicemanager (3.1.0) 
   - Instalpng zendframework/zend-servicemanager (3.2.0) 
   Downloading: 100%           
    
   - Removing zendframework/zend-escaper (2.5.1) 
   - Instalpng zendframework/zend-escaper (2.5.2) 
   Loading from cache  
   
   - Removing zendframework/zend-http (2.5.4) 
   - Instalpng zendframework/zend-http (2.5.5) 
   Loading from cache  
    
   - Removing zendframework/zend-mvc (3.0.1)
   - Instalpng zendframework/zend-mvc (3.0.4)  
   Downloading: 100%           
   
   - Removing phpunit/phpunit (5.7.4) 
   - Instalpng phpunit/phpunit (5.7.5) 
   Downloading: 100%           
  
Writing lock file 
Generating autoload files     

Step 3: module.config.php for the Employee Module

Create the module configuration file, “module.config.php” under the myapp/module/Employee/config with the following code.

<?php  
namespace Employee;  
use ZendServiceManagerFactoryInvokableFactory; 
use ZendRouterHttpSegment;  
return [ 
    controllers  => [ 
       factories  => [ 
         ControllerEmployeeController::class => InvokableFactory::class, 
      ], 
   ], 
    view_manager  => [ 
       template_path_stack  => [ employee  => __DIR__ .  /../view ,], 
   ], 
];

Now, configure the Employee module in the apppcation level configuration file – myapp/config/modules.config.php.

return [ ZendRouter ,  ZendVapdator ,  Apppcation ,  Tutorial ,  Employee ];

Step 4: EmployeeController

Create a new PHP class, EmployeeController by extending the AbstractActionController and place it at the myapp/module/Employee/src/Controller directory.

The complete code psting is as follows −

<?php  
namespace EmployeeController;  
use ZendMvcControllerAbstractActionController; 
use ZendViewModelViewModel;  
class EmployeeController extends AbstractActionController { 
   pubpc function indexAction() { 
      return new ViewModel(); 
   } 
}

Step 5: Router Configuration

Let us add a segment route in our Employee module. Update the employee module configuration file, module.config.php available at myapp/module/Employee/config.

<?php  
namespace Employee;
use ZendServiceManagerFactoryInvokableFactory; 
use ZendRouterHttpSegment;  
return [ 
    controllers  => [ 
       factories  => [ 
         ControllerEmployeeController::class => InvokableFactory::class, 
      ], 
   ], 
    router  => [ 
       routes  => [ 
          employee  => [ 
             type  => Segment::class,
             options  => [ 
                route  =>  /employee[/:action[/:id]] ,
                constraints  => [
                   action  =>  [a-zA-Z][a-zA-Z0-9_-]* ,
                   id  =>  [0-9]+ , 
               ], 
                defaults  => [ 
                   controller  => ControllerEmployeeController::class,
                   action  =>  index , 
               ], 
            ], 
         ], 
      ], 
   ], 
    view_manager  => [ 
       template_path_stack  => [ 
          employee  => __DIR__ .  /../view , 
      ], 
   ], 
]; 

We have successfully added the routing for our Employee module. The next step is to create a view script for the Employee apppcation.

Step 6: Create ViewModel

Create a file called as “index.phtml” under the myapp/module/Employee/view/employee/employee directory.

Add the following changes in the file −

<span class = "row content"> 
   <h3>This is my first Zend apppcation</h3> 
</span> 
Move to “EmployeeController.php” file and edit the following changes, 

<?php 
namespace EmployeeController;  
use ZendMvcControllerAbstractActionController; 
use ZendViewModelViewModel;  
class EmployeeController extends AbstractActionController { 
   pubpc function indexAction() { 
      return new ViewModel();  
   } 
}

Finally, we have successfully completed the Employee module. we can access it using the following url − http://localhost:8080/employee.

Result

Apppcation Template

In the next step, we will perform add, edit and delete data operations in the employee apppcation. To perform these operations, we should first create a database model. It is described in the next step.

Step 7: Create a Model

Let us create a model, Employee in our module src directory. Generally, models are grouped under the Model folder (myapp/module/Employee/src/Model/Employee.php)

<?php  
namespace EmployeeModel;  
class Employee { 
   pubpc $id; 
   pubpc $emp_name; 
   pubpc $emp_job; 
}

Step 8: MySQL Table

Create a database named as tutorials in the local MYSQL server using the following command −

create database tutorials;

Let us create a table named as employee in the database using following SQL command −

use tutorials;  
CREATE TABLE employee ( 
   id int(11) NOT NULL auto_increment, 
   emp_name varchar(100) NOT NULL, 
   emp_job varchar(100) NOT NULL, 
   PRIMARY KEY (id) 
);

Insert data into the employee table using the following query −

INSERT INTO employee (emp_name, emp_job) VALUES ( Adam ,   Tutor ); 
INSERT INTO employee (emp_name, emp_job) VALUES ( Bruce ,   Programmer ); 
INSERT INTO employee (emp_name, emp_job) VALUES ( David ,   Designer ); 

Step 9: Update the Database Configuration

Update the Global Configuration file, myapp/config/autoload/global.php with the necessary database drive information.

return [
    db  => [
       driver  =>  Pdo ,
       dsn  =>  mysql:dbname = tutorials;host=localhost ,
       driver_options  => [PDO::MYSQL_ATTR_INIT_COMMAND =>  SET NAMES  UTF8  ],
   ],
];

Now, Update the database credentials in the local configuration file – myapp/config/autoload/local.php. In this way, we can separate local and pve database connection credentials.

<?php 
return array( 
    db  => array( username  =>  <user_name> ,  password  =>  <password> ,), 
); 

Step 10: Implement exchangeArray

Implement exchangeArray function in Employee model.

<?php 
namespace EmployeeModel; 
class Employee { 
   pubpc $id; 
   pubpc $emp_name; 
   pubpc $emp_job;  
   pubpc function exchangeArray($data) { 
      $this->id = (!empty($data[ id ])) ? $data[ id ] : null; 
      $this->emp_name = (!empty($data[ emp_name ])) ? $data[ emp_name ] : null; 
      $this->emp_job = (!empty($data[ emp_job ])) ? $data[ emp_job ] : null; 
   } 
}

Step 11: Use TableGateway to fetch the Employee Data

Create the class, EmployeeTable in the Model folder itself. It is defined in the following code block.

<?php  
namespace EmployeeModel;  
use ZendDbTableGatewayTableGatewayInterface;  
class EmployeeTable { 
   protected $tableGateway; 
   pubpc function __construct(TableGatewayInterface $tableGateway) { 
      $this->tableGateway = $tableGateway; 
   }
   pubpc function fetchAll() { 
      $resultSet = $this->tableGateway->select();  
      return $resultSet; 
   } 
}    

Step 12: Configure EmployeeTable Class

Update employee service in Module.php using getServiceConfig() method

<?php
namespace Employee;
use ZendDbAdapterAdapterInterface;
use ZendDbResultSetResultSet;
use ZendDbTableGatewayTableGateway;
use ZendModuleManagerFeatureConfigProviderInterface;

class Module implements ConfigProviderInterface {
   pubpc function getConfig() {
      return include __DIR__ .  /../config/module.config.php ;
   }
   pubpc function getServiceConfig() {
      return [
          factories  => [
            ModelEmployeeTable::class => function (    $container) {
               $tableGateway = $container>get( ModelEmployeeTableGateway::class);
               $table = new ModelEmployeeTable($tableGateway);
               return $table;
            },
            ModelEmployeeTableGateway::class => function ($container) {
               $dbAdapter = $container->get(AdapterInterface::class);
               $resultSetPrototype = new ResultSet();
               $resultSetPrototype->setArrayObjectPrototype(new ModelEmployee());
               return new TableGateway( employee , $dbAdapter, null, $resultSetPrototype);
            },
         ],
      ];
   }
}

Step 13: Add Employee Service in Controller

Update the controller section of the Employee Module Configuration in − myapp/module/config/module.config.php as shown below.

 controllers  => [
    factories  => [
      ControllerEmployeeController::class => function($container) {
         return new ControllerEmployeeController(
            $container->get(ModelEmployeeTable::class)
         ); 
      }, 
   ], 
]

Step 14: Add Constructor for EmployeeController

Add the constructor with EmployeeTable as the argument and edit the following changes.

<?php  
namespace EmployeeController; 
use ZendMvcControllerAbstractActionController; 
use ZendViewModelViewModel;
use EmployeeModelEmployee; 
use EmployeeModelEmployeeTable;  

class EmployeeController extends AbstractActionController { 
   private $table;  
   pubpc function __construct(EmployeeTable $table) { 
      $this->table = $table; 
   }  
   pubpc function indexAction() { 
      $view = new ViewModel([ 
          data  => $this->table->fetchAll(), 
      ]);  
      return $view; 
   } 
} 

Step 15: Display Employee Information in the view script “index.phtml”

Move to the file − index.phtml and make the following changes −

<?php 
$title =  Employee apppcation ; 
$this->headTitle($title); 
?>  

<table class="table"> 
   <tr> 
      <th>Employee Name</th> 
      <th>Employee Job</th> 
      <th>Edit/Delete operations</th>
   </tr> 
   <?php foreach ($data as $empdata) : ?> 
   <tr>  
      <td><?php echo $this->escapeHtml($empdata->emp_name);?></td> 
      <td><?php echo $this->escapeHtml($empdata->emp_job);?></td> 
      <td> 
         <a href="<?php echo $this->url( employee , 
            array( action => edit ,  id  =>$empdata->id));?>">Edit</a> 
         <a href="<?php echo $this->url( employee , 
            array( action => delete ,  id  => $empdata->id));?>">Delete</a> 
      </td> 
   </tr> 
   <?php endforeach; ?> 
</table> 

Now we have successfully created a database model and can fetch the records within the apppcation.

Request the apppcation using the url − http://localhost:8080/employee.

Result

Successful Database

The next step explains about the insert, edit and delete data operations in the employee module.

Step 16: Create an Employee Form

Create a file called EmployeeForm.php in myapp/module/Employee/src/Form directory. It is described in the code block below.

<?php  
namespace EmployeeForm; 
use ZendFormForm;  

class EmployeeForm extends Form { 
   pubpc function __construct($name = null) { 
      /
      / we want to ignore the name passed 
      parent::__construct( employee );  
      $this->add(array( 
          name  =>  id , 
          type  =>  Hidden , 
      )); 
      $this->add(array( 
          name  =>  emp_name , 
          type  =>  Text , 
          options  => array( 
             label  =>  Name , 
         ), 
      )); 
      $this->add(array( 
          name  =>  emp_job , 
          type  =>  Text , 
          options  => array( 
             label  =>  Job , 
         ), 
      )); 
      $this->add(array( 
          name  =>  submit , 
          type  =>  Submit , 
          attributes  => array(
             value  =>  Go , 
             id  =>  submitbutton , 
         ), 
      )); 
   } 
}                    

Step 17: Update the Employee Model

Update the employee model and implement the InputFilterAwareInterface. Move to the directory myapp/module/Employee/src/Employee/Model and add the following changes in the Employee.phpfile.

<?php  
namespace EmployeeModel;  

// Add these import statements 
use ZendInputFilterInputFilter; 
use ZendInputFilterInputFilterAwareInterface; 
use ZendInputFilterInputFilterInterface;  

class Employee implements InputFilterAwareInterface { 
   pubpc $id; 
   pubpc $emp_name; 
   pubpc $emp_job; 
   protected $inputFilter;                         
   pubpc function exchangeArray($data) { 
      $this->id = (isset($data[ id ])) ? $data[ id ] : null;         
      $this->emp_name = (isset($data[ emp_name ])) ? $data[ emp_name ] : null;         
      $this->emp_job = (isset($data[ emp_job ]))  ? $data[ emp_job ] : null; 
   }  
    
   // Add content to these methods:
   pubpc function setInputFilter(InputFilterInterface $inputFilter) { 
      throw new Exception("Not used"); 
   }  
   pubpc function getInputFilter() { 
      if (!$this->inputFilter) { 
         $inputFilter = new InputFilter();  
         $inputFilter->add(array( 
             name  =>  id , 
             required  => true, 
             filters  => array( 
               array( name  =>  Int ), 
            ), 
         ));  
         $inputFilter->add(array( 
             name  =>  emp_name , 
             required  => true, 
             filters  => array( 
               array( name  =>  StripTags ), 
               array( name  =>  StringTrim ), 
            ), 
             vapdators  => array( 
               array( name  =>  StringLength , 
                         options  => array( 
                            encoding  =>  UTF-8 , 
                            min  => 1, 
                            max  => 50, 
                        ), 
                    ), 
                ), 
            ));
         $inputFilter->add(array( 
             name  =>  emp_job , 
             required  => true, 
             filters  => array( 
               array( name  =>  StripTags ),  
               array( name  =>  StringTrim ), 
            ), 
             vapdators  => array( 
               array( name  =>  StringLength , 
                   options  => array( 
                      encoding  =>  UTF-8 , 
                      min  => 1, 
                      max  => 50, 
                  ), 
                  ), 
               ), 
         ));  
         $this->inputFilter = $inputFilter; 
      } 
      return $this->inputFilter; 
   } 
}             

Step 18: Add addAction in the Employee Controller

Add the following changes in the EmployeeController class.

<?php  
use ZendMvcControllerAbstractActionController; 
use ZendViewModelViewModel; 
use EmployeeModelEmployee;       
use EmployeeModelEmployeeTable;    
use EmployeeFormEmployeeForm;

pubpc function addAction() { 
   $form = new EmployeeForm();  
   $form->get( submit )->setValue( Add );  
   $request = $this->getRequest(); 
   
   if ($request->isPost()) { 
      $employee = new Employee(); 
      $form->setInputFilter($employee->getInputFilter()); 
      $form->setData($request->getPost());  
      
      if ($form->isVapd()) { 
         $employee->exchangeArray($form->getData()); 
         $this->table->saveEmployee($employee);  
         
         // Redirect to pst of employees 
         return $this->redirect()->toRoute( employee ); 
      } 
   } 
   return array( form  => $form); 
} 

Step 19: Add save functionapty in the EmployeeTable class

Add the following two functions in the EmployeeTable class – myapp/module/Employee/src/Model/EmployeeTable.php

pubpc function getEmployee($id) { 
   $id  = (int) $id; 
   $rowset = $this->tableGateway->select(array( id  => $id)); 
   $row = $rowset->current();  
   if (!$row) { 
      throw new Exception("Could not find row $id"); 
   }
   return $row; 
}  
pubpc function saveEmployee(Employee $employee) { 
   $data = array (  
       emp_name  => $employee->emp_name, 
       emp_job   => $employee->emp_job, 
   );  
   $id = (int) $employee->id; 
   if ($id == 0) { 
      $this->tableGateway->insert($data); 
   } else { 
      if ($this->getEmployee($id)) { 
         $this->tableGateway->update($data, array( id  => $id)); 
      } else { 
         throw new Exception( Employee id does not exist ); 
      } 
   } 
}

Step 20: Create View script for AddAction method, Add.phtml

Add the following changes in the “Add.phtml” file in the − myapp/module/view/employee/employee.

<?php 
   $title =  Add new employee ; 
   $this->headTitle($title); 
?> 
<h1><?php echo $this->escapeHtml($title); ?></h1>  

<?php 
   $form->setAttribute( action , $this->url( employee , array( action  =>  add ))); 
   $form->prepare(); 
   echo $this->form()->openTag($form); 
   echo $this->formHidden($form->get( id )); 
   echo $this->formRow($form->get( emp_name ))."<br>"; 
   echo $this->formRow($form->get( emp_job ))."<br>";   
   echo $this->formSubmit($form->get( submit )); 
   echo $this->form()->closeTag(); 
Request the apppcation using the url, http://localhost:8080/employee/add 

Result

New Employee

Once the data has been added, it will redirect to the home page.

Redirect Home Page

Step 21: Edit Employee Records

Let us perform the editing data operations in the Employee module. Update the following changes in the Employeecontroller.php.

pubpc function editAction() { 
   $id = (int) $this->params()->fromRoute( id , 0); 
   if (!$id) { 
      return $this->redirect()->toRoute( employee , array( 
          action  =>  add  
      )); 
   }  
   try { 
      $employee = $this->table->getEmployee($id); 
   } catch (Exception $ex) { 
      return $this->redirect()->toRoute( employee , array( 
          action  =>  index  
      )); 
   }  
   $form = new EmployeeForm(); 
   $form->bind($employee); 
   $form->get( submit )->setAttribute( value ,  Edit );  
   $request = $this->getRequest(); 
   
   if ($request->isPost()) { 
      $form->setInputFilter($employee->getInputFilter()); 
      $form->setData($request->getPost());  
      if ($form->isVapd()) { 
         $this->table->saveEmployee($employee);  
         
         // Redirect to pst of employees 
         return $this->redirect()->toRoute( employee ); 
      } 
   }  
   return array( id  => $id,  form  => $form,); 
}

Here, we look for the id, which is in the matched route and then load the employee details for the editing operation.

Step 22: Employee.php

Now add the following changes in the “Employee.php” file, which resides in the − myapp/module/Employee/src/Employee/Model/ directory.

pubpc function getArrayCopy() { 
   return get_object_vars($this); 
}

Here, the ZendStdpbHydratorArraySeriapzable expects to find two methods in the model: getArrayCopy() and exchangeArray().

In which, the exchangeArray() is used for iteration. This function is used for binding the data from the employee table.

Now, we need to create a view script for editAction().

Step 23: Create Edit.phtml

Create a view script file in the module/Employee/view/employee/employee/edit.phtml

<?php 
   $title =  Edit employee records ; 
   $this->headTitle($title); 
?>  
<h1><?php echo $this->escapeHtml($title); ?></h1>  

<?php 
$form = $this->form;  
$form->setAttribute( action , $this->url( 
    employee , 
   array( action  =>  edit ,  id  => $this->id,) 
)); 
$form->prepare();  
echo $this->form()->openTag($form); 
echo $this->formHidden($form->get( id )); 
echo $this->formRow($form->get( emp_name ))."<br>"; 
echo $this->formRow($form->get( emp_job ))."<br>"; 
echo $this->formSubmit($form->get( submit )); 
echo $this->form()->closeTag();

Editing the employee details is shown in the following screenshot.

Edit Record

Once the data has been edited, it will redirect to the home page.

Edited Data

Step 24: Add deleteEmployee method

Add the deleteEmployee method in the EmployeeTable class – myapp/module/Employee/src/Model/EmployeeTable.php

pubpc function deleteEmployee($id) { 
   $this->tableGateway->delete([ id  => (int) $id]); 
}

Step 25: Delete the Employee Records

Let us now perform the deleting data operations in the Employee module. Add the following method, deleteAction in the EmployeeController class.

pubpc function deleteAction() { 
   $id = (int) $this->params()->fromRoute( id , 0); 
   if (!$id) { 
      return $this->redirect()->toRoute( employee ); 
   }  
   $request = $this->getRequest(); 
   if ($request->isPost()) { 
      $del = $request->getPost( del ,  No );  
      if ($del ==  Yes ) { 
         $id = (int) $request->getPost( id );
         $this->table->deleteEmployee($id); 
      } 
      return $this->redirect()->toRoute( employee ); 
   }  
   return array( 
       id  => $id, 
       employee  => $this->table->getEmployee($id) 
   ); 
}            

Here, the deleteEmployee() method deletes the employee by his id and redirects to the employees pst page (home page).

Let us now create a corresponding view scripts for the deleteAction() method.

Step 26: Create a View Script

Create a file named delete.phtml in the − myapp/module/Employee/view/employee/employee/delete.phtml and add the following code in it.

<?php 
   $title =  Delete an employee record ; 
   $this->headTitle($title);  
?> 
<h1><?php echo $this->escapeHtml($title); ?></h1>  

 <?php echo $this->escapeHtml($employee->emp_name); ?>  by 
 <?php echo $this->escapeHtml($employee->emp_job); ?& ?  
<?php 
   $url = $this->url( employee , array( action  =>  delete ,  id  => $this->id,)); 
?>  

<form action ="<?php echo $url; ?>" method = "post">
   <span> 
      <input type = "hidden" name = "id" value = "<?php echo (int) $employee->id; ?>" /> 
      <input type = "submit" name = "del" value = "Yes" /> 
      <input type = "submit" name = "del" value = "No" /> 
   </span> 
</form>  

Now, delete any employee using the edit pnk in the home page and the result will be as shown in the following screenshot.

Result

Deleted Record

We have successfully completed the Employee module by implementing all necessary features.

Conclusion

In the current competitive environment, Zend framework is placed at the top spot by the developer. It provides abstractions to any program or any type of an apppcation in the PHP language. It is a matured framework and supports modern PHP language features. It is fun, professional, evolving and keeping pace with the current technology.

Advertisements