Skip to main content

This site requires you to update your browser. Your browsing experience maybe affected by not having the most up to date version.

We've moved the forum!

Please use forum.silverstripe.org for any new questions (announcement).
The forum archive will stick around, but will be read only.

You can also use our Slack channel or StackOverflow to ask for help.
Check out our community overview for more options to contribute.

Data Model Questions /

Moderators: martimiz, Sean, Ed, biapar, Willr, Ingo, swaiba

Returning Database data as an ordinary array (instead of a dataobject)


Go to End


7 Posts   12087 Views

Avatar
Yokelassence

Community Member, 15 Posts

10 July 2012 at 1:34am

Hello, I have a dumb question to ask but strangely enough my search results for it have turned up null.

I want to do some PHP manipulation on my dataobject contents rather than just display it on a page. To do this, I often need to convert my dataobjects into arrays as I find it easier to access and manipulate array properties than dataobject properties

I use a function like this to do it:

        $array = array();

        $result = Dataobject::get("table");
        foreach ($result as $row) {
            $array[$row->field] = $row->field;
            //do something like this for every field
        }

        return $array;

My question is if there is a Silverstripe feature that already returns Database data as a regular array. If one exists, I can skip this step altogether but I am having trouble finding it.

Surely Silverstripe has something that does this. I just haven't found it yet.

Avatar
cuSSter

Community Member, 56 Posts

10 July 2012 at 2:49am

Edited: 10/07/2012 2:56am

Hi Yokelassence,

Instead of using the ORM way of getting objects, you can use the SQLQuery class to query for certain database entries. This will also decrease the execution time of your query since the DataObject::get function also gets rows from related tables, which, I believe, in many instances not needed.

$sql = new SQLQuery();
$sql->select = array( 'Field1', 'Field2' );
$sql->from = array( 'Table1' );
$sql->where = array( 'ID = 1', 'Value = <something>' );
$result = $sql->execute();
if( $result ) {
     foreach( $result as $item ) {
          echo $item[ 'Field1' ];
     }
}

Or use DB::query(). Using the example above:

$result = DB::query( 'SELECT Field1, Field2, FROM Table1 WHERE ID = 1 AND Value = <something>' );
if( $result ) {
     foreach( $result as $item ) {
          echo $item[ 'Field1' ];
     }
}

Avatar
Yokelassence

Community Member, 15 Posts

10 July 2012 at 4:34am

I am aware of those other methods. I suppose I could get away with either of those in my current code since I am not doing anything related to the front-end. This is back end code here.

However, both those cases return an SQLQueryobject or a Dataobject. I'm just looking for the most efficient way to get a plain old-fashioned array out of my database.

Avatar
cuSSter

Community Member, 56 Posts

10 July 2012 at 5:04am

Edited: 10/07/2012 5:08am

Yeah, they both return an SS_Query object if I'm not mistaken. I haven't encountered any method yet that just returns an array from an SQL query, usually they are wrapped in an object. Maybe for each DataObject in DataObject::get() method, you can use ArrayData:: object_to_array() static method. I remembered using that a few projects back.

Avatar
Yokelassence

Community Member, 15 Posts

10 July 2012 at 5:32pm

Creating a new ArrayData object from the dataobject is very, VERY close to what I want here.

That trunctates most of the irrelevant properties, converts everything to array objects and simplifies the array to just a two dimensional array

To make it perfect, I just need to un-protect the root parent array for the data and get rid of the rest of properties I don't need

EG, this:

ArrayData Object
(
    [array:protected] => Array
        (
            [items] => Array
                (
                    [properties] => x
                )

        )

    [iteratorPos:protected] => 
    [iteratorTotalItems:protected] => 
    [failover:protected] => 
    [customisedObject:protected] => 
    [objCache:ViewableData:private] => Array
        (
        )

    [class] => ArrayData
    [extension_instances:protected] => Array
        (
        )

)

To this:

Array
(
    [array] => Array
        (
            [items] => Array
                (
                    [properties] => x
                )

        )
)

Avatar
swaiba

Forum Moderator, 1899 Posts

10 July 2012 at 8:38pm

Avatar
jak

Community Member, 46 Posts

11 July 2012 at 9:22pm

I think the way to go is to iterate over the DataObjectSet, call toMap() on each DataObject and store the result in an array.