In an array that is chunked into blocks of 11 values, I need to know if a particular one has a TRUE value. If only one is TRUE, that's all I need and the foreach can stop after it sets a value. All I could think of to do was to make it set a SESSION value to TRUE if a match but that does not stop the loop from continuing and then I had the issue of the SESSION giving false results unless it was then unset which I did after the value was set. Seems rather an indirect way to do it so any suggestions?
$FormValues = array_chunk($Fields, $NoValues); // Group together the field values
// Check if form uses multiple selection fields and add appropriate form tags
foreach ($FormValues as $multi) :
if (isset($multi[9]) === TRUE) $_SESSION['useMulti'] = TRUE;
endforeach;
$enableMulti = (isset($_SESSION['useMulti'])) ? " enctype=\"multipart/form-data\"" : "";
unset($_SESSION['useMulti']);
Here is an example of an array and, in this case, none should return TRUE:
$Fields = array("First Name","Title",$Title,1,0,30,"","","","","",
"Quote","Quote",$Quote,4,0,30,"","",$quoteSQL,FALSE,$siteDB,
"Location","Location",$Location,1,0,30,"","","","","",
"Date","EventDate",$EventDate,41,0,15,"",TRUE,"","","",
"Time","Time",$Time,39,0,0,"","",$sqlTime,"","",
);
You can simply iterate over the original array in strides of 11, rather than using array_chunk.
To make the loop stop iterating once you've found what you want, use break.
You don't need a session variable for this, they're only for preserving values between different PHP scripts. You don't really even need another variable, you can just set the enableMulti variable in the loop.
$enableMulti = "";
for ($i = 9; i < count($Fields); $i += $NoValues) {
if ($Fields[$i] === true) {
$enableMulti = " enctype=\"multipart/form-data\"";
break;
}
}
If you really want to use foreach you do need to use array_chunk, and you can also use array_column.
$enableMulti = "";
$chunks = array_chunk($Fields, $NoValues);
foreach (array_column($chunks, 9) as $value) {
if ($value === true) {
$enableMulti = " enctype=\"multipart/form-data\"";
break;
}
}
You can also get rid of the loop entirely:
if array_search(TRUE, array_column($chunks, 9)) {
$enableMulti = " enctype=\"multipart/form-data\"";
} else {
$enableMulti = "";
}
Related
i'm sorry if my english not good.
I have a problem in my code. how I can stop access when in my array have duplicate. I mean, when one or more data in array have duplicate, user must repeat input from first page. and when array have not duplicate, user can access next page.
this is my code I have try.
$no_id=array('100100','100200','100300','100200','100200','100100');
$array = array();
foreach ($no_id as $key => $value)
{
if(isset($array[$value]))
{
$array[$value] += 1;
} else
{
$array[$value] = 1;
}
}
foreach ($array as $alert => $n)
{
if($n >= 2)
{
header('location:../../home');
} else
{
header('location:../../questionnair');
}
}
but when found the duplicate data (in array 100100 have two data and 100200 three data), the system still bring user to access questionnair page, not home.
thanks for helping.
I think the main problem is that you should always use exit() after using header() with location, otherwise the page will continue to execute.
This would still cause a problem though if the first value was a unique value as the first loop would always exit;.
You could fix this (only ever call header() if the value is > 2, then the default of all are unique is after the loop), but an alternative is to use array_count_values() which counts how many each value exists in the list and then use max() to find the most occurring one, then test against that...
$no_id=array('100100','100200','100300','100200','100200','100100');
$n = max(array_count_values($no_id));
if($n >= 2)
{
header('location:../../home');
exit;
} else
{
header('location:../../questionnair');
exit;
}
Update:
An alternative and slightly quicker version would be to use your original first loop, but as soon as it detects the value is already set, then it can stop working and just return then...
$no_id=array('100100','100200','100300','100200','100200','100100');
$array = array();
foreach ($no_id as $key => $value)
{
if(isset($array[$value]))
{
header('location:../../home');
exit;
} else
{
$array[$value] = 1;
}
}
header('location:../../questionnair');
exit;
If you just need to check if the array does have dupliate, you can use array_unique and compare the new array with the old array. If the arrays are not the same, it means there are duplicates.
With code:
$no_id = array('100100','100200','100300','100200','100200','100100');
$new_array = array_unique($no_id);
if (count($no_id) == count($new_array)) {
// 2 arrays have same number of items => they are equal => no duplicates
$redirect = "questionnair.php";
} else {
// 2 arrays have different number of items => they are not equal => duplicates
$redirect = "home.php";
}
header("location: {$redirect}");
NOTE
You have to redirect to an another PHP page (ex. home.php and not just home).
First of all, it's simplier to use array_unique function, which will remove all duplicated values.
After that you can make checks, if nothing was changed, then there is no duplicated items.
Like this:
$no_id=array('100100','100200','100300','100200','100200','100100');
$no_id_unique = array_unique($no_id);
if(count($no_id)===count($no_id_unique)){
header('location:../../questionnair');
}else{
header('location:../../home');
}
exit();
Next thing that you using ../ in path which means go to parent directory.
I don't know your environment, but must likely it's a bad idea.
According to documentation it's better to specify full url of page where user must be forwarded:
header("Location: http://www.example.com/home/");
Also, please be aware, that you need to prevent all others output from a script, especcially before the header() call. Read more here.
you can use foreach (array_unique($no_id) as $key => $value)
You can use array_count_values for this, not tested, but could be like:
$counts = array_count_values($no_id);
$duplicate = false;
foreach ($no_id as $value) {
if ($counts[$value] > 1) {
$duplicate = true;
break; // found a duplicate, no need to check further.
}
}
if ($duplicate === true) {
header('location:../../home');
} else {
header('location:../../questionnair');
}
Using array_flip()
$no_id = array('100100','100200','100300','100200','100200','100100');
$no_id_unique = array_flip($no_id);
if(count($no_id) === count($no_id_unique)){
header('location:../../questionnair');
}else{
header('location:../../home');
}
exit();
I am working on Do While loop in my project its working fine first time.
Before while statement, I assigned a value to an array I could able to print the array successfully at bottom of the code, BUT its become 0 when I check at top of the loop.
Code:
$looparray = array();
$loopend = 0;
$arraymer = array();
$poolafirtsid = $previous_array_values; //previous array values
do {
if (sizeof($looparray) == 0) {
$firstsponarray = $poolafirtsid;
} else {
$firstsponarray = $looparray;
}
$firstsponarray = getUserArray($poolafirtsid);
//get user arraylist of first
foreach ($firstsponarray as $avalue) {
$rooparray = membercount($avalue);
$bsponarray = getUserArray($avalue);
//get second users arraylist 9
if (sizeof($bsponarray > 0)) {
$barraymer = array_merge($barraymer, $bsponarray);
}
$aarraylist[$avalue] = $rooparray;
}
$asmallestsponid = getSmallestID($aarraylist);
//get smallest id in the array
if (membercount($asmallestsponid) < 3) {
$loopend = 1;
} else {
global $pooldata;
if (count($barraymer) > 0) {
$pooldata = $barraymer;
}
print_r($pooldata);
}
} while ($loopend == 1);
When I print in else its working but I am unable to print starting of do loop its showing array size is 0
I will ignore all the name issues but address your while loop issue:
$loopend =0;
do {
...
if(membercount($asmallestsponid)<3) {
$loopend = 1;
}else{
...
}
while ($loopend == 1);
There are 2 options:
The if condition is true: if so, $loopend will get 1 so the loop continue (which not seem fit the call him "loop end" but what ever...)
The if condition is false: then the $loopend stay the same (init as 0) so the loop will stops
IMHO - this will simplify your loop:
do {
...
while (membercount($asmallestsponid)<3);
We don't know what membercount($asmallestsponid) returns, but it appears (most likely) that on the 1st pass it gets into
} else {
$looparray = $arraymer;
//print_r($looparray);
}
the value of $loopend doesn't change, i.e. remains at 0 and on the first pass it compares 0 to 1 and decides to exit the do {} while loop as 0 != 1
There are several problems with your code. First of all, this does nothing:
if (sizeof($looparray)==0) {
$firstsponarray= $poolafirtsid;
} else {
$firstsponarray= $looparray;
}
since the very next line after that piece of code is:
$firstsponarray= getUserArray($poolafirtsid);
which overrides any prior assignment of $firstsponarray.
Second, the value of $looparray doesn't change at all in the do loop, so it'll always be an empty array. I found this line:
$rooparray=membercount($avalue);
which I assume is a typo and the correct line is $looparray=membercount($avalue);. Same with the line $aarraylist[$avalue]=$rooparray;. However, changing that also does nothing since $firstponarray will never be equal to $looparray for the reason I described at the top.
Try debugging your code first, and if the problem persists post the updated code.
I have a very long list of strings called $stringfilter1 $stringfilter2 etc all the way up to $stringfilter50
I have another string $reporteremail and I want to make a conditional statement whereby if any of the $stringfilter strings is present in the $reporteremail, some code is executed. At the moment my code looks like this and it works:
if (stripos($reporteremail, $stringfilter1) !== false || stripos($reporteremail, $stringfilter2) !== false || stripos($reporteremail, $stringfilter3) !== false [...]) {
runcode();
}
This is very very long though. I have cut it short here.
I was wondering if there's a cleaner, more efficient way to do this?
EDIT:
I am writing a plugin for a bug tracker. The strings are entered on another page in text boxes. I access them on this page by running a function that looks like
$t_filter = plugin_config_get( 'filter1' );
$stringfilter1 = string_attribute( $t_filter1 );
I would agree looping through an array would be the best way to do this. How can I push each new string onto the end of an array without having to write that snippet above out 50 times?
How can I push each new string onto the end of an array without having to write that snippet above out 50 times?
Try this:
$needles = [];
for ($i = 0; $i < 50; $i++) {
$t_filter = plugin_config_get("filter$i");
$needles[] = string_attribute($t_filter);
}
I have a very long list of strings called $stringfilter1 $stringfilter2 etc all the way up to $stringfilter50
[...]
This is very very long though. I have cut it short here.
I was wondering if there's a cleaner, more efficient way to do this?
Try this, it should go after the code block above.
$flag = false;
foreach ($needles as $needle) {
if (stripos($reporteremail, $needle) !== false) {
$flag = true;
break;
}
}
if ($flag) {
runcode();
}
The code above works by iterating through the $needles array and sets a flag if stripos doesn't return false. After it's finished iterating, it checks if the flag is true, if so, this means that one of the needles was found in the array.
EDIT
Alternatively, you could do it all in one loop, which is both faster and more efficient.
$flag = false;
for ($i = 0; $i < 50; $i++) {
$t_filter = plugin_config_get("filter$i");
$needle = string_attribute($t_filter);
if (stripos($reporteremail, $needle) !== false) {
// One of the needles was found in $reporteremail.
runcode();
break;
}
}
You don't need a loop. First put all your filters in an array instead of having them in separate variables. I would try to do this by modifying the input source rather than doing it in your PHP script. (Based on your comments I'm not sure if that's possible or not, so maybe you do need a loop like the one in the other answer.) Then you can use str_ireplace to check for your filter strings in the $reporteremail. (This will not modify $reporteremail.)
str_ireplace($filters, '', $reporteremail, $count);
if ($count) {
// run code
}
The $count parameter will contain a count of how many replacements were performed. If it's nonzero, then at least one of the filters was found in $reporteremail.
Im am so lost. Can anyone explain how i can shorten this code. I have hundreds of these! I submit a form with input value. Whenever i dont fill in a value, i get an error. So i made these isset blocks to prevent returning the error. But i seem so unefficient! Please help...thanks
if(isset($_POST['input74'])){
$value74 = $_POST['input74'];
}else{
$value74 = "";#default value
}
if(isset($_POST['input75'])){
$value75 = $_POST['input75'];
}else{
$value75 = "";#default value
}
if(isset($_POST['input76'])){
$value76 = $_POST['input76'];
}else{
$value76 = "";#default value
you could wrap the isset in a function like this
function myIsset(&$variable, $default = "")
{
if(isset($variable))
{
return $variable;
}
else
{
return $default;
}
}
then you just call it like $value74 = myIsset($_POST['input74']);
the second argument defaults to an empty string so if you want to set the default value you can supply it or change what the default is in the function header if they will just all be the same. bellow is a screen shot showing the code working
while yes you are still going to have one line per $_POST at least you exchnge 5 lines of code with 1 line of code and the function above. you can possibly reduce this to a loop like how i explain in this answer however without seeing the form and confirming any pattern i can't give any code examples for that since what you have shown could just be a coincidence
PHP 7 has a new operator to address this specific situation: the null coalesce operator (??) replaces this:
$foo = isset($foo) ? $foo : $bar
With this:
$foo = $foo ?? $bar;
PHP has support for arrays in forms. You can name your form fields with indexes, e.g. <input type="text" name="input[74]" ... />. Then in PHP, you can access those with a for or foreach loop, because they will be available as an array (i.e. you will have $_POST["input"][74]). You could thus write something like:
$values = $_POST["input"];
for ($i = 0; $i < MAX_INPUTS; $i++) {
if (!isset($values[$i])) {
$values[$i] = ""; // default value
}
}
If for some reason you can't change the HTML side, you could still use a loop to dynamically create the field names and copy the data to an array on the PHP side, something like:
$value = array();
for ($i = 0; $i < MAX_INPUTS; $i++) {
$name = sprintf("input%d", $i);
if (isset($_POST[$name])) {
$value[$i] = $_POST[$name];
} else {
$value[$i] = ""; // default
}
}
In both proposed solutions, you only have some lines of code instead of dozens of repetitions of almost the same lines. In both examples, I assumes that your fields start with input0 and that there is a total of MAX_INPUTS fields. If not all fields exist (e.g. you only have input1, intput2, input74 and input75), you can create an array with the fields numbers:
$field_list = array(1,2,74,75);
And then use that to check your data (here the example with arrays in HTML field names):
$values = $_POST["input"];
foreach ($field_list as $num) {
if (!isset($values[$num])) {
$values[$num] = ""; // default value
}
}
Use ternaries to shorten the code:
$value74 = isset($_POST['input74']) ? $_POST['input74'] : 'Default value';
$value75 = isset($_POST['input75']) ? $_POST['input75'] : 'Default value';
$value76 = isset($_POST['input76']) ? $_POST['input76'] : 'Default value';
Or you could loop through $_POST array as well, but some filtering/validation must be done. Quick idea:
if(!empty($_POST)) {
$i = 0;
$arr = array();
foreach($_POST as $input) {
$arr[$i] = $input;
$i++;
}
}
$arr would then produce an array like
Array
(
[74] => 'value74'
[75] => 'value75'
[76] => 'value76'
)
If I understand you correctly seeing that you want to set a variable to post or otherwise default value you can do it following the below structure:
$variable = isset($_POST['name']) ? $_POST['name] : "defaultvalue";
That will set the variable of it exists otherwise set the default value specified. I hope this helps.
You could use array_merge.
You would set up your default array with all the default input values provided.
$aryDefault = ['input74'=>'', 'input75'=>'',...]
Then array_merge this with your post array, and it will fill in all the missing values. NOTE: Order is important check out the docs.
If the input arrays have the same string keys, then the later value
for that key will overwrite the previous one. If, however, the arrays
contain numeric keys, the later value will not overwrite the original
value, but will be appended.
Use array_merge($aryDefault, $_POST) so that $_POST overwrites the defaults.
Also, you can use variable variables so you can do this in a loop. If all your variable are named after your array keys, like in your example.
Full Code:
$aryDefault = ['input74'=>'', 'input75'=>'',...];
$aryFinal = array_merge($aryDefaults, $_POST);
foreach( $aryFinal as $key=>$value){
$$key = $value;
}
You could even generate $aryDefault with a loop, if its super big.
$aryDefault = array();
for(i=0;i<=100;i++){
$aryDefault["input$i"] = "";
}
You can create a simple function to encapsulate the code before PHP 7:
function post($key, $default = null){
return isset ($_POST[$key])?$_POST[$key]:$default;
}
Since PHP 7 (using the null coalescing operator (??)):
function post($key, $default = null){
return $_POST[$key] ?? $default;
}
or better whithout function just simple (as mentioned above)
$value74 = $_POST['input74'] ?? ''; #default value
$value75 = $_POST['input75'] ?? ''; #default value
$value76 = $_POST['input76'] ?? ''; #default value
Currently I am checking if the $_FILES array is empty to unset like so:
if ($var === 'AP' && empty($_FILES['field_1']['name'])) {
unset($_FILES['field_1']);
}
if ($var === 'AP' && empty($_FILES['field_2']['name'])) {
unset($_FILES['field_2']);
}
if ($var === 'AP' && empty($_FILES['field_1']['name']) && empty($_FILES['field_2']['name'])) {
unset($_FILES['field_1']);
unset($_FILES['field_2']);
}
This is for image uploads, it works when there are a small amount of images that can be uploaded. Now I'm going to have 15 upload fields with them all being optional. Is there a better way to unset those arrays that are empty without doing conditionals like above for each and every possible combination?
Instead of unsetting the ones that are empty, why not set the ones that are set?
(This is good practice, since you may want to perform some validation action on the ones that are set)
$clean = array();
foreach($_FILE as $fileKey => $fileValue){
if($fileValue) {
$clean[$fileKey] = $fileValue;
}
// if you really want to unset it :
else{
unset($_FILE[$fileKey]);
}
}
for ($x = 0; $x < 15; $x++) {
if ($var === 'AP' && empty($_FILES[$x]['name'])) {
unset($_FILES[$x]);
}
}
Should do the trick. (Could use a check to make sure elements are set and some cleanup, but you get the idea)
It will actually be $_FILES['name'][0] not $_FILES[0]['name'] ,etc so just remove the empties:
$_FILES['name'] = array_filter($_FILES['name']);
Then just use $_FILES['name'] as the array to loop over and the keys will still be the same as the other arrays.
You can use array_filter to remove empty elements:
$emptyRemoved = array_filter($linksArray);
If you have (int) 0 in your array, you may use the following:
$emptyRemoved = remove_empty($linksArray);
function remove_empty($array) {
return array_filter($array, '_remove_empty_internal');
}
function _remove_empty_internal($value) {
return !empty($value) || $value === 0;
}
EDIT: Maybe your elements are not empty per say but contain one or more spaces... You can use the following before using array_filter
$trimmedArray = array_map('trim', $linksArray);