kayue/WordpressBundle

Wordpress rewrote the $_GET variable

kayue opened this issue · 5 comments

If I do a var_dump($_GET) before Wordpress, I get this:

array(1) {
  ["test"]=>
  string(9) "quote"
}

And this is what I get after Wordpress loaded, something similar to magic quote in PHP!

array(1) {
  ["test"]=>
  string(9) "\"quote\""
}

All this happens in load.php of Wordpress, called by wp-settings.php

/**
 * Add magic quotes to $_GET, $_POST, $_COOKIE, and $_SERVER.
 *
 * Also forces $_REQUEST to be $_GET + $_POST. If $_SERVER, $_COOKIE,
 * or $_ENV are needed, use those superglobals directly.
 *
 * @access private
 * @since 3.0.0
 */
function wp_magic_quotes() {
    // If already slashed, strip.
    if ( get_magic_quotes_gpc() ) {
        $_GET    = stripslashes_deep( $_GET    );
        $_POST   = stripslashes_deep( $_POST   );
        $_COOKIE = stripslashes_deep( $_COOKIE );
    }

    // Escape with wpdb.
    $_GET    = add_magic_quotes( $_GET    );
    $_POST   = add_magic_quotes( $_POST   );
    $_COOKIE = add_magic_quotes( $_COOKIE );
    $_SERVER = add_magic_quotes( $_SERVER );

    // Force REQUEST to be GET + POST.
    $_REQUEST = array_merge( $_GET, $_POST );
}

Strange! Does it affect your Symfony app?
On Feb 10, 2012 10:01 AM, "Ka Yue Yeung" <
reply@reply.github.com>
wrote:

If I do a var_dump($_GET) before Wordpress, I get this:

array(1) {
 ["test"]=>
 string(9) "quote"
}

And this is what I get after Wordpress loaded, something similar to magic
quote in PHP!

array(1) {
 ["test"]=>
 string(9) "\"quote\""
}

OMG!


Reply to this email directly or view it on GitHub:
#8

This is a problem if I initiate Symfony after Wordpress is loaded.

If I do it the other way around, it seems it won't affect Symfony's HttpFoundation\Request object because Symfony seems keep a copy of the globals in somewhere else.

I am taking a look.

Yes Symfony\Component\HttpFoundation\Request::createFromGlobals() keep a copy of the globals.

So to fix this we have to strip slashes before $kernel->handle(Request::createFromGlobals()), I don't think we can fix this in Wordpress bundle.

...
$_GET     = stripslashes_deep($_GET);
$_POST    = stripslashes_deep($_POST);
$_COOKIE  = stripslashes_deep($_COOKIE);
$_SERVER  = stripslashes_deep($_SERVER);
$_REQUEST = array_merge($_GET, $_POST);

$kernel = new AppKernel('dev', true);
$kernel->loadClassCache();
$response = $kernel->handle(Request::createFromGlobals());
...

No, I don't think this is within the scope of the bundle. Also, what's the
use case for loading WordPress before Symfony? Generally if you're using
the bundle it will happen after.
On Feb 11, 2012 2:01 AM, "Ka Yue Yeung" <
reply@reply.github.com>
wrote:

Yes Symfony\Component\HttpFoundation\Request::createFromGlobals() keep a
copy of the globals.

So to fix this we have to strip slashes before
$kernel->handle(Request::createFromGlobals());, I don't think we can fix
this in Wordpress bundle.

...
$_GET     = stripslashes_deep($_GET);
$_POST    = stripslashes_deep($_POST);
$_COOKIE  = stripslashes_deep($_COOKIE);
$_SERVER  = stripslashes_deep($_SERVER);
$_REQUEST = array_merge($_GET, $_POST);

$kernel = new AppKernel('dev', true);
$kernel->loadClassCache();
$response = $kernel->handle(Request::createFromGlobals());
...


Reply to this email directly or view it on GitHub:
#8 (comment)

I want to run Wordpress first because most people visit my site are for the blog, not my Symfony app, so I only want to load Symfony if I need to.

I use the status_header filter in Wordpress to detect is page found or not, if page not found, then I load Symfony. I added the following code to my Wordpress theme's functions.php:

<?php

require_once __DIR__.'/symfony/app/bootstrap.php.cache';
require_once __DIR__.'/symfony/app/AppKernel.php';

use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\HttpFoundation\Request;

/**
 * Send response from Symfony if page not found in Wordpress.
 *
 * @see /wp-includes/functions.php
 */
add_filter('status_header', function($status){  
    // if page not found in Wordpress
    if('Not Found' === substr($status,strlen('Not Found') * -1)) {
        $kernel = new AppKernel('prod', false);

        // strips magic quotes added by Wordpress
        $_GET     = stripslashes_deep($_GET);
        $_POST    = stripslashes_deep($_POST);
        $_COOKIE  = stripslashes_deep($_COOKIE);
        $_SERVER  = stripslashes_deep($_SERVER);
        $_REQUEST = array_merge($_GET, $_POST);

        // load Symfony
        $kernel->loadClassCache();
        $response = $kernel->handle(Request::createFromGlobals());

        // send response from Symfony if found
        if(404 !== $response->getStatusCode()) {
            $response->send();

            // We already got what we want. Exit from Wordpress so it won't return 404 from Wordpress.
            exit(); 
        }
    }

    return $status;
});