How to turn off magic quotes on shared hosting?
Asked Answered
D

13

40

I want to turn off PHP's magic quotes. I don't have access to php.ini.

When I tried to add php_flag magic_quotes_gpc off to my .htaccess file, I get a 500 internal server error. This is what my .htaccess file looks like:

AddType x-mapp-php5 .php
php_flag magic_quotes_gpc off

Then I tried to use ini_set('magic_quotes_gpc', 'O'), but that had no effect.

How do I turn magic quotes off?

Dittany answered 5/2, 2009 at 17:47 Comment(3)
since none of the answer's are helping, i would go with Toytown's suggestion of going to the your provider's forum.Dispute
ok yup, making a call to their tech supportDittany
if you're using cpanel, look for "php.ini quickconfig". might be an option there for ya. there is on hostgator.Highpowered
M
41

As per the manual you can often install a custom php.ini on shared hosting, where mod_php isn't used and the php_value directive thus leads to an error. For suexec/FastCGI setups it is quite common to have a per-webspace php.ini in any case.

--

I don't think O (uppercase letter o) is a valid value to set an ini flag. You need to use a true/false, 1/0, or "on"/"off" value.

ini_set( 'magic_quotes_gpc', 0 );   // doesn't work

EDIT

After checking the list of ini settings, I see that magic_quotes_gpc is a PHP_INI_PERDIR setting (after 4.2.3), which means you can't change it with ini_set() (only PHP_INI_ALL settings can be changed with ini_set())

What this means is you have to use an .htaccess file to do this - OR - implement a script to reverse the effects of magic quotes. Something like this

if ( in_array( strtolower( ini_get( 'magic_quotes_gpc' ) ), array( '1', 'on' ) ) )
{
    $_POST = array_map( 'stripslashes', $_POST );
    $_GET = array_map( 'stripslashes', $_GET );
    $_COOKIE = array_map( 'stripslashes', $_COOKIE );
}
Mechanist answered 5/2, 2009 at 17:54 Comment(7)
thanks, but i tried each of those ini_set statements and there was no effect.Dittany
You can set them through set_ini, but it has no effect, since the magic is already done at that point.Ironware
i put this 'php_flag magic_quotes_gpc Off' in an .htaccess file and uploaded it onto my root folder. Its working now.Supra
an interesting solution with not touching the .ini configuration and using array_map, thanks for itButtonhole
This worked for me. I only used with POST but that is usually all you need. Just put this in a file that you likely already have included with your form files. THANKS.Gerrigerrie
The code example is misleading- it effectively NULL's array values.Polio
array_walk_recursive($_POST,function(&$a,$b){$a=stripslashes($a);}); req PHP 5.3 or laterNeomineomycin
I
30

While I can't say why php_flag is giving you 500 Internal Server Errors, I will point out that the PHP manual has an example of detecting if magic quotes is on and stripping it from the superglobals at runtime. Unlike the others posted, this one is recursive and will correctly strip quotes from arrays:

Update: I noticed today that there's a new version of the following code on the PHP manual that uses references to the super-globals instead.

Old version:

<?php
if (get_magic_quotes_gpc()) {
    function stripslashes_deep($value)
    {
        $value = is_array($value) ?
                    array_map('stripslashes_deep', $value) :
                    stripslashes($value);

        return $value;
    }

    $_POST = array_map('stripslashes_deep', $_POST);
    $_GET = array_map('stripslashes_deep', $_GET);
    $_COOKIE = array_map('stripslashes_deep', $_COOKIE);
    $_REQUEST = array_map('stripslashes_deep', $_REQUEST);
}
?>

New version:

<?php
if (get_magic_quotes_gpc()) {
    $process = array(&$_GET, &$_POST, &$_COOKIE, &$_REQUEST);
    while (list($key, $val) = each($process)) {
        foreach ($val as $k => $v) {
            unset($process[$key][$k]);
            if (is_array($v)) {
                $process[$key][stripslashes($k)] = $v;
                $process[] = &$process[$key][stripslashes($k)];
            } else {
                $process[$key][stripslashes($k)] = stripslashes($v);
            }
        }
    }
    unset($process);
}
?>
Industry answered 6/2, 2009 at 13:34 Comment(9)
This solution is both cleaner and more rigorous than the accepted one.Perspiration
Updated this post with PHP manual's current method for removing slashes.Industry
@Industry Does this update the POST/GET/REQUEST variables directly? It looks like you do everything to $process, then unset it at the end?Gallaher
@Gallaher (Note: I didn't write this code, it was from the PHP manual) Because $process is filled with references, I assume it updates POST/GET/REQUEST directly.Industry
Confirming the "New version" works great. I placed at the top of [Joolma Installation Directory]/Administrator/index.phpUnclassified
I don't think this is a good solution because the magic_quotes_gpc flag influence other functions like parse_str. This could produce some strange side effects.Edbert
"New Version" works fantastically on my website. Thanks!! Had an absolute nightmare trying to get my site configured on a shared server with per directory configurations. Decided to use this instead.Phenylalanine
@homePageCreator Forgot to reply to this earlier... the best solution would be to convince your provider to turn off magic_quotes_gpc, but shared hosts may not be willing to do that.Industry
Will it be placed in the .htaccess file?Publicize
U
20

This will solve the problem of getting "Class 'PDO' not found" when you create a local php.ini file.

If you can't turn off magic quotes using the htaccess file (for reasons already given by Pete Bailey) just:

  1. Create a text file
  2. Rename it to 'php.ini'
  3. Add the lines
magic_quotes_gpc = Off
magic_quotes_runtime = Off
magic_quotes_sybase = Off
extension=pdo.so
extension=pdo_mysql.so
  1. Save it to the directory/ies in which your scripts are executing.

Update: if you want to have just one copy of the new php.ini file then add this line to your root .htaccess file:

SetEnv PHPRC /path/to/site/root/public_html/php.ini

Obviously you need to move the ini file to this location of it's not there already.

Hope that saves someone the 2 hours it's just taken me!

Unashamed answered 10/5, 2012 at 12:27 Comment(3)
You saved me quite the headache. The magic_quotes setting was on for some reason(!), and disabling it effectively hosed my install. Luckily, the re-addition of the PDO extensions as you mentioned fixed it. Kudos.Sextillion
Good grief, this was just what I needed. Death to quotes.Gerrigerrie
thx for giving us a php.ini template. My only problem is I have to copy it into every folder where I'm using php, SetEnv PHPRC /public_html/php.ini isn't working :(Abyssal
A
10

The php_flag and php_value inside a .htaccess file are technically correct - but for PHP installed as an Apache module only. On a shared host you'll almost never find such a setup; PHP is run as a CGI instead, for reasons related to security (keeping your server neighbours out of your files) and the way phpsuexec runs scripts as 'you' instead of the apache user.

Apache is thus correct giving you a server error: it doesn't know about the meaning of php_flag unless the PHP module is loaded. A CGI binary is to Apache an external program instead, and you can't configure it from within Apache.

Now for the good news: you can set up per-directory configuration putting there a file named 'php.ini' and setting there your instructions using the same syntax as in the system's main php.ini. The PHP manual lists all settable directives: you can set those marked with PHP_INI_PERDIR or PHP_INI_ALL, while only the system administrator can set those marked PHP_INI_SYSTEM in the server-wide php.ini.

Note that such php.ini directives are not inherited by subdirectories, you'll have to give them their own php.ini.

Accept answered 7/2, 2009 at 1:24 Comment(0)
I
5

======================== =============== MY SOLUTION ============================ (rename your php.ini to php5.ini)

and in the top (!), add these:

magic_quotes_gpc = Off
magic_quotes_runtime = Off
magic_quotes_sybase = Off
extension=pdo.so
extension=pdo_mysql.so

then in .htaccess, add this (in the top):

SetEnv PHPRC /home/your_path/to/public_html/php5.ini

p.s. change /home/your_path/to/ correctly (you can see that path by executing the <?php phpinfo(); ?> command from a typical .php file.)

Illuminant answered 16/9, 2013 at 18:23 Comment(0)
M
1

If you're running PHP 5.3+ this will do the trick, place it at the topmost of your page:

if (get_magic_quotes_gpc() === 1)
{
    $_GET = json_decode(stripslashes(json_encode($_GET, JSON_HEX_APOS)), true);
    $_POST = json_decode(stripslashes(json_encode($_POST, JSON_HEX_APOS)), true);
    $_COOKIE = json_decode(stripslashes(json_encode($_COOKIE, JSON_HEX_APOS)), true);
    $_REQUEST = json_decode(stripslashes(json_encode($_REQUEST, JSON_HEX_APOS)), true);
}

Handles keys, values and multi-dimensional arrays.

Microelement answered 17/1, 2010 at 2:50 Comment(0)
N
1

if your hosting provider using cpanel, you can try copying php.ini into your web directory and edit it with magic_quotes_gpc = off

Newark answered 25/7, 2011 at 12:7 Comment(1)
You cannot add a php.ini file to the web directory, it needs to be located where PHP can read, but 99% of shared hosting do not allow you to change PHP settings. Also, you cannot edit a php.ini. VPS/Dedicated allows more freedom.Pastiche
S
1

I know I'm late to answer this, but I read most of the answers and while many were great, only djn actually explained why you were getting this 500 Internal Server Error.

While his explanation was 100% correct, this is a perfect example of why you should always wrap those in an <IfModule>. While this won't fix the actual problem of not being able to set those flags in your .htaccess, it will at least prevent the 500 error.

<IfModule mod_php5.c>
    # put all of your php_flags here, for example:
    php_flag magic_quotes_gpc off
</IfModule>

Or for older versions it would be <IfModule mod_php.c> etc.

I try to make a habit out of always doing this so as to avoid any such 500 errors. After that, just apply what Peter Bailey said.

Simulation answered 19/11, 2012 at 4:57 Comment(0)
O
0

Different hosting providers have different procedures for doing this, so I would ask on their forums or file a support request.

If you can't turn them off, you could always using something like this which will escape input regardless of whether magic quotes are on or off:

//using mysqli

public function escapeString($stringToBeEscaped) {

    return $this->getConnection()->real_escape_string(stripslashes($stringToBeEscaped));
}
Offcenter answered 5/2, 2009 at 17:52 Comment(0)
S
0
  1. Does it work if you remove the AddType line? I'm not quite sure why that's relevant to turning magic quotes off.

  2. If PHP isn't running under mod_php, htaccess won't work. Does it work as a CGI?

This is one for your hosting company really.

Schnorkle answered 5/2, 2009 at 17:54 Comment(2)
I removed the AddType line and i still get the 500 internal server error. I use taht add type line so all my php scripts are interpreted as php5 as opposed to php4 (the default version the shared host uses)Dittany
Yeh, so you're not running your scripts under mod_php anymore, but using the CGI binary PHP provides which means htaccess directives won't work.Schnorkle
I
0

BaileyP's answer is already pretty good, but I would use this condition instead:

if(function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc() === 1){
  $_POST = array_map( 'stripslashes', $_POST );
  $_GET = array_map( 'stripslashes', $_GET );
  $_COOKIE = array_map( 'stripslashes', $_COOKIE );
}

It is more defensive.

Interflow answered 6/2, 2009 at 13:6 Comment(0)
B
0

How about $_SERVER ?

if (get_magic_quotes_gpc() === 1) {

    $_GET = json_decode(stripslashes(json_encode($_GET, JSON_HEX_APOS)), true);
    $_POST = json_decode(stripslashes(json_encode($_POST, JSON_HEX_APOS)), true);
    $_COOKIE = json_decode(stripslashes(json_encode($_COOKIE, JSON_HEX_APOS)), true);
    $_REQUEST = json_decode(stripslashes(json_encode($_REQUEST, JSON_HEX_APOS)), true); 
    $_SERVER = json_decode( stripslashes(json_encode($_SERVER,JSON_HEX_APOS)), true); 
}
Bonbon answered 5/4, 2011 at 12:57 Comment(0)
C
-1

If you can't turn it off, here is what I usually do:

get_magic_quotes_gpc() ? $_POST['username'] : mysql_real_escape_string($_POST['username']);

It will be placed in the database in its proper format.

Checked answered 5/2, 2009 at 18:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.