Finding a string by looping through an array php - php

I have this array $filelist
Array ( [0] => . [1] => .. [2] => .DS_Store [3] => 11-96.eml [4] => 11-97.eml )
Which is a list of all files in a particular directory... Sometimes there is no .DS_Store file, sometimes there is, sometimes there are 2 eml files, sometimes there are as many as 6. I'm trying to loop through and find the first array position a .eml file exists so that I can work out how many file are eml and where to start referencing the array.. I have tried...
function firstFileInList($filelist) {
$x = 0;
foreach ($filelist as $value) {
if(strpos($filelist, ".eml") == false) {
$x = $x + 1;
//break;
}
}
return $x;
}
This returns 5, if I include the break it returns 1 and I was expecting to get 4.
Please could somebody point me in the right direction or even if there is a completely better way to do this then I would be more than grateful to see that...
Thanks Paul,

break exists every PHP loop directly when it is called, even if there are other elements. Use continue to get to the next element.
Based on your question
I'm trying to loop through and find the first array position a .eml file exists
function firstFileInList($filelist) {
foreach($filelist as $k => $v)
if(strpos($v, ".eml") !== false)
return $k;
return false;
}

The best way to grab a key from an array in a foreach is to define the key before it starts. Try updating your code with this:
function firstFileInList($filelist) {
$x = false;
foreach ($filelist as $key => $value) {
if(strpos($value, ".eml") == false) {
$x = $key;
break;
}
}
return $x;
}
What this does is set $x to the actual key instead of a number that you increment like you would in a for() loop. $key will always be the array key, so in this example 0, 1, 2, 3, 4.

function firstFileInList($filelist) {
$key=false;
foreach ($filelist as $key=>$value) {
if(strpos($value, ".eml") !==false){
break;
}
}
return $key;
}
In case there is no match you get false.

The problem lies here:
foreach ($filelist as $value) {
if(strpos($filelist, ".eml") == false) {
Note that, for the foreach loop as you have written, it takes each element of the $filelist array, and puts it into the $value variable. Maybe you don't have warnings turned on in PHP, but when I tried your code, I got the following:
Warning: strpos() expects parameter 1 to be string, array given in test/a.php on line 6
What you want is
foreach ($filelist as $value) {
if(strpos($value, ".eml") == false) {
$x = $x + 1;
}
}
Note $value in the second line.

Related

Invalid argument supplied to foreach using php

$numofOfficer = sizeof($_POST['officer']); // = 2
for ($cntr = 0; 0 < $numOfficer; $cntr++)
{
foreach ($_POST['officer'][$cntr] as $index => $value)
{
// DO SOMETHING HERE...
}
}
Please help. I don't how to fix this warning.
The argument of foreach is an array having 2 length and 2 dimension. BUT, the other codes same with this went well, same length and length dimension of array argument. I just cant figure what is difference of the code above to the other.
There is no need to use for and foreach doing the same. You can omit the for and reduce you code to:
if (is_array($_POST['officer']))
{
foreach ($_POST['officer'] as $officer)
{
foreach ($officer as $index => $value)
{
// DO SOMETHING HERE...
}
}
}

Illegal string offset 'result' in php echo

function RetrieveAllPages() {
$dir = '../pages';
$root = scandir($dir);
$result = array();
foreach($root as $value){
if($value === '.' || $value === '..') {
continue;
}
if(is_file("$dir/$value")) {
$result[]="$dir/$value";
continue;
}
foreach(find_all_files("$dir/$value") as $value){
$result[]=array('filename' => $value,);
}
}
print_r ($result);
var_dump($result);
return $result;
}
<?php
//echo'<select>';
foreach (RetrieveAllPages() as $value){
//echo "<option value='".$value['rolename']."'>".$value['rolename']."</option>";
echo'<input type="checkbox" value='.$value['result'].' name='.$value['result'].'/>';
}
//echo'</select>';
?>
getting this kind of error in php the code is above i have research and cant find any source that fits solution..any suggestion or idea is appreaciated
UPDATE
function RetrieveAllPages() {
$result = array();
$dir = "../pages";
$dh = opendir($dir);
while (false !== ($filename = readdir($dh))) {
$files[] = $filename;
}
print_r ($result);
var_dump($result);
return $result;
}
result is Array ( ) array(0) { }
if you don't want to list files recursively you can use this.
function RetrieveAllPages() {
$dir = '../pages';
$root = scandir($dir);
$result = array();
foreach($root as $value){
if($value === '.' || $value === '..') {
continue;
}
if(is_file("$dir/$value")) {
$result[]="$dir/$value";
}
//Note: removed the recursive call
}
print_r ($result);
var_dump($result);
return $result;
}
//echo'<select>';
foreach (RetrieveAllPages() as $value){
//echo "<option value='".$value['rolename']."'>".$value['rolename']."</option>";
// Note $value contains the filename!!!
echo'<input type="checkbox" value='.$value.' name='.$value.'/>' ;
}
//echo'</select>';
Here is another method which is much shorter! uses array_filter and anonymous function.
$all_files = array_filter(scandir('../pages'),function($v){return(!($v === '.' || $v === '..'));});
foreach ($all_files as $value){
echo'<input type="checkbox" value='.$value.' name='.$value.'/>' . $value .'<br/>';
}
You are getting an Illegal offset error because of the way you have defined the function RetrieveAllPages(). From the code, it basically scans a root folder for files and directories. If it encounters a directory, it tries to find all the files in that directory and pushes them into the result array which you return.
If you notice the output when you print the result array it would look something like this (just an example):
Array ( [0] => foo.jpg [1] => bar.txt [2] => Array ( [filename] => Testfile.pdf ) )
Now that you have an idea of what your function returns, let's get back to the echo statement:
foreach (RetrieveAllPages() as $value){
//Here the $value could be either string of the form root/foo etc or
echo $value; //String of file directly found in root directory
//It would be of the form of an array where you would get file names by doing something like:
echo $value[0]['filename']; //from the nested array
}
In any case, you are not using the string offset result anywhere in the array that you create in RetrieveAllPages(). The only string offset you use is filename. That is probably why you get this error when you try to create checkboxes out of these values. The way you handle this two kinds of values in your returned array is completely upto you.
Sidenote - The way you save your values, it's pretty likely that your function will return a nested array. One workaround could be if you, come across a directory instead of a file just prefix the string to the file names found in that directory instead of creating nested arrays with the prefix filename. It would greatly simplify your echo statements where you create the HTML checkboxes.
Like I said, the implementation is upto you and depends on what you are trying to achieve ultimately. Hope it gets you started in the right direction.

Using nested foreach loop on same array

Is it ok to loop array again in nested loop and also change the array?
I've an URL's array with entries(as array key) of either an URL or domain:example.com
In case of this entry : domain:example.com I want to remove all URLS containing example.com as domain:
foreach (array_keys($urls1) as $line) {
if (preg_match('/domain:(.*)/i', $line, $matches)) {
$domain = $matches[1];
foreach (array_keys($urls1) as $line2) {
if ($url_domains[$line2] == $domain) {
unset($urls1[$line2]);
}
}
}
}
There is no problem looping over it a second time, however you will get yourself and your code into a big knot if you start removing items. My suggestion would be to save a copy and modify that.
This is not ideal, but I'm not sure what you wish to do.
//Make a copy of your array
$URLCopy = $urls1;
foreach (array_keys($urls1) as $line) {
if (preg_match('/domain:(.*)/i', $line, $matches)) {
$domain = $matches[1];
foreach (array_keys($urls1) as $line2) {
if ($url_domains[$line2] == $domain) {
unset($URLCopy[$line2]);
}
}
}
}
I ran into a similar problem and making a copy of the array was the answer. This was my problem:
If a particular text string existed towards the beginning of the file and (an array of approximately 80 members) matched a string towards the end of the file, I had to remove three lines towards the end. The problem that happened when I didn't use a copy is that the index would reset from 30, back to 9, and this caused me some issues.
This is what worked for me.
$rowCopy = $row
foreach($row as $index => &$line) {
////previous code
if ($line[0] === "NM1" && $line[1] === "77") {
//read through the $row array and find the NM*85 string
foreach ($rowCopy as $index2 => $lineT) {
if ($s = strpos($lineT, "NM1*85") !== false) {
$npiTest = explode("*", $lineT);
if (strcmp(preg_replace("/[^0-9,.]/", "", $npiTest[9]), $line[9]) === 0) {
// $line = false;
$index--;
unset($row[$index + 1]);
$index++;
unset($row[$index + 1]);
$index++;
unset($row[$index + 1]);
$erased = $erased + 3;
$index++
}
}
}
}
}

What's wrong with this array search function?

I have written the following function to search an multi-dimensional array by key, but if I call the function with key uri, it appends arrays having key 0 to the found array. What's wrong?
function search_arr($array, $key, &$found) {
foreach ($array as $k => $each) {
if ($k == $key) {
// output of "print $k = $key" is "0 = uri"
$found[] = $each;
}
if (is_array($each)) {
search_arr($each, $key, $found);
}
}
}
Use === to force a value and type match. You get zeros because comparing 0 and "uri" is true - think of them as both evaluating to 0. For complete details of how PHP handles these 'loose' comparisons, see this section of the manual.

Removing object from PHP array of arrays

I have a PHP array of associative arrays with the following format:
array(1) {
[0]=>
{ ["name"]=> "Steve Jobs"
["email"]=> "steve#gmail.com" }
}
I'm very new to PHP, but what I want to do is search for a specific email, and if found, delete that specific array (name & email pair) from the array (without leaving an empty space in the array where the removed object used to be).
I found this code here that searches for an entry but returns an array. How would I modify this to delete the found array?
function search($array, $key, $value)
{
$results = array();
if (is_array($array))
{
if (isset($array[$key]) && $array[$key] == $value)
$results[] = $array;
foreach ($array as $subarray)
$results = array_merge($results, search($subarray, $key, $value));
}
return $results;
}
Something like this?
function delete_user(&$arr, $name){
for($i = count($arr)-1; $i >= 0; $i--){
if($arr[$i]["name"] == $name){
unset($arr[$i]);
}
}
}
the &$arr tells PHP to pass the array by reference, so it can be modified from the function, otherwise, it'll be pass-by-value.
You have to use unset to remove an element and use in_array or array_search method to search an element from an array.
unset($array[0]);
Sample from PHP manual (array_search)
function array_key_index(&$arr, $key) {
$i = 0;
foreach(array_keys($arr) as $k) {
if($k == $key) return $i;
$i++;
}
}
I believe there's a small problem with raser's answer. I tried to comment on it, but I can't since I don't have 50 reputation.
Let me know if you agree: count($arr) returns the number of elements in the array. He's using a decremental for loop, except the array's index starts at 0 and his loop ends before it reaches 0, so the first element of the array is never searched. I believe the correct code would be something like:
function delete_user(&$arr, $name){
for($i = count($arr) - 1; $i >= 0; $i--){
if($arr[$i]["name"] == $name){
unset($arr[$i]);
}
}
}
Thanks!
just found array index, and
unset(array(key));
this will not showing that array

Categories