Well you have an interestingly different approach!

Personally I kind of like either having the SQL statements in-line with the rest
of the code or functions that retrieve data for that particular query e.g.
function get_students($class) {....

Anyway based on your approach: 

1. You could still solve your problem of having to worry when the constant
definitions are included by setting global variables instead of constants
and then doing an explicit eval-uation at their time of use e.g. 

In include : 
   global $SelectByClass;
   $SelectByClass = 'Select * from students where class = \'.$class.\'';

In code : 
GetData('SelectByClass');

In GetData: 
function GetData($query_mask) {
extract($GLOBALS);
eval ('$query_string = "'.${$query_mask}.'"');
mysql_query($query_string .....

This would guarantee that you always use the values of the global variables current 
when
you issue the query.  So you can move your includes back up the top! Of course it 
doesn't 
help if you ever want to use a local value of a variable in a query but it seems that 
doesn't interest you.


2. I notice you return a pointer to the results set rather than the results 
themselves.  This means you still have to have mysql_fetch_... outside
of GetData.  Why not return an array of the result rows instead?
i.e. add to GetData

while ($rows[] = mysql_fetch_array($result));
mysql_free_result($result);
return ($rows);

This has the advantage of letting the rest of your code remain database independent.


3. You may not need to pass the connection id ($db_conn) to mysql_query.  Mysql will
default to using the last connect if none is specified.

4. You should be aware that you approach may have performance implications since
you are carting ALL global variables into the symbol space of each call to GetData.
Running under Apache with register_global_vars that meant 158 variables even
without any GET or POST variables.  However the new reference count implementation 
of variables in php4 may minimise the impact of this. With any luck, it won't
actually make a copy of any of your global variables in memory! I was pleasantly
surprised at how fast an extract($GLOBALS) ran, (7ms for me).

I guess the choice between your approach and the more conventional approaches 
of in-line selects, per-select function call, or encapsulation as a data object 
is simply about maintainability.  Personally I always prefer more lines of boring 
but simple code to clever structures which may be obtuse to the poor guy who ends up 
maintaining my code. 

Anyway, it's always interesting to see different approaches.  I'd never properly 
checked out define, extract and $GLOBALS until now.  

Good Luck,

George


Fred wrote:
> 
> I would like to offer my recent experience in the hope that it will help
> others avoid the wasted effort and frustration I managed to burden myself
> with yesterday.  I will start by stating that the conclusions I have drawn
> may seem obvious at first blush, however in a troubleshooting environment it
> is sometimes difficult to see the forest for the trees.  This is
> particularly true when several principles of PHP syntax are working in
> concert to produce a problem.
> 
> My problems started when I found myself in the rare position of needing to
> write a function that accessed global variables rather than passed values or
> references.  This need arose because I was writing a data access abstraction
> function and would have no way of knowing in advance what variables would
> need to be accessed or in what order.  The total number of possible
> variables was large when compared with the total number of lines of code in
> the function.  If I had chosen to write the function to accept an
> associative array that could be extracted within the function to produce the
> needed variables the total number of lines of code needed outside of the
> function to produce the array would have been greater than the total number
> of lines of code within the function.
> 
> Because the purpose of choosing to use a function rather than writing the
> code several times was to reduce the number of lines of code and provide
> clarity to the script I decided that passing an array to the function was
> not an option.
> 
> I decided to simply write the function so that it had access to all
> variables in the GLOBALS array to overcome this problem.  The function was
> as follows:
> 
> // Function to send query and retrieve result pointer
> function GetData($Query)
> {
> extract  ($GLOBALS);
> $Result = mysql_query($Query, $db_conn)
>        or die (mysql_error());
> Return $Result;
> }
> 
> The function accepts an SQL statement as an argument and returns a pointer
> to a result set.  The SQL statement that is passed to the function is one of
> many defined constants, many of which contain variables.  For example:
> 
> define ("ClassesByTeacher","SELECT Classes.SectionNo, Period, CourseNo,
> Title, Teacher FROM Classes, Attendance WHERE Classes.SectionNo =
> Attendance.SectionNo AND Teacher LIKE \"$Teach\" AND Attendance.Date =
> \"$SQLDate\" GROUP BY Classes.SectionNo");
> 
> This particular statement needs to have access to the $Teach and $SQLDate
> variables.  When these variables were passed as GET values in the URL the
> function worked as expected.  However, if I assigned the variables within
> the code of the script outside the function I invariably received empty
> result sets.  I spent quite a bit of time under the impression that the
> global variables where not being accessed by the function unless they where
> GET variables.  This did not turn out to be the case.  Upon adding debug
> code to the script I was able to determine that the function was correctly
> accessing the global variables, but the mysql_query function was not.  As it
> turned out, and this is the part that may seem obvious, the problem resulted
> from the fact that the define statement was evaluating the variables to ""
> before they were actually set in code.
> 
> The result was an SQL statemente like this:
> 
> SELECT Classes.SectionNo, Period, CourseNo, Title, Teacher FROM Classes,
> Attendance WHERE Classes.SectionNo = Attendance.SectionNo AND Teacher LIKE
> "" AND Attendance.Date = "" GROUP BY Classes.SectionNo
> 
> which explains the empty data sets and lack of an error message.
> 
> The define statements are in a seperate file that is included into the
> script.  It is my general practice to include all files that contain
> functions as the beginning of a script and this is what I had done here.  As
> soon as the file containing the defines was included the variables were
> evaluated to empty strings within the defined constant before the variables
> were set to usable values within the code.  Moving the include statement
> below the variable assignments in the script provided the solution.
> 
> The lesson I learned is this:
> 
> When including files that contain declare statements which in turn contain
> variables, always include the file after the variables have actually been
> set to their desired values.
> 
> Fred

-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
To contact the list administrators, e-mail: [EMAIL PROTECTED]

Reply via email to