0

I'm working on a project in CodeIgniter 2 and now I'm stuck on the most basic of concepts.

Model:

Get an object array from my table which contains all rows that match a specific value for a field named foo. There can be one or more rows that match. In this example, two rows.

public function get_sample($foo)
{
    $query = $this->db->get_where('sample_db', array('foo' => $foo));

    return $query->result();
}

Controller:

Assign the results and make output available to view.

public function view($foo)
{
    $data['array'] = $this->sample_model->get_sample($foo);

    $this->load->view('view', $data);
}

View:

echo var_dump($array); // for testing

echo $array[1]->text

var_dump() of $array:

array(2) {
    [0]=> object(stdClass)#23 (4) {
        ["id"]=> string(1) "1"
        ["foo"]=> string(3) "bar"
        ["number"]=> string(4) "1234"
        ["text"]=> string(23) "This is content in 1234"
    }
    [1]=> object(stdClass)#24 (4) {
        ["id"]=> string(1) "2"
        ["foo"]=> string(3) "bar"
        ["number"]=> string(4) "9999"
        ["text"]=> string(23) "This is content in 9999"
    } 
} 

The rendered ouput of echo $array[1]->text; is: This is content in 9999

And I understand how all that is working: $array[1]->text is the content of the text field in the array object with the index of 1, my second object.

However, I have a field called number and I want to access the object with a certain number and get its corresponding text value.

Example: How can I retrieve the value of text where the number is 9999? I cannot use $array[1]->text since I can never be sure of the object's position in the array. Something like $array['number' => '9999']->text, but I know that's not right. Maybe I need to loop through the array looking for a match?

This looks so simple yet everything I've tried has failed and resulted in various PHP errors. I've been studying the PHP manual here and here, but cannot seem to find anything about what I'm looking to do, or maybe I'm just misapplying what I'm reading. Any guidance is appreciated.

In addition to an answer using best practices following the MVC model, I'm hoping for a link to the proper page in the documentation, as well as pointing out any errors in my wording/terminology above.


EDIT:

This answer contains the actual code I used to solve my problem. Although, Yagi's answer was accepted because it put me in the right direction.

4 Answers 4

2

How about using this :

foreach ($array as $row) {
        if ($row->number == '9999') {
            echo $row->text;
        }
    }

Loop through the array, and find the number object value of 9999 and get the text

Sign up to request clarification or add additional context in comments.

Comments

0

Why don't you just to a query and search for that number (or order by that number?)

Either way, what you need is a multidimensional array search function (that iterates through array of object and returns the found field value combo )

Something like this (put this in helper)

function multi_array_search($array, $field, $value) 
 { 
     $results = array(); 

     if (is_array($array)) 
     { 
         if ($array->$field == $value)  //chek the filed against teh value, you can do addional check s(i.e. if field has been set)

             $results[] = $array; 

         foreach ($array as $subarray) 
             $results = array_merge($results,  multi_array_search($subarray, $key, $value));  //recurisve serach
     } 

     return $results; 
 }


    //than in view or in controller, depending where you need it

   $result  = multi_array_search($array, "number", "9999");

var_dump($result) will return or whether number of foudn instances

array() {
    [0]=> object(stdClass)#24 (4) {
        ["id"]=> string(1) "2"
        ["foo"]=> string(3) "bar"
        ["number"]=> string(4) "9999"
        ["text"]=> string(23) "This is content in 9999"
    } 

}

Comments

0

you might be looking for something like this...

array_filter($array, function($o){ return $o->number == 9999; } );

http://php.net/manual/en/function.array-filter.php

EDIT

$o is the parameter in the callback function. each element of the array is passed to the callback function. if the function returns false, the element will be filtered out.

$arr = array(
    (object) array(
        'num' => 33,
        'text' => 'hello',
    ),
    (object) array(
        'num' => 44,
        'text' => 'world',
    ),
);
$filtered = array_filter($arr, function($o){ return $o->num == 33; });
echo $filtered[0]->text; // hello

as you stated, index will remain, so use array_values or array_shift. here's an example with function

function get_by_num($arr, $num){
    return array_shift(array_filter($arr, function($o) use ($num) { return $o->num == $num; }));
}
$obj = get_by_num($arr, 44);
var_dump($obj);
// object(stdClass)#2 (2) { ["num"]=> int(44) ["text"]=> string(5) "world" }

in this case $obj will be either NULL if element is not found, or the first match. $num is transferred along so you can use any value. you can even improve it:

function get_first_match($arr, $field, $val){
    return array_shift(array_filter($arr, function($o) use ($field, $val) { return $o->{$field} == $val; }));
}
$obj = get_first_match($arr, 'num', 44);

and now you can search any field. in your case

$obj = get_first_match($array, 'number', 9999);

4 Comments

echo $filtered[0]->text; is giving a Undefined offset: 0 error.
then you must have done something wrong... code is fine if element is found. if it's not found the $filtered would be empty and you'll get the warning. in our case it works
var_dump($filtered) is returning an array that contains a single object, array(1) { [1]=> object(stdClass)#24.... So actually echo $filtered[1]->text works but that puts me back at square one since that's the same index I was using in my original example.
run array_values on it, i'll add it underneath
0

Thanks to Yagi's answer, I came up with the following very simple solution. I loop through the array and assign the value of text to a new array with an index that matches the value of number. Then in the view file, I can access the text value based on this index.

Controller:

public function view($foo)
{
    $data['array'] = $this->sample_model->get_sample($foo);

    foreach ($data['array'] as $row) {
        $data['result'][$row->number] = $row->text;
    };

    $this->load->view('view', $data);
}

View:

if (isset($result[9999])) echo $result[9999];

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.