使一个对象可供所有控制器使用

时间:2013-05-01 07:54:26

标签: php codeigniter pdo codeigniter-2

我正在尝试为我的所有控制器提供一个变量(一个PDO实例)。在我的application / core / MY_Controller.php中,我有:

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

class MY_Controller extends CI_Controller
{
    public $pdo;
}

应用程序/控制器/ login.php中:

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

class Login extends MY_Controller 
{
    public function index()
    {
        if(!$this->pdo instanceof PDO)
        {
            $this->load->view('login_form');
        }
        else
        {
            redirect('home');
        }
    }

    public function connect()
    {
        $hostname = $this->input->post('hostname');
        $username = $this->input->post('username');
        $password = $this->input->post('password');

        $this->pdo = new PDO("mysql:host=$hostname", $username, $password);

        if($this->pdo instanceof PDO)
        {
            redirect('home');
        }
        else
        {
            $this->index();
        }
    }
}

应用/控制器/ home.php:

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

class Home extends MY_Controller
{
    public function index()
    {
        echo 'PDO should be available here but it is not:';
        print_r($this->pdo);
    }
}

应用/视图/ login_form.php:

<!DOCTYPE html>
<html lang="en">
<head>
    <title>Login form</title>
</head>
<body>
    <div>
        <?php echo form_open('login/connect'); ?>
        <label for="hostname">Hostname</label>
        <input type="text" id="hostname" name="hostname" />
        <label for="username">User name</label>
        <input type="text" id="username" name="username" />
        <label for="password">Password</label>
        <input type="text" id="password" name="password" />
        <input type="submit" id="submit" name="submit" />
        <?php echo form_close(); ?>
    </div>
</body>

我正在本地测试。当我转到站点地址时,登录表单将按预期显示。在提交login :: connect()被调用,我知道$ this-&gt; pdo包含一个PDO实例(如果我使用print_r($ this-&gt; pdo在login :: connect中显示'PDO Object()')。但是当我重定向到Home控制器时,$ this-&gt; pdo不包含PDO实例。

我做错了什么?是否与我重定向到Home控制器有关?提前谢谢。

1 个答案:

答案 0 :(得分:1)

首先,您的PDO对象不应该在您的控制器中。

第二个问题是“Home”实例从未创建过pdo对象。这不是控制器,重定向或任何东西的错误,而是面向对象思考的一个基本缺陷。

class A {
  public $test;
}

class B extends A {
  function setTest($test) { $this->test = $test; }
}

class C extends A
{
}

$b = new B(); // create instance of B
$b->setTest("hello"); // set value in INSTANCE of B
$c = new C(); // create instance of C
echo $c->test; // get value from instance of C

这基本上就是你在做的事情。您希望在B的实例中设置的值可以在C的实例中使用。但是这不起作用。你可以在构造函数或init中初始化pdo,但是这会创建很多pdo实例,所以这并不好。你需要一个单身人士或注册表,你可以存储它并随时可用。

再一次重复。 pdo不应该在控制器中,而应该在域逻辑中(所以你的模型)