最新文章专题视频专题问答1问答10问答100问答1000问答2000关键字专题1关键字专题50关键字专题500关键字专题1500TAG最新视频文章推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37视频文章20视频文章30视频文章40视频文章50视频文章60 视频文章70视频文章80视频文章90视频文章100视频文章120视频文章140 视频2关键字专题关键字专题tag2tag3文章专题文章专题2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章专题3
问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501
当前位置: 首页 - 科技 - 知识百科 - 正文

zendframework2使用教程【二】–读取数据

来源:懂视网 责编:小采 时间:2020-11-09 07:42:45
文档

zendframework2使用教程【二】–读取数据

zendframework2使用教程【二】–读取数据:这篇教程篇幅可能会很长,大家要有耐心看,文章最后有源码下载,站长建议大家下载了源码后对照教程看,会更顺畅。 zf2是用模块系统在每个模块中来组织管理你的主应用程序代码,在上一教程中,Application模块被用来向整个应用程序提供bootstrapping
推荐度:
导读zendframework2使用教程【二】–读取数据:这篇教程篇幅可能会很长,大家要有耐心看,文章最后有源码下载,站长建议大家下载了源码后对照教程看,会更顺畅。 zf2是用模块系统在每个模块中来组织管理你的主应用程序代码,在上一教程中,Application模块被用来向整个应用程序提供bootstrapping

这篇教程篇幅可能会很长,大家要有耐心看,文章最后有源码下载,站长建议大家下载了源码后对照教程看,会更顺畅。 zf2是用模块系统在每个模块中来组织管理你的主应用程序代码,在上一教程中,Application模块被用来向整个应用程序提供bootstrapping,错误处理

这篇教程篇幅可能会很长,大家要有耐心看,文章最后有源码下载,站长建议大家下载了源码后对照教程看,会更顺畅。

zf2是用模块系统在每个模块中来组织管理你的主应用程序代码,在上一教程中,Application模块被用来向整个应用程序提供bootstrapping,错误处理和路由控制。它通常为每个应用的首页提供应用层的控制器,但是在这个教程中我们将不使用这个默认的模块,因为我们想要相册列表作为我们的主页,这将由我们自己创建的模块来完成。

我们将把所有的代码放置于Album模块中,其中包含控制器、模型、表单和视图,当然是经过配置的。我们会根据需要来对Application模块进行调整。

我们首先来创建模块目录。

在module目录中创建一个名为Album的目录,结构如下:

zf/
 /module
 /Album
 /config
 /src
 /Album
 /Controller
 /Form
 /Model
 /view
 /album
 /album
正如你所见,Album模块为我们将创建的不同类型的文件分配了独立的目录。在Album名称空间内包含有类的PHP文件位于src/Album目录,所以当我们需要时,在我们的模块中我们可以拥有多个名称空间。view目录也有一个名为album的子目录,该目录中存放我们的视图脚本。

zf2提供了一个ModuleManager【模块管理器】来载入和配置模块。它将在模块根目录【这里是module/album】中查找module.php,并且希望在文件中找到一个名为module的类,这就是说已知模块中的类将拥有模块名字的名称空间,即模块目录的名称。

在Album模块中创建Module.php:在zf/Module/Album目录中创建Module.php:
 array(
 __DIR__ . '/autoload_classmap.php',
 ),
 'Zend\Loader\StandardAutoloader' => array(
 'namespaces' => array(
 __NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__,
 ),
 ),
 );
 }

 public function getConfig()
 {
 return include __DIR__ . '/config/module.config.php';
 }
}

模块管理器将为我们自动调用 getAutoloaderConfig()和getConfig()方法。

getAutoloaderConfig()方法将返回一个数组,该数组与zf2的AutoloaderFactory兼容。为了对它进行配置,所以我们要向ClassmapAutoloader添加一个类映射文件,并且将该模块的名称空间添加到StandardAutoloader【标准自动载入器】。StandardAutoloader需要一个名称空间和路径来查找文件。它遵循PSR-0标准,所以类名到文件名的映射规则跟PSR-0 rules中的每个规则一样。

由于我们是在开发中,所以我们不需要使用类映射来载入文件。所以我们为类映射自动载入器提供了一个空数组,在Module/Album目录中创建一个名为autoload_classmap.php的文件,代码如下:
StandardAutoloader【标准自动载入器】。

在注册了自动载入器之后,让我们再来看一看getConfig()方法。这个方法仅仅载入config/module.config.php文件。

在module/Album/config目录中创建一个名为module.config.php的文件:
 array(
 'invokables' => array(
 'Album\Controller\Album' => 'Album\Controller\AlbumController',
 ),
 ),
 'view_manager' => array(
 'template_path_stack' => array(
 'album' => __DIR__ . '/../view',
 ),
 ),
);

配置信息将会由ServiceManager【服务管理器】传递给相关组件,我们需要2个初始部分:controllers【控制器】和view_manager【视图管理器】。控制器部分呈现了由模块提供的所有控制器列表;我们将需要一个控制器:AlbumController。通过键名"Album\Controller\Album"来引用,控制器名称必须在整个模块中唯一,所以我们为它加了一个前缀--即我们的模块名称。

在view_manager部分,我们将添加我们的视图目录到TemplatePathStack选项,这将允许它在我们的view目录中找到Album模块的视图脚本。

现在我们需要告诉ModuleManager【模块管理器】,这个新的模块存在。我们可以在config/application.config.php文件中完成这项工作,更新这个文件,那么它的的modules部分将包含Album模块,所以该文件现在的内容应该如下:
 array(
 'Application',
 'Album', // <-- 这是我们需要添加的行
 ),
 'module_listener_options' => array(
 'config_glob_paths' => array(
 'config/autoload/{,*.}{global,local}.php',
 ),
 'module_paths' => array(
 './module',
 './vendor',
 ),
 ),
);
正如你所见,我们将Album模块添加到了Application模块之后。

我们现在可以准备为我们的模块添加自定义的代码了。

我们将建立一个非常简单的存货清单系统来展现我们的相册集合。在主页中,我们将列出相册集合并且允许我们添加、修改和删除。我们将需要以下页面:
Page Description
主页 现实相册列表并提供修改、删除的链接。同样的还有一个添加新相册的链接。
添加新相册 这个页面将允许我们添加新的相册。
编辑相册 这个页面将提供一个表单来编辑相册
删除相册 这个页面将确认我们想删除一个相册并最终删除它。
在我们建立我们的文件之前,理解框架如何组织页面非常重要。应用程序中的每个页面都被视作为一个action【动作】,而所有的actions都位于模块的控制器中。因此,一般来说你需要将相关的action组织到对应的控制器中,例如,一个全新的控制器可能含有actions:current, archivedview。

由于我们的相册系统含有4个页面,我们将把它们组织到Album模块的 AlbumController控制器中,作为4个actions。如下:
Page Controller Action
主页 AlbumController index
添加新相册 AlbumController add
编辑相册 AlbumController edit
删除相册 AlbumController delete
从URL到一个action的映射,使用路由来完成。可以在模块的module.config.php文件中定义路由。我们将为actions定义路由,以下是配置过的
module.config.php文件,高亮部分是新加的:
 array(
 'invokables' => array(
 'Album\Controller\Album' => 'Album\Controller\AlbumController',
 ),
 ),

 // 下面的部分是新加的,你应该将它们添加到你自己的文件中
 'router' => array(
 'routes' => array(
 'album' => array(
 'type' => 'segment',
 'options' => array(
 'route' => '/album[/:action][/:id]',
 'constraints' => array(
 'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
 'id' => '[0-9]+',
 ),
 'defaults' => array(
 'controller' => 'Album\Controller\Album',
 'action' => 'index',
 ),
 ),
 ),
 ),
 ),

 'view_manager' => array(
 'template_path_stack' => array(
 'album' => __DIR__ . '/../view',
 ),
 ),
);
路由的名称叫album,类型【type】为segment,segment【分割】路由将允许我们识别url中的占位符,并且将这些占位符映射到匹配出的路由中的参数。在当前情况下是:/album[/:action][/:id],它将匹配任何以/album开头的url,下一个segment将会是一个可选的action的名称,再下一个将被映射到一个可选的id,方括号表示一个segment是可选的。constraints部分,将限制segment的字符是我们所预期的,在这里我们限制action以一个字母开头,接下来的字符只能是字母、下划线或星号。我们将id限制为数字。

这项路由将允许我们拥有下面的url:
URL Page Action
/album 主页 index
/album/add 添加新相册 add
/album/edit/2 使用id2编辑相册 edit
/album/delete/4 使用id4删除相册 delete

下面我们准备建立控制器:在zf2中,控制器是一个被称为{Controllername}Controller的类。{Controllername}必须以大写字母开头,这个类位于一个名叫 {Controllername}Controller.php的文件中,该文件位于模块的Controller目录。在这里,即:module/Album/src/Album/Controller。每一个行为在控制器中是一个public方法,以{action name}Action形式命名,这里的{action name}应该以小写字母开头。

让我们在zf/module/Album/src/Album/Controller目录中继续创建我们的控制类:AlbumController.php,代码如下:

URL Method called
http://localhost/zf/public/album Album\Controller\AlbumController::indexAction
http://localhost/zf/public/album/add Album\Controller\AlbumController::addAction
http://localhost/zf/public/album/edit Album\Controller\AlbumController::editAction
http://localhost/zf/public/album/delete Album\Controller\AlbumController::deleteAction

我们现在拥有了一个可用的路由器,并且已经为应用程序的每个页面建立了action。

现在是时候建立视图和模型层了。

为了将视图整合进我们的应用,我们需要做的就是创建视图脚本文件。这些文件将由DefaultViewStrategy【默认视图策略】来执行,并且可以传递给由控制器action方法返回的任何变量或视图模型。这些视图脚本存储在我们模块的视图目录中,目录名称跟控制器目录名称一样。创建如下4个空视图文件:

  • module/Album/view/album/album/index.phtml
  • module/Album/view/album/album/add.phtml
  • module/Album/view/album/album/edit.phtml
  • module/Album/view/album/album/delete.phtml
  • 现在我们可以向其中填充任何内容,接下来开始使用数据库和模型。

    我们创建一个名为zf的数据库,使用下面的语句建立数据表并插入测试数据:

    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 ('The Military Wives', 'In My Dreams');
    INSERT INTO album (artist, title)
     VALUES ('Adele', '21');
    INSERT INTO album (artist, title)
     VALUES ('Bruce Springsteen', 'Wrecking Ball (Deluxe)');
    INSERT INTO album (artist, title)
     VALUES ('Lana Del Rey', 'Born To Die');
    INSERT INTO album (artist, title)
     VALUES ('Gotye', 'Making Mirrors');
    
    我们将使用PHP的PDO驱动,现在我们在数据库中有了一些测试数据,我们可以为它写一个非常简单的模型。
    
    zf2并不提供一个Zend\Model组件,因为model是你自己的业务逻辑,由你自己来决定它如何工作。根据你的需求,这里有许多其他的组件供你选择。其中一个方法是让你的模型类在应用程序中呈现每个实体,然后使用映射对象来载入和保存实体内容到数据库。另一种方法是使用ORM,就像Doctrine或Propel。
    
    在本教程中,我们将使用Zend\Db\TableGateway\TableGateway类来创建一个非常简单的模型--AlbumTable类,在TableGateway中,每一个album对象都是一个Album对象【即实体】,这是一种”表数据网关设计模式“的部署方式,它允许我们访问数据库中的一张表里的数据。需要注意,尽管如此,表数据网关设计模式在较大的系统中可能成为瓶颈。可能你想要把数据库访问代码放置于一个控制器action方法里,因为这些都呈现在 Zend\Db\TableGateway\AbstractTableGateway中,zf2开发小组强烈建议你不要这么做!
    
    现在我们在module/Album/src/Album/Model:目录中来创建一个名为Album.php的文件。代码如下:
    
    id = (isset($data['id'])) ? $data['id'] : null;
     $this->artist = (isset($data['artist'])) ? $data['artist'] : null;
     $this->title = (isset($data['title'])) ? $data['title'] : null;
     }
    }
    
    我们的Album实体对象是一个简单的php类。为了让它与Zend\Db’s TableGateway一起工作,我们需要实现一个exchangeArray()方法。这个方法将由数组传递过来的数据复制给实体的属性。稍后,我们将为我们的表单添加一个输入过滤器。
    
    接下来,我们在module/Album/src/Album/Model目录中创建AlbumTable.php。代码如下:
    
    tableGateway = $tableGateway;
     }
    
     public function fetchAll()
     {
     $resultSet = $this->tableGateway->select();
     return $resultSet;
     }
    
     public function getAlbum($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 saveAlbum(Album $album)
     {
     $data = array(
     'artist' => $album->artist,
     'title' => $album->title,
     );
    
     $id = (int)$album->id;
     if ($id == 0) {
     $this->tableGateway->insert($data);
     } else {
     if ($this->getAlbum($id)) {
     $this->tableGateway->update($data, array('id' => $id));
     } else {
     throw new \Exception('Form id does not exist');
     }
     }
     }
    
     public function deleteAlbum($id)
     {
     $this->tableGateway->delete(array('id' => $id));
     }
    }
    
    我们仍然有许多事情要做,第一,我们要为TableGateway实体设置一个访问规则为protected的属性$tableGateway,它被传递给构造函数。我们将使用这个类来为我们的相册系统操作数据库。
    
    接下来我们还要创建一些应用程序要用来与表数据网关交互的方法, fetchAll()方法从数据库获取所有的相册记录,类型为ResultSet【结果集】。getAlbum()方法将获取单独的一行记录作为一个Album对象,saveAlbum()方法可以在数据库创建一条新的记录或者更新一条已存在的记录。deleteAlbum()将完全删除一条记录。这些方法的代码意义当然是不言自明。
    
    为了总是能够使用AlbumTable对象的相同实例,我们将使用ServiceManager【服务管理器】来定义如何创建一个实例。在模型类中这是最容易完成的,在类里我们创建一个getServiceConfig()方法,它将被ModuleManager自动调用,并且应用到ServiceManager。当我们需要它的时候,我们就能够重新获得。
    
    要配置ServiceManager,我们可以在ServiceManager需要的时候,提供一个将被实例化的类的名称或者实例化对象的工厂(闭包或回调函数)。我们首先来实现getServiceConfig()方法,该方法提供一个创建AlbumTable的工厂。将这个方法添加到 Module.php的底部,位于module/Album。
    
     array(
     'Album\Model\AlbumTable' => function($sm) {
     $tableGateway = $sm->get('AlbumTableGateway');
     $table = new AlbumTable($tableGateway);
     return $table;
     },
     'AlbumTableGateway' => function ($sm) {
     $dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
     $resultSetPrototype = new ResultSet();
     $resultSetPrototype->setArrayObjectPrototype(new Album());
     return new TableGateway('album', $dbAdapter, null, $resultSetPrototype);
     },
     ),
     );
     }
    }
    
    这个方法返回一个工厂数组,在被传递给ServiceManager之前,这些工厂都被ModuleManager整合在一起。Album\Model\AlbumTable的工厂使用ServiceManager来创建一个传递给AlbumTable的AlbumTableGateway。我们同时也告诉了ServiceManager一个AlbumTableGateway通过获取Zend\Db\Adapter\Adapter【这也是从ServiceManager获取的】被创建,我们将使用AlbumTableGateway来创建一个TableGateway对象。 一旦 TableGateway创建一个新的结果行,它将被告知使用一个Album对象。TableGateway类在创建结果集和实体时,使用原型模式。这意味着,当需要时,代之于即时实例化,系统将克隆一个预先实例化好了的对象。查看PHP Constructor Best Practices and the Prototype Pattern以获取更多细节。
    
    最后我们需要配置ServiceManager,这样它就知道该如何来获取一个 Zend\Db\Adapter\Adapter。我们将使用一个名叫Zend\Db\Adapter\AdapterServiceFactory的工厂来完成这一配置,我们可以在内置的配置系统中来配置这个工厂。zf2的ModuleManager从每个模块的 module.config.php文件中整合了所有的配置,然后将它们整合到 位于config/autoload(*.global.php and then *.local.php files)目录的文件中。我们将向global.php添加数据库配置信息,这些信息你应该提交给你的版本控制系统。在CVS之外,你可以使用local.php来为你的数据库存储凭据【即用户名和密码】,如果你想这么做的话。修改zf/config/autoload/global.php,如下:
    
     array(
     'driver' => 'Pdo',
     'dsn' => 'mysql:dbname=zf2tutorial;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',
     ),
     ),
    );
    你应该将你的数据库凭据存储在config/autoload/local.php文件中,这样它们就不会位于git仓库中【因为local.php被忽略了。
     array(
     'username' => 'YOUR USERNAME HERE',
     'password' => 'YOUR PASSWORD HERE',
     ),
    );
    
    现在ServiceManager已经为我们创建了一个AlbumTable实例,我们可以向控制器添加一个方法来获取它。将getAlbumTable()方法添加到AlbumController控制器类:
    
    // module/Album/src/Album/Controller/AlbumController.php:
     public function getAlbumTable()
     {
     if (!$this->albumTable) {
     $sm = $this->getServiceLocator();
     $this->albumTable = $sm->get('Album\Model\AlbumTable');
     }
     return $this->albumTable;
     }
    在类的顶部,你还应该添加:protected $albumTable;
    
    现在,当我们需要和模型交互时,我们可以从控制器中调用getAlbumTable()方法。
    
    为了现实相册列表,我们需要从模型获取它们并传递给视图。为了达到这一目的,我们需要实现AlbumController控制器中的indexAction()方法。更新 AlbumController的indexAction()方法如下:
    
    // module/Album/src/Album/Controller/AlbumController.php:
    // ...
     public function indexAction()
     {
     return new ViewModel(array(
     'albums' => $this->getAlbumTable()->fetchAll(),
     ));
     }
    // ...
    
    使用zf2,要在视图中设置变量,我们返回一个ViewModel模型实例,这个模型实例构造函数的第一个参数是一个来自于action的数组,其中包含了我们需要的数据,这些数据接下来将被自动传递给视图脚本。ViewModel对象也允许我们来改变已经被使用的视图脚本,但是默认情况下是用的是{controller name}/{action name},现在我们可以完成index.phtml视图脚本。

    // module/Album/view/album/album/index.phtml:

    $title = ‘My albums’;
    $this->headTitle($title);
    ?>

    escapeHtml($title); ?>



    url(‘album’, array(‘action’=>’add’));?>”>Add new album














    Title Artist
    escapeHtml($album->title);?> escapeHtml($album->artist);?>
    url(‘album’,
    array(‘action’=>’edit’, ‘id’ => $album->id));?>”>Edit
    url(‘album’,
    array(‘action’=>’delete’, ‘id’ => $album->id));?>”>Delete

    我们要做的第一件事,是使用headTitle()视图帮助函数来设置页面的标题和head部分的标题,该函数将现实浏览器的标题栏。接下来我们创建一个添加新相册的链接。

    url()视图帮助函数由zf2提供,被用来创建我们需要的链接。它的第一个参数是我们想要用来构造url的路由名称,第二个参数是一个数组,包含了所有要填充进占位符的变量【译者注:其实就是action的名称】。在这里,我们使用album路由,它被设置为接受2个占位符:action和id。

    我们变量从控制的action分配来的变量$albums,zf2视图系统将自动确保这些变量被释放到视图脚本的范围内。所以我们不需要担心要像zf1中那样使用$this->前缀来获取它们的值,但是,如果你喜欢,你仍然可以这样做。

    接下来我们创建一个表格来现实相册的标题和作者,并且提供允许编辑和删除记录的链接。一个标准的foreach循环被用来遍历相册列表,我们使用替代语法冒号和 endforeach;因为这样比使用花括号更简单。再一次使用url()视图帮助函数来创建编辑和删除的链接。

    注意:我们总是使用escapeHtml()视图帮助函数来避免XSS【跨站脚本攻击】。

    现在,如果你浏览http://localhost/zf/public/album,将看见相册列表。

    源码下载吧:http://pan.baidu.com/share/link?shareid=272621&uk=2585386604

    声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

    文档

    zendframework2使用教程【二】–读取数据

    zendframework2使用教程【二】–读取数据:这篇教程篇幅可能会很长,大家要有耐心看,文章最后有源码下载,站长建议大家下载了源码后对照教程看,会更顺畅。 zf2是用模块系统在每个模块中来组织管理你的主应用程序代码,在上一教程中,Application模块被用来向整个应用程序提供bootstrapping
    推荐度:
    标签: 操作 使用 数据
    • 热门焦点

    最新推荐

    猜你喜欢

    热门推荐

    专题
    Top