【问题标题】:Codeigniter Controller name and Object name collisionCodeigniter 控制器名称和对象名称冲突
【发布时间】:2017-03-03 12:53:28
【问题描述】:

我遇到了问题,不知道如何解决。

我有一个控制器 Pusher 和一个方法 Auth

class Pusher extends MX_Controller
{
    /**
     *
     */
    public function auth()
    {
        $this->load->model('pusher/Pusher_model');
        $p = $this->Pusher_model->newPusher();
        var_dump($p);die;
    }
}

我有一个模型 Pusher_model,它有一个实例化 new Pusher() 对象的方法

require 'vendor/autoload.php';

class Pusher_model extends CI_Model
{
    public $options;
    /**
     *
     */
    public function __construct()
    {
        $this->config->load('api_config');
        $this->options = array(
            $this->config->item('pusher_cluster'),
            $this->config->item('pusher_is_encrypted')
        );

    }

    /**
     *
     */
    public function newPusher()
    {
        return new Pusher(
            $this->config->item('pusher_public_key'),
            $this->config->item('pusher_secret_key'),
            $this->config->item('pusher_api_id'),
            $this->options
        );
    }
}

当我 var_dump() 在我的控制器中返回 Pusher 对象时...

var_dump($p)

结果我得到了整个控制器“Pusher”...

object(Pusher)#24 (2) {
  ["autoload"]=>
  array(0) {
  }
  ["load"]=>
  object(MY_Loader)#25 (13) {
    ["_module":protected]=>
    string(6) "pusher"
    ["_ci_plugins"]=>
    array(0) {
    }
    ["_ci_cached_vars"]=>
    &array(0) {
    }
    ["_ci_ob_level":protected]=>
    int(1)
    ["_ci_view_paths":protected]=>
    &array(1) {
      ["C:\xampp\htdocs\php\twocan\twocan_beta\App\views\"]=>
      bool(true)
    }
    ["_ci_library_paths":protected]=>
    &array(2) {
      [0]=>
      string(43) "C:\xampp\htdocs\php\twocan\twocan_beta\App\"
      [1]=>
      string(43) "C:\xampp\htdocs\php\twocan\twocan_beta\Sys\"
    }
    ["_ci_model_paths":protected]=>
    &array(2) {
      [0]=>
      string(58) "C:\xampp\htdocs\php\twocan\twocan_beta\App\modules/pusher/"
      [1]=>
      string(43) "C:\xampp\htdocs\php\twocan\twocan_beta\App\"
    }
    ["_ci_helper_paths":protected]=>
    &array(2) {
      [0]=>
      string(43) "C:\xampp\htdocs\php\twocan\twocan_beta\App\"
      [1]=>
      string(43) "C:\xampp\htdocs\php\twocan\twocan_beta\Sys\"
    }
    ["_ci_classes":protected]=>
    &array(15) {
      ["benchmark"]=>
      string(9) "Benchmark"
      ["hooks"]=>
      string(5) "Hooks"
      ["config"]=>
      string(6) "Config"
      ["log"]=>
      string(3) "Log"
      ["utf8"]=>
      string(4) "Utf8"
      ["uri"]=>
      string(3) "URI"
      ["router"]=>
      string(6) "Router"
      ["output"]=>
      string(6) "Output"
      ["security"]=>
      string(8) "Security"
      ["input"]=>
      string(5) "Input"
      ["lang"]=>
      string(4) "Lang"
      ["loader"]=>
      string(6) "Loader"
      ["session"]=>
      string(7) "Session"
      ["form_validation"]=>
      string(15) "Form_validation"
      ["model"]=>
      string(5) "Model"
    }
    ["_ci_models":protected]=>
    &array(1) {
      [0]=>
      string(12) "Pusher_model"
    }
    ["_ci_helpers":protected]=>
    &array(5) {
      ["url_helper"]=>
      bool(true)
      ["html_helper"]=>
      bool(true)
      ["security_helper"]=>
      bool(true)
      ["language_helper"]=>
      bool(true)
      ["form_helper"]=>
      bool(true)
    }
    ["_ci_varmap":protected]=>
    &array(2) {
      ["unit_test"]=>
      string(4) "unit"
      ["user_agent"]=>
      string(5) "agent"
    }
    ["controller"]=>
    *RECURSION*
  }
}

这让我相信实例化的对象和控制器本身存在名称冲突。

问:

如何在不重命名控制器的情况下解决此冲突,或者我是否必须对通过该控制器实例化的任何对象使用不同的控制器名称?

【问题讨论】:

    标签: php codeigniter oop controller composer-php


    【解决方案1】:

    如何在不重命名控制器的情况下解决此冲突,或者我是否必须对通过该控制器实例化的任何对象使用不同的控制器名称?

    好吧,让我们看看..

    • 控制器被调用:Pusher->auth()
    • 控制器加载并调用模型:$this->Pusher_model->newPusher();
    • 然后您将使用return new Pusher 实例化一个新的Pusher 对象并将其返回给Pusher 控制器。
    • 这意味着您的 Pusher 控制器有一个属性 $p 包含一个新的推送器对象
    • 是的,你在这里绕圈子。

    我建议保持简单:

    • 不要实例化new Pusher,而只是将模型(Pusher_model)的连接数据返回给控制器,例如

      public function newPusher()
      {
          return array(
              $this->config->item('pusher_public_key'),
              $this->config->item('pusher_secret_key'),
              $this->config->item('pusher_api_id'),
              $this->options
          );
      }
      
    • 您也可以将方法重命名为getCredentialsgetApiConfig

    • 这意味着$p 是一个数组,您可以使用控制器Psuher 中的数据来设置您的API,以便以后调用它

    另一种选择是在控制器和模型之间引入一个服务层:

    • 新班级PusherAPIService
    • controller 中实例化
    • 在控制器调用model->getCredentials
    • 将凭据设置/传递给PusherAPIService,例如configure($credentials)
    • PusherAPIService 添加操作,例如connect(), pull(), push() 无论你的服务做什么。这意味着服务类封装了与外部 API 的所有交互。
    • 最后在我们的控制器中:在需要时调用服务方法。例如当一个 post 请求进来时,让控制器处理传入的数据,然后将数据注入到服务层,然后在现在配置的服务上调用一个方法,将结果返回给控制器。

    【讨论】:

    • 哇,很好的 Jens,感谢您提供有关建筑的建议,我觉得这很有教育意义!目前我重命名了我的控制器 Websockets,但你的实现是个好主意。
    • 很高兴我能帮上忙 :)
    猜你喜欢
    • 2011-08-17
    • 2013-11-06
    • 1970-01-01
    • 2011-10-16
    • 1970-01-01
    • 2013-04-20
    • 2011-07-11
    • 2015-08-07
    相关资源
    最近更新 更多