1

我目前想知道如果我有相互引用的理论 2 实体,那么让 ZF2 模块从一个项目复制到另一个项目的好方法是什么。

我目前的情况是这样的:我有一个实体User,我希望能够访问该用户说的所有语言。

当然,Language它不是模块的一个组件Authentication,因为我可能还想将它用于其他目的。

namespace Authentication\Entity;

class User {
    public function getSpokenLanguages();
}

和:

namespace Application\Entity;

class Language {
    public function getUsersWhoSpeakThisLanguage();
}

问题是,我希望我的Authentication模块完全独立于项目特定的模块Application

Application有没有一种好方法可以将这些关系排除在我的实体之外,或者可能从模块中注入它们?也许UserService(在Application模块中)给我Language[]特定的语言User是个好主意?我可以这样称呼它:

$userService->getUsersLanguages($user);

我认为,尤其是注入可能是 ZF2 解决方案,但我不知道如何从另一个模块扩展类似的 Doctrine2 实体。

4

1 回答 1

1

我认为您谈论的更多是语义问题,而不是 ZF2 特有的问题。阅读您的问题,我认为您的语言更像是一个托管层,您可以轻松地使用工厂和 DI 来促进它 - 幸运的是 ZF2 拥有所有正确的工具。考虑这样的事情作为解决方案的潜在草案:

创建一个LanguageAbstractFactory

namespace Your\Namespace;

use Zend\ServiceManager\AbstractFactoryInterface,
    Zend\ServiceManager\ServiceLocatorInterface;

class LanguageAbstractFactory implements AbstractFactoryInterface
{
    /**
     * Determine if we can create a service with name
     *
     * @param ServiceLocatorInterface $serviceLocator
     * @param                         $name
     * @param                         $requestedName
     * @return bool
     */
    public function canCreateServiceWithName( ServiceLocatorInterface $serviceLocator, $name, $requestedName )
    {
        return stristr( $requestedName, 'Namespace\Language' ) !== false;
    }


    public function createServiceWithName(ServiceLocatorInterface $locator, $name, $requestedName)
    {
        $filter = new $requestedName();
        $filter->setServiceLocator( $locator );
        return $filter;
    }

}

然后,在同一个命名空间中创建您的语言,作为实现ServiceLocatorAwareInterface的 Language 的子类(以便您以后可以访问数据库等)。上面工厂中的代码注入了服务定位器(这就是您调整它以注入其他优点以满足您的语言架构的地方):

namespace Your\Namespace;

use Zend\ServiceManager\ServiceLocatorAwareInterface,
    Zend\ServiceManager\ServiceLocatorInterface;


class Language implements ServiceLocatorAwareInterface
{

    protected $serviceLocator;


    public function setServiceLocator(ServiceLocatorInterface $serviceLocator)
    {
        $this->serviceLocator = $serviceLocator;
    }

    public function getServiceLocator()
    {
        return $this->serviceLocator;
    }

    // ... other things your factory knows, that this class may not go here
}

语言实现可能如下所示:

namespace Your\Namespace\Language;

class English extends \Your\Namespace\Language
{

    public function getUsersWhoSpeakThisLanguage()
    {
        $sm = $this->getServiceManager();
        // get your entities or w/e using the SM
    }
}

通过在 getServiceConfig 中调整模块的 Module.php 来连接工厂:

公共函数getServiceConfig(){返回数组(

        'abstract_factories' => array(
            // this one generates all of the mass email filters
            'Your\Namespace\LanguageAbstractFactory',
        ),

    );
}

这使您能够使用服务管理器非常轻松地获得服务感知语言。例如,来自服务感知类:

$sm->getServiceManager()->get( '\Your\Namespace\Language\English' );

由于配置,并且工厂可以满足请求,您的工厂将以非常便携的方式使用您构建到其中的任何逻辑自动配置英语实例。

这是工厂的入门知识 - 如果您装配了一个接口类,该服务可以用来与您的用户类对话,您可以将控制权从用户反转到语言服务。让您的用户实现包含语言服务可以使用的类的 LanguageAware(例如)应该是几步之遥。

希望这可以帮助。给这只猫剥皮的方法大概有 15 种;这种方法是我用来解决类似问题的一种方法,例如“过滤”数据。一个过滤器,可以过滤信息,信息可以通过过滤器过滤。

祝你好运!

于 2013-02-08T04:27:42.373 回答