阅读时间 7 分钟 (1463 个单词)

在 Joomla! 中使用 Doctrine ORM

Joomla! 是一个功能丰富的 CMS,具有许多优秀的功能。它非常适合最终用户,并且可以从在线世界中使用许多组件。但作为开发者,我个人不喜欢 Joomla! 中的模型实现方式。对我来说,'模型和表' 类的实现方式感觉并不合适。此外,在控制器或其他模型类中获取其他模型也非常困难。我在使用 Symfony 时经常与 Doctrine 一起工作,在这篇博客中,我将向您展示如何在 Joomla! 中使用 Doctrine 为您的组件。Doctrine 是一个对象关系映射框架,并提供了一个持久化库。这并非万能的解决方案,您应该确定是否需要额外的开销,并且是否能够适应它。

 

第一步

我将从一个干净的 Joomla 1.6 安装开始,这个安装来自 Joomla! 网站。我还从 Doctrine 网站安装了 Doctrine ORM。我将存档解压到 Joomla! 文件夹中的一个新的文件夹里。这个新文件夹的结构将与存档相同,所以您会在 libraries/doctrine 文件夹中获得一个 Doctrine 文件夹和一个 bin 文件夹。顺便说一句,我们现在生活在 2011 年,当前的 PHP 版本是 5.3.5。Doctrine 和我在这里向您展示的实现假设您使用的是 PHP 5.3。如果您仍然使用 PHP 5.2,您真的需要考虑升级这些项目。

示例

我将提供一个非常简单的示例。我想向您展示的最重要的是如何在您的 Joomla! 项目中实现 Doctrine,而不是如何使用 Doctrine。Doctrine 网站的文档质量很高,应该提供足够的信息帮助您开始。我们正在编写一个新的组件,称为 Bugs,并包含一个名为 'Bug' 的实体。它有五个属性。ID、标题、描述、通知日期和解决日期。在控制器中,我将向您展示一些如何使用它的示例。

设置默认值

您可能希望将Doctrine应用于您将要编写的多个组件中。这就是我选择将Doctrine添加到库文件夹中的原因。在这个文件夹中,我们将添加两个文件。一个是提供通用接口的接口,另一个是启动器以启动Doctrine。首先,先说简单的事情,接口。接口看起来像这样:{codecitation style="brush: javascript;"} interface JoomlaDoctrineController { public function setEntityManager(Doctrine\ORM\EntityManager $entityManager); {/codecitation} 这里没有什么特别的地方,我们继续前进。Doctrine需要一些基本配置才能开始。我们需要告诉Doctrine它可以在哪里找到实体,以及它需要在哪里放置生成的代理。下面是JoomlaDoctrineBootstrapper的实现:{codecitation style="brush: javascript;"} /** * 配置类以将Doctrine集成到Joomla中。 * * @author pderaaij*/ use Doctrine\Common\ClassLoader, Doctrine\ORM\EntityManager, Doctrine\ORM\Configuration, Doctrine\Common\Cache\ArrayCache; if( !class_exists('\Doctrine\Common\Classloader')) { require_once dirname(__FILE__) . '/../doctrine/Doctrine/Common/ClassLoader.php'; } class JoomlaDoctrineBootstrapper { const APP_MODE_DEVELOPMENT = 1; const APP_MODE_PRODUCTION = 2; private $applicationMode; private $cache; private $entityLibrary; private $proxyLibrary; private $proxyNamespace; private $entityManager; private $connectionOptions; public function __construct($applicationMode) { $this->applicationMode = $applicationMode; } public function getConnectionOptions() { return $this->connectionOptions; } public function setConnectionOptions($connectionOptions) { $this->connectionOptions = $connectionOptions; } public function getProxyLibrary() { return $this->proxyLibrary; } public function setProxyLibrary($proxyLibrary) { $this->proxyLibrary = $proxyLibrary; } public function getProxyNamespace() { return $this->proxyNamespace; } public function setProxyNamespace($proxyNamespace) { $this->proxyNamespace = $proxyNamespace; } public function getCache() { return $this->cache; } public function setCache($cache) { $this->cache = $cache; } public function getEntityLibrary() { return $this->entityLibrary; } public function setEntityLibrary($entityLibrary) { $this->entityLibrary = $entityLibrary; } public function getApplicationMode() { return $this->applicationMode; } public function setApplicationMode($applicationMode) { $this->applicationMode = $applicationMode; } public function getEntityManager() { return $this->entityManager; } public function setEntityManager($entityManager) { $this->entityManager = $entityManager; } /** * 启动Doctrine,设置库和命名空间以及创建entitymanager */ public function bootstrap() { $this->registerClassLoader(); // 加载缓存 if ($this->getApplicationMode() == self::APP_MODE_DEVELOPMENT) { $this->cache = new ArrayCache; } else { $this->cache = new ApcCache; } /** @var $config Doctrine\ORM\Configuration */ $config = new Configuration; $config->setMetadataCacheImpl($this->cache); $driverImpl = $config->newDefaultAnnotationDriver($this->getEntityLibrary()); $config->setMetadataDriverImpl($driverImpl); $config->setQueryCacheImpl($this->cache); $config->setProxyDir($this->getProxyLibrary()); $config->setProxyNamespace($this->getProxyNamespace()); if ($this->applicationMode == self::APP_MODE_DEVELOPMENT) { $config->setAutoGenerateProxyClasses(true); } else { $config->setAutoGenerateProxyClasses(false); } $this->entityManager = EntityManager::create($this->getConnectionOptions(), $config); } /** * 注册不同类型的不同类加载器。 */ private function registerClassLoader() { // Doctrine库文件的自动加载器 $classLoader = new ClassLoader('Doctrine', dirname(__FILE__) . '/'); $classLoader->register(); // 实体的自动加载器 $modelLoader = new ClassLoader('Entities', $this->getEntityLibrary()); $modelLoader->register(); // 代理的自动加载器 $proxiesClassLoader = new ClassLoader('Proxies', $this->getProxyLibrary()); $proxiesClassLoader->register(); } } {/codecitation}
好的,这里发生了什么。如前所述,我们期望的是一个PHP 5.3应用程序,所以我们在这里大量使用了命名空间。我们加载了Doctrine的一些基本类,以便启动它。
在这个类中,您可以看到两个常量。这些常量是您可以使用来设置应用程序所处环境的标志。如果应用程序在生产环境中使用,它将使用APC缓存。在开发中,它将使用简单的ArrayCache,它是易变的。
如果我们跳过getter和setter,我们会看到两个有趣的功能。第一个是registerClassLoader。在这里,我们注册了三个类加载器。第一个用于自动加载所有Doctrine类。第二个用于我们创建的实体。代理由第三个类加载器自动加载。最后两个类加载器接收的参数只是包含相关文件的文件夹的绝对路径。
在bootstrap函数中,我们定义了Doctrine的配置。我们定义了它需要使用的缓存、AnnotationDriver以及Doctrine可以找到代理和实体的文件夹。要了解更多关于此配置的信息,您应该阅读Doctrine手册。我们在这里执行的是标准配置,设置正确的位置。

创建组件

现在我们可以开始设置我们的组件了。在components中创建一个com_bugs文件夹,在其中创建一个models文件夹。在models文件夹中,您应该创建一个Entities文件夹(注意大小写,这是很重要的!)。接下来创建'Bug'实体。将下面的文本复制到models/Entities文件夹中的Bug.php中。不要忘记设置namespace,这是至关重要的。如果您忘记了它,实体就无法被类加载器找到。这也是为什么大小写如此重要的原因。{codecitation style="brush: javascript;"} namespace Entities; /** * @Entity * @Table(name="bugs") */ class Bug { /** * @Id * @Column(type="integer") * @GeneratedValue */ private $id; /** * @Column(type="string") */ private $title; /** * @Column(type="string") */ private $description; /** * @Column(type="datetime") */ private $notificationDate; /** * @Column(type="datetime") */ private $solvedDate; public function getId() { return $this->id; } public function setId($id) { $this->id = $id; } public function getTitle() { return $this->title; } public function setTitle($title) { $this->title = $title; } public function getDescription() { return $this->description; } public function setDescription($description) { $this->description = $description; } public function getNotificationDate() { return $this->notificationDate; } public function setNotificationDate($notificationDate) { $this->notificationDate = $notificationDate; } public function getSolvedDate() { return $this->solvedDate; } public function setSolvedDate($solvedDate) { $this->solvedDate = $solvedDate; } } {/codecitation} 这就是我们的实体!现在我们需要一种方法来将实体定义放入我们的数据库中。Doctrine为我们提供了命令行工具来做这件事,但它们需要与我们在前端控制器中给出的相同配置。所以,让我们设置这个配置并在命令行中使用它。

配置

为了在我们的控制器中使用Doctrine,我们必须创建配置并使用我们创建的启动器来启动Doctrine。目前,我选择了组件初始化文件来进行Doctrine的初始化工作。我正在寻找一种将初始化提取到更合适位置的方法,但我尝试的选项并没有让我感到满意。我们需要做什么?嗯,我们需要告诉Doctrine我们的实体存储在文件系统的哪个位置,以及我们希望将代理文件存储在哪里。此外,我们还需要将数据库参数传递给Doctrine,以便它能够访问数据库。以下是组件的初始化文件(bugs.php):

结束

就是这样,现在你可以在你的组件中使用Doctrine了。这是一篇很长的博客文章,但我希望我向你展示了一种在Joomla中开始使用Doctrine的简单方法。我希望你喜欢这篇文章。你可以在博客上留下反馈,因为我总是对新的见解感兴趣,这些见解可以帮助我作为一个开发者学习和成长。

在Joomla社区杂志上发表的一些文章代表了作者在特定主题上的个人意见或经验,可能并不代表Joomla项目的官方立场

0
Joomla! 世界的声音
 

评论

已经注册? 登录这里
尚未发表评论。成为第一个发表评论的人

通过接受,您将访问https://magazine.joomla.net.cn/之外的第三方外部服务