Why does class.function "global" variable return null when called from inside a WordPress function?

I’m trying to understand why accessing a global works in a class function when called outside of WordPress vs called inside WordPress (not sure if this is a PHP or Wordpress question…)

The psudo code below just has a parent script with an include child script. I’ve been having problems in the child script so I put in some var_dump to see what the difference is between running this outside/inside WordPress.

Inside the class I set up a function using “global $db”.

What I’ve noticed is that the $db object is null when it gets into the __construct if the script is run inside WordPress but it is fine if run outside WordPress. Any advise as to why this might be?

**parent.php script...**
<?php
$db = (some sql connection that works) 
include child.php;
?>

**child.php script...**
<?php

        // Check to see values of the $db object when first entering child.  
        // It returns valid data whether called inside / outside WordPress.
        // So I know the child.php script can see $db.
	var_dump($db); 
	echo '<br><br>';

    	// Setup a class and function.	
	class wssCurrencySetup
	{
		public function __construct()
		{
			global $db;
    		        // The following dump only shows valid data if parent script called outside of Wordpress.  Inside WP it returns null.
    		        var_dump($db);
    		}
       }
?>

Probably something in wordpress is overriding the $db value.

This is why you should not use global variables, they’re a mess to debug.

1 Like

I thought of that, but WP isn’t overriding it. It is available to other scripts and functions in WP. It seems to be something to do with accessing it from within a class.function.

In the first line of child.php I dump $db and the values are correctly there, no matter if I call it from WP or not. But when I drop into the class defined in child.php and try to access $db from within the class.function, that’s when $db is null if the script is called from within WP.

Just a wild guess but it is possible that wssCurrencySetup is being created before the $db connection is. Adding a couple of trace statements might confirm this.

$db connection is established and setup prior to calling wssCurrencySetup. I’ll have to add in some trace statements, but I just double checked the code and it seems to be in the right order. This seems to be the order…

  1. Establish $db connection.
  2. Include child.php from parent.php
  3. dump $db via first line of child.php (valid result in/out of Wordpress)
  4. call new wssCurrencySetup (i.e. setup new object)
  5. dump $db via second line of __construct (valid outside of WP, null inside WP)

I avoid globals unless absolutely necessary, so this is untested. I’m wondering if the problem is how it’s done in a function vs. in a class method. eg.

class wssCurrencySetup
{
  public $wcs_db; 
  public function __construct() 
  { 
    global $db; 
    $this->wcs_db = $db; 
// The following dump only shows valid data if parent script called outside of Wordpress.  Inside WP it returns null. 
    var_dump($this->wcs_db); 
  } 
} 

I would change the class to

class wssCurrencySetup
{
  private $db; 
  public function __construct($db)
  {
    $this->db = $db;
  } 
} 

And then in the driving code

require 'child.php';
$setup = new wssCurrencySetup($db);

Look ma, no globals!

2 Likes

Thanks everyone for your help and advice. I knew it had to be something about accessing globals from within an include class when run from WordPress. I found this little infoNugget that kinda confirmed to me that it is a WordPress scoping constraint.

If you’re using global variables, you may find that the function you pass to register_activation_hook() does not have access to global variables at the point when it is called, even though you state their global scope within the function

Function Reference/register activation hook

So I took some time (lots) and recode to not use the globals and it is starting to work. It’s a large script that I inherited and am trying to modify.

Thanks again!

1 Like

You’ll be glad you did. One benefit is that GC (Garbage Collection) doesn’t remove anything it “thinks” it might need to be around later whether or not code will need it later. So as a global you would have the connection hanging around after you were done with it.

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.