In one application I am building, I have a variable amount of text inputs (fill-in-the-blank questions in an online quiz, with variable amounts of blanks). The question ID needs to be identified in the name, as the blank information also needs to be passed back. I also have some hidden validation inputs (a nonce and formID that are checked against values stored on the server, and if the values are sent via javascript an extra value to flag the system to send JSON back) that are identified with an underscore.
Therefore, to filter the system values and the ID's of questions I need, I'm using regex (which works fine).
Currently I'm getting my values with code similar to the following:
function input_filter_post($regexfilter,$escapetype,$options) {
$keys = array_keys($_POST);
$return = array();
foreach($keys as $key) {
if (preg_match($regexfilter,$key)) {
$return[$key] = filter_input(INPUT_POST,$key,$escapetype,$options);
}
}
return $return
}
note that I need to use $_POST to find the array keys. However, for my actual application I want to unset $_POST to force the use of filter_input. Is there some way to retrieve the keys from $_POST without using $_POST?
Finally, I used a wrapper object around $_POST that indirectly used filter_input to grab the information.
Related
I'm creating a HTML form that had a dynamically-generated list of select inputs. I'd like to cycle through these inputs (in the $_POST array) with a foreach block and make updates in the DB based on the information in each of these inputs. I know I have to name each select input something different so I've appended a unique identifier onto the inputs name (i.e. name="confidenceLevel45").
Is there are a way to preg_match the associative keys in the $_POST array and have a callback to process the values associated with them? Is there another way to do this besides regex'ing the $_POST array keys? I feel like this is a fairly common occurrence in application development but, for some reason, I can't find any answers online. I rather not make an AJAX call and use jQuery to process such a form...
Thank you in advance!
I don't have the reputation to make comments, slightly confused by what you are attempting to do and whether you want to process this client side in jQuery or server side in PHP.
If you want to process on the server side you could foreach over the $_POST array and match the key value to a switch case or condition:
foreach ($_POST as $key => value) {
switch ($key) {
case 'foo':
callToFunctionA($value);
break;
case 'bar':
callToFunctionB($value);
break;
}
if ($key == 'fizzbuzz') {
callToFunctionC($value);
}
}
Where your cases or conditions match up to the name attributes on your form.
I was dealing with security, and I came up with an idea:
if (!isset($_POST['id']))
{
$_POST['id'] = 0;
}
$_POST['id'] = (int)$_POST['id']; // kill SQL injection
but what if id was an array? It would force this method to knee! But I dont know if its even possible to generate array.
Don't reinvent the wheel: php has a nice set of filters to deal with $_GET and $_POST: see http://php.net/filter - there are filters even for arrays.
If in your form you have a <SELECT multiple>, which will send out an array of options picked by the user, the name must be something like name="MySelection[]" instead of a plain name="MySelection". In this way, with the square brackets, an array will be automatically generated, and it will be $_POST['MySelection'][0], $_POST['MySelection'][1] and so on. You can loop on it with a the usual foreach.
Is there a way to create a dynamic sql query so that certain where clauses only run if a variable isn't null?
So say a user can select various options to filter results and they can chose not to select a an option from certain dropdowns if they don't need to. That would result in certain variables being null.
I'd like to do it in a way that wouldn't result in writing if statements to cater for every eventuality.
Don't mind suggestions in PHP or Laravel specific answers.
Thanks!
I'd prefer the if statements, but you can look into the Coalesce operator: http://dev.mysql.com/doc/refman/5.0/en/comparison-operators.html#function_coalesce
Create a client-side jQuery function
One of the things you could do is write a bit if jQuery that goes through all your input client-side and only submits the input where the value is not empty/null. The jquery code could be used for all your forms or input data. So you simply never get the passed parameters that have null values coming into your server-side controller (and eventually into your dynamic query). You can find solutions in this stackoverflow question here for this. Personally, I just have all my input in a class and cycle through it to remove the empty values. See my simple Fiddle here. You can even create special conditions for special types of inputs, that way your script covers for all types of null/empty/etc if you wanted.
OR
Create a helper function in PHP/Laravel
You could also do this server-side. You could write a helper function that loops through all your input coming in and removes the empty inputs. It could also build the WHERE clause at the same time for you (either raw, or you could pass your query object into the helper and it could add each ->where as it loops through the input and returns the query object back to you).
$query = DB::table('my_table')->select('abc', 'xyz');
// This could be your helper. Pass in your query and input...
dynamicWhereHelper($query, Input::all());
$rows = $query->get();
and in your dynamicWhereHelper:
function dynamicWhereHelper($query, $input = array())
{
// Assuming you named each of your inputs the same as your database fields
foreach ($input as $key => $value){
if(!empty($value)){
$query->where($key, $value);
}
}
}
NOTE: A safer approach would be to additionally pass an array of acceptable input names in order to verify that no random $key is passed into the WHERE. You can define this array once per page you build, and it could be used to both build your form and then later used in the helper: dynamicWhereHelper($query, Input::all(), $acceptableInputs);
Disclaimer: I am fairly new to using json.
I am trying to use php to receive json data from an iPAd application. I know how to convert json to an array in php, but how do I actually receive it and store it into a variable so it can be decoded?
Here are a couple examples that I have tried based on google and stackoverflow searches.
$json_request = #file_get_contents('php://input');
$array = json_decode($json_request);
AND ALSO
$array = json_decode($_POST['data'], true);
Any suggestions?
You have the basic idea already.
you should test that the value is set and also strip extra slashes from the incoming string before trying to parse it as JSON.
if(isset($_POST['data'])){
$array = json_decode(stripslashes($_POST['data']),true);
//$array now holds an associative array
}//Data Exists
It also would not be a bad idea before you start working with the array to test that the call to json_decode() was successful by ensuring that $array isn't null before use.
If you do not fully trust the integrity of the information being sent you should do extended checking along the way instead of trusting that a given key exists.
if($array){ // Or (!is_null($array)) Or (is_array($array)) could be used
//Process individual information here
//Without trust
if(isset($array['Firstname'])){
$CustomerId = $array['Firstname'];
}//Firstname exists
}//$array is valid
I in-particular like to verify information when I am building queries dynamically for information that may not be required for a successful db insert.
In the above example $_POST['data'] indicates that what ever called the PHP script did so passing the JSON string using the post method in a variable identified as data.
You could check more generically to allow flexibility in the sending method by using the $_REQUEST variable, or if you know it is coming as via the get method you can check $_GET. $_REQUEST holds all incoming parameters from both get and post.
If you don't know what the name of the variable coming in is and want to play really fast and loose you could loop over the keys in $_REQUEST trying to decode each one and use the one that successfully decoded (if any). [Note: I'm not encouraging this]
I'm new to OOP and want to revamp this function to get rid of using globals.
function CatchListing() {
$parseform = array('itemnum','msrp','edprice','itemtype','box','box2','box25','box3','box4','box5','box6','box7','itemcolor','link');
foreach ($parseform as $globalName) {
$GLOBALS[$globalName] = mysql_real_escape_string($_POST[$globalName]);
}
}
I was told to use array_map & then extact, but I am not sure of how to structure this.
function CatchListing() {
$_POST['listing'] = array_map('mysql_real_escape_string', $_POST);
$nst = extract($_POST['listing']);
}
(listing is the form name btw)
Thanks
Be VERY careful about using extract with externally inputted values as from $_GET and $_POST.
you're much better off extracting the values manually to known values.
It's far too easy for an extract from _GET or _POST to clobber existing variables.
There are so many things to say and Jonathan makes a very good start. Every time the user has the opportunity to play with your internal data and you don't check them, there is a huge "opportunity" (depends on the view..) that something goes wrong. Here is another approach on how to "maybe" get where you want to go:
<?php
function Sanitize($string){
return mysql_real_escape_string(trim($string));
}
function CatchListing(){
foreach($_POST as $key => $value) {
$key = Sanitize($key);
$value = Sanitize($value);
if($key && $value && !$GLOBALS[$key]){ /* prevent overwriting existing globals*/
$GLOBALS[$key] = $value;
}
}
}
global $nice;
$nice = "working";
CatchListing();
print_r($GLOBALS);
?>
To be honest, it still has not really anything to do with OOP and furthermore should be seen as a procedural approach. Personally I would use an additional and reusable function to "sanitize" the input, because you never know, if someday you want to change your database or the "escape" function and then you exactly know where to look for possible changes. Ah one more thing: Are you certain that you don't know all the possible names of all the variables you have to expect? Maybe you can predetermine them and put them in another array and check each user supplied argument with in_array.
To completely get rid of the usage of globals in your code, and also to make it much better overall, you can do something along these lines:
stop using $_POST, as it's a superglobal. When code needs values from superglobals, pass them as parameters
don't store values into $GLOBALS. If you need to return more than one value, consider returning an object or an array
Here's how I think I would modify your code to improve it:
function CatchListings($listings) {
$filteredListings = array_map('mysql_real_escape_string', $listings);
//I assume you only need the values in the array in the original snippet,
//so we need to grab them from the parameter array and return only that
$requiredListings = array();
$requiredKeys = array('itemnum','msrp','edprice','itemtype','box','box2','box25','box3','box4','box5','box6','box7','itemcolor','link');
foreach($requiredKeys as $key) {
$requiredListings[$key] = $filteredListings[$key];
}
return $requiredListings;
}
To use this function, you simply do $result = CatchListings($_POST);. Same result, no globals used.
There is one thing to consider, though. It may not be best possible form to just pass a randomly filled array (ie. $_POST) to the function, and expect it to contain specific keys (ie. $requiredKeys array). You might want to either add logic to check for missing keys, or process the post array before passing it.