如何在CodeIgniter中创建自定义驱动程序

作为CodeIgniter开发人员,您可能遇到过丰富核心框架功能的库​​的概念,而CodeIgniter本身在核心中提供了许多有用的库。

同样,驱动程序是一种特殊的库,允许您添加自定义功能,以便主驱动程序类充当父类,而适配器被视为子类。

理解驱动程序概念的最佳方法是查看如何在核心CodeIgniter框架中实现缓存。 主Cache类充当父类,并扩展了CI_Driver_Library类。 另一方面,您最终将找到实现为可插入适配器的APC,Memcached,Redis等的子类。 子类扩展了CI_Driver类,而不是主驱动程序类。

这种方法的优点在于,您可以根据需要添加新的适配器来轻松扩展驱动程序的功能。 与缓存一样,如果您需要添加自定义缓存策略,则距离以自定义适配器的形式实现它仅一步之遥。

今天的文章旨在在CodeIgniter应用程序中创建自定义驱动程序。 在此过程中,我们将通过一个真实的示例创建一个MediaRenderer驱动程序,该驱动程序用于渲染来自YouTube,Vimeo等类似服务的媒体。 不同的服务将以适配器类的形式实现。

档案设定

我们将在本文中实现的驱动程序的名称为MediaRenderer。 让我们快速查看所需设置所需的文件列表:

  • application/libraries/MediaRenderer/MediaRendererInterface.php :这是适配器需要实现的接口。
  • application/config/mediarenderer.php :包含与我们的自定义驱动程序相关的设置的配置文件。
  • application/libraries/MediaRenderer/MediaRenderer.php :它是扩展CI_Driver_Library的类,用于操作应用程序中可用的不同适配器。
  • application/libraries/MediaRenderer/drivers/MediaRenderer_youtube.php :这是实现YouTube适配器的类。
  • application/libraries/MediaRenderer/drivers/MediaRenderer_vimeo.php :这是实现Vimeo适配器的类。
  • application/controllers/Media.php :这是我们将实现的控制器类,用于演示自定义驱动程序的用法。

这就是我们将在本文中实现的文件列表。

创建驱动程序

在本节中,我们将创建自定义驱动程序的基本文件。

我们需要做的第一件事是定义自定义驱动程序的配置文件。 让我们定义application/config/mediarenderer.php文件,如下所示。

<?php
$config['media_services'] = array('youtube', 'vimeo');
$config['media_default'] = 'youtube';

它表明我们将实现两个适配器-YouTube和Vimeo。 默认适配器设置为YouTube。

继续并使用以下内容创建文件application/libraries/MediaRenderer/MediaRendererInterface.php

<?php
defined('BASEPATH') OR exit('No direct script access allowed');

/**
 * MediaRendererInterface
 */
interface MediaRendererInterface
{
    public function display($id);
}

如您所见,这是一个非常基本的接口,可确保实现此接口的适配器必须实现display方法。

接下来,让我们看一下MediaRenderer驱动程序文件。 继续并使用以下内容创建文件application/libraries/MediaRenderer/MediaRenderer.php

<?php
if ( ! defined('BASEPATH')) exit('No direct script access allowed');
interface_exists('MediaRendererInterface', FALSE) OR require_once(APPPATH.'/libraries/MediaRenderer/MediaRendererInterface.php');

/**
 * MediaRenderer Class
 */
class MediaRenderer extends CI_Driver_Library {
    
  public $valid_drivers;
  public $CI;
  protected $_adapter = 'youtube';

  /**
   * Class constructor
   */
  public function __construct()
  {
    $this->CI =& get_instance();
    $this->CI->config->load('mediarenderer');
    $this->valid_drivers = $this->CI->config->item('media_services');
    $this->_adapter = $this->CI->config->item('media_default');
  }

  /**
   * Overrided __get method to check if the adapter implements MediaRendererInterface interface
   * @see CI_Driver_Library::__get()
   */
  public function __get($child)
  {
      if (in_array($child, $this->valid_drivers))
      {
          $object = $this->load_driver($child);
          
          if ($object instanceof MediaRendererInterface)
          {
              return $object;
          }
          else
          {
              show_error("MediaRenderer: Adapter '".$child."' doesn't implement MediaRendererInterface. Aborting.");
              return;
          }
      }
      else
      {
                show_error('Unable to load the requested adapter: '.$child);
                return;
      }
  }

  /**
   * @param string $adapter Adapter name
   * @return MediaRenderer
   */
  public function setAdapter($adapter)
  {
      $this->_adapter = $adapter;
      return $this;
  }

  /**
   * @param string $id Media ID
   */
  public function display($id)
  {
      return $this->{$this->_adapter}->display($id);
  }

}

在文件的开头,我们包括本节前面已经定义的MediaRendererInterface接口。

由于每笨司机的标准,我们班MediaRenderer扩展CI_Driver_Library 该类可确保我们可以使用CI_Driver_Library类中定义的load_driver方法轻松访问驱动程序适配器。

接下来,让我们仔细看一下构造函数。

public function __construct()
{
  $this->CI =& get_instance();
  $this->CI->config->load('mediarenderer');
  $this->valid_drivers = $this->CI->config->item('media_services');
  $this->_adapter = $this->CI->config->item('media_default');
}

回忆一下我们先前定义的mediarenderer配置文件,该文件首先已完全加载到构造函数中。 要求将驱动程序支持的适配器列表设置为valid_drivers属性,因此我们也这样做。 最后,为方便起见,我们将默认驱动程序的值设置为_adapter属性。

更进一步,让我们拉入__get方法的代码。

public function __get($child)
{
    if (in_array($child, $this->valid_drivers))
    {
        $object = $this->load_driver($child);
        
        if ($object instanceof MediaRendererInterface)
        {
            return $object;
        }
        else
        {
            show_error("MediaRenderer: Adapter '".$child."' doesn't implement MediaRendererInterface. Aborting.");
            return;
        }
    }
    else
    {
            show_error('Unable to load the requested adapter: '.$child);
            return;
    }
}

我想说您不需要重写此方法,而没有它,我们的驱动程序也可以正常工作。 在我们的案例中,此方法的实现背后的原因是强制执行MediaRendererInterface接口的实现,因此可以确保每个驱动程序都必须实现display方法。

接下来,让我们看一下setAdapter方法。

public function setAdapter($adapter)
{
    $this->_adapter = $adapter;
    return $this;
}

如您所见,如果您暂时想使用其他适配器,它仅用于覆盖默认适配器设置。

最后,有一个display方法可以调用相应适配器的显示方法。

public function display($id)
{
    return $this->{$this->_adapter}->display($id);
}

再说一遍,我想说您可以跳过display方法的实现,因为您总是可以直接调用适配器的display方法,正如我们将在本文后面看到的那样。 但是,我想通过MediaRenderer类的display方法访问适配器,因为在这里您可以重构适配器可能实现的通用代码。

这就是您可以使用的MediaRenderer类。

创建适配器

我们讨论驱动程序适配器已有一段时间了,现在是时候实际实现它们了。

让我们从application/libraries/MediaRenderer/drivers/MediaRenderer_youtube.php的YouTube适配器文件开始。

<?php
if ( ! defined('BASEPATH')) exit('No direct script access allowed');

/**
 * MediaRenderer_youtube Class
 */
class MediaRenderer_youtube extends CI_Driver implements MediaRendererInterface {

  /**
   * @param string $id Media ID
   * @see MediaRendererInterface::display()
   */
  public function display($id)
  {
    if ($id)
    {
      return '<iframe width="420" height="315" src="//www.youtube.com/embed/'.$id.'" frameborder="0"
allowfullscreen></iframe>';
    }
  }

}

重要的是要注意,适配器名称以MediaRenderer_为前缀,并且它还扩展了CI_Driver类。 此外,它实现MediaRendererInterface接口,以确保我们遵守前面讨论的标准。

我们的适配器类扩展CI_Driver类的原因是要利用所有父方法和属性。 你没有听错,你可以访问的方法和属性MediaRenderer从内类MediaRenderer_youtube类,即使它不扩展MediaRenderer直接类。

除此之外,很容易理解display方法的实现,只要将媒体ID作为方法的参数传递,它就会返回嵌入代码。

Vimeo适配器类与YouTube完全相同。 继续在application/libraries/MediaRenderer/drivers/MediaRenderer_vimeo.php创建一个。

<?php
if ( ! defined('BASEPATH')) exit('No direct script access allowed');

/**
 * MediaRenderer_vimeo Class
 */
class MediaRenderer_vimeo extends CI_Driver implements MediaRendererInterface {
    
    /**
     * @param string $id Media ID
     * @see MediaRendererInterface::display()
     */
  public function display($id)
  {
      if ($id)
      {
      return '<iframe width="420" height="247" src="//player.vimeo.com/video/'.$id.'"></iframe>';
      }
  }

}

这样就结束了适配器的讨论。

放在一起

在最后两节中,我们讨论了驱动程序和适配器类。 在本节(这是本文的最后一部分)中,我们将扩展旅程,以演示基本的驱动程序用法。

首先创建一个控制器文件application/controllers/Media.php

<?php
defined('BASEPATH') OR exit('No direct script access allowed');

/**
 * Media Controller Class
 */
class Media extends CI_Controller {
  public function index()
  {
    // this will use default adapter as per the config file
    $this->load->driver('mediaRenderer');
    
    // IMP: it must be a lowercase drivername when you use it
    echo $this->mediarenderer->display("0GfCP5CWHO0");
    
    // override adapter settings by setting it explicitly
    echo $this->mediarenderer->setAdapter('vimeo')->display("225434434");
    
    // access the adapter directly
    echo $this->mediarenderer->vimeo->display("225434434");
    echo $this->mediarenderer->youtube->display("0GfCP5CWHO0");
  }
}

我们需要做的第一件事是加载自定义驱动程序mediaRenderer ,这就是以下代码片段的作用。

$this->load->driver('mediaRenderer');

要访问我们刚刚加载的自定义驱动程序,应使用$this->mediarenderer语法。 重要的是要注意,驱动程序的名称必须小写,与实际的驱动程序名称无关。

接下来,让我们检查以下代码的作用。

echo $this->mediarenderer->display("0GfCP5CWHO0");

它首先调用MediaRenderer类的display方法,因为它将控件委托给相应适配器的display方法,该适配器在mediarenderer配置文件中设置为默认适配器。 最终,它最终调用了YouTube适配器的display方法,因为在我们这里是默认适配器。

另一方面,如果要调用任何特定适配器的显示方法,则始终可以显式地执行该操作,如以下代码片段所示。

echo $this->mediarenderer->setAdapter('vimeo')->display("225434434");

如前所述,您也可以直接调用任何特定适配器的display方法,而无需通过MediaRenderer类的display方法。

echo $this->mediarenderer->vimeo->display("225434434");
echo $this->mediarenderer->youtube->display("0GfCP5CWHO0");

因此,这就是您应该同时调用驱动程序及其适配器的原因,这要归功于驱动程序结构,该结构允许您根据需要即时插入新适配器。

就是这样。 我希望您喜欢这篇文章,并且可以随时单击“评论”部分来表达您的想法和疑虑。

结论

今天,本文将介绍在CodeIgniter框架中遍历驱动程序的过程。

与往常一样,本文从基本介绍CodeIgniter框架中的驱动程序概念开始。 如我所言,我们继续基于实际用例创建自定义驱动程序,我相信这是理解新概念的最佳方法。

我很想听听您是否可以就这个令人兴奋的概念提出一些建议!

翻译自: https://code.tutsplus.com/tutorials/how-to-create-custom-drivers-in-codeigniter--cms-29339

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值