I am debugging some MODX code that was moved from one host to another and stopped working. The code takes an order number from the query string, looks it up in the database, and returns a record if one is found. The lookup stopped working properly after the migration.
The code looked like this:
- cacheable resource
- resource contained cached chunk call
- chunk contained uncached snippet call
- snippet contained two include_once() calls and then a database connection, like this:
include_once('config.php'); // declares array w/ config info (including database username & password).
include_once('db.php'); // database connection functions
$conn = db_connect($MY_CART["db_user"], $MY_CART["db_pass"]);
$link = db_select($MY_CART["db_name"]);
The include statements were succeeding, and the functions from the 2nd include were available, but the connect to the database but was failing. The values from the array in the first include_once were not available to the function call.
On Friday I falsely diagnosed this as "I can't get variable declarations from included files, but functions are working fine." I rewrote config.php as a function that returned the array, then called that function, and everything worked:
include_once('config.php'); // get_my_array() function
include_once('db.php'); // database connection functions
$MY_CART = get_my_array();
$conn = db_connect($MY_CART["db_user"], $MY_CART["db_pass"]);
$link = db_select($MY_CART["db_name"]);
When called as a function like this, the $MY_CART array was available to the db functions and the code all worked. Hence my false diagnosis on Friday.
This morning I dug a little deeper and found that the real issue is a matter of caching and "what's-available-when?" First I switched the first include back to its original form - just defining an array, not in a function. Then I added a var_dump of the config array.
include_once('config.php'); // declares array w/ config info (including database username & password).
include_once('db.php'); // database connection functions
var_dump($MY_CART);
$conn = db_connect($MY_CART["db_user"], $MY_CART["db_pass"]);
$link = db_select($MY_CART["db_name"]);
Output: NULL (and database error)
Then I tried commenting out the database connection code:
include_once('config.php'); // declares array w/ config info (including database username & password).
include_once('db.php'); // database connection functions
var_dump($MY_CART);
//$conn = db_connect($MY_CART["db_user"], $MY_CART["db_pass"]);
//$link = db_select($MY_CART["db_name"]);
Output: full vardump of MY_CART array
Hmm. So this debunks my weird conspiracy theory about not being able to access variables from include files.
As long as the database code doesn't ask for it, the array is available.
That started leading me to think about caching.
I decided to try calling the original snippet cached. All the code worked as intended - the db user info from the array was available to the functions.
However, in this setup, the lookup of the order number from the query string also gets cached.
The final working solution was to call the snippet as cached, but change the resource itself to "non-cacheable".
Everything works.
I'm just hoping someone can now explain it to me. Why, if the snippet is called uncached, are the variables declared in the first include_once call not available to the functions from the second include_once call?