[dev] Horde_Session thoughts
Chuck Hagenbuch
chuck at horde.org
Fri Nov 5 02:56:18 UTC 2010
Quoting Michael M Slusarz <slusarz at horde.org>:
> Quoting Jan Schneider <jan at horde.org>:
>
>> Zitat von Michael M Slusarz <slusarz at horde.org>:
>>
>>> Quoting Jan Schneider <jan at horde.org>:
>>>
>>>> Zitat von Michael M Slusarz <slusarz at horde.org>:
>>>>
>>>>> Allow ability to search session subkeys.
>>>>>
>>>>> We store values with key & subkey together to save on
>>>>> storage/serialization
>>>>> costs. To retrieve array like output, simply need to call
>>>>> $session['app:name/'] - returns an array with subkeys as keys and session
>>>>> values as values.
>>>>
>>>> This sounds like a bit too much magic for a small performance
>>>> gain. I'd rather like this to be a real array for
>>>> readability/maintainability, and loose a bit of performance.
>>>> Can't be too much anyway.
>>>
>>> Disagree. I personally am finding that storing something with a
>>> session index like:
>>> ['imp:imp_mailbox/INBOX']
>>> is *much* clearer (since all the pertinent information is in the
>>> same string and not separated by PHP-ish cruft) in the code than:
>>> ['imp']['imp_mailbox']['INBOX']
>>> not to mention easier to write and less prone to typos/errors.
>>>
>>> Especially since I have only found *1* instance in the code so far
>>> where we were actually using the iterative/collective property of
>>> arrays (the horde:auth_app variable). In every other instance, we
>>> are carrying around the overhead of an array data structure solely
>>> for the fact that it might make things a bit clearer in the code -
>>> but, as I argue above, that is not true anymore either.
>>>
>>> But nothing I have added will prevent anybody from storing arrays
>>> if they want.
>>
>> I feel rather strong about this being counter-intuitive. Any other
>> opinions about this?
>
> My (belated) take on this...
>
> I have very strong feelings that the way I have implemented is
> *much* preferable - and these opinions are because I have spent 5+
> hours converting things and tweaking the API syntax to make things
> as easy as possible to both code, read, and debug. But I need to
> pick my battles and since everyone else seems to be against it, I'm
> going to concede this issue for now.
>
> Well... only somewhat concede because there have been several other
> comments about implementation changes that are DEFINITELY not
> happening. Hopefully I touch on all points below
>
> 1. API
>
> The API must be as follows:
> $horde_session->get($app, $name[, $options_mask])
> $horde_session->set($app, $name, $value[, $options_mask])
> $horde_session->remove($app, $name)
>
> Writing this out, it is painfully apparent how much cleaner the
> array syntax is. E.g.,
> $horde_session['app:foo'] = $value;
> vs.
> $horde_session->set('app', 'foo', $value);
> But I digress...
>
> Most important, and this goes for classes/objects other than
> Horde_Session, you absolutely CAN NOT USE MAGIC PROPERTY ACCESS
> METHODS (i.e. $horde_session->variable name). First, in the
> Horde_Session case, it can't be used since session data is not a
> simple key->value lookup. It is stored by app name. You could
> theoretically do fancy manipulation by stacking objects on top of
> objects, (i.e. $horde_session->horde->variable_name) but what's the
> point besides adding a bunch of unneeded complexity? And you can't
> pass options using this syntax.
>
> Most important, using magic properties is simply a terrible design
> decision for data objects where the key name is entirely dynamic,
> for the obvious reason that the possible keys are limited. This was
> precisely why I used array access in the first place - to prevent
> this limitation. The only time using __get() makes sense for
> dynamic property accesses is when the keys are already defined and
> limited (see, e.g., IMP_Mailbox_Element - property access makes
> sense here to prevent us from having to write 30 mini-methods of 1-2
> lines each to return a dynamic value).
>
> This is precisely why I added an array access possibility to
> Horde_Prefs, but there can not be a parallel object property access
> API.
>
> 2. Storage in the session needs to be as flat as possible.
>
> Don't have the link in front of me, but read somewhere recently that
> a PHP array with a single element requires 300+ bytes (as opposed to
> something like 68 bytes for a scalar value). So deep arrays need to
> be avoided at all costs.
>
> Through my process of converting so far, my conclusion is that there
> is absolutely no reason that 99% of session variables need to be
> living in an array format. The vast majority of session variables
> are scalar values and don't need to be living in an array.
>
> Debugging is not a valid argument against this. If we need a way to
> pretty print the current session, it is trivial to add a debug
> method to Horde_Session.
>
> And this argument is moot anyway, since actual storage format can be
> easily changed in the future once all session reading/writing is
> filtered through Horde_Session.
>
> This leads to...
>
> 3. For technical reasons, DIRECT ARRAY ELEMENT ACCESS ISN'T POSSIBLE ANYWAY
>
> This is no longer possible:
> $_SESSION['app']['foo']['bar']['enabled'] = 1;
>
> Nothing you can do about it. This MUST be done this way (with the
> proposed API from above):
> $a = $horde_session->get('app', 'foo');
> $a['bar']['enabled'] = 1;
> $horde_session->set('app', 'foo', $a);
>
> This is a technical limitation due to the fact that we need to track
> if a session element has been altered in order to determine if we
> need to update the session data on shutdown. Right now we use md5()
> checksums to do this check, but the new method is magnitudes faster
> (just like using md5 checksums is magnitudes faster than writing to
> the session storage backend on every pageload, even if session data
> doesn't change).
>
> As a compromise to limiting array access, this is why I added...
>
> 4. The *EXTREMELY* useful 'varname/subname' format
>
> There are certain situations where it is useful to allow at least a
> basic key->value lookup for certain data items. For example, the
> authentication data stored in horde. It is much clearer code to
> store things as 'auth/appname' than creating a bunch of individual
> keys like 'auth-appname'. More important, it gives us the ability
> to later be able to work with these data elements as a whole - like
> if we wanted to reset all authentication tokens at once. Thus the
> need for a shorthand format to allow us to do this.
>
> I really don't see how this is "counter-intuitive". If you don't
> like this feature, don't use it. It doesn't affect anything else,
> while providing shortcuts to allow iteration and easy removal.
>
> I will reserve comment on removing our Horde globals for another
> time other to see I _deeply_ disagree with that decision. I have
> absolutely no problem with providing a small number (for us it is 10
> or less) of globally available variables for items that are
> universally used. These globals are available only to applications.
> Asking an application developer to start to have to inject
> EVERYTHING into a page seems to be a GIANT step backwards in terms
> of making the framework easier to use. There is absolutely nothing
> wrong with providing intelligent shortcuts to make coding easier.
> This idea seems more like a quest for perfect OO-coding purity than
> a decision to make actual coding better.
>
> I will start work on moving converted code to the new API.
I'm fine with all of this. Thank you. On the globals I will say that
no one is rushing to just delete all of them; we'll see how things are
as we progress.
-chuck
More information about the dev
mailing list