Link to home
Start Free TrialLog in
Avatar of elepil
elepil

asked on

Is filter_input reliable??

Being a NetBeans user, I keep getting the warnings: "Do not access Superglobal variable directly".

So I started getting into the habit of using filter_input(). But today, it cost me 4 hours of debugging time.

Let's say my remote web host domain name is www.MySite.com. Because my application resides in multiple servers (i.e., local server and remote), I have the following code to determine how PHPMailer would be initialized:

$server = filter_input(INPUT_SERVER, 'SERVER_NAME', FILTER_SANITIZE_FULL_SPECIAL_CHARS);

if (($pos = stripos($server, "localhost")) !== FALSE) {
    .... PHPMailer initialization code here ....
}
if (($pos = stripos($server, "MySite")) !== FALSE) {
    .... PHPMailer initialization code here ....
}

Open in new window


In my local server, filter_input() appropriately returns "localhost" and initializes PHPMailer correctly. So I thought it was working right, and never doubted that it would cause me trouble.

But when I uploaded my work to the remote web host, I was surprised why email wasn't getting sent when expected. I was talking with my web host's technical support for more than 2 hours, and I had spent an additional 2 hours trying to debug this, thinking something was wrong with their email server. To make a long story short, there was nothing wrong with their email server, it was the above filter_input statement returning an empty string!! I have no idea why it was failing on their server, but it was running PHP 5.5 like I was, so I couldn't understand. Because it was returning an empty string (not FALSE, I checked), the if-statement was never becoming true and was never executing the block of PHPMailer initialization code. Needless to say, PHPMailer could not send email if it didn't have a SMTP Host, user name, password, etc.

Has anyone ever had this kind of experience with filter_input()? Is there something in the way I implemented it that's incorrect? Or is filter_input() just unreliable? I went back to accessing Superglobal variables, I don't trust filter_input() anymore.
ASKER CERTIFIED SOLUTION
Avatar of Dave Baldwin
Dave Baldwin
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
I misspoke.  Only two of my servers appear to be FastCGI.  They return a blank but all the others using Apache SAPI do return the server name.  I have an nginx server with FastCGI and it returns the server name but even if I use the IP address, it still returns 'localhost'.
Let's take a slightly different view of it... What exactly are you trying to achieve or prevent?  The PHP environmental variables (can be found with phpinfo() are not particularly sturdy because they depend on installation settings, and I would generally not depend on them without verification if there is an alternate approach.  But to suggest an alternate approach, I'd need to understand your objectives.
Avatar of elepil
elepil

ASKER

To Dave Baldwin. Thanks for responding.

I am relieved that you were able to replicate the issue with filter_input. So many times during my programming career, I've had bizarre things happen to me with language features, server issues, etc., things that seemingly only happen to me. When I googled about this issue, I couldn't find a single article about this; I may have missed it, but it's that sparse.

Yet, NetBeans issues a warning every single time I access a superglobal variable directly. I know this is something that can be turned off in the Options, but I got the impression that having to use filter_input was so important. NetBeans has been around for a long time, and I'd think they are some sort of authority on the languages their IDE supports.

This is a pernicious issue for filter_input, and I'm not sure I can trust it anymore.
Avatar of elepil

ASKER

To Ray Paseur. Thanks for responding.

I normally access the superglobal variables directory (e.g. $server = $_SERVER['SERVER_NAME']) and never really intended to use filter_input. NetBeans is the IDE I use, and it constantly flags a warning everytime I access a superglobal this way. So despite the more tedious syntax of filter_input, I decided to use it, thinking that NetBeans probably has a very good reason for flagging a warning on this.

When I researched a bit on why it's not good to access superglobal variables directly, I never really got a very good answer other than the values might sometimes not be there. This disappointments me with PHP because for something that's been around for so long, I expected it to be more robust, especially on variables it advertises as superglobal. Now I'm feel like I'm damned if I do and damned if I don't use either superglobals or filter_input.
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of elepil

ASKER

To Ray Paseur.

When I decided to abandon Adobe Flex/Java, it was the very things you mentioned that made me decide to go the PHP route. When I hear Google, Facebook, Wordpress, etc. heavily using PHP, it boosts my confidence on the platform, thinking if its good enough for the big guys, it would be good for me. I got the impression that PHP had to be some robust web scripting language, especially since it's been around for ages.

But having learned more about PHP now, I'm a bit disappointed in its occasional convolution. For example, one of the big turnoffs I noticed was how functions would return mixed values. In other languages I've used, the return value is always the same. So a strpos() function would return either a positive integer or a -1. But its PHP counterpart returns an integer or FALSE. Worse, TRUE in PHP prints out as 1, but FALSE does not print out as 0.

And now, this filter_input issue disenchants me even more where known authorities in PHP tell me not to access superglobals directly because it's not reliable, only to find out filter_input is unreliable in itself as well.

And you tell me that storing objects in the session is not always reliable ... good grief. If I hadn't spent so much time already in PHP, and knowing what I know today about it, I have to be honest and admit I'm regretting I decided to go the PHP route.
This seemed to make sense to me.  A different filter function works fine.
<?php // demo/temp_elepil_0.php

/**
 * Filter_Input()
 * See http://www.experts-exchange.com/Programming/Languages/Scripting/PHP/Q_28654329.html
 * http://php.net/manual/en/function.filter-input.php
 * http://php.net/manual/en/filter.filters.sanitize.php
 * http://php.net/manual/en/filter.filters.flags.php
 */
error_reporting(E_ALL);


// TRY THE FILTER - FAIL
$server = filter_input(INPUT_SERVER, $_SERVER["SERVER_NAME"], FILTER_SANITIZE_FULL_SPECIAL_CHARS);
var_dump($server);

// TRY THE FILTER IN A DIFFERENT WAY - FAIL
$server = filter_input(INPUT_SERVER, $_SERVER["SERVER_NAME"], FILTER_SANITIZE_STRING);
var_dump($server);


// TRY A DIFFERENT FILTER FUNCTION - SUCCESS
$server = filter_var($_SERVER["SERVER_NAME"], FILTER_SANITIZE_STRING);
var_dump($server);


// SHOW THE SERVER VARIABLES
echo '<pre>';
var_dump($_SERVER);

Open in new window

Avatar of elepil

ASKER

To Ray Paseur.

I never said filter_input doesn't work all the time. The problem is that it doesn't work all of the time. If you read my original post, it worked all the time for me in my local server, but it fails sporadically in the remote web host.
where known authorities in PHP tell me not...
Heh, heh.  Like I said, PHP is a funhouse language.  Nobody who intended to write a robust programming language would write PHP the way it is today.  Same is true of JavaScript (WTF - the plus sign is overloaded and causes type coercion?  WTF - the statement terminator semi-colon is sometimes assumed?)  But both of the languages have good parts, and once you get past the bad parts you can find good examples of the major design patterns implemented in PHP.  One of the best places to look is the Laravel framework, where Taylor Otwell has used PHP very cleverly.  It's free and open source - you might want to get a copy and see what he's doing in there!
Just a footnote, but I've been using PHP a long time, and this is the first time I have ever seen anyone use the filter_input() function.  I've seen filter_var() plenty of times, and even recommended it to replace awkward regular expressions, but I've never seen filter_input() before, not even once.
Avatar of elepil

ASKER

To Ray Paseur.

but I've never seen filter_input() before, not even once.

Now I'm really confused why NetBeans was so dead-determined to keep warning me to use filter_input instead. I'm encountering these illogical situations in the PHP world lately. :(
Avatar of elepil

ASKER

That filter_input works erratically was already fact to me. But I thank Dave Baldwin for confirming to me that it happens to him, too, and that it's not just something wrong with my remote web host; that went a long way in providing me relief.

And to Ray Paseur, thanks for confirming to me the convolution of PHP that I was already strongly sensing.

Thanks both for your help.

P.S. I swear, if I didn't know better, I'd think only both of you frequent this forum since I get responses from both of you the most, LOL.
NetBeans is not exactly the "center of gravity" in the PHP world -- more like an edge case.  It's not as bad as Dreamweaver, but if I were to look for a PHP editor or IDE I might choose PHPStorm or maybe TextMate 2.  Have a look at Laracasts and see what Jeffrey Way uses.
Avatar of elepil

ASKER

Ray, I've asked questions about the best IDE before, and PHPStorm came up. My problem with that is its user interface. If I remember right, it had TONS of icons that were so small and cramped, I swear it was the author's intention to overwhelm the user with icons. Also, I wanted a quick way to know if it allowed me to set breakpoints in JavaScript and PHP, and I couldn't do it in any easy and intuitive way. Because I didn't like how the UI was organized, I didn't bother looking into it further.

NetBeans isn't exactly perfect either, but it had less flaws than the other ones I looked at.
To add to both your education and confusion, here is a PHP program that displays the $_SERVER variables that are available on the server it is run on.  In addition to the fact that hosting companies turn off some of the variables, different web servers and different versions of them do not report exactly the same info.  When ever I run into odd behavior with $_SERVER variables, I run this.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>PHP Server Variables</title>
</head>
<body><h1>PHP Server Variables</h1>
<?php

//reset($_SERVER);
foreach($_SERVER as $key => $value) {
    echo "<b>$key :</b> $value<br />\n";
}

print_r ($_POST);
?>
</body>
</html>

Open in new window

If you're not using it yet, get yourself into Google Chrome Dev Tools.  VERY helpful!  Good online learning resources.
Avatar of elepil

ASKER

To Dave Baldwin.

Would not a var_dump done something similar?


To Ray Paseur.

I do use ChromePHP to output variables to the Chrome console, and I do use Chrome's debugging tools (F12).

Thanks both for the tips.
Maybe var_dump would, never tried it.  It wouldn't be as legible to me and I use pages like that to copy and paste.