By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
458,084 Members | 1,266 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 458,084 IT Pros & Developers. It's quick & easy.

Confused about scope of globals in included files

P: n/a
I'm having an issue where what should be global variables are not in
scope and I'm confused as to why.

In Case 1 the variables are not in scope for functions in File2
In Case 2 the varibales are in scope for access in File1's functions
AFTER the include
In Case 3 the varibales are in scope for functionsin File2
Why does case 1 not work but case 3 does? Does case 2 the proper method
to use?

CASE 1:

File1:

switch (OBJ) {
case 1:
include "file2.php"
if Function_In_File2()
....
break;
}

File2:

<?php

$MY_GLOBAL_VARIABLE = "TEST";

Function Function_In_FIle()
{
global $MY_GLOBAL_VARIABLE;
echo $My_GLOBAL_VARIABLE; /* Produces Notice: Undefined variable:
$My_GLOBAL_VARIABLE in File2.php on line xx */
}

?>

CASE 2:
File1:

switch (OBJ) {
case 1:
include "file2.php"
if Function_In_File2()
....
break;
}

File2:

<?php

global $MY_GLOBAL_VARIABLE; $MY_GLOBAL_VARIABLE = "TEST";

Function Function_In_FIle()
{
global $MY_GLOBAL_VARIABLE;
echo $My_GLOBAL_VARIABLE; /* Displays "TEST" */
}

?>

CASE 3:
File1:

switch (OBJ) {
case 1:
include "file2.php"
echo $MY_GLOBAL_VARAIBLE; /* Displays "TEST" Why does this work and
not case 1? */

}

File2:

<?php

$MY_GLOBAL_VARIABLE = "TEST";

?>

Feb 22 '06 #1
Share this Question
Share on Google+
6 Replies


P: n/a
Please post the actual code. It's hard to tell what's wrong with
pseudo-code containing multiple typos. There is no reason for case 1 to
not work. Most likely you just have a spelling error somewhere.

Feb 23 '06 #2

P: n/a
Create_Batch.php file

Function Create_Batch($Batch_Number, $EDI_Data)
{
switch( Detect_Type_of_EDI_File($EDI_Data) ) {
case "FDX":
include "EDI_Fedex.php";
echo "AFTER INCLUDE CHECK COMPANY NAME ($COMPANY_NAME_ID)<br>";
if ( !Extract_EDI_Data($Batch_Number, $EDI_Data) )
return false;
echo "AFTER BATCH CREATION CHECK COMPANY NAME
($COMPANY_NAME_ID)<br>";
break;
case "DHL":
include "EDI_DHL.php";
if ( !Extract_EDI_Data($Batch_Number, $EDI_Data) )
return false;
break;
default:
echo "ERROR! Unable to detect EDI file type <BR>";
return false;
break;
}
return !Duplicate_Batch_Found($Batch_Number);
}

EDI_Fedex.php file

<?php

include "EDI_STD_Functions.php";

$CURRENT_CHARGE = array();

$EDI_REFERENCE = "";

$PAYMENT_TYPE = "WIRE";

$COMPANY_NAME_ID = "FDX";
echo "OUTSIDE FUNCTION CHECK COMPANY NAME($COMPANY_NAME_ID)<br>";
$VENDOR_NUMBER = "97139";

Function Extract_EDI_Data($Batch_Number, $EDI_Data)
{
global $COMPANY_NAME_ID;
echo "INSIDE FUNCTION CHECK COMPANY NAME ($COMPANY_NAME_ID)<br>";
}

OUTPUT:
OUTSIDE FUNCTION CHECK COMPANY NAME(FDX)
AFTER INCLUDE CHECK COMPANY NAME (FDX)
INSIDE FUNCTION CHECK COMPANY NAME ()
AFTER BATCH CREATION CHECK COMPANY NAME (FDX)

If I use the global $COMPANY_NAME_ID; $COMPANY_NAME_ID = "FDX"; it
works for all 4 cases.

I did a FIND "$COMPANY_NAME_ID" * > search.txt

and here's the output from my entire source directory. There is no
other instances where I use this variable name so I'm completely
baffled as to what is causing this issue. I actually wrote a test case
matching the case 1 and 2 I spoke about above and both functioned
correctly.
---------- CLOSE_BATCH.PHP

---------- CONSTANTS.PHP

---------- CREATE_BATCH.PHP
echo "AFTER INCLUDE CHECK COMPANY NAME ($COMPANY_NAME_ID)<br>";
echo "AFTER BATCH CREATION CHECK COMPANY NAME
($COMPANY_NAME_ID)<br>";

---------- CREATE_EDI_TABLES.PHP

---------- CREATE_WIRE_FORM.PHP

---------- EDI_DHL.PHP
global $COMPANY_NAME_ID; $COMPANY_NAME_ID = "DHL";
global $COMPANY_NAME_ID, $EDI_REFERENCE, $REMITTANCE_EMAIL_ADDRESS;
echo "Creating remit file for $COMPANY_NAME_ID";
$query = "SELECT BATCHNUM FROM $TABLE_HEADER WHERE COMPID =
'$COMPANY_NAME_ID' AND PAYREF = '$Pay_Ref' AND PAYDATE = '$Pay_Date'";
echo "ERROR: Nothing to remit for Company: $COMPANY_NAME_ID PayRef:
$Pay_ref Date: $Pay_Date<br>";
$COMPANY_NAME_ID = "DHL";
return ( Build_Header_Detail($Batch_Number, $COMPANY_NAME_ID,
$EDI_REFERENCE) );

---------- EDI_FEDEX.PHP
$COMPANY_NAME_ID = "FDX";
echo "OUTSIDE FUNCTION CHECK COMPANY NAME($COMPANY_NAME_ID)<br>";
global $COMPANY_NAME_ID, $REMITTANCE_FILE_PATH, $REMITTANCE_FILE_NAME;
echo "Creating remit file for $COMPANY_NAME_ID";
$query = "SELECT BATCHNUM FROM $TABLE_HEADER WHERE COMPID =
'$COMPANY_NAME_ID' AND PAYREF = '$Pay_Ref' AND PAYDATE = '$Pay_Date'";
echo "ERROR: Nothing to remit for Company: $COMPANY_NAME_ID PayRef:
$Pay_ref Date: $Pay_Date<br>";
global $COMPANY_NAME_ID;
echo "INSIDE FUNCTION CHECK COMPANY NAME ($COMPANY_NAME_ID)<br>";
return ( Build_Header_Detail($Batch_Number, $COMPANY_NAME_ID,
$EDI_REFERENCE) );

---------- EDI_STD_FUNCTIONS.PHP

---------- FREIGHT_EDI.JS

---------- FREIGHT_EDI.PHP

---------- FREIGHT_EDI_DISPLAYBATCH.PHP

---------- GENERATE_GL_DATA.PHP

---------- GET_FEDEX_EDI_FILES.PHP

---------- OPEN_BATCH.PHP

---------- PAY_VENDOR.PHP

---------- PRINT_PAYMENT_FORM.PHP

---------- SAVE_BATCH.PHP

---------- SEARCH.TXT

---------- SENDREMIT.BAT

---------- SPLIT_CHARGE.HTML

---------- TOOLBAR_FREIGHT_EDI.HTML

---------- TOOLBAR_WORK_BATCH.HTML

---------- VALIDATE_GL_DATA.PHP

---------- WIRETRANSFERFORM.HTML

---------- WIRETRANSFERFORM.HTML.BACKUP

---------- WIRETRANSFORMLAYOUT.XLS

---------- WORK_BATCH.PHP

Feb 23 '06 #3

P: n/a
You need to use the global keyword. When you do an include inside a
function, any global code will end up running inside the scope of that
function.

You might also want to use include_once(), so that you don't end up
with a fatal error (function already defined) when Create_Batch() is
called more than once.

Feb 23 '06 #4

P: n/a
Wescotte wrote:
I'm having an issue where what should be global variables are not in
scope and I'm confused as to why.

In Case 1 the variables are not in scope for functions in File2
In Case 2 the varibales are in scope for access in File1's functions
AFTER the include
In Case 3 the varibales are in scope for functionsin File2
Why does case 1 not work but case 3 does? Does case 2 the proper method
to use?

CASE 1:

File1:

switch (OBJ) {
case 1:
include "file2.php"
if Function_In_File2()
....
break;
}

File2:

<?php

$MY_GLOBAL_VARIABLE = "TEST";

Function Function_In_FIle()
{
global $MY_GLOBAL_VARIABLE;
echo $My_GLOBAL_VARIABLE; /* Produces Notice: Undefined variable:
$My_GLOBAL_VARIABLE in File2.php on line xx */
}

?>

CASE 2:
File1:

switch (OBJ) {
case 1:
include "file2.php"
if Function_In_File2()
....
break;
}

File2:

<?php

global $MY_GLOBAL_VARIABLE; $MY_GLOBAL_VARIABLE = "TEST";

Function Function_In_FIle()
{
global $MY_GLOBAL_VARIABLE;
echo $My_GLOBAL_VARIABLE; /* Displays "TEST" */
}

?>

CASE 3:
File1:

switch (OBJ) {
case 1:
include "file2.php"
echo $MY_GLOBAL_VARAIBLE; /* Displays "TEST" Why does this work and
not case 1? */

}

File2:

<?php

$MY_GLOBAL_VARIABLE = "TEST";

?>


Case 1 did not work because you did not specify $MY_GLOBAL_VARIABLE as
global in the main part of your code (outside your function
Function_in_file_2).

Case 2 worked because you did define it as global in the main part of
your code also.

Case 3 works because you're not in any function in either case.

The include "file2.php" adds the code in file2.php right where the
include statement is. It's exactly like removing the include statement
and pasting the contents of file2 in file 1 at that point.

So - in your third case, the result is just like:

switch (OBJ) {
case 1:
$MY_GLOBAL_VARIABLE = "TEST"; // From file2.php
echo $MY_GLOBAL_VARIABLE;
}

As to which is the "correct way" - none of the above are good. You
should try to avoid using globals as it ties the code together more.
For instance, what happens if $MY_GLOBAL_VARIABLE gets a bad value in
it? Where was it changed? Being a global, it could be anywhere.
Rather, pass $MY_GLOBAL_VARIABLE as a parameter to the function, i.e.
for case 1:

File1:

switch (OBJ) {
case 1:
include "file2.php"
if Function_In_File2($MY_GLOBAL_VARIABLE)
....
break;
}

File2:

<?php
$MY_GLOBAL_VARIABLE = "TEST";

Function Function_In_File($var)
{
echo $var;
}
?>

I don't like this - it means File1 depends on a value set in File2 which
also ties things together more. But it does solve the global problem.

You could also use a constant, i.e.

define ("GLOBAL_CONSTANT", "TEST");

and use GLOBAL_CONSTANT where you have MY_GLOBAL_VARIABLE, but this only
works if you include one file each run (i.e. don't look and include
multiple files defining GLOBAL_CONSTANT).

Personally, I think I'd look at how I could restructure the files. But
not knowing your code, I can't recommend how to do it.

BTW - the norm in PHP is to use upper case for constants and lower case
(or mixed upper/lower, depending on your style) for variables, i.e.
$my_global_variable or $myGlobalVariable.

I hope this helps.
--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
js*******@attglobal.net
==================
Feb 23 '06 #5

P: n/a
Here is what I'm actually trying to do. I have several different types
of files the user is loading into the application.
I have several freight vendors and each has a slightly differnet file
type. So I detect the file type and then based on that load a specific
file that sets various constants for this particular vendor and has a
common set of functions.

So something like (sudocode)

$type = Detect_File_Type($file);

switch ($type) {
case: "FEDEX"
include "Fedex.php";
Create_Batch($Batch_Number, $file);
break;
case: "DHL"
include "DHL.php";
Create_Batch($Batch_Number, $file);
break;
default:
echo "unable to process file";
return false;
break;
}

Fedex.php

include "general_batch_functions.php";

Define constants

Function Create_Batch()
{
}

other specific functions for FEDEX file processing
DHL.php

include "general_batch_functions.php";

Define constants

Function Create_Batch()
{
}

other specific functions for DHL file processing

How would you go about doing such a task?

The constants defined in each file aren't needed anymore after the
batch is created.

The only time they are another switch takes place and it's included
again (done for the payment process because most of the constants are
like a remittance address and the bank account numbers to make ACH
payments to and such.) I supose I could simply store these constants in
a database table but because I need specific functions to read the data
it seemed like a better caseto group it all into one file. Any
suggestions on possibly a better design?

Feb 23 '06 #6

P: n/a
Wescotte wrote:
Here is what I'm actually trying to do. I have several different types
of files the user is loading into the application.
I have several freight vendors and each has a slightly differnet file
type. So I detect the file type and then based on that load a specific
file that sets various constants for this particular vendor and has a
common set of functions.

So something like (sudocode)

$type = Detect_File_Type($file);

switch ($type) {
case: "FEDEX"
include "Fedex.php";
Create_Batch($Batch_Number, $file);
break;
case: "DHL"
include "DHL.php";
Create_Batch($Batch_Number, $file);
break;
default:
echo "unable to process file";
return false;
break;
}

Fedex.php

include "general_batch_functions.php";

Define constants

Function Create_Batch()
{
}

other specific functions for FEDEX file processing
DHL.php

include "general_batch_functions.php";

Define constants

Function Create_Batch()
{
}

other specific functions for DHL file processing

How would you go about doing such a task?

The constants defined in each file aren't needed anymore after the
batch is created.

The only time they are another switch takes place and it's included
again (done for the payment process because most of the constants are
like a remittance address and the bank account numbers to make ACH
payments to and such.) I supose I could simply store these constants in
a database table but because I need specific functions to read the data
it seemed like a better caseto group it all into one file. Any
suggestions on possibly a better design?


Well, if you're only going to use them in the Create_Batch() function,
you could put them right in that function.

Or, if you have more than one function using the values and your
Create_Batch function differs between the various types, create classes
for each of the various types, i.e.

class fedex
var $company_id = 'FEDEX';
Create_batch() {
// use as $this->company_id
}
Another_Func () {
...
}
}

class dhl
var $company_id = 'DHL';
Create_batch() {
// use as $this->company_id
}
Another_Func () {
...
}
}

class xyz
var $company_id = 'XYZ';
Create_batch() {
// use as $this->company_id
}
Another_Func () {
...
}
}

Then include all of them in your first file and instantiate an object of
the appropriate type, i.e.

switch ($type) {
case: "FEDEX"
$shipper = new fedex();
break;
case: "DHL"
$shipper = new dhl();
break;
default:
shipper = null;
break;
}

if ($shipper == null)
echo "unable to process file";
else
$shipper->Create_Batch($Batch_Number, $file);
Much cleaner.

--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
js*******@attglobal.net
==================
Feb 23 '06 #7

This discussion thread is closed

Replies have been disabled for this discussion.