PHP: Retrieving value of checkboxes when name doesn't have array - php

A form I don't have any control over is POSTing data to my PHP script. The form contains checkboxes along these lines:
<input type="checkbox" value="val1" name="option"/>
<input type="checkbox" value="val2" name="option"/>
If I were to write the code for the form, I'd write name="option[]" instead of name="option". But this is not a change I can do. Now, if both checkboxes are checked, $_POST["option"] returns just one of the values. How can I, in PHP retrieve all the values selected?

You can read the raw post data. For example:
<fieldset>
<legend>Data</legend>
<?php
$data = file_get_contents("php://input");
echo $data."<br />";
?>
</fieldset>
<fieldset>
<legend>Form</legend>
<form method="post" action="formtest.php">
<input type="checkbox" value="val1" name="option"/><br />
<input type="checkbox" value="val2" name="option"/><br />
<input type="submit" />
</form>
</fieldset>
Check both boxes and the output will be:
option=val1&option=val2
Here's a live demo. All you have to do then is to parse the string yourself, into a suitable format. Here's an example of a function that does something like that:
function parse($data)
{
$pairs = explode("&", $data);
// process all key/value pairs and count which keys
// appear multiple times
$keys = array();
foreach ($pairs as $pair) {
list($k,$v) = explode("=", $pair);
if (array_key_exists($k, $keys)) {
$keys[$k]++;
} else {
$keys[$k] = 1;
}
}
$output = array();
foreach ($pairs as $pair) {
list($k,$v) = explode("=", $pair);
// if there are more than a single value for this
// key we initialize a subarray and add all the values
if ($keys[$k] > 1) {
if (!array_key_exists($k, $output)) {
$output[$k] = array($v);
} else {
$output[$k][] = $v;
}
}
// otherwise we just add them directly to the array
else {
$output[$k] = $v;
}
}
return $output;
}
$data = "foo=bar&option=val1&option=val2";
print_r(parse($data));
Outputs:
Array
(
[foo] => bar
[option] => Array
(
[0] => val1
[1] => val2
)
)
There might be a few cases where this function doesn't work as expected though, so be careful.

Related

Foreach - How to print a only the third and 4th value

I have form with the option to add more fields.
I'd like to know if i could print the individual values of a foreach loop.
eg. if the person added to forms and i want to print the second value how would i do that ?
So Far what i have tried only printed the first Character.
HTML
<form action="careerHistoryCon.php" method="post" enctype="multipart/form-data">
<label for="industry[]">Industry Segmentation</label>
<input type="text" name="industry[]" id="" placeholder="Finance / Insurance ...."><br>
<p>To add another feild Click here </p> <br><br>
</form>
JQ
$("#addMore").click(function(){
$(".form-group:last").clone().appendTo(".wrapper");
});
PHP - Problem here
if ($_SERVER["REQUEST_METHOD"] == "POST") {
if (isset($_POST['submit'])){
$industry= $_POST['industry'];
foreach ($industry as $key => $value) {
echo $value[0]. '<BR>';
echo $value[1]. '<BR>';
}
}
You are pretty near to the solution. Using foreach on an array gives you the index as key.
foreach ($industry as $key => $value) {
if($key == 1) echo $value; // array starts with 0, so 1 is the second element.
}
or you can use an iterator
// using foreach
$i = 0;
foreach ($industry as $key => $value) {
if($i == 1) echo $value;
$i++;
}
//using for
for($i = 0; $i < count($industry); $i++) {
if($i == 1) echo $industry[$i];
}
btw. since $value is the input string of the user, $value[0] would just be the first letter the user entered. Because a string is just an array of chars.

How to pass multiple urls from text fields into array

I am trying to enter multiple urls from text field as input, into array to extract some data.
Here's my code
<form method="post">
<textarea name="urls[]" cols="150" rows="15" value=""></textarea>
<input type="submit" value="Get URLs" />
</form>
if (isset($_POST['urls']) && !empty($_POST['urls'])) {
// fetch data from specified url
foreach($_POST['urls'] as $key => $value){
$data = array($value);
$r = multiRequest($data);
}
}
foreach ($r as $key => $url){
$res = preg_match_all( "/[a-z0-9]+[_a-z0-9\.-]*[a-z0-9]+#[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})/i",
$url, $matches);
if($res) {
foreach(array_unique($matches[0]) as $email) {
echo $email . "<br />";
}
} else {
echo "No data found.";
}
unset($value);
Now if I enter single url,www.example1.com, if fetches the data (email). But if I enter more than one url in the form, it doesn't works (No data found).
If I define url in array manually
$data = array('www.example1.com', 'www.example2.com', 'www.example3.com');
I can extract the data (email).
How to do it for multiple entries?
If you delimit your urls by a line return, we can split and process them:
<form method="post">
<textarea name="urls" cols="150" rows="15" value=""></textarea>
<input type="submit" />
Omit the square brackets on the input name if we have one textarea. (Alternatively use many text inputs with the name attribute urls[], to get your input into an array.)
<?php
$urls = $_POST['urls'] ?? '';
$urls = preg_split('#\R#', $urls);
$emails = [];
foreach ($urls as $url)
{
$pattern = '/[a-z0-9]+[_a-z0-9\.-]*[a-z0-9]+#[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})/i';
if (preg_match_all($pattern, $url, $matches))
{
foreach(array_unique($matches[0]) as $email) {
$emails[] = $email;
}
}
}
if(empty($emails)) {
echo 'No emails found.';
} else {
print implode('<br>', $emails);
}
The input:
http://example.com
mailto://foo#example.com
Will output:
foo#example.com
You're passing one value in $data array by this syntax $data = array($value);.
Replace $data = array($value);
with
$data = array();
$data[] = $value;
This will append each new value to the &data array.
Example
Also, you have one textarea, it means that the value(text input) of it comes into name=urls[] as a first value of array urls[]. In PHP you'll get one value.
If you want to separate inputted data you need to split it. For example, if you will write inputs comma separated, then you'll need to make explode(",",$_POST["urls"];) at least. By the way, change name="urls[]" to simply name="urls".
Use this code for retrieving inputs comma separated:
<form method="post">
<textarea name="urls" cols="150" rows="15" value=""></textarea>
<input type="submit" value="Get URLs" />
</form>
if (isset($_POST['urls']) && !empty($_POST['urls'])) {
// fetch data from specified url
$inputs = explode(",",$_POST["urls"]);
$data = array();
foreach($inputs as $key => $value){
$data[] = $value;
}
$r = multiRequest($data);
}
As I understood your multiRequest() function should process your $data array, put this line outside the foreach loop. If you won't you will process $data array each loop.
Note: inputs should be comma separated in this case(in textarea).

How not to echo a value if already in the input value?

I have some values in a custom field:
save_post = "1200"
Or it could be, since I need a list eventually:
save_post = "1200, 1460, 1334"
Now when I load the page, I get these values and I set them in an input field, and I also add the current value id from the current page:
$allPosts = $userPosts.", ".$postid;
Where $userPostsis the single value or the value list from the custom field, and $postid is the current page id I want to add.
The result is:
<input type="text" value="1200, 23138, 23138, 23138">
I would always get duplicate values each time I hit the update submit button as the page refreshes itself:
<form id="saveId" action="" method="POST" class="" autocomplete="off">
<input type="text" name="save_post_value" value="<?php echo $userPosts.", ".$postid; ?>">
<button type="submit" class="save_post btn btn-danger">Update</button>
</form>
How can I check if a value is already in the input and if so, don't echo it?
A way would be to have them in an Array and then output in the input field the unique array, not sure if there is a shorter way.
Trying:
$allPosts = array($userPosts.", ".$postid);
$allPosts = array_unique($allPosts);
<input type="text" name="save_post_value" value="<?php foreach ($allPosts as $value) { echo $value; } ?>">
Also:
$allPosts = array($userPosts.", ".$postid);
$allPosts = array_unique($allPosts);
$allPosts = explode(", ", $allPosts);
<input type="text" name="save_post_value" value="<?php echo $allPosts; ?>"
And tried with implode() too:
$allPosts = array($userPosts.", ".$postid);
$allPosts = array_unique($allPosts);
$allPosts = implode(", ", $allPosts);
<input type="text" name="save_post_value" value="<?php echo $allPosts; ?>"
This is very basic example, but I think that this can be useful for your needs:
<?php
// Input data
$userPosts = '19000, 23138, 23138';
$postid = '23138';
// With array
$userPosts = str_replace(' ', '', $userPosts);
if (empty($userPosts)) {
$a = array();
} else {
$a = explode(',', $userPosts);
}
$a = array_unique($a, SORT_STRING);
if (in_array($postid, $a) === false) {
$a[] = $postid;
}
$userPosts = implode(', ', $a);
echo 'Result using array: '.$userPosts.'</br>';
?>
UPDATE:
It is possible to use a function. Check for empty posts is made using empty().
<?php
function getUniquePosts($xposts, $xid) {
$xposts = str_replace(' ', '', $xposts);
if (empty($xposts)) {
$a = array();
} else {
$a = explode(',', $xposts);
}
$a = array_unique($a, SORT_STRING);
if (in_array($xid, $a) === false) {
$a[] = $xid;
}
$xposts = implode(', ', $a);
$xposts = ltrim($xposts, ",");
return $xposts;
}
$userPosts = '19000, 23138, 23138';
$postId = '23138';
echo getUniquePosts($userPosts, $postId).'</br>';
?>
Then when loading form you can try with this:
...
$a = array_unique($a, SORT_STRING);
...
update_user_meta($user_id, 'save_post', getUniquePosts($a, $user_id));
Here is my code on checking duplicate values after submission:
$userPosts = '19000, 23138, 23138';
$postid = '23138';
$pattern = "/(?:^|\W)".$postid."(?:$|\W)/";
if(preg_match($pattern, $userPosts, $matches))
{
print 'There is a duplicate '.rtrim($matches[0] , ",");
}
Basically I reuse Zhorov's variables but on his approach he put it in an array, and then check if that array contains the submitted value, mine is almost the same as his approach but instead of putting it in an array; I use regex to determine is the value existed in the string.

Get POST variable using wildcard or regex

How to get POST variable using regex like this:
$var = $_POST['foo?'];
or
$var = $_POST['foo\w{1}'];
Edit:
My form has many buttons with separate names: file1, file2, file3. When pressing a button, of course it pass file1 or file2, ... I want to get the value using that name.
The easiest thing I can think of is this:
$allPostKeys = implode(',',array_keys($_POST));
$wildcardVals = array();
if (preg_match_all('/,?(foo[0-9]),?/',$allPostKeys,$matches))
{
$wildCardKeys = $matches[1];
while($key = array_shift($wildCardKeys))
{
$wildcardVals[$key] = $_POST[$key];
}
}
if (!empty($wildcardVals))
{//do stuff with all $_POST vals that you needed
}
Replace [0-9] in the regex with . to match any char, or whatever you need to see matched.
Tested this out with an array that had the following keys bar,zar,foo1,foo2,foo3, and it returned array('foo1' => 'val1','foo2' => 'val2','foo3' => 'val3'), which is what you need, I think.
In response to your edit
The $_POST super-global can be a multi dimensional array, too:
<input type="file" name="file[]" id="file1"/>
<input type="file" name="file[]" id="file2"/>
<input type="file" name="file[]" id="file3"/>
That way, you can easily loop through the files:
foreach($_POST['file'] as $file)
{
//process each file individually: $file is the value
}
run in a loop through the array, and check on the keys
like:
// some POST: array('a' => 1, 'b' => 2, 'cc11' => 6666666)
foreach( $_POST as $k => $v ) {
if ( preg_match('#^[^\d]+$#', $k) ) { // not number key
// you actions ...
}
}
You'd have to loop through the $_POST array:
$regex = "#foo\w{1}#";
$vars = array();
foreach($_POST as $name=>$value) {
if(preg_match($regex, $name)) {
$vars[$name] = $value;
}
}
Hope this helps.
In your case, you could do this:
<?php
$_POST = array(
"foo" => "bar",
"file1" => "something",
"file2" => "somethingelse",
"file3" => "anothervalue",
"whocares" => "aboutthis"
);
$files = array();
foreach ($_POST as $key => $value) {
if (preg_match("/file(\d+)/", $key, $match)) {
$files[$match[1]] = $value;
}
}
print_r($files);
?>
Output (where the key matches file[NUMBER]):
Array (
[1] => something
[2] => somethingelse
[3] => anothervalue
)
Name your form fields as array data structures:
<input name="files[]" ...>
foreach ($_POST['files'] as $file) {
...
}

PHP how to loop through a post array

I need to loop through a post array and sumbit it.
#stuff 1
<input type="text" id="stuff" name="stuff[]" />
<input type="text" id="more_stuff" name="more_stuff[]" />
#stuff 2
<input type="text" id="stuff" name="stuff[]" />
<input type="text" id="more_stuff" name="more_stuff[]" />
But I don't know where to start.
This is how you would do it:
foreach( $_POST as $stuff ) {
if( is_array( $stuff ) ) {
foreach( $stuff as $thing ) {
echo $thing;
}
} else {
echo $stuff;
}
}
This looks after both variables and arrays passed in $_POST.
Likely, you'll also need the values of each form element, such as the value selected from a dropdown or checkbox.
foreach( $_POST as $stuff => $val ) {
if( is_array( $stuff ) ) {
foreach( $stuff as $thing) {
echo $thing;
}
} else {
echo $stuff;
echo $val;
}
}
for ($i = 0; $i < count($_POST['NAME']); $i++)
{
echo $_POST['NAME'][$i];
}
Or
foreach ($_POST['NAME'] as $value)
{
echo $value;
}
Replace NAME with element name eg stuff or more_stuff
I have adapted the accepted answer and converted it into a function that can do nth arrays and to include the keys of the array.
function LoopThrough($array) {
foreach($array as $key => $val) {
if (is_array($key))
LoopThrough($key);
else
echo "{$key} - {$val} <br>";
}
}
LoopThrough($_POST);
Hope it helps someone.
You can use array_walk_recursive and anonymous function, eg:
$sweet = array('a' => 'apple', 'b' => 'banana');
$fruits = array('sweet' => $sweet, 'sour' => 'lemon');
array_walk_recursive($fruits,function ($item, $key){
echo "$key holds $item <br/>\n";
});
follows this answer version:
array_walk_recursive($_POST,function ($item, $key){
echo "$key holds $item <br/>\n";
});
For some reason I lost my index names using the posted answers. Therefore I had to loop them like this:
foreach($_POST as $i => $stuff) {
var_dump($i);
var_dump($stuff);
echo "<br>";
}

Categories