Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

result_array(), result_object() to accept a field name to use as key of returned array #429

Open
wants to merge 8 commits into from

7 participants

@wyred

http://codeigniter.com/forums/viewthread/193209/

http://codeigniter.uservoice.com/forums/40508-codeigniter-reactor/suggestions/1561893-pass-column-name-into-active-record-result-to-be

Example use:
In my users database table, I have:

id  - name - email
1 - Preston - preston@libria.com
3 - Seamus - seamus@libria.com
4 - Dupont - dupont@libria.com

In my app, I do:

$rs = $this->db->select('id, name')->get('users');
$users = $rs->result_array('id');

$users will be:

Array
(
    [1] => Array
        (
            [id] => 1
            [name] => Preston
        )

    [3] => Array
        (
            [id] => 3
            [name] => Seamus
        )

    [4] => Array
        (
            [id] => 4
            [name] => Dupont
        )
)
@wyred wyred commented on the diff
system/database/DB_result.php
((7 lines not shown))
{
- $object = new $class_name();
-
- foreach ($row as $key => $value)
+ $row = $this->_fetch_object();
+ if (isset($row->$object_key)) $key_exists = TRUE;
+ $this->_data_seek(0);
+ }
+
+ if ($key_exists) {
@wyred
wyred added a note

Instead of evaluating if $key_exists at line 98, I chose to duplicate the code just so that $key_exists will only need to be evaluated once instead n times for n results.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@dbpolito

Really good idea!

@jondavidjohn

I also think this makes sense at first glance...

@vmichnowicz

I love making the ID be the array key. This really simplifies the process. Good idea.

@joelcox

Nice pull request. I often find myself looping over the result array to do just this. Don't forget to actually add this functionality to the docs, not just to the changelog.

@wyred

Thanks everyone!

@joelcox is it ok to proceed with user_guide changes yet?
Last I heard was this: http://twitter.com/#!/philsturgeon/status/108154732987686913

@joelcox
@ftwbzhao

really good

@wyred

If this request is being ignored because the code is messy, would it be better if we create a new function instead?

Something like: $query->result_array_key('id');

I'm not good at naming this. D:

@joelcox

I actually like the original way where you pass the key name to the result/result_array method. Read this to see why your request isn't merged yet.

@wyred
@ferozsho

the key is not working while cache is on ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Sep 12, 2011
  1. @wyred
Commits on Sep 13, 2011
  1. @wyred

    User guide explanation

    wyred authored
Commits on Sep 16, 2011
  1. @wyred
  2. @wyred

    User guide explanation

    wyred authored
  3. @wyred
Commits on Sep 18, 2011
  1. @wyred
  2. @wyred

    User guide explanation

    wyred authored
  3. @wyred
This page is out of date. Refresh to see the latest.
View
96 system/database/DB_result.php
@@ -45,11 +45,11 @@ class CI_DB_result {
* @param string can be "object" or "array"
* @return mixed either a result object or array
*/
- function result($type = 'object')
+ function result($type = 'object', $key = '')
{
- if ($type == 'array') return $this->result_array();
- else if ($type == 'object') return $this->result_object();
- else return $this->custom_result_object($type);
+ if ($type == 'array') return $this->result_array($key);
+ else if ($type == 'object') return $this->result_object($key);
+ else return $this->custom_result_object($type, $key);
}
// --------------------------------------------------------------------
@@ -58,9 +58,10 @@ function result($type = 'object')
* Custom query result.
*
* @param class_name A string that represents the type of object you want back
+ * @param string Name of field you want to use as the $result_object's array key
* @return array of objects
*/
- function custom_result_object($class_name)
+ function custom_result_object($class_name, $object_key = '')
{
if (array_key_exists($class_name, $this->custom_result_object))
{
@@ -76,18 +77,41 @@ function custom_result_object($class_name)
$this->_data_seek(0);
$result_object = array();
- while ($row = $this->_fetch_object())
+ $key_exists = FALSE;
+ if ($object_key!='')
{
- $object = new $class_name();
-
- foreach ($row as $key => $value)
+ $row = $this->_fetch_object();
+ if (isset($row->$object_key)) $key_exists = TRUE;
+ $this->_data_seek(0);
+ }
+
+ if ($key_exists) {
@wyred
wyred added a note

Instead of evaluating if $key_exists at line 98, I chose to duplicate the code just so that $key_exists will only need to be evaluated once instead n times for n results.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ while ($row = $this->_fetch_object())
{
- $object->$key = $value;
+ $object = new $class_name();
+
+ foreach ($row as $key => $value)
+ {
+ $object->$key = $value;
+ }
+
+ $result_object[$row->$object_key] = $object;
}
-
- $result_object[] = $object;
}
+ else
+ {
+ while ($row = $this->_fetch_object())
+ {
+ $object = new $class_name();
+
+ foreach ($row as $key => $value)
+ {
+ $object->$key = $value;
+ }
+ $result_object[] = $object;
+ }
+ }
// return the array
return $this->custom_result_object[$class_name] = $result_object;
}
@@ -100,7 +124,7 @@ function custom_result_object($class_name)
* @access public
* @return object
*/
- function result_object()
+ function result_object($key = '')
{
if (count($this->result_object) > 0)
{
@@ -116,9 +140,27 @@ function result_object()
}
$this->_data_seek(0);
- while ($row = $this->_fetch_object())
+
+ $key_exists = FALSE;
+ if ($key!='')
{
- $this->result_object[] = $row;
+ $row = $this->_fetch_object();
+ if (isset($row->$key)) $key_exists = TRUE;
+ $this->_data_seek(0);
+ }
+
+ if ($key_exists) {
+ while ($row = $this->_fetch_object())
+ {
+ $this->result_object[$row->$key] = $row;
+ }
+ }
+ else
+ {
+ while ($row = $this->_fetch_object())
+ {
+ $this->result_object[] = $row;
+ }
}
return $this->result_object;
@@ -132,7 +174,7 @@ function result_object()
* @access public
* @return array
*/
- function result_array()
+ function result_array($key = '')
{
if (count($this->result_array) > 0)
{
@@ -148,9 +190,27 @@ function result_array()
}
$this->_data_seek(0);
- while ($row = $this->_fetch_assoc())
+
+ $key_exists = FALSE;
+ if ($key!='')
{
- $this->result_array[] = $row;
+ $row = $this->_fetch_assoc();
+ if (isset($row[$key])) $key_exists = TRUE;
+ $this->_data_seek(0);
+ }
+
+ if ($key_exists) {
+ while ($row = $this->_fetch_assoc())
+ {
+ $this->result_array[$row[$key]] = $row;
+ }
+ }
+ else
+ {
+ while ($row = $this->_fetch_assoc())
+ {
+ $this->result_array[] = $row;
+ }
}
return $this->result_array;
View
5 user_guide/changelog.html
@@ -91,6 +91,11 @@
<li>
Added additional option 'none' for the optional third argument for <kbd>$this->db->like()</kbd> in the <a href="database/active_record.html">Database Driver</a>.
</li>
+ <li>
+ <kbd>result_array()</kbd> and <kbd>result_object()</kbd> now accepts an optional argument to specify which field in the query result to use as array key.<br />
+ One generally specifies the primary key field because it contains unique values.<br />
+ <kbd>result()</kbd> also accepts this value, but as a second argument.
+ </li>
</ul>
</li>
<li>Libraries
View
51 user_guide/database/results.html
@@ -109,6 +109,27 @@
&nbsp;&nbsp;&nbsp;echo $user->reverse_name(); // or methods defined on the 'User' class<br />
}
</code>
+
+ <p>You can specify a field name from your results in the second parameter to use as the array key.</p>
+ <p>Usually you would use the primary key field of the table so that you won't lose any data because of duplicate keys.</p>
+ <p>Consider the following database data:</p>
+ <code>
+ mysql> select * from users;<br />
+ +----+------+<br />
+ | id | name |<br />
+ +----+------+<br />
+ |&nbsp; 1 | John |<br />
+ |&nbsp; 3 | Jane |<br />
+ |&nbsp; 4 | Joe&nbsp; |<br />
+ +----+------+<br />
+ </code>
+ <p>In your application, you run the following code:</p>
+ <code>
+ $query = $this->db->query("SELECT id, name FROM users;");<br />
+ $results = $query->result('User','id');<br />
+ <br />
+ echo $results[3]->name; //prints Jane
+ </code>
<h2>result_array()</h2>
@@ -122,6 +143,36 @@
&nbsp;&nbsp;&nbsp;echo $row['name'];<br />
&nbsp;&nbsp;&nbsp;echo $row['body'];<br />
}</code>
+
+ <p>You can specify a field name from your results to use as the array key, similar to the previous example in result()</p>
+ <code>
+ $query = $this->db->query("SELECT id, name FROM users");<br />
+ $results = $query->result_array('id');<br />
+ print_r($results);</code>
+
+ <p>Output:</p>
+
+ <code>
+ Array<br />
+ (<br />
+ &nbsp;&nbsp;&nbsp;[1] => Array<br />
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<br />
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[id] => 1<br />
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[name] => John<br />
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;)<br />
+ <br />
+ &nbsp;&nbsp;&nbsp;[3] => Array<br />
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<br />
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[id] => 3<br />
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[name] => Jane<br />
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;)<br />
+ <br />
+ &nbsp;&nbsp;&nbsp;[4] => Array<br />
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<br />
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[id] => 4<br />
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[name] => Joe<br />
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;)<br />
+ )</code>
<h2>row()</h2>
Something went wrong with that request. Please try again.