Welcome Guest, Not a member yet? Register   Sign In
Troubles with __destructor
#1

[eluser]@l1[/eluser]
Hi to all! I'm just start to learn CodeIgniter, and meet some trouble that seems to be a bug.
After reading manual section about views I conclude that CodeIgniter has not "magic loading" views per controler/action like it work in Zend or Cake etc. So i try to make it. First of all i load "layout library" and some customize it. Then, i create __destruct() in my Index controler(almost full copy of welcome controller).

Here it is:

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

class Layout {
    
    private $obj;
    private $layout;
    private $controller;
    private $action;
    
    public function __construct($layout = "layouts/layout") {
        $this->obj =& get_instance();
        $this->layout = $layout;
        $this->controller = $this->obj->router->class;
        $this->action = $this->obj->router->method;
    }

    public function setLayout($layout) {
        $this->layout = $layout;
    }
    
    public function view($view = false, $data = null, $return = false) {
        $this->obj->is_rendered = true;
        
        if (!$view)
            $view = $this->action;

        $loadedData = array();
        $loadedData['content_for_layout'] = $this->obj->load->view($this->controller . '/' . $view, $data, true);
        if ($return) {
            $output = $this->obj->load->view($this->layout, $loadedData, true);
            return $output;
        } else {
            $this->obj->load->view($this->layout, $loadedData, false);
        }
    }
    
    public function setData($data = null) {
        $this->view(false, $data);
    }
}
?>

Code:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Index extends CI_Controller {
    
    public $is_rendered = false;

    public function __construct() {
        parent::__construct();
    }

    public function index() {
        //$this->layout->setData(array('hello' => 'HELLO'));
    }
    
    public function hello() {
        $this->layout->view('hello');
    }    
    
    public function __destruct() {
        if (!$this->is_rendered) {
            $this->layout->view(false, array('hello' => 'HELLO'));
        }
    }
}

So when i try to call index action of index controller with settingData($this->layout->setData(array('hello' => 'HELLO'))Wink all working good, but if i comment this line, appear warnings:


Warning: include(application/errors/error_php.php) [function.include]: failed to open stream: No such file or directory in F:\www\htdocs\local.example.com\system\core\Exceptions.php on line 167

Warning: include() [function.include]: Failed opening 'application/errors/error_php.php' for inclusion (include_path='.;C:\php5\pear') in F:\www\htdocs\local.example.com\system\core\Exceptions.php on line 167

Warning: include(application/errors/error_php.php) [function.include]: failed to open stream: No such file or directory in F:\www\htdocs\local.tendy.com\system\core\Exceptions.php on line 167

Warning: include() [function.include]: Failed opening 'application/errors/error_php.php' for inclusion (include_path='.;C:\php5\pear') in F:\www\htdocs\local.example.com\system\core\Exceptions.php on line 167

So i fix it by setting include path:

Code:
set_include_path(get_include_path() . ';' . dirname(__FILE__) . '/../../');

And after that i have next error:

An Error Was Encountered
Unable to load the requested file: index/index.php

When i debug it, i found that error here:

Code:
if ( ! file_exists($_ci_path))

system/core/Loader.php line #637

I understand that it can be fixed by adding something like

Code:
if ( ! file_exists(dirname(__FILE__) . '/../../' . $_ci_path))

But after fixing this things in other places i have a clean screen output without my layout or view script Sad

P.S. Sorry for my english.
#2

[eluser]danmontgomery[/eluser]
Rather than hacking away at the core, you would be better served using a post_controller or display_override hook.

http://ellislab.com/codeigniter/user-gui...hooks.html
#3

[eluser]Phil Sturgeon[/eluser]
__destruct does not work as expected due to the way everything is inherited. You can have a look at Jamie's Base Controller to see how he has implemented this convention into controllers.

This reminds me of the before() and after() feature I have suggested on UserVoice which would really help make this easier.
#4

[eluser]@l1[/eluser]
[quote author="noctrum" date="1299094859"]Rather than hacking away at the core, you would be better served using a post_controller or display_override hook.

http://ellislab.com/codeigniter/user-gui...hooks.html[/quote]
Tnx, I found info about it in manual and use post_controller hook to solve my problem, but this strange behavior of destructor, make me surprised Smile
#5

[eluser]Progressed[/eluser]
@l1

What have you done to solve this? got the same problem Sad

see: http://ellislab.com/forums/viewthread/184096/
#6

[eluser]@l1[/eluser]
[quote author="Progressed" date="1300730304"]@l1

What have you done to solve this? got the same problem Sad

see: http://ellislab.com/forums/viewthread/184096/[/quote]
Hi, for my case I create method in Layout library called hookTest, it look into property of controller($is_rendered), and if it is set to false, than i should to call $this->view(). After that i use post_controller hook in hooks.php, that call my method after controller executed.
#7

[eluser]WanWizard[/eluser]
The problem is that the controller IS the CI superobject, once you destroy that, you lose all access to CI. And you don't have any control over the destruct process, so you don't know what is still accessable, and what isn't.

Using __destruct() for anything other than cleanup actions for destruction of the current object is a very bad idea...




Theme © iAndrew 2016 - Forum software by © MyBB