Welcome Guest, Not a member yet? Register   Sign In
Change data retrieved from model in controller
#1

[eluser]pyrokinesis[/eluser]
Hi guys,

I am trying to change the value retrieved from a model in my controller.
The table in my db is:

Code:
+----------+--------------+--------------------+
| staff_id | name         | email_address      |
+----------+--------------+--------------------+
|        1 | William Hill | [email protected]    |
|        2 | John Carlson | [email protected] |
|        3 | Hugh Bishop  | [email protected]  |
+----------+--------------+--------------------+

Model:
Code:
function get_data() {
    $query =
            "SELECT
                staff_id AS 'Staff ID',
                name AS 'Name',
                email_address AS 'Email Address',
            FROM staff
            ";
    return $this->db->query($query);
}

Controller:
Code:
function show_data() {
    $this->output->enable_profiler(TRUE);
    $this->load->model('test_model');
    $result = $this->test_model->get_data();
    
    foreach ($result->result() as $row) {
        $row->{'Email Address'} = str_replace('gmail', 'yahoo', $row->{'Email Address'});
    }
    
    echo '<pre>';
    print_r($result);
    echo '</pre>';
    //Values are changed in $result here

    echo $this->table->generate($result);

    //Replaced values are not put into the table

}

The values seem to be changed but the updated values are not replaced in the table though...

Does anyone have any ideas? :ohh:

Thanks.
#2

[eluser]TheFuzzy0ne[/eluser]
I've never worked with database fields with spaces in them, in fact, I didn't even know it was possible. I'd suggest you change it to email_address, and see if that helps. You're calling on an object property, and one thing I do know is that you can't have spaces in property names. If spaces in database fields are valid, I'd suggest you use the result_array() instead of an objects.

However, in the meantime, changing this:

Code:
foreach ($result->result() as $row) {
        $row->{'Email Address'} = str_replace('gmail', 'yahoo', $row->{'Email Address'});
    }

to this:

Code:
foreach ($result->result() as &$row) {
        $row->{'Email Address'} = str_replace('gmail', 'yahoo', $row->{'Email Address'});
    }

might help you.
#3

[eluser]pyrokinesis[/eluser]
Hi TheFuzzyOne,

The spaces in the property names seem to be working fine as long as I surround them with {' '}.
I didn't think I could work with fields with spaces on db fields either but I saw a post in the forums had a example of it.
I tried the same code on property names that don't have spaces and I got the same result.

I changed the code (as $row TO as &$row) and I got this error:
Fatal error: Cannot create references to elements of a temporary array expression in ...

Out of curiosity what does the '&' in front of the variable do?

Thanks
#4

[eluser]TheFuzzy0ne[/eluser]
Whoops. My bad. Try this:

Code:
$res = $result->result()
foreach ($res as &$row) {
        $row->{'Email Address'} = str_replace('gmail', 'yahoo', $row->{'Email Address'});
    }

The ampersand allows you to assign a reference to another variable. Rather than copying it, the variable points to it.

My problem was that I was trying to create a reference to something that was returned from a method, which does not work.

Code:
$arr1 = array('test'); # make a simple array
$arr2 =& $arr1; # Assign it by reference to $arr2
print_r($arr2); # $arr2 is the same as $arr1 (because it IS $arr1)

Array
(
    [0] => test
)


$arr1[] = 'test2'; # Update the first array.
print_r($arr2); # Now we can see the changes in $arr2 also, as both variables point to the same block of memory.

Array
(
    [0] => test
    [1] => test2
)

Hope this helps.
#5

[eluser]pyrokinesis[/eluser]
Hi TheFuzzyOne,

Thanks for the explanation about references.

I tired that, the code in my controller is now:
Code:
function show_data() {
    $this->output->enable_profiler(TRUE);
    $this->load->model('test_model');
    
    $result = $this->test_model->get_data();
    $res = $result->result();
    foreach ($res as &$row) {
        $row->{'Email Address'} = str_replace('gmail', 'yahoo', $row->{'Email Address'});
    }
    
    echo $this->table->generate($result);
}

but the data being outputted to the table is still not being changed.
It's weird because if I print_r($result) before I generate the table, it looks like it has been changed, maybe the table is outputted before the str_replace?

The other thing is as soon as I put the code in the controller, the table looses it's heading (the columns from the db)..

Thanks 8-/
#6

[eluser]TheFuzzy0ne[/eluser]
You need to use $res in $this->table->generate(), as that's contains the array we are modifying by reference. I'd suggest you use $this->table->set_heading() to set the table header.
#7

[eluser]pyrokinesis[/eluser]
Thanks TheFuzzy0ne,

Should have said, I tried that and got:

A PHP Error was encountered
Severity: 4096
Message: Object of class stdClass could not be converted to string
Filename: libraries/Table.php
Line Number: 269


LOL, Am I doing something I am not supposed to be doing in the controller?

Cheers
#8

[eluser]TheFuzzy0ne[/eluser]
Please post a dump of $res after you've finished manipulating it. I honestly think that retrieving the results as arrays rather than objects will help.
#9

[eluser]pyrokinesis[/eluser]
It's so strange, here is the data from the controller:
Code:
function show_data_new() {
        $this->output->enable_profiler(TRUE);
        $this->load->model('test_model');
        
        $result = $this->test_model->get_data();
        $res = $result->result();
        
        foreach ($res as &$row) {
            $row->{'Email Address'} = str_replace('gmail', 'yahoo', $row->{'Email Address'});
        }
        
        echo '<pre>';
        print_r($res);
        echo '</pre>';
        
        echo $this->table->generate($res);
    }

and here is the html output:

Code:
Array
(
    [0] => stdClass Object
        (
            [Staff ID] => 1
            [Name] => William Hill
            [Email Address] => [email protected]
        )

    [1] => stdClass Object
        (
            [Staff ID] => 2
            [Name] => John Carlson
            [Email Address] => [email protected]
        )

    [2] => stdClass Object
        (
            [Staff ID] => 3
            [Name] => Hugh Bishop
            [Email Address] => [email protected]
        )

)

A PHP Error was encountered
Severity: 4096
Message: Object of class stdClass could not be converted to string
Filename: libraries/Table.php
Line Number: 269

The different ways to change the returned data in the model seem to change the values but the table class never gets them.

So the values were changed but not being outputted?

I read somewhere that it's best to keep the data as an object, I don't get why the replace data is not being sent to the table if it's in the variable before the generatetable method is called. Only thing I can think of is the parser execution order?

Maybe it is not possible to change the value of returned in the controller, but I am relucantant do it in the model as it isn't MVC?
#10

[eluser]kgill[/eluser]
While this probably has nothing to do with your current problem, SPACES DO NOT BELONG IN TABLE NAMES, there I feel better now. Seriously, it's just bad design, while wrapping the statement in {}'s will work you need to understand that the reason it works is that it's exploiting the way PHP's eval works, any patch or upgrade could remove that and your code breaks. Is that likely to happen, not really but the possibility is there nonetheless.




Theme © iAndrew 2016 - Forum software by © MyBB