Welcome Guest, Not a member yet? Register   Sign In
Can't send data from controller to view - variable scope problem?
#1

[eluser]duartix[/eluser]
Cheers.

This is most probably a noob problem, but I'm having difficulties passing data from a controller to a view. I've copied the philosophy of the news section tutorial and wrote the controller as follows:

application/controllers/home.php

Code:
<?php

class Home extends CI_Controller {

    public function __construct() {

        parent::__construct();

        // Initializes connection data
        $data['connection'] = array(
            'logged' => TRUE,
            'username' => 'duarte',
        );
        
        if ($data['connection']['logged']) {
            $this->load->view('templates/logged',$data);
        } else {
            $this->load->view('templates/login');
        }
    }
}

and the view is:

application/views/logged.php

Code:
<div id="login_form">
    &lt;form method="post" acti&gt;
        Connected as:
        &lt;?php echo $data['connection']['username'] ?&gt;  
    &lt;/form&gt;
</div>

The view tells me: Undefined variable: data

From what I've gathered about PHP, the scope of $data is local to the Home controller class, so it would make sense that the view wouldn't see it, but then again I'm passing it explicitly... If I change $data to $GLOBALS it will work, but it looks very dirty from an abstraction point of view.

So why does it work on the tutorial? Are the tutorial's view and controller married in a way that I am missing and share their little dirty data? How else can I send that data?

Thanks In Advance.
Duarte Bruno.
#2

[eluser]InsiteFX[/eluser]
Code:
&lt;?php

class Home extends CI_Controller {

    public function __construct() {

        parent::__construct();

        // Initializes connection data
        $data['connection'] = array(
            'logged' => TRUE,
            'username' => 'duarte',
        );
        
        if ($data['connection']['logged'] == TRUE) {
            $this->load->view('templates/logged',$data);
        } else {
            $this->load->view('templates/login');
        }
    }
}

You should moce the view stuff to the index method.
#3

[eluser]duartix[/eluser]
You're very right. Loading the views shouldn't be done in the constructor. However, $data is still not recognized in the view. :-(
Any ideas?

The view application/views/logged.php wasn't changed.
The controller application/controllers/home.php is now:

Code:
&lt;?php

class Home extends CI_Controller {

    public function __construct() {

        parent::__construct();

        // Initializes connection data
        $data['connection'] = array(
            'logged' => TRUE,
            'username' => 'duarte',
        );
    }

    public function index() {
        if ($data['connection']['logged']) {
            $this->load->view('templates/logged', $data);
        } else {
            $this->load->view('templates/login');
        }
    }

}
#4

[eluser]noideawhattotypehere[/eluser]
Code:
&lt;?php

class Home extends CI_Controller {

    public function __construct() {

        parent::__construct();

        // Initializes connection data
        $data = array(
            'logged' => TRUE,
            'username' => 'duarte',
        );
    }

    public function index() {
        if ($data['logged']) {
            $this->load->view('templates/logged', $data);
        } else {
            $this->load->view('templates/login');
        }
    }

}

in view
Code:
&lt;?php echo $username?&gt;
#5

[eluser]duartix[/eluser]
[quote author="noideawhattotypehere" date="1377868499"]

in view
Code:
&lt;?php echo $username?&gt;
[/quote]

It still doesn't recognize the variable.
Let me put it in the crudest of forms:

application/controllers/home.php :

Code:
&lt;?php
class Home extends CI_Controller {
    public function index() {
        $username = 'ME!';
        $this->load->view('templates/logged', $username);
    }
}

application/views/templates/logged.php :

Code:
&lt;?php echo $username ?&gt;

This is what I get:

A PHP Error was encountered
Severity: Notice
Message: Undefined variable: username
Filename: templates/logged.php
Line Number: 2


What am I doing wrong?
#6

[eluser]InsiteFX[/eluser]
Is your templates directory under application/views ?

If not it will not see them as view files.
#7

[eluser]duartix[/eluser]
[quote author="InsiteFX" date="1377871689"]Is your templates directory under application/views ?
If not it will not see them as view files.
[/quote]

It is. It's at: application/views/templates/logged.php
#8

[eluser]InsiteFX[/eluser]
Try this and see if it echo's out.
Code:
&lt;?php
class Home extends CI_Controller {
    public function index() {
        $data['username'] = 'ME!';
        $this->load->view('templates/logged', $data);
    }
}

Code:
&lt;?php echo $username; ?&gt;

Also did you save the file with a .php extension?
#9

[eluser]CroNiX[/eluser]
[quote author="duartix" date="1377855224"]

From what I've gathered about PHP, the scope of $data is local to the Home controller class, so it would make sense that the view wouldn't see it, but then again I'm passing it explicitly... If I change $data to $GLOBALS it will work, but it looks very dirty from an abstraction point of view.

So why does it work on the tutorial? Are the tutorial's view and controller married in a way that I am missing and share their little dirty data? How else can I send that data?
[/quote]
When you pass an array to a CI View, CI takes that array variable and runs it through php's extract(), which makes that arrays keys available as individual variables within the view.

Try this:
Code:
$test = array(
  'one' => 'first',
  'two' => 'second',
  'three' => array('a', ' separate', ' array')
);

extract($test);

echo $one; // outputs 'first'
echo $two; // outputs 'second'
echo $three; //oops, error, this is an array...

//iterate over it
foreach($three as $value)
{
  echo $value;
}
//echo's 'a separate array'

I think the only thing you were doing wrong in the initial post was accessing the variable in the view.
Code:
Connected as:
        &lt;?php echo $data['connection']['username'] ?&gt;
should have been
Code:
Connected as:
        <php echo $connection['username'] ?&gt;
#10

[eluser]duartix[/eluser]
Thank you very much @InsiteFX & @CroNiX for the probable solution and for the explanation.

@InsiteFX: I admit I was less than hopeful with your suggestion (as it didn't make any sense to me) but now that @CroNiX detailed the CI's mechanics it makes A LOT OF SENSE.

Unfortunately I'll be away from the office for another week and I can't give it a go until then, Sad but I promise it will be the first thing I try when I return.
Anyway thank you SO MUCH for this invaluable help! It's most appreciated!




Theme © iAndrew 2016 - Forum software by © MyBB