如何在控制器的__construct()函数中退出没有die()的编码点火器


How to exit codeigniter without die() in __construct() function of controller?

我有一个控制器,在构造函数中,我想检查用户是否已登录。如果没有,我希望显示一条错误消息,并且脚本退出而不在控制器中运行任何其他函数。此控制器仅由 ajax 调用,因此错误将通过 JSON 显示,然后客户端上的 javascript 将向用户显示错误。

我该怎么做?如果我这样做:

function __construct()
{
   if (! $this->loggedIn() )
   {
      echo json_encode( array('error'=> true) );
      die;
   }    
}

我认为不会显示该消息,因为代码点火器使用输出缓冲。有什么想法吗?

我知道您的问题是客户端期望 JSON 类型的响应,因此可以使用两个选项:

public function __construct(){
    $_bad_login_msg = 'please try again' ;
    parent::__construct();
    if(!userLoggedIn()){
        $this->output
        ->set_content_type('application/json')
        ->set_output(json_encode($_bad_login_msg));
        //or just use 
        //     echo json_encode($_bad_login_msg);
        die;
    }
}

http://codeigniter.com/user_guide/libraries/output.html

您不会有任何缓冲问题,缓冲内容将在模具发送到客户端...

最好的方法是将用户重定向到登录页面。如前所述: https://stackoverflow.com/a/10399199/876117

public function __construct(){
  parent::__construct();
  if(!userLoggedIn())
    $this->load->view('promptlogin');
    $this->output->_display();
    exit();
}
public function index(){
  // one will never reach here unless he is logged in
  $this->load->view('actualcontent');
}

我很确定你可以使用这样的东西:

function __construct()
{
   if (! $this->loggedIn() )
   {
     exit('Please login before visiting this page');
   }    
}

MY_Controller是你的顶级/父控制器,所以它都在那里完成,因为所有其他控制器都会扩展它。 因此,如果您有一个身份验证控制器(扩展MY_Controller),您将可以访问其逻辑。

所以MY_Controller

class MY_Controller extends CI_Controller{
    protected $_user;
    public function __construct(){
        parent::__construct();
        $this->_user = $this->session->userdata('uid')
                     ? find_a_user : NULL;
        // if a session of user_id exists and is found in DB
        // we have a live user
    }
}

认证

class Auth extends MY_Controller{
   public function __construct(){
        parent::__construct();
        // we now have access to $this->_user
        if($this->_user !== NULL)  // we have active user
    }
}

我认为您应该使用flashdata并重定向到带有它的控制器。然后,您可以控制是否有任何闪存数据进入会话,然后将其写入视图中。