Re: [development] Drupal - to use objects or arrays
I think the general guideline is "use what makes semantic sense at the time". A single entity is an object. (Eg, nodes, users, etc.) A list of things is an array. A list of entities is an array of objects. When you get into really complex data structures, like FAPI, then I think deeply-nested arrays are easier to work with and more predictable (esp. between PHP 4 and PHP 5) than deeply-nested objects. You can have an object one of whose properties is a complex nested array (Nodes created with CCK, esp. in Drupal 5, do that). There's no hard rule, but I think "what makes semantic sense when writing it" is the guideline. Oh yes, and when iterating over records from a database where it really doesn't make a difference, using db_fetch_object() seems more common than db_fetch_array(), simply because there's fewer funky characters involved with objects than arrays. :-) On Tuesday 09 January 2007 3:57 pm, Doug Green wrote:
To use objects or arrays? What is the "Drupal way"? I'd rather write code using objects (php's stdClass). But I've run into a ton of problems using objects on php4.
The CiviCRM folks have this handy guide for php5 -> php4:
http://wiki.civicrm.org/confluence/display/CRM/Writing+PHP4+Compatible+code
But even after using it, I'm having difficulties. I'm starting to conclude that I should convert all my object references to arrays. I only see a couple of object references in core, and none to anything complicated (arrays of objects, objects pointing to objects, object elements of arrays of objects, etc).
Doug Green
www.douggreenconsulting.com <http://www.douggreenconsulting.com/>
www.civicactions.com
Changing the world one node at a time!
-- Larry Garfield AIM: LOLG42 larry@garfieldtech.com ICQ: 6817012 "If nature has made any one thing less susceptible than all others of exclusive property, it is the action of the thinking power called an idea, which an individual may exclusively possess as long as he keeps it to himself; but the moment it is divulged, it forces itself into the possession of every one, and the receiver cannot dispossess himself of it." -- Thomas Jefferson
On 1/9/07, Larry Garfield <larry@garfieldtech.com> wrote:
There's no hard rule, but I think "what makes semantic sense when writing it" is the guideline. Oh yes, and when iterating over records from a database where it really doesn't make a difference, using db_fetch_object() seems more common than db_fetch_array(), simply because there's fewer funky characters involved with objects than arrays. :-)
I'd be happy to see objects removed completely from Drupal...
On Tuesday 09 January 2007 10:08 pm, Rowan Kerr wrote:
On 1/9/07, Larry Garfield <larry@garfieldtech.com> wrote:
There's no hard rule, but I think "what makes semantic sense when writing it" is the guideline. Oh yes, and when iterating over records from a database where it really doesn't make a difference, using db_fetch_object() seems more common than db_fetch_array(), simply because there's fewer funky characters involved with objects than arrays. :-)
I'd be happy to see objects removed completely from Drupal...
That's been proposed at least twice since I started following this list. Both times there was a big argument and we ended up right back where we started: Use what makes semantic sense. Please don't open that can of worms again. :-) -- Larry Garfield AIM: LOLG42 larry@garfieldtech.com ICQ: 6817012 "If nature has made any one thing less susceptible than all others of exclusive property, it is the action of the thinking power called an idea, which an individual may exclusively possess as long as he keeps it to himself; but the moment it is divulged, it forces itself into the possession of every one, and the receiver cannot dispossess himself of it." -- Thomas Jefferson
I think Doug is taking about PHP objects, not objects as they are used in core Drupal. By PHP objects, I mean created using "new", having inheritance, methods, and the whole nine yards as defined by OOP. Drupal objects are things like the $user, $node, and the objects from db_fetch_object() calls. Those are not real classes cannot be inherited from, have no methods, ...etc. (Well, $node is an object, but can it be inherited from? Can it have methods?) So, when Larry says we had this discussion before, he is referring to the latter (and if I recall correctly, more specifically the database objects). And yes, we did not reach consensus on that. (Can someone link to the mailing list discussion on that). I personally find that it is easier to say $foo->$bar['baz'] rather than $foo['bar']['bar]'. But I think Doug is talking about the real objects as used in some modules that are OOP.
From Khalid B:
I think Doug is taking about PHP objects, not objects as they are used in core Drupal.
I wasn't referring to full OOP objects (those with functions and inheritance). I am mostly referring to objects as data storage and the php4/php5 language syntactical differences (and php4 mishandling). For example, the following code snippet in php5: $someobject = new stdClass; $someobjectarray[$someobjectkey] = $someobject; $someobject->element = 'something'; // modifies object in array Must be the following in php4: $someobject =& new stdClass; $someobjectarray[$someobjectkey] =& $someobject; $someobject->element = 'something'; // modifies object in array You must make sure all object assignments are done with =& and instead of =. (I'm not certain of the assignment of the object instantiation, but the CiviCRM folks say it is needed.) And then the problem with loops in php5: Foreach ($someobjectarray as $someobject) { $someobject->element = 'something'; // modifies original object } Is really shorthand for: Foreach ($someobjectarray as &$someobject) { $someobject->element = 'something'; // modifies original object } But php4 doesn't support either, so in php4, you must write: Foreach ($someobjectarray as $someobjectkey => $someobjectreadonly) { $someobjectreadonly->element = 'something'; // modifies w/I loop $someobject =& $someobjectarray[$someobjectkey]; $someobject->element = 'something'; // modifies original object } There are a few other idiosyncrasies. See also: http://wiki.civicrm.org/confluence/display/CRM/Writing+PHP4+Compatible+code I'm probably going to rip them out of the releasemonitor project (http://cvs.drupal.org/viewcvs/drupal/contributions/modules/releasemonitor/) and just use arrays. I'm hearing some feedback that others agree and that there is no advantage to objects, and that there may actually be a disadvantage to using them!
From Larry Garfield:
I think the general guideline is "use what makes semantic sense at the time".
IMHO, objects make "semantic" sense most of the time, but php4 makes them impractical. Doug Green www.civicactions.com www.douggreenconsulting.com Changing the world one node at a time!
On 10 Jan 2007, at 6:08 AM, Rowan Kerr wrote:
There's no hard rule, but I think "what makes semantic sense when writing it" is the guideline. Oh yes, and when iterating over records from a database where it really doesn't make a difference, using db_fetch_object() seems more common than db_fetch_array(), simply because there's fewer funky characters involved with objects than arrays. :-)
I'd be happy to see objects removed completely from Drupal...
agreed. We do all that extra casting , for no real reason.
On Tue, 2007-01-09 at 23:08 -0500, Rowan Kerr wrote:
On 1/9/07, Larry Garfield <larry@garfieldtech.com> wrote:
There's no hard rule, but I think "what makes semantic sense when writing it" is the guideline. Oh yes, and when iterating over records from a database where it really doesn't make a difference, using db_fetch_object() seems more common than db_fetch_array(), simply because there's fewer funky characters involved with objects than arrays. :-)
I'd be happy to see objects removed completely from Drupal...
I'd have to disagree... I like objects in a lot of ways. I work with arrays a lot because they're predictable between php4 and php5. There is, however, some very cool stuff you can do with objects. I wouldn't like to see Drupal completely excluded from it... caveat: I strongly prefer functional programming. I wouldn't want to see Drupal as an all OO system. Objects used in places where appropriate is really cool. I think what the developer is most comfortable with is the best way... For Drupal's sake I remember this discussion from a while back... Structured Data that doesn't have a variable structure (node, user, etc) should be objects. More freeform things, like FormAPI, should be arrays. Settling on one or the other would save a bit of type casting here and there, but that isn't so hard to deal with. .darrel.
Darrel O'Pry wrote:
Settling on one or the other would save a bit of type casting here and there, but that isn't so hard to deal with.
The type casting isnt the difficult part it is actually remembering when you have to and not to do it what makes things difficult. I still have trouble remembering from time to time which is which. But i agree with your sentiment regarding the usefulness of the objects for structured data. -- Michael Favia michael@favias.org tel. 512.585.5650 http://michael.favias.org
Darrel wrote:
There is, however, some very cool stuff you can do with objects. I wouldn't like to see Drupal completely excluded from it...
Michael wrote:
But i agree with your sentiment regarding the usefulness of the objects for structured data.
With the exception of ->foo over ['foo'] which I do agree is a "nicer looking shorthand" what exactly do you get in terms of "cool stuff" and "usefulness" from using objects over arrays in a procedural environment when all your using is the object properties as an array? --Andy (AjK)
A single entity is an object. (Eg, nodes, users, etc.) A list of things is an array. A list of entities is an array of objects.
If only that were true. I'll give you an example of where it isn't true. I once created a "directory of people" for a client. I created a node type to hold the records so tax could be used. I created a form builder function and a db update function to handle it. All's well. Then the client says "some of the people in the directory are actual site users, would be nice if those users could be joined to their record so they can edit their own entry". Made sense, so I used a tab in "my account" to allow for "per user" editing and I initially tried to reuse my existing form builder and db update functions. Guess what? When the form is submitted on "edit node" the update function gets an object, when it's submitted via drupal_get_form() it's an array. Solution, I just cast the array to object in the db update function. But it demonstrates where Drupal is not consistent in it's use of data type containers. Is it an array or an object? Who knows unless you test for it.
where it really doesn't make a difference, using db_fetch_object() seems more common than db_fetch_array(), simply because there's fewer funky characters involved with objects than arrays. :-)
Yes, I see this. fetch_object is slower than fetch_array. Not by much granted, but given we're always looking at performance issues and the speed of Drupal as a whole I'm left wondering why developers are left to use less funky characters over performance. Imho, use an object when you need the functionality of an object, otherwise use arrays. Since Drupal has chosen (at this time) not to use classes I'm surprised the -> operator exists at all anywhere, but it's everywhere! I've discussed this on IRC before (changing objects to arrays) but it's probably a mega change too far, at this time at least ;) As Rowan says: "I'd be happy to see objects removed completely from Drupal..." +1 ;) And Larry, sorry, I'm not looking to open a can of worms here (that's why I said mega change to far) but I just want to point out that if a page makes 100's of SQL queries and they are all served by db_fetch_object() over db_fetch_array() then you are effectively burdening the performance of your application in favour of "having a nice semantic sense" for the developer. If performance wasn't an issue I would give two hoots or care less. But performance IS an issue so it's a valid "can of worms". "personally find that it is easier to say $foo->$bar['baz'] rather than $foo['bar']['bar]'." Exactly what I'm saying. To allow for ease of writing you're adding cpu cycles (not to mention confusion as noted at the beginning of my email, "is it an array or an object? Dunno, must check it, more cpu cycles). Remember, generally you write it once, computers run it millions and millions (if not billions) of times. For whose benefit should it be written, the developers tastes because it looks nice or easier to write or the target hardware where it's actually going to run? Mind you, having said all that, those extra cycles pale into insignificance when you count the number of fstat() calls ;) You can probably tell I come from a coding environment where every cycle counts (machine vision). </rant> --Andy (AjK)
On 10 Jan 2007, at 10:58 AM, AjK wrote:
If only that were true. I'll give you an example of where it isn't true. I once created a "directory of people" for a client. I created a node type to hold the records so tax could be used. I created a form builder function and a db update function to handle it. All's well. Then the client says "some of the people in the directory are actual site users, would be nice if those users could be joined to their record so they can edit their own entry". Made sense, so I used a tab in "my account" to allow for "per user" editing and I initially tried to reuse my existing form builder and db update functions. Guess what? When the form is submitted on "edit node" the update function gets an object, when it's submitted via drupal_get_form() it's an array. Solution, I just cast the array to object in the db update function. But it demonstrates where Drupal is not consistent in it's use of data type containers. Is it an array or an object? Who knows unless you test for it.
Well. Forms in html / php are returned as arrays. And any casting we do from that, is going to end up having to be cast back if we want to use the form submission stuff. Some of my data api stuff requires doing away with objects in relation to forms / data models entirely (such as fixing the horrible node form situation where you have to pass it an empty node object with the right type) Arrays are just simpler and more flexible to work with in php. We often need to do things like array_merge, which won't work with objects.
participants (8)
-
adrian rossouw -
AjK -
Darrel O'Pry -
Doug Green -
Khalid B -
Larry Garfield -
Michael Favia -
Rowan Kerr