This question already has an answer here:
Is is bad practice to use array_walk with mysqli_real_escape_string?
(1 answer)
Closed 1 year ago.
My code is like this
public function addQuestions($data){
$ans = array();
$ans[1] = $data['ans1'];
$ans[2] = $data['ans2'];
$ans[3] = $data['ans3'];
$ans[4] = $data['ans4'];
$ans= mysqli_real_escape_string($this->db->link, $data[$ans]);
}
Is this right way to use array in this sql function ??
Since you wish to do something to each element of array $ans, it would be most appropriate to use array_map(), as follows:
public function addQuestions($data){
$ans = array();
$ans[1] = $data['ans1'];
$ans[2] = $data['ans2'];
$ans[3] = $data['ans3'];
$ans[4] = $data['ans4'];
$escaped_ans = array_map(function( $e ) {
return mysqli_real_escape_string( $this->db->link, $e);
}, $ans );
I don't have enough reputation to comment on Milan's post, but beware of array_walk, it won't change your original array. For Milan's code to actually affect your array, the function would have to be
function myescape(&$val) //Note the '&' which calls $val by reference.
{
$val = mysqli_real_escape_string($val);
}
array_walk($ans, 'myescape');
To answer your question though:
public function addQuestions($data){
$ans = array('',$data['ans1'],$data['ans2'],$data['ans3'],$data['ans4']);
//I would recommend using an object/associative array in this case though, just the way $data is already
$ans_escaped = array_map(function($val) {
return mysqli_real_escape_string($this->db->link, $val);
}, $ans);
//do whatever you need to do with escaped array
}
My advice though, would be to really look into prepared statements. It might just seem like extra work that you don't want to bother with - at first - but once you learn it, you will never want to do it any other way.
Since you have an array, and you want mysqli_real_escape_string on each element of an array, you can use array_walk():
function myescape($val)
{
return mysqli_real_escape_string($val);
}
... then
array_walk($ans, 'myescape');
if you use MYSQL PDO you won't need add "mysqli_real_escape_string" because all your variables a safe (from SQL injection) after you bind it
http://php.net/manual/en/pdostatement.bindparam.php
Related
This question already has answers here:
Dynamically create PHP object based on string
(5 answers)
Closed 8 years ago.
I have a bunch of functions depending on a variable, I want to be able to do something like this:
(It returns an error hence the problem I'm unable to solve)
function($x) {
fetch.$x.() // if x=Name I would like it to execute fetchName()...and so on
}
and something like this
function($x) {
$article = new \Cc\WebBundle\Entity\$X();
// if x='name' to be executed Cc\WebBundle\Entity\name()
}
Sure, you could do that:
$basename = "fetch";
$key = ...; // your logic for generating the rest of function's name
$functionName = $basename . $key;
$functionName(); // execute function
Now, the tricky part would be if functions contain arbitrary set of arguments. In that case you should use call_user_func_array (docs).
As for creating of objects, meagar explained here please clear how to achieve that.
P.S. This, in fact, has very little to do with Symfony2. This is a pure PHP question ;)
Personally, I use the handy call_user_func_array() function like this:
<?php
$class = 'MyClassName';
$method = 'someMethod';
$parameters = array('foo', 'bar', 'baz');
call_user_func_array(array($class, $method), $parameters);
I imagine you would need to escape back-slashes in any name-spaced class names though, i.e. MCB\\MyClassName.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Any way to specify optional parameter values in PHP?
PHP function - ignore some default parameters
Suppose I have function like this:
function foo($name = "john", $surname = "smith") { ... }
And I am calling like this:
$test = foo("abc", "def");
Imagine now that I would like to skip the name and only use the surname, how is that achievable? If I only do $test = foo("def"); how can the compiler know I am referring to the surname and not to the name? I understand it could be done by passing NULL, but I need this for something more like this:
$test = foo($_POST['name'], $_POST['surname']);
Thanks in advance.
You can try this-
$num_args = func_num_args();
if($num_args == 1)
$surname = func_get_arg(1);
else
$surname = func_get_arg(2);
$name = func_get_arg(1);
Please test it before you use it.
Your code
$test = foo($_POST['name'], $_POST['surname']);
will also pass NULL in the first PARAMETER if it is empty so the compiler will know that it is up to the second parameter. Having a comma in the parameter list will already inform PHP that there are two parameters here.
You can do so by passing an empty string to your function and detecting in your function if the passed argument is an empty string, and if it is, then replacing it by the default value. this would make your function call like:
foo('','lastname');
And you can add these few lines to beginning of your function to detect if an empty string has been passed as a parameter:
function foo($name = "john", $surname = "smith") {
if($name==='') { $name = 'john'}
//more code
... }
I usually do something like so:
function foo($parameters = array())
{
print_r($parameters);
}
foo($_POST); //will output the array
It's what I use, when I expect more than 3 parameters.
But you might as well use the following:
function foo()
{
$args = func_get_args();
foreach ($args as $arg) {
echo "$arg \n";
}
}
This question already has answers here:
Sanitizing user's data in GET by PHP [duplicate]
(5 answers)
What are the best PHP input sanitizing functions? [duplicate]
(14 answers)
Closed 7 months ago.
I have a form with a lot of variables which is then sending an email, rather than sanitizing each $_POST value with filter_var($_POST['var'], FILTER_SANITIZE_STRING); I was after a more simple piece of code. I came up with the below, which seems to work as I believe the default action is FILTER_SANITIZE_STRING, but I was just wondering what peoples opinions are, and if this is not good practice, perhaps you could tell me why? The $_POST values are then individually embedded into new variables, so I would only be using array_map just at the start to sanitize everything...
$_POST = array_map('filter_var', $_POST);
Thank you for your replies, to give you a little more information, basically:
I have 20-30 input fields in a form which are being captured,
the data is then displayed to the user to check their input,
variables are then sanitized,
the user is then sent an email
and then finally the details are entered into a db.
currently I am sanitizing using the above array_map function, as well as FILTER_SANITIZE_EMAIL on the email address before sending an email and then escaping the input using mysql_real_escape_string() before the insert into the db. Without getting into prepared statements etc.. do you think I should be doing anything additionally? thanks again!
Just use filter_input_array() from the filter extension.
/* prevent XSS. */
$_GET = filter_input_array(INPUT_GET, FILTER_SANITIZE_STRING);
$_POST = filter_input_array(INPUT_POST, FILTER_SANITIZE_STRING);
This will sanitize your $_GET and $_POST.
Depends what its being used for.
If you are inserting it into the database then mysql_real_escape_string() for quoted strings and type casting for numbers would be the way to go - well ideally prepared statements, but thats an entirely different matter.
If you plan on outputting the data onto the webpage then I would recommend something like htmlspecialchars()
If you plan on using the user input as a shell argument, then you would use escapeshellarg()
Moving onto your question about sending emails. Well, the following should suffice:
filter_var($_POST['message'], FILTER_SANITIZE_STRING);
All this does is basically strip tags and encode special characters.
You can use strip_tags() with array_map()
<?php
$a = array(
'title' => 'Title',
'data' => array(
'hdr' => 'Header',
'bdy' => 'Body'
),
'foo' => array(1, 23, 65)
);
$b = array_map("strip_tags", $a);
print_r($b);
?>
Update for 2D array:
function array_map_r( $func, $arr )
{
$newArr = array();
foreach( $arr as $key => $value )
{
$newArr[ $key ] = ( is_array( $value ) ? array_map_r( $func, $value ) : ( is_array($func) ? call_user_func_array($func, $value) : $func( $value ) ) );
}
return $newArr;
}
Usage:
$a = array(
'title' => 'Title',
'data' => array(
'hdr' => 'Header',
'bdy' => 'Body'
),
'foo' => array(1, 23, 65)
);
$ar =array_map_r('strip_tags', $a);
print_r($ar);
Note I found this just by searching the comments for Dimension
There is no correct way to do blanket sanitation. What sanitation method you need depends on what is done to the data.
Sanitize the data directly before it is used.
function strip($string, $allowed_tags = NULL)
{
if (is_array($string))
{
foreach ($string as $k => $v)
{
$string[$k] = strip($v, $allowed_tags);
}
return $string;
}
return strip_tags($string, $allowed_tags);
}
Just an example of a recursive function, for stripping tags in this case.
$arr = strip($arr);
This is what I use in all my projects:
function util_array_trim(array &$array, $filter = false)
{
array_walk_recursive($array, function (&$value) use ($filter) {
$value = trim($value);
if ($filter) {
$value = filter_var($value, FILTER_SANITIZE_STRING);
}
});
return $array;
}
It allows to trim and sanitize a nested array of posted data
This looks ok, but please comment if it can be improved or has any misgivings:
$_GET =filter_var_array($_GET);
$_POST=filter_var_array($_POST);
To apply specific filters on multiple fields, use a switch statement.
$post = filter_input_array(INPUT_POST, FILTER_SANITIZE_STRING);
foreach($post as $k => $v) {
switch ($k) {
case 'int_1':
case 'int_2':
$post[$k] = filter_var($v, FILTER_SANITIZE_NUMBER_INT) * 1;
break;
case 'float_1':
case 'float_2':
$post[$k] = filter_var($v, FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION) * 1;
break;
default:
break;
}
}
Note: My IDE (NetBeans) warns about using global $_POST anywhere as a security violation, so I've just gotten into the habit of using a local $post variable instead. If you choose not to do the blanket string sanitation first, FILTER_SANITIZE_STRING could be used for the default: case.
Let's say we want to sanitize the $_POST array:
foreach($_POST as $k=>$v) {$_POST[$k] = htmlspecialchars($v);}
This simple. Isn't it?
This question already has answers here:
Sanitizing user's data in GET by PHP [duplicate]
(5 answers)
What are the best PHP input sanitizing functions? [duplicate]
(14 answers)
Closed 7 months ago.
I have a form with a lot of variables which is then sending an email, rather than sanitizing each $_POST value with filter_var($_POST['var'], FILTER_SANITIZE_STRING); I was after a more simple piece of code. I came up with the below, which seems to work as I believe the default action is FILTER_SANITIZE_STRING, but I was just wondering what peoples opinions are, and if this is not good practice, perhaps you could tell me why? The $_POST values are then individually embedded into new variables, so I would only be using array_map just at the start to sanitize everything...
$_POST = array_map('filter_var', $_POST);
Thank you for your replies, to give you a little more information, basically:
I have 20-30 input fields in a form which are being captured,
the data is then displayed to the user to check their input,
variables are then sanitized,
the user is then sent an email
and then finally the details are entered into a db.
currently I am sanitizing using the above array_map function, as well as FILTER_SANITIZE_EMAIL on the email address before sending an email and then escaping the input using mysql_real_escape_string() before the insert into the db. Without getting into prepared statements etc.. do you think I should be doing anything additionally? thanks again!
Just use filter_input_array() from the filter extension.
/* prevent XSS. */
$_GET = filter_input_array(INPUT_GET, FILTER_SANITIZE_STRING);
$_POST = filter_input_array(INPUT_POST, FILTER_SANITIZE_STRING);
This will sanitize your $_GET and $_POST.
Depends what its being used for.
If you are inserting it into the database then mysql_real_escape_string() for quoted strings and type casting for numbers would be the way to go - well ideally prepared statements, but thats an entirely different matter.
If you plan on outputting the data onto the webpage then I would recommend something like htmlspecialchars()
If you plan on using the user input as a shell argument, then you would use escapeshellarg()
Moving onto your question about sending emails. Well, the following should suffice:
filter_var($_POST['message'], FILTER_SANITIZE_STRING);
All this does is basically strip tags and encode special characters.
You can use strip_tags() with array_map()
<?php
$a = array(
'title' => 'Title',
'data' => array(
'hdr' => 'Header',
'bdy' => 'Body'
),
'foo' => array(1, 23, 65)
);
$b = array_map("strip_tags", $a);
print_r($b);
?>
Update for 2D array:
function array_map_r( $func, $arr )
{
$newArr = array();
foreach( $arr as $key => $value )
{
$newArr[ $key ] = ( is_array( $value ) ? array_map_r( $func, $value ) : ( is_array($func) ? call_user_func_array($func, $value) : $func( $value ) ) );
}
return $newArr;
}
Usage:
$a = array(
'title' => 'Title',
'data' => array(
'hdr' => 'Header',
'bdy' => 'Body'
),
'foo' => array(1, 23, 65)
);
$ar =array_map_r('strip_tags', $a);
print_r($ar);
Note I found this just by searching the comments for Dimension
There is no correct way to do blanket sanitation. What sanitation method you need depends on what is done to the data.
Sanitize the data directly before it is used.
function strip($string, $allowed_tags = NULL)
{
if (is_array($string))
{
foreach ($string as $k => $v)
{
$string[$k] = strip($v, $allowed_tags);
}
return $string;
}
return strip_tags($string, $allowed_tags);
}
Just an example of a recursive function, for stripping tags in this case.
$arr = strip($arr);
This is what I use in all my projects:
function util_array_trim(array &$array, $filter = false)
{
array_walk_recursive($array, function (&$value) use ($filter) {
$value = trim($value);
if ($filter) {
$value = filter_var($value, FILTER_SANITIZE_STRING);
}
});
return $array;
}
It allows to trim and sanitize a nested array of posted data
This looks ok, but please comment if it can be improved or has any misgivings:
$_GET =filter_var_array($_GET);
$_POST=filter_var_array($_POST);
To apply specific filters on multiple fields, use a switch statement.
$post = filter_input_array(INPUT_POST, FILTER_SANITIZE_STRING);
foreach($post as $k => $v) {
switch ($k) {
case 'int_1':
case 'int_2':
$post[$k] = filter_var($v, FILTER_SANITIZE_NUMBER_INT) * 1;
break;
case 'float_1':
case 'float_2':
$post[$k] = filter_var($v, FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION) * 1;
break;
default:
break;
}
}
Note: My IDE (NetBeans) warns about using global $_POST anywhere as a security violation, so I've just gotten into the habit of using a local $post variable instead. If you choose not to do the blanket string sanitation first, FILTER_SANITIZE_STRING could be used for the default: case.
Let's say we want to sanitize the $_POST array:
foreach($_POST as $k=>$v) {$_POST[$k] = htmlspecialchars($v);}
This simple. Isn't it?
any idea how if the following is possible in PHP as a single line ?:
<?php
$firstElement = functionThatReturnsAnArray()[0];
... It doesn't seem to 'take'. I need to do this as a 2-stepper:
<?php
$allElements = functionThatReturnsAnArray();
$firstElement = $allElements[0];
... just curious - other languages I play with allow things like this, and I'm lazy enoug to miss this in PHP ... any insight appreciated ...
#Scott Reynen
that's not true. This will work:
list(,,$thirdElement) = $myArray;
Try:
<?php
$firstElement = reset(functionThatReturnsAnArray());
If you're just looking for the first element of the array.
Unfortunately, that is not possible with PHP. You have to use two lines to do it.
You can do this in one line! Use array_shift().
<?php
echo array_shift(i_return_an_array());
function i_return_an_array() {
return array('foo', 'bar', 'baz');
}
When this is executed, it will echo "foo".
list() is useful here. With any but the first array element, you'll need to pad it with useless variables. For example:
list( $firstElement ) = functionThatReturnsAnArray();
list( $firstElement , $secondElement ) = functionThatReturnsAnArray();
And so on.
I actually use a convenience function i wrote for such purposes:
/**
* Grabs an element from an array using a key much like array_pop
*/
function array_key_value($array, $key) {
if(!empty($array) && array_key_exists($key, $array)) {
return $array[$key];
}
else {
return FALSE;
}
}
then you just call it like so:
$result = array_key_value(getMeAnArray(), 'arrayKey');
You can use array_slice(), like so:
$elementX = array_slice(functionThatReturnsAnArray(), $x, 1);
Also noticed that end() is not mentioned. It returns the last element of an array.
Either current($array) or array_shift($array) will work, the former will leave the array intact.
nickf, good to know, thanks. Unfortunately that has readability problems beyond a few commas.
I think any of the above would require a comment to explain what you're doing, thus becoming two lines. I find it simpler to do:
$element = functionThatReturnsArray();
$element = $element[0];
This way, you're not using an extra variable and it's obvious what you're doing.
$firstItem = current(returnsArray());
Well, I have found a couple of ways to get what you want without calling another function.
$firstElement = ($t = functionThatReturnsAnArray()) ? $t[0] : false;
and for strings you could use
$string = (($t = functionThatReturnsAnArray())==0) . $t[0];
.. Interesting problem
Draco
I am guessing that this is a built-in or library function, since it sounds like you cannot edit it directly. I recommend creating a wrapper function to give you the output you need:
function functionThatReturnsOneElement( $arg )
{
$result = functionThatReturnsAnArray( $arg );
return $result[0];
}
$firstElement = functionThatReturnsOneElement();
As far as I know this is not possible, I have wanted to do this myself several times.
http://us3.php.net/reset
Only available in php version 5.
If it's always the first element, you should probably think about having the function return just the first item in the array. If that is the most common case, you could use a little bit of coolness:
function func($first = false) {
...
if $first return $array[0];
else return $array;
}
$array = func();
$item = func(true);
My php is slightly rusty, but i'm pretty sure that works.
You can also look at array_shift() and array_pop().
This is probably also possible:
array(func())[0][i];
The 0 is for the function.
Sometimes I'll change the function, so it can optionally return an element instead of the entire array:
<?php
function functionThatReturnsAnArray($n = NULL) {
return ($n === NULL ? $myArray : $myArray[$n]);
}
$firstElement = functionThatReturnsAnArray(0);