草庐IT

php - 如何扩展 ZF2 骨架应用程序 - 带外键的实体

coder 2024-04-13 原文

根据 Zend 用户指南,我的 ZF2 骨架应用程序运行良好。但现在我在兜圈子,试图扩展应用程序,以便专辑的艺术家不再是字符串,而是数据库中艺术家表的外键。

我已经创建了所有必要的模型、 Controller 、 View 来创建、编辑和查看艺术家,它们也工作正常。但我如何将两者结合起来,以便我的专辑列表显示艺术家的名字?

我是否使用保湿策略 as suggested here ?如果是这样,我该如何实现? Zend\Stdlib\Hydrator\Strategy 手册没有告诉我在哪里注册 hydrator 策略。是的,有一个简短的实现代码:

$foo = new Foo();
$foo->setFoo("bar");
$foo->setBar("foo");

$hydrator = new ClassMethods();
$hydrator->addStrategy("foo", new Rot13Strategy());

但这要到哪里去呢?在我的 AlbumController 中?为什么每个人都说保湿器“主要用于成型”?

或者我要找的不是保湿器吗?在寻求解决方案的过程中,我不断遇到的另一件事是依赖注入(inject)。我再次找到了这个 kind of tutorial ,但在使用类 A、B 和 C 时,不告诉我所有这些代码片段的去向,这对理解概念没有多大帮助。

我想我想做的事情很常见,我很惊讶我找不到任何真实世界的教程。经过几个小时的研究,我确信我离突破很近了——但我再也看不到了,需要插入。谢谢:-)

最佳答案

当您需要从对象/实体中获取数据或从中获取数据时,可以使用 Hydrator,这可能是在使用表单时,也可能是在从存储中保存或加载实体时。

我不会使用 Hydrator 将相关对象填充到您的对象中(例如,将反抗对象添加到您的相册)。我会将其留给您的服务/映射器。

这是我如何做的一个例子:

Album.php

<?php
class Album
{
     // .. properties / getters/setters etc ..

     public function setArtist(ArtistInterface $artist)
     {
         $this->artist = $artist;
     }

     public function getArtist()
     {
          return $this->artist;
     }
}

AlbumHydrator.php

这可能会有所不同,您可以使用 getters/setters 或属性,查看基础水化器来决定您要采用哪条路线..

您的 Hydrator 将获取组装对象,并返回显示表单或保存到持久性等所需的数据。

<?php
class AlbumHydrator // extends Zend\Stdlib\Hydrator\ClassMethods
{
    public function extract($object)
    {
         return array(
             'artist_id'   => $object->getArtist()->getId(),
             'albumn_name' => $object->getAlbumName()
         )
    }

    // .. etc
}

AlbumService.php

<?php
use Zend\ServiceManager\ServiceManagerAwareInterface;
use Zend\ServiceManager\ServiceManager; 

class AlbumService  implements ServiceManagerAwareInterface
{
    /**
     * Get an album, we'll also load any related objects here
     *
     * @param int
     */
    public function find($id)
    {
        $album = $this->_getAlbumMapper()->find($id);
        $artist = $this->_getArtistMapper()->findByAlbum($id);
        $album->setArtist($artist);

        return $album;
    }

     /**
     * Get the Mapper
     * 
     * @return  Application\Mappers\AlbumMapper
     */
    protected function _getAlbumMapper()
    {
        return $this->getServiceManager()
            ->get('AlbumMapper')
        ;
    }

    // ..
}

您可以像这样在服务管理器配置中设置您的服务:

'AlbumService' => function($sm) {
    $mapper = $sm->get('AlbumMapper');
    $service = new Application\Service\AlbumService();
    $service->setAlbumMapper($mapper);

    return $service;
},

然后您可以使用您的服务来创建您需要的对象图。您将为每个实体拥有单独的映射器,服务可以使用映射器生成您需要的对象。

通常每个实体都有一个 Hydrator,映射器会使用它们为您填充对象。这将取决于您的实现,您可能会使用 TableGateway 或其他东西而不是映射器,这仍然可以正常工作。

现在在 Controller 内部访问对象的示例

SomeController.php

public function albumAction()
{
    $id = (int) $this->params()->fromRoute('id', FALSE);
    if( ! $id) {
        // do something with errors etc ..
        return $this->redirect()->toRoute('default_route', array(
            'controller'    => 'index',
            'action'        => 'index'
        ));
    }
    $request = $this->getRequest();

    $album = $this->getServiceLocator()->get('AlbumService')->find($id);
    $artistName = $album->getArtist()->getName();

    return new ViewMdoel(
       'album'      => $ablum,
       'artistName' => $artistName
    );
}

在使用集合时填充对象图有点棘手,但我倾向于使用延迟加载和虚拟代理来进行这种设置,这基本上会延迟加载您需要的对象,直到您需要它们,检查这些:

http://phpmaster.com/intro-to-virtual-proxies-1/ http://phpmaster.com/intro-to-virtual-proxies-2/

关于php - 如何扩展 ZF2 骨架应用程序 - 带外键的实体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15827905/

有关php - 如何扩展 ZF2 骨架应用程序 - 带外键的实体的更多相关文章

  1. ruby - 如何使用 Nokogiri 的 xpath 和 at_xpath 方法 - 2

    我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div

  2. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  3. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  4. ruby-on-rails - 如何验证 update_all 是否实际在 Rails 中更新 - 2

    给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru

  5. ruby-on-rails - 'compass watch' 是如何工作的/它是如何与 rails 一起使用的 - 2

    我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t

  6. ruby - 将差异补丁应用于字符串/文件 - 2

    对于具有离线功能的智能手机应用程序,我正在为Xml文件创建单向文本同步。我希望我的服务器将增量/差异(例如GNU差异补丁)发送到目标设备。这是计划:Time=0Server:hasversion_1ofXmlfile(~800kiB)Client:hasversion_1ofXmlfile(~800kiB)Time=1Server:hasversion_1andversion_2ofXmlfile(each~800kiB)computesdeltaoftheseversions(=patch)(~10kiB)sendspatchtoClient(~10kiBtransferred)Cl

  7. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

    我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

  8. ruby - 如何指定 Rack 处理程序 - 2

    Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack

  9. ruby - 如何每月在 Heroku 运行一次 Scheduler 插件? - 2

    在选择我想要运行操作的频率时,唯一的选项是“每天”、“每小时”和“每10分钟”。谢谢!我想为我的Rails3.1应用程序运行调度程序。 最佳答案 这不是一个优雅的解决方案,但您可以安排它每天运行,并在实际开始工作之前检查日期是否为当月的第一天。 关于ruby-如何每月在Heroku运行一次Scheduler插件?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/8692687/

  10. ruby-on-rails - 如何从 format.xml 中删除 <hash></hash> - 2

    我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为

随机推荐