ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
### 创建你的第一个字段集 > module/Blog/src/Form/PostFieldset.php ``` <?php namespace Blog\Form; use Zend\Form\Fieldset; use Blog\Model\Post; use Zend\Hydrator\Reflection as ReflectionHydrator; class PostFieldset extends Fieldset { public function init() { $this->setHydrator(new ReflectionHydrator()); $this->setObject(new Post('', '')); $this->add([ 'type' => 'hidden', 'name' => 'id', ]); $this->add([ 'type' => 'text', 'name' => 'title', 'options' => [ 'label' => 'Post Title', ], ]); $this->add([ 'type' => 'textarea', 'name' => 'text', 'options' => [ 'label' => 'Post Text', ], ]); } } ``` **创建表单类** > module/Blog/src/Form/PostForm.php ~~~ <?php namespace Blog\Form; use Zend\Form\Form; class PostForm extends Form { public function init() { $this->add([ 'name' => 'post', 'type' => PostFieldset::class, 'options' => [ 'use_as_base_fieldset' => true, ], ]); $this->add([ 'type' => 'submit', 'name' => 'submit', 'attributes' => [ 'value' => 'Insert new Post', ], ]); } } ~~~ ### 模型 帖子数据表的增删改查 **帖子命令类** > module/Blog/src/Model/PostCommand.php ~~~ <?php namespace Blog\Model; class PostCommand implements PostCommandInterface { /** * {@inheritDoc} */ public function insertPost(Post $post) { } /** * {@inheritDoc} */ public function updatePost(Post $post) { } /** * {@inheritDoc} */ public function deletePost(Post $post) { } } ~~~ **数据库命令类** > module/Blog/src/Model/ZendDbSqlCommand.php ~~~ <?php namespace Blog\Model; use RuntimeException; use Zend\Db\Adapter\AdapterInterface; use Zend\Db\Adapter\Driver\ResultInterface; use Zend\Db\Sql\Delete; use Zend\Db\Sql\Insert; use Zend\Db\Sql\Sql; use Zend\Db\Sql\Update; class ZendDbSqlCommand implements PostCommandInterface { /** * @var AdapterInterface */ private $db; /** * @param AdapterInterface $db */ public function __construct(AdapterInterface $db) { $this->db = $db; } /** * {@inheritDoc} */ public function insertPost(Post $post) { $insert = new Insert('posts'); $insert->values([ 'title' => $post->getTitle(), 'text' => $post->getText(), ]); $sql = new Sql($this->db); $statement = $sql->prepareStatementForSqlObject($insert); $result = $statement->execute(); if (! $result instanceof ResultInterface) { throw new RuntimeException( 'Database error occurred during blog post insert operation' ); } $id = $result->getGeneratedValue(); return new Post( $post->getTitle(), $post->getText(), $result->getGeneratedValue() ); } /** * {@inheritDoc} */ public function updatePost(Post $post) { } /** * {@inheritDoc} */ public function deletePost(Post $post) { } } ~~~ **数据库命令工厂类** > module/Blog/src/Factory/ZendDbSqlCommandFactory.php ~~~ <?php namespace Blog\Factory; use Interop\Container\ContainerInterface; use Blog\Model\ZendDbSqlCommand; use Zend\Db\Adapter\AdapterInterface; use Zend\ServiceManager\Factory\FactoryInterface; class ZendDbSqlCommandFactory implements FactoryInterface { public function __invoke(ContainerInterface $container, $requestedName, array $options = null) { return new ZendDbSqlCommand($container->get(AdapterInterface::class)); } } ~~~ ### 增加新建帖子功能 **创建写作控制器** > module/Blog/src/Controller/WriteController.php ``` <?php namespace Blog\Controller; use Blog\Form\PostForm; use Blog\Model\Post; use Blog\Model\PostCommandInterface; use Zend\Mvc\Controller\AbstractActionController; use Zend\View\Model\ViewModel; class WriteController extends AbstractActionController { /** * @var PostCommandInterface */ private $command; /** * @var PostForm */ private $form; /** * @param PostCommandInterface $command * @param PostForm $form */ public function __construct(PostCommandInterface $command, PostForm $form) { $this->command = $command; $this->form = $form; } public function addAction() { $request = $this->getRequest(); $viewModel = new ViewModel(['form' => $this->form]); // 注意下面的通用表单处理逻辑 if (! $request->isPost()) { return $viewModel; } $this->form->setData($request->getPost()); if (! $this->form->isValid()) { return $viewModel; } $post = $this->form->getData(); try { $post = $this->command->insertPost($post); } catch (\Exception $ex) { // An exception occurred; we may want to log this later and/or // report it to the user. For now, we'll just re-throw. throw $ex; } return $this->redirect()->toRoute( 'blog/detail', ['id' => $post->getId()] ); } } ``` **控制器工厂类** > module/Blog/src/Factory/WriteControllerFactory.php ~~~ <?php namespace Blog\Factory; use Blog\Controller\WriteController; use Blog\Form\PostForm; use Blog\Model\PostCommandInterface; use Interop\Container\ContainerInterface; use Zend\ServiceManager\Factory\FactoryInterface; class WriteControllerFactory implements FactoryInterface { /** * @param ContainerInterface $container * @param string $requestedName * @param null|array $options * @return WriteController */ public function __invoke(ContainerInterface $container, $requestedName, array $options = null) { $formManager = $container->get('FormElementManager'); return new WriteController( $container->get(PostCommandInterface::class), $formManager->get(PostForm::class) ); } } ~~~ **模块配置** > module/Blog/config/module.config.php ~~~ <?php namespace Blog; use Zend\Router\Http\Literal; use Zend\Router\Http\Segment; use Zend\ServiceManager\Factory\InvokableFactory; return [ // This lines opens the configuration for the RouteManager 'router' => [ 'routes' => [ 'blog' => [ 'type' => Literal::class, 'options' => [ 'route' => '/blog', 'defaults' => [ 'controller' => Controller\ListController::class, 'action' => 'index', ], ], 'may_terminate' => true, 'child_routes' => [ 'detail' => [ 'type' => Segment::class, 'options' => [ 'route' => '/:id', 'defaults' => [ 'action' => 'detail', ], 'constraints' => [ 'id' => '[1-9]\d*', ], ], ], // 添加以下路由: 'add' => [ 'type' => Literal::class, 'options' => [ 'route' => '/add', 'defaults' => [ 'controller' => Controller\WriteController::class, 'action' => 'add', ], ], ], ], ], ], ], 'controllers' => [ 'factories' => [ Controller\ListController::class => Factory\ListControllerFactory::class, // 添加以下行: Controller\WriteController::class => Factory\WriteControllerFactory::class, ], ], 'view_manager' => [ 'template_path_stack' => [ __DIR__ . '/../view', ], ], 'service_manager' => [ 'aliases' => [ Model\PostRepositoryInterface::class => Model\ZendDbSqlRepository::class, // 添加以下行: Model\PostCommandInterface::class => Model\ZendDbSqlCommand::class, ], 'factories' => [ Model\PostRepository::class => InvokableFactory::class, Model\ZendDbSqlRepository::class => Factory\ZendDbSqlRepositoryFactory::class, // 添加以下 2 行: Model\PostCommand::class => InvokableFactory::class, Model\ZendDbSqlCommand::class => Factory\ZendDbSqlCommandFactory::class, ], ], ]; ~~~ **模板文件** > module/Blog/view/blog/write/add.phtml ~~~ <h1>Add a blog post</h1> <?php $form = $this->form; $form->setAttribute('action', $this->url()); $fieldset = $form->get('post'); $title = $fieldset->get('title'); $title->setAttribute('class', 'form-control'); $title->setAttribute('placeholder', 'Post title'); $text = $fieldset->get('text'); $text->setAttribute('class', 'form-control'); $text->setAttribute('placeholder', 'Post content'); $submit = $form->get('submit'); $submit->setAttribute('class', 'btn btn-primary'); $form->prepare(); echo $this->form()->openTag($form); ?> <fieldset> <div class="form-group"> <?= $this->formLabel($title) ?> <?= $this->formElement($title) ?> <?= $this->formElementErrors()->render($title, ['class' => 'help-block']) ?> </div> <div class="form-group"> <?= $this->formLabel($text) ?> <?= $this->formElement($text) ?> <?= $this->formElementErrors()->render($text, ['class' => 'help-block']) ?> </div> </fieldset> <?php echo $this->formSubmit($submit); echo $this->formHidden($fieldset->get('id')); echo $this->form()->closeTag(); ~~~