RFD: PDO::FETCH_2D or a hierarchical FETCH_ASSOC

php.internals

Hans-Peter Oeri

18 years ago
Hi! I'm surely not the only one that ran into the problem of queries returning several columns with identical names. I didn't find anything about my following suggestion in the archives - if however, I'm only warming up old cheese, please ignore/bash me ;) As I see, there is an connection attribute ATTR_FETCH_TABLE_NAMES that - depending on driver support - qualifies column names: column 'a' on table 'b' => $result['b.a'] Given support for that attribute, a FETCH_ASSOC returns a one-dimensional array with qualified column names. However, I don't consider this solution as good as it could be... E.g. it's rather hard to extract the values from a specific table (short of running over the whole index array). There is useful information "hidden" in the text... I therefore suggest a fetch mode that returns TWO-DIMENSIONAL arrays, the first dimension being the table/relation name, the second the column identification: column 'a' on table 'b' => $result['b']['a'] Such a solution would ease a lot of my 'framework' tasks. Open questions/ideas: - columns not originating from a table? Those could be entered in the first hierarchy (possibility of conflict with table names): $result['computed_value'] or in sort of a 'pseudo table' like '0' or 'unknown' (possibility of conflict by that pseudo name): $result['unknown']['computed_value'] - separate fetch mode or mode modification flag? There could be uses for a modified FETCH_BOTH as well, with column numbers all on first level plus hierarchical FETCH_2D. - what about a hybrid fetch? There could be uses for sort of a hybrid fetch, which would result in FETCH_ASSOC (each column name only once, first level) plus FETCH_2D (all columns hierarchically). To reduce memory consumption, the "doubly represented" columns could share a Z_VAL reference. Compatibility issues: - A quick glance only reveals fetchColumn and getColumnMeta as obvious compatibility issues. Should they be enhanced to not only accept column numbers, but textual column identifiers as well... - A hybrid mode (see above) that works 1:1 with existing code plus offers the advantages of hierarchical access would only be feasible with 'hidden' keys. I don't think that's necessary. What do you think? HPO

Sam Barrow

18 years ago
I am trying to develop a patch for personal use to enable custom superglobals. I seemed to have had it working, but am I allowed to specify superglobals in my script, or do they have to be specified in an ini file or statically in the PHP code? I created a superglobal keyword and a function that calls zend_register_auto_global upon the use of this keyword, but it doesn't work. It calls zend_register_auto_global correctly and passes the variable name and length of the variable name, but when i try to access the variable inside a function in my PHP script, it is undefined. However I am able to hard code my superglobal into the PHP source files and it works. Is there some type of restriction on setting superglobals at runtime, or does the structure of the PHP interpreter not allow this, or am I doing something wrong? Thanks in advanced for your help.

Hans-Peter Oeri

18 years ago
Hi! Sam Barrow wrote:
> I am trying to develop a patch for personal use to enable custom > superglobals.
I may have missed your point. But does the pecl extension "runkit" not fulfill your desires? HPO

Johannes Schlueter

18 years ago
Hi Sam, you could use pecl/runkit for registering your own super globals. See example 2071 on http://de3.php.net/manual/en/ref.runkit.php johannes On Fri, 2007-11-16 at 15:53 -0500, Sam Barrow wrote:

Sam Barrow

18 years ago
Thanks everyone, I knew this, but I didn't want to use runkit because it is a beta, and i don't want all that other stuff, just superglobals. Also, runkit only allows you to use php.ini, but my patch allows you to specify superglobals in your script with the keyword "superglobal" by saying: superglobal $var1, $var2 ; Thanks for your help though, if anyone else is interested in the patch send me a message. This isn't something the developers would want to implement I assume, but it would be useful if they would, at a very small cost too (the patch probably under 50 lines, very simple code too). If anyone would like the patch to be implemented in CVS, let me know. On Fri, 2007-11-16 at 22:58 +0100, Johannes Schlüter wrote:

Michael McGlothlin

18 years ago
I think the superglobal keyword is a great idea. I have a custom class that implements a custom interface to memcache with a MySQL backend for data that drops out of memcache or is to big to be stored easily in memcache. I get annoyed at needing to include a global statement in every place I want to use memcache.
> Thanks everyone, I knew this, but I didn't want to use runkit because it > is a beta, and i don't want all that other stuff, just superglobals. > Also, runkit only allows you to use php.ini, but my patch allows you to > specify superglobals in your script with the keyword "superglobal" by > saying: > > superglobal $var1, $var2 ; > > Thanks for your help though, if anyone else is interested in the patch > send me a message. > > This isn't something the developers would want to implement I assume, > but it would be useful if they would, at a very small cost too (the > patch probably under 50 lines, very simple code too). If anyone would > like the patch to be implemented in CVS, let me know. > > On Fri, 2007-11-16 at 22:58 +0100, Johannes Schlüter wrote: > >> Hi Sam, >> >> you could use pecl/runkit for registering your own super globals. See >> example 2071 on http://de3.php.net/manual/en/ref.runkit.php >> >> johannes >> >> On Fri, 2007-11-16 at 15:53 -0500, Sam Barrow wrote: >> >>> I am trying to develop a patch for personal use to enable custom >>> superglobals. >>> >>> I seemed to have had it working, but am I allowed to specify >>> superglobals in my script, or do they have to be specified in an ini >>> file or statically in the PHP code? >>> >>> I created a superglobal keyword and a function that calls >>> zend_register_auto_global upon the use of this keyword, but it doesn't >>> work. It calls zend_register_auto_global correctly and passes the >>> variable name and length of the variable name, but when i try to access >>> the variable inside a function in my PHP script, it is undefined. >>> However I am able to hard code my superglobal into the PHP source files >>> and it works. >>> >>> Is there some type of restriction on setting superglobals at runtime, or >>> does the structure of the PHP interpreter not allow this, or am I doing >>> something wrong? >>> >>> Thanks in advanced for your help. >>> > >
-- Michael McGlothlin Southwest Plumbing Supply

Stanislav Malyshev

18 years ago
> I think the superglobal keyword is a great idea. I have a custom class > that implements a custom interface to memcache with a MySQL backend for > data that drops out of memcache or is to big to be stored easily in > memcache. I get annoyed at needing to include a global statement in > every place I want to use memcache.
I don't think it's a good idea. Superglobals are special for a reason - if everybody would just add stuff into global space and make it superglobal because they can't type a couple of keystrokes, it would be a mess. Just declare a class and use statics or singletons.
-- Stanislav Malyshev, Zend Software Architect stas@zend.com http://www.zend.com/ (408)253-8829 MSN: stas@zend.com

Sam Barrow

18 years ago
Well this is very common with PHP, it's very flexible and it's easy for a bad programmer to create chaotic code and get away with it, but this can happen with many features of PHP. For serious developers however, this could prove to be very useful when used appropriately. People will do what they will and make sloppy programs, but that's completely up to them. No point in holding stuff back from people who could benefit from it just to protect inexperienced them from their own sloppiness. You know what I mean? On Fri, 2007-11-16 at 16:28 -0800, Stanislav Malyshev wrote:

Stanislav Malyshev

18 years ago
> Well this is very common with PHP, it's very flexible and it's easy for > a bad programmer to create chaotic code and get away with it, but this > can happen with many features of PHP. For serious developers however,
Right. This is why I don't think it's a good idea to add one more feature with very high potential for abuse. Code that changes behaviour of unrelated other code is usually very bad idea - think about what happens if some of your functions somewhere among 10K lines of code used $cfg as local variable and then you added $cfg as superglobal.
> them. No point in holding stuff back from people who could benefit from > it just to protect inexperienced them from their own sloppiness. You > know what I mean?
Yes, there is a point in not implementing features that would promote bad coding and unnecessary surprises for the users. Especially when the same function can be achieved with existing functionality in a much better way.
-- Stanislav Malyshev, Zend Software Architect stas@zend.com http://www.zend.com/ (408)253-8829 MSN: stas@zend.com

Michael McGlothlin

18 years ago
Stanislav Malyshev wrote:
>> Well this is very common with PHP, it's very flexible and it's easy for >> a bad programmer to create chaotic code and get away with it, but this >> can happen with many features of PHP. For serious developers however, > > Right. This is why I don't think it's a good idea to add one more > feature with very high potential for abuse. Code that changes > behaviour of unrelated other code is usually very bad idea - think > about what happens if some of your functions somewhere among 10K lines > of code used $cfg as local variable and then you added $cfg as > superglobal. > >> them. No point in holding stuff back from people who could benefit from >> it just to protect inexperienced them from their own sloppiness. You >> know what I mean? > > Yes, there is a point in not implementing features that would promote > bad coding and unnecessary surprises for the users. Especially when > the same function can be achieved with existing functionality in a > much better way.
This assumes there is never a good reason for a super global which makes me wonder why PHP has super globals at all then? What if, because I use it so often and want to differentiate it, it just works better for me to make it a super global? I could always name it with the standard $_ naming scheme so as to not run into accidental use. I don't often use globals but when I do it's usually because it's something I'll use a lot. It doesn't benefit code readability to have the same thing repeated hundreds of times. It's not a big issue but I do like the idea of making super globals easy to do. All this forcefulness of writing pristine code from the people that teach people that it's okay to inline their HTML, Javascript, CSS, SQL, and who knows what else into their PHP? Talk about a recipe for disaster. Oh well, at least you didn't refuse to add a switch statement like Python.

Sam Barrow

18 years ago
That's a good point too, usually when globals are used at all they are used in numerous functions It's very rare to see a variable that's used as a global in one or two functions.
> This assumes there is never a good reason for a super global which makes > me wonder why PHP has super globals at all then? What if, because I use > it so often and want to differentiate it, it just works better for me to > make it a super global? I could always name it with the standard $_ > naming scheme so as to not run into accidental use. I don't often use > globals but when I do it's usually because it's something I'll use a > lot. It doesn't benefit code readability to have the same thing repeated > hundreds of times. It's not a big issue but I do like the idea of making > super globals easy to do.
On Fri, 2007-11-16 at 20:44 -0700, Michael McGlothlin wrote:

Sam Barrow

18 years ago
But why not have maximum flexibility? A language should provide as many tools to the user as possible, a tool doesn't hurt. If you don't want to do it, don't, who cares? But an extra tool never hurts in any situation, real life or a programming language. Any language and any features of a language can be abused horribly by someone who doesn't know what they're doing. On Fri, 2007-11-16 at 20:44 -0700, Michael McGlothlin wrote:

Stanislav Malyshev

18 years ago
> This assumes there is never a good reason for a super global which makes > me wonder why PHP has super globals at all then? What if, because I use
There is a good reason, and exactly for things that PHP has as superglobals. Because these variables - system variables - are unique and well-known. We have to balance between cases where some dangerous functionality can be useful, and cases where some useful functionality can be dangerous. For superglobals, user-defined ones have danger far outweight the usefulness, and we have a number of good and working alternatives, so the case seems to be clear.
> All this forcefulness of writing pristine code from the people that > teach people that it's okay to inline their HTML, Javascript, CSS, SQL, > and who knows what else into their PHP? Talk about a recipe for > disaster. Oh well, at least you didn't refuse to add a switch statement > like Python.
We do not (at least I do not :) refuse things just because we like to be purists and torture developers. There's a good reason for that, and I believe it was explained in the emails in this thread.
-- Stanislav Malyshev, Zend Software Architect stas@zend.com http://www.zend.com/ (408)253-8829 MSN: stas@zend.com

Sam Barrow

18 years ago
However, if you're a programmer with a 10,000 line application, are you going to just forget that you've used your $cfg variable a hundred times, and accidentally make a new one? And the error is detectable. Maybe all superglobals could be required to start with an underscore, like _GET and _POST, to decrease confusion. I personally don't think this would be necessary, but it is a compromise. But what you're saying applies to the php superglobals too, what if someone makes a variable called _GET? It will have the same problem. And you can say, yeah but _GET is an obscure name, to that I would say we can require superglobals to start with underscores or something. But regardless, if someone specifies a superglobal it's on them to remember, it's not our job to protect a sloppy programmer who does stupid things in his coding. This feature would maybe be a disadvantage to a couple people who abuse the flexibility we give them, but it would benefit many more people. Flexibility does not hurt anyone except the people who abuse it. If they're going to make mistakes like this, they're going to make mistakes regardless. We don't have to hold back new features and flexibiltiy in order to prevent a couple of people from messing up. If everyone went by this logic then PHP would not even have functions, because people might use them wrongly. On Fri, 2007-11-16 at 18:00 -0800, Stanislav Malyshev wrote:

Michael McGlothlin

18 years ago
PHP needs more options for both tighter and looser control of variables. I could use an extra superglobal here and there but I also suggested recently, without response, a way to make variables local to a chunk of code without it needing to be a function. Both would be useful in the right conditions - conditions that come up quite often in large programs.
> Well this is very common with PHP, it's very flexible and it's easy for > a bad programmer to create chaotic code and get away with it, but this > can happen with many features of PHP. For serious developers however, > this could prove to be very useful when used appropriately. People will > do what they will and make sloppy programs, but that's completely up to > them. No point in holding stuff back from people who could benefit from > it just to protect inexperienced them from their own sloppiness. You > know what I mean? > > On Fri, 2007-11-16 at 16:28 -0800, Stanislav Malyshev wrote: > >>> I think the superglobal keyword is a great idea. I have a custom class >>> that implements a custom interface to memcache with a MySQL backend for >>> data that drops out of memcache or is to big to be stored easily in >>> memcache. I get annoyed at needing to include a global statement in >>> every place I want to use memcache. >>> >> I don't think it's a good idea. Superglobals are special for a reason - >> if everybody would just add stuff into global space and make it >> superglobal because they can't type a couple of keystrokes, it would be >> a mess. Just declare a class and use statics or singletons. >> > >
-- Michael McGlothlin Southwest Plumbing Supply

Sam Barrow

18 years ago
Yes, and in even larger scale applications it can become even more useful. I have a web framework I'm working on, it's about 9,500 lines of code now with hundreds of functions/classes. Every function/method has to specify global for my 3 universal variables which contain large arrays of configuration information. With this, I can say "superglobal $mod, $sec, $cfg" in my root include file, and not worry about it again. On Fri, 2007-11-16 at 17:23 -0700, Michael McGlothlin wrote:

Sean Coates

18 years ago
> Yes, and in even larger scale applications it can become even more > useful. I have a web framework I'm working on, it's about 9,500 > lines of > code now with hundreds of functions/classes. Every function/method has > to specify global for my 3 universal variables which contain large > arrays of configuration information. With this, I can say "superglobal > $mod, $sec, $cfg" in my root include file, and not worry about it > again.
class Config { const FOO = "Bar"; } function oink() { if (Config::FOO == 'Bar') { echo "OINK"; } } etc. IMO, you really don't need more superglobals. S

Michael McGlothlin

18 years ago
So the idea now is to inappropriately force everything to be a class?
>> Yes, and in even larger scale applications it can become even more >> useful. I have a web framework I'm working on, it's about 9,500 lines of >> code now with hundreds of functions/classes. Every function/method has >> to specify global for my 3 universal variables which contain large >> arrays of configuration information. With this, I can say "superglobal >> $mod, $sec, $cfg" in my root include file, and not worry about it again. > > class Config { > const FOO = "Bar"; > } > > function oink() { > if (Config::FOO == 'Bar') { > echo "OINK"; > } > } > > etc. > IMO, you really don't need more superglobals. > > S
-- Michael McGlothlin Southwest Plumbing Supply

Sean Coates

18 years ago
> So the idea now is to inappropriately force everything to be a class? >>
It is appropriate. That's how it was designed. Obviously superglobals were not designed to be user-definable. If configuration is defined in a class, then as a maintainer, you can easily determine where the data was defined (unless you do things are even less appropriate), but simply looking up the class. Globals (and superglobals) can be defined _anywhere_. This makes them a maintenance nightmare, and a very inappropriate place to store data such as configuration information. S

Sam Barrow

18 years ago
You say that superglobals were not designed to be user defined, think about it, the concept of a superglobal is present in C and C++, two of the maturest and strictest languages around. On Fri, 2007-11-16 at 22:34 -0500, Sean Coates wrote:

Sam Barrow

18 years ago
I agree, I wouldn't want to create a class just for one variable to be in it. It works, yes, but it's just not the clean way to do things. Why not allow maximum flexibility? On Fri, 2007-11-16 at 20:26 -0700, Michael McGlothlin wrote:

Sam Barrow

18 years ago
If anyone wants the patch, you can get it from my blog at http://www.sambarrow.com/. Keep in mind however I only tried it with PHP 5.3, I don't know if it will work on 5.2, as I am trying to transition to 5.3 completely because it has namespaces. On Fri, 2007-11-16 at 17:23 -0700, Michael McGlothlin wrote:

Carl P. Corliss

18 years ago
Sam Barrow wrote:
> Thanks everyone, I knew this, but I didn't want to use runkit because it > is a beta, and i don't want all that other stuff, just superglobals. > Also, runkit only allows you to use php.ini, but my patch allows you to > specify superglobals in your script with the keyword "superglobal" by > saying: > > superglobal $var1, $var2 ;
I don't get why you can't just use a Registry pattern here. Having a simpleRegistry object that you can throw data into and pull out of not only allows you to keep your global space clean, but allows you to encapsulate your "global" data and access it via a simple interface. Sure, it might be a few extra keystrokes to type something akin to: Registry::get('var1'); but, personally, I think the trade-off is well worth it. simple example class: -------------------- class Registry { protect function __construct() {} // no instantiation - static class static protected $data = array(); static public function get($name) { return (isset(self::$data[$name]) ? self::$data[$name] : null); } static public function set($name, value) { self::$data[$name] = $value; } } -------------------- summary: why "fix" what ain't really broke...? Cheers!,
-- Carl

Sam Barrow

18 years ago
Not a bad idea, however in my case (don't know about others) I have very deep arrays i use for my configuration. This would be more of a pain to use with these get and set functions. Also, the performance would probably be worse than just directly accessing the variable. Good point about not fixing what's not broken, but I think in this context it couldn't hurt to fix it. I have already fixed it, my patch is already written and I will continue testing it but I haven't come across any problems using it. On Sat, 2007-11-17 at 01:05 -0500, Carl P. Corliss wrote:

Larry Garfield

18 years ago
Off the cuff, may have a bug or two, but you get the idea: function get_config() { static $config; if (empty($config)) { // Something to load the configuration here. } $params = func_get_args(); $return = $config; foreach ($params as $param) { if (isset($return[$param]) { $return = $return[$param]; } else { trigger_error(...); } } return $return; } $bob = get_config('thing', 'silly', 'bob'); No, not as fast as global $config;, but more self-documenting and therefore easier to maintain and the difference is smaller than the cost of one SQL query. Human cycles cost more than CPU cycles. On Saturday 17 November 2007, Sam Barrow wrote:
> Not a bad idea, however in my case (don't know about others) I have very > deep arrays i use for my configuration. This would be more of a pain to > use with these get and set functions. Also, the performance would > probably be worse than just directly accessing the variable. > > Good point about not fixing what's not broken, but I think in this > context it couldn't hurt to fix it. I have already fixed it, my patch is > already written and I will continue testing it but I haven't come across > any problems using it. > > On Sat, 2007-11-17 at 01:05 -0500, Carl P. Corliss wrote: > > Sam Barrow wrote: > > > Thanks everyone, I knew this, but I didn't want to use runkit because > > > it is a beta, and i don't want all that other stuff, just superglobals. > > > Also, runkit only allows you to use php.ini, but my patch allows you to > > > specify superglobals in your script with the keyword "superglobal" by > > > saying: > > > > > > superglobal $var1, $var2 ; > > > > I don't get why you can't just use a Registry pattern here. Having a > > simpleRegistry object that you can throw data into and pull out of not > > only allows you to keep your global space clean, but allows you to > > encapsulate your "global" data and access it via a simple interface. > > Sure, it might be a few extra keystrokes to type something akin to: > > Registry::get('var1'); but, personally, I think the trade-off is well > > worth it. > > > > simple example class: > > -------------------- > > class Registry { > > protect function __construct() {} // no instantiation - static class > > static protected $data = array(); > > > > static public function get($name) { > > return (isset(self::$data[$name]) ? self::$data[$name] : null); > > } > > > > static public function set($name, value) { > > self::$data[$name] = $value; > > } > > } > > -------------------- > > > > summary: why "fix" what ain't really broke...? > > > > Cheers!, > > > > -- > > Carl
-- 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

Sam Barrow

18 years ago
If i were to implement some type of patch, could i define a php constant to indicate the patch has been applied while staying within the php naming conventions? If so, what should i prefix with?

Stanislav Malyshev

18 years ago
> If i were to implement some type of patch, could i define a php constant > to indicate the patch has been applied while staying within the php > naming conventions? If so, what should i prefix with?
I don't think we have any standard for third-party engine functionality detection. Since you add a function there, maybe you could do just with function_exists("get_my_superglobals")?
-- Stanislav Malyshev, Zend Software Architect stas@zend.com http://www.zend.com/ (408)253-8829 MSN: stas@zend.com