Zend Framework - Рабочий пример

В этой главе мы узнаем, как создать полное приложение для сотрудников на основе MVC в Zend Framework. Следуйте инструкциям ниже.

Шаг 1: Module.php

Сначала мы должны создать модуль Employee внутри каталога - myapp / module / Employee / src /, а затем реализовать интерфейс ConfigProviderInterface.

Полный код для класса Module выглядит следующим образом:

<?php  
namespace Employee;  
use Zend\ModuleManager\Feature\ConfigProviderInterface;  
class Module implements ConfigProviderInterface { 
   public function getConfig() {    
      return include __DIR__ . '/../config/module.config.php'; 
   }    
}

Шаг 2: composer.json

Настроить Tutorial модуль в composer.json в разделе автозагрузки, используя следующий код.

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

Теперь обновите приложение, используя команду composer update.

composer update

Команда Composer внесет необходимые изменения в приложение и покажет журналы, как показано в командной строке ниже.

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

Шаг 3: module.config.php для модуля сотрудников

Создайте файл конфигурации модуля «module.config.php» в myapp / module / Employee / config с помощью следующего кода.

<?php  
namespace Employee;  
use Zend\ServiceManager\Factory\InvokableFactory; 
use Zend\Router\Http\Segment;  
return [ 
   'controllers' => [ 
      'factories' => [ 
         Controller\EmployeeController::class => InvokableFactory::class, 
      ], 
   ], 
   'view_manager' => [ 
      'template_path_stack' => ['employee' => __DIR__ . '/../view',], 
   ], 
];

Теперь настройте модуль Employee в файле конфигурации уровня приложения - myapp / config / modules.config.php.

return ['Zend\Router', 'Zend\Validator', 'Application', 'Tutorial', 'Employee'];

Шаг 4: EmployeeController

Создайте новый класс PHP, EmployeeController, расширив AbstractActionController и поместив его в каталог myapp / module / Employee / src / Controller.

Полный список кода выглядит следующим образом -

<?php  
namespace Employee\Controller;  
use Zend\Mvc\Controller\AbstractActionController; 
use Zend\View\Model\ViewModel;  
class EmployeeController extends AbstractActionController { 
   public function indexAction() { 
      return new ViewModel(); 
   } 
}

Шаг 5: Конфигурация маршрутизатора

Давайте добавим сегментный маршрут в наш модуль «Сотрудник». Обновите файл конфигурации модуля сотрудника, module.config.php, доступный в myapp / module / Employee / config.

<?php  
namespace Employee;
use Zend\ServiceManager\Factory\InvokableFactory; 
use Zend\Router\Http\Segment;  
return [ 
   'controllers' => [ 
      'factories' => [ 
         Controller\EmployeeController::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' => Controller\EmployeeController::class,
                  'action' => 'index', 
               ], 
            ], 
         ], 
      ], 
   ], 
   'view_manager' => [ 
      'template_path_stack' => [ 
         'employee' => __DIR__ . '/../view', 
      ], 
   ], 
];

Мы успешно добавили маршрутизацию для нашего модуля «Сотрудник». Следующим шагом является создание сценария просмотра для приложения Employee.

Шаг 6. Создайте ViewModel

Создайте файл под названием «index.phtml» в каталоге myapp / module / Employee / view / employee / employee.

Добавьте следующие изменения в файл -

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

<?php 
namespace Employee\Controller;  
use Zend\Mvc\Controller\AbstractActionController; 
use Zend\View\Model\ViewModel;  
class EmployeeController extends AbstractActionController { 
   public function indexAction() { 
      return new ViewModel();  
   } 
}

Наконец, мы успешно завершили модуль «Сотрудник». мы можем получить к нему доступ, используя следующий URL-адрес -http://localhost:8080/employee.

Результат

На следующем этапе мы выполним add, edit и deleteоперации с данными в приложении сотрудника. Чтобы выполнить эти операции, мы должны сначала создать модель базы данных. Это описано в следующем шаге.

Шаг 7: Создайте модель

Давайте создадим модель Employee в нашем модуле src directory. Как правило, модели группируются в папке Model (myapp / module / Employee / src / Model / Employee.php).

<?php  
namespace Employee\Model;  
class Employee { 
   public $id; public $emp_name; 
   public $emp_job; 
}

Шаг 8: таблица MySQL

Создайте базу данных с именем tutorials на локальном сервере MYSQL, используя следующую команду -

create database tutorials;

Давайте создадим таблицу с именем employee в базе данных, используя следующую команду SQL -

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) 
);

Вставьте данные в employee таблицу, используя следующий запрос -

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');

Шаг 9: Обновите конфигурацию базы данных

Обновите файл глобальной конфигурации myapp / config / autoload / global.php, указав необходимую информацию о диске базы данных.

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

Теперь обновите учетные данные базы данных в локальном файле конфигурации - myapp / config / autoload / local.php. Таким образом, мы можем разделить учетные данные для подключения к локальной и действующей базе данных.

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

Шаг 10. Реализуйте exchangeArray

Реализуйте функцию exchangeArray в модели Employee.

<?php 
namespace Employee\Model; 
class Employee { 
   public $id; 
   public $emp_name; public $emp_job;  
   public 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; 
   } 
}

Шаг 11. Используйте TableGateway для получения данных о сотрудниках

Создайте класс EmployeeTable в самой папке Model. Это определено в следующем блоке кода.

<?php  
namespace Employee\Model;  
use Zend\Db\TableGateway\TableGatewayInterface;  
class EmployeeTable { 
   protected $tableGateway; public function __construct(TableGatewayInterface $tableGateway) { 
      $this->tableGateway = $tableGateway; 
   }
   public function fetchAll() { 
      $resultSet = $this->tableGateway->select();  
      return $resultSet; 
   } 
}

Шаг 12: настройте класс EmployeeTable

Обновление службы сотрудника в module.php с помощью getServiceConfig () метод

<?php
namespace Employee;
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\EmployeeTable::class => function (    $container) {
               $tableGateway = $container>get( Model\EmployeeTableGateway::class);
               $table = new Model\EmployeeTable($tableGateway);
               return $table; }, Model\EmployeeTableGateway::class => function ($container) {
               $dbAdapter = $container->get(AdapterInterface::class);
               $resultSetPrototype = new ResultSet(); $resultSetPrototype->setArrayObjectPrototype(new Model\Employee());
               return new TableGateway('employee', $dbAdapter, null, $resultSetPrototype);
            },
         ],
      ];
   }
}

Шаг 13: добавьте службу сотрудников в контроллер

Обновите раздел контроллера конфигурации модуля сотрудников в - myapp / module / config / module.config.php, как показано ниже.

'controllers' => [
   'factories' => [
      Controller\EmployeeController::class => function($container) { return new Controller\EmployeeController( $container->get(Model\EmployeeTable::class)
         ); 
      }, 
   ], 
]

Шаг 14: добавьте конструктор для EmployeeController

Добавьте конструктор с помощью EmployeeTable в качестве аргумента и отредактируйте следующие изменения.

<?php  
namespace Employee\Controller; 
use Zend\Mvc\Controller\AbstractActionController; 
use Zend\View\Model\ViewModel;
use Employee\Model\Employee; 
use Employee\Model\EmployeeTable;  

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

Шаг 15. Отобразите информацию о сотрудниках в скрипте представления «index.phtml»

Перейти к файлу - index.phtml и внесите следующие изменения -

<?php 
$title = 'Employee application'; 
$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>

Теперь мы успешно создали модель базы данных и можем извлекать записи из приложения.

Запросите приложение, используя URL-адрес - http://localhost:8080/employee.

Результат

Следующий шаг объясняет insert, edit и delete операции с данными в модуле сотрудников.

Шаг 16. Создайте форму сотрудника

Создайте файл с именем EmployeeForm.phpв каталоге myapp / module / Employee / src / Form. Это описано в блоке кода ниже.

<?php  
namespace Employee\Form; 
use Zend\Form\Form;  

class EmployeeForm extends Form { 
   public 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', 
         ), 
      )); 
   } 
}

Шаг 17: обновите модель сотрудника

Обновите модель сотрудника и реализуйте InputFilterAwareInterface. Перейдите в каталог myapp / module / Employee / src / Employee / Model и добавьте следующие изменения вEmployee.phpfile.

<?php  
namespace Employee\Model;  

// Add these import statements 
use Zend\InputFilter\InputFilter; 
use Zend\InputFilter\InputFilterAwareInterface; 
use Zend\InputFilter\InputFilterInterface;  

class Employee implements InputFilterAwareInterface { 
   public $id; 
   public $emp_name; public $emp_job; 
   protected $inputFilter; public 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: public function setInputFilter(InputFilterInterface $inputFilter) { 
      throw new \Exception("Not used"); 
   }  
   public 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'), 
            ), 
            'validators' => 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'), ), 'validators' => array( array('name' => 'StringLength', 'options' => array( 'encoding' => 'UTF-8', 'min' => 1, 'max' => 50, ), ), ), )); $this->inputFilter = $inputFilter; } return $this->inputFilter; 
   } 
}

Шаг 18: добавьте addAction в контроллер сотрудников

Добавьте следующие изменения в EmployeeController класс.

<?php  
use Zend\Mvc\Controller\AbstractActionController; 
use Zend\View\Model\ViewModel; 
use Employee\Model\Employee;       
use Employee\Model\EmployeeTable;    
use Employee\Form\EmployeeForm;

public 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->isValid()) { $employee->exchangeArray($form->getData()); $this->table->saveEmployee($employee); // Redirect to list of employees return $this->redirect()->toRoute('employee'); 
      } 
   } 
   return array('form' => $form); 
}

Шаг 19. Добавьте функцию сохранения в класс EmployeeTable

Добавьте следующие две функции в класс EmployeeTable - myapp / module / Employee / src / Model / EmployeeTable.php

public 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; 
}  
public 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'); 
      } 
   } 
}

Шаг 20: Создайте сценарий просмотра для метода AddAction, Add.phtml

Добавьте следующие изменения в файл «Add.phtml» в - 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 application using the url, http://localhost:8080/employee/add

Результат

Как только данные будут добавлены, они будут перенаправлены на домашнюю страницу.

Шаг 21: отредактируйте записи о сотрудниках

Выполним операции редактирования данных в модуле Сотрудник. Обновите следующие изменения вEmployeecontroller.php.

public 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->isValid()) { 
         $this->table->saveEmployee($employee);  
         
         // Redirect to list of employees 
         return $this->redirect()->toRoute('employee'); } } return array('id' => $id, 'form' => $form,); 
}

Здесь мы ищем id, который находится в согласованном маршруте, а затем загрузите сведения о сотруднике для операции редактирования.

Шаг 22: Employee.php

Теперь добавьте следующие изменения в файл «Employee.php», который находится в каталоге - myapp / module / Employee / src / Employee / Model /.

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

Здесь Zend \ Stdlib \ Hydrator \ ArraySerializable ожидает найти в модели два метода: getArrayCopy() и exchangeArray().

В котором exchangeArray () используется для итерации. Эта функция используется для привязки данных из таблицы сотрудников.

Теперь нам нужно создать сценарий просмотра для editAction().

Шаг 23: Создайте Edit.phtml

Создайте файл сценария просмотра в модуле / 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();

Редактирование сведений о сотруднике показано на следующем снимке экрана.

Как только данные будут отредактированы, они будут перенаправлены на домашнюю страницу.

Шаг 24: добавьте метод deleteEmployee

Добавьте метод deleteEmployee в класс EmployeeTable - myapp / module / Employee / src / Model / EmployeeTable.php

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

Шаг 25: удалите записи о сотрудниках

Давайте теперь выполним операции удаления данных в модуле Employee. Добавьте следующий метод,deleteAction в классе EmployeeController.

public 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) 
   ); 
}

Здесь метод deleteEmployee () удаляет сотрудника по его id и перенаправляет на страницу со списком сотрудников (домашнюю страницу).

Давайте теперь создадим соответствующие скрипты представления для метода deleteAction ().

Шаг 26: Создайте сценарий просмотра

Создайте файл с именем delete.phtml в - myapp / module / Employee / view / employee / employee / delete.phtml и добавьте в него следующий код.

<?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">
   <div> 
      <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" /> 
   </div> 
</form>

Теперь удалите любого сотрудника, использующего edit ссылку на домашней странице, и результат будет таким, как показано на следующем снимке экрана.

Результат

Мы успешно завершили работу с модулем «Сотрудник», реализовав все необходимые функции.

Заключение

В нынешней конкурентной среде Zend framework занимает первое место среди разработчиков. Он предоставляет абстракции для любой программы или любого типа приложения на языке PHP. Это зрелая структура, поддерживающая современные языковые функции PHP. Это весело, профессионально, развивается и идет в ногу с современными технологиями.