WordPress.org

Make WordPress Core

Opened 3 years ago

Closed 3 years ago

Last modified 3 years ago

#15344 closed defect (bug) (invalid)

global variables get cleared

Reported by: OS1 Owned by:
Milestone: Priority: normal
Severity: normal Version: 3.0.1
Component: General Keywords: reporter-feedback
Focuses: Cc:

Description

It appears that global variables get cleared somewhere inside of WP. If I set a global variable then while I'm still in the function I set it in all is ok. Even if I step on and leave said function I can still see the global variable in NetBeans debugger. However, at some point I click continue, and the next time WP performs a filter on 'the_content' the global variable has been cleared. I am at the plugin top level so I have no class I can store this variable in and even if I did I assume I would need a pointer to this class instance and that would also need to be a global variable because of my scope!

I am sure this used to work! Has something changed between 2.8 and 3.0.1 in the way globals are handled? The forums and web seem to offer no help.

Change History (9)

comment:1 westi3 years ago

  • Cc westi added
  • Keywords reporter-feedback added

Please share some example code which shows the bug.

Without that we are all in the dark as to what the cause may be.

comment:2 OS13 years ago

$shopMessages = null;
function displayShopMessages($page_content)
{

global $shopMessages;


$messages = "";
if ((null != $shopMessages) && (gettype($shopMessages) === "array"))
{

for ($mI = 0; $mI < count($shopMessages); $mI++)
{

$messages .= $shopMessages[$mI]."<br>";

}
$messages .= "<br><br>";

}
unset($shopMessages);
$shopMessages = null;


$pageC = $messages.$page_content;
return $pageC;

}

add_filter('the_content', 'displayShopMessages');

function checkHeaderParameters()
{

global $current_user, $error, $shopMessages;
if ($_GETlogout?)
{

wp_logout();
wp_set_current_user(0);

}
else if ($_POSTwp-submit? === "Log In")
{

$newUser = wp_signon(array('user_login' => $_POSTlog?, 'user_password' => $_POSTpwd?, 'remember' => true));
if (is_callable(array($newUser, "get_error_code")) && $newUser->get_error_codes())
{

if (null == $shopMessages)
{

$shopMessages = array();

}
$shopMessages[] = "Sorry, log in failed, the following issues were reported:<br>";
foreach($newUser->errors as $error)
{

foreach($error as $errMsg)
{

$shopMessages[] = $error;

}

}
$newUser = null;

}
wp_redirect("/login/");
exit();

wp_login($_POSTlog?, $_POSTpwd?);
/* $newUser = wp_signon(array('user_login' => $_POSTlog?, 'user_password' => $_POSTpwd?, 'remember' => true));

if (!$error)
{

$current_user = $newUser;
wp_set_auth_cookie($newUser->id);

}
else
{

if (null == $shopMessages)
{

$shopMessages = array();

}
$shopMessages[] = $error;

} */

}
else if ($_POSTwp-submit? === "Register")
{

require_once("logInOut.php");
$reqAuthU = new AuthUser();
$dataOk = $reqAuthU->checkNewUser($_POSTuser_login?, $_POSTuser_email?, $_POSTpwd?);
if ($dataOk)
{

$userId = wp_create_user($_POSTuser_login?, $_POSTpwd?, $_POSTuser_email?);
if (!$userId)
{

if (null == $shopMessages)
{

$shopMessages = array();

}
$shopMessages[] = "Registration failed";

}
else
{

$newUser = wp_signon(array('user_login' => $_POSTuser_login?, 'user_password' => $_POSTpwd?, 'remember' => true));
if (is_callable(array($newUser, "get_error_code")) && $newUser->get_error_codes())
{

if (null == $shopMessages)
{

$shopMessages = array();

}
$shopMessages[] = "Sorry, user registration failed, the following issues were reported:";
foreach($newUser->errors as $error)
{

foreach($error as $errMsg)
{

$shopMessages[] = $errMsg;

}

}
$newUser = null;

}
else
{

if (null == $shopMessages)
{

$shopMessages = array();

}
$shopMessages[] = "Thankyou for registering with us.";
wp_login($_POSTlog?, $_POSTpwd?);
$current_user = $newUser;
wp_set_auth_cookie($newUser->id);
wp_redirect("/my-account/?task=dets");
exit();

}

}

}

}

}
add_filter('init', 'checkHeaderParameters');

comment:3 OS13 years ago

This same function reports the error messages accumulated in $shopMessages in our other site which is on 2.8.6.

comment:4 OS13 years ago

  • Resolution set to invalid
  • Status changed from new to closed

Sorry I think this may be something in my code! The error messages work for user registration just not for login. I'll look into this tomorrow and if this is the case I'll mark this OR as Invalid.

comment:5 OS13 years ago

  • Resolution invalid deleted
  • Status changed from closed to reopened

comment:6 nacin3 years ago

  • Resolution set to invalid
  • Status changed from reopened to closed

This isn't an issue with WordPress. We do muck with globals but only a certain set, nothing by the name of shopMessages.

Side note, you should check out using the WP_Error object.

comment:7 OS13 years ago

Ok, so here's the scenario as best as I can determine, and I don't fully understand what is happening. I could be being mislead by the tools and debug output.

Change index.php to be
if (!isset($wp_did_header))
{

$wp_did_header = true;

}
and that's all.

Now add debug code or set a breakpoint at the first line. Refresh the page in a browser. The script is called twice. Odd seeing as how this is the server entry point. Second time around wp_did_header is cleared as are all globals because this is now a new instance.

Step 2, rename the project base directory, i.e. effectively remove WP. Make a new project base directory and copy in the modified index.php. Refresh the browser page and now, as expected, the code is only called once.

So put everything back as it should be but now add the debug code or set the break point in the plugin init function. This is now called three times and the stack trace indicates that index.php has been re-entered each time thus instantiating a new set of globals.

The result of this appears unexpected. On a "registration failure" the error messages make it out the the browser, but for other scenarios the messages are lost due to what? re-entrancy?! It looks for all the world like a race condition! Which is why I can't get my head around exactly what is happening.

Using this code
$handle = fopen("log.txt", "r");
$res = fread($handle, 2);
fclose($handle);
$handle = fopen("log.txt", "w");
$str = $res + 1;
fwrite($handle, $str);
fclose($handle);

making sure that log.txt contains 0 and pressing the refresh button of the page only once results in the file contents being 3, suggesting that the thread of execution has been entered three times.

Putting similar code where I populate the global variable $shopMesssages results in a file containing the expected error messages even though the global variable has been cleared.

I can't even populate session variables since these are also cleared as this is a new session!

I'll look into WP_Error but surely this will suffer from the same effect. I probably need to seriously re-organise my code to try to get around this race condition :-(

Have I lost the plot?! Is this just the way we use WP? Have I missed something obvious? Am I just being stoooopid?!

comment:8 nacin3 years ago

  • Milestone Awaiting Review deleted

comment:9 OS13 years ago

The "re-entrancy" appears to be due to the line

RewriteRule . /index.php [L]

in .htaccess

Without this the site breaks. With it in the site is re-entered from the top level index.php so it appears the variables get reset.

Note: See TracTickets for help on using tickets.