Illegal string offset 'result' in php echo - php

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.

Related

PHP method of function for remove child dirs on array

I create a function for remove child dirs on arrays structure. USer for error or mistake, has put on scenario, subdirs child of a parent dir already in config list.
/dir_a/subdir_a
/dir_b/subdir_a/subdir_a
/dir_b/subdir_a/subdir_b
/dir_b/
/dir_c/subdir_a/
...
Code
$local_pre_order = array_unique($local_sync);
asort($local_pre_order);
$local_order = array();
foreach ($local_pre_order as $value)
{
$repeat = false;
foreach ($local_pre_order as $value2)
{
$pos = strpos($value,$value2);
if (($pos !== false ) && ($value != $value2) && ($pos == 0)) {
$repeat = true;
break;
}
}
if (!$repeat) {
$local_order[] = $value;
}
}
Sort OK
/dir_a/subdir_a
/dir_b/
/dir_c/subdir_a/
I think it's a no good programing. Work but not fine. IMHO. Any ideas for best code?
Sorting is the way to go. Note that when sorted, all the child subdirs will be immediatelly after their parents. So it's just a matter of avoiding adding subdirs if the last added dir has a common prefix with it.
PHP isn't my first language, so please don't mind this non-idiomatic code.
$local_sync = [
"/dir_a/subdir_a",
"/dir_b/subdir_a/subdir_a",
"/dir_b/subdir_a/subdir_b",
"/dir_b/",
"/dir_c/subdir_a/"
];
$copy = $local_sync;
asort($copy);
$output = array();
foreach ($copy as $value)
if (strpos($value, end($output)) !== 0)
$output[] = $value;
print_r($output)
It's best not to rely on the array's structure, don't rely on the array being sorted or a comparison between the current path and the previous. What you want to do is use dirname () to get each path's directory name, and search the output array for each path, only adding the path to the output array if it's not already in the output array.
Like so...
$directory_paths = array (
'/dir_a/subdir_a',
'/dir_b/subdir_a/subdir_a',
'/dir_b/subdir_a/subdir_b',
'/dir_b/',
'/dir_c/subdir_a/'
);
$sorted_paths = $directory_paths;
asort ($sorted_paths);
$output = array ();
foreach ($sorted_paths as $key => $path) {
$directory = $path;
$levels = substr_count (trim ($path, '/'), '/') - 1;
for ($i = 0; $i < $levels; $i++) {
$directory = dirname ($directory);
}
if (in_array ($directory, $sorted_paths)) {
$output[$key] = $path;
}
}
ksort ($output);
$output = array_values ($output);
echo print_r ($output, true);

PHP - Get directory contents and info and output array

I'm working on the following but have become stumped as to how to get this to output.
I have the following which scans the directory contents, then gets the info and saves it as an array:
//SCAN THE DIRECTORY
$directories = scandir($dir);
$directinfo = array();
foreach($directories as $directory){
if ($directory === '.' or $directory === '..') continue;
if(!stat($dir.'/'.$directory)){
} else {
$filestat = stat($dir.'/'.$directory);
$directinfo[] = array(
'name' => $directory,
'modtime' => $filestat['mtime'],
'size' => $filestat['size']
);
}
}
When trying to output it however, I'm just getting single letters with a lot of breaks. Im obviously missing something here with the output loop.
foreach($directinfo as $dirInfo){
foreach($dirInfo as $drInfo){
for ($x=0; $x<=2; $x++) {
<span>"".$drInfo[$x]."<br/></span>";
}
}
}
Help is greatly appreciated. :)
You have already did everything just remove your for loop.
and try to do the following-
foreach($directinfo as $dirInfo){
foreach($dirInfo as $key=>$drInfo){
echo "<span>".$key."=>".$drInfo."<br/></span>";
}
}
I think your dealing with a 2d array, but treating it like a 3d array.
what does
foreach($directinfo as $dirInfo){
foreach($dirInfo as $drInfo){
var_dump($drInfo);
}
}
give you?
You're building a single array, dirInfo.
Php foreach takes the array first;
foreach($dirInfo as $info) {
echo "<span>" . $info['name'] . "</span>";
}
Try this function. It will return you list of all files with path.
// to list the directory structure with all sub folders and files
function getFilesList($dir)
{
$result = array();
$root = scandir($dir);
foreach($root as $value) {
if($value === '.' || $value === '..') {
continue;
}
if(is_file("$dir$value")) {
$result[] = "$dir$value";
continue;
}
if(is_dir("$dir$value")) {
$result[] = "$dir$value/";
}
foreach(getFilesList("$dir$value/") as $value)
{
$result[] = $value;
}
}
return $result;
}

list files in subfolders and put in array as key = value

I am sorry if this question is obvious for the ninjas, but I am quite a novice in PHP and I am struggling with it all day ..
I am trying to get a list of all files from a folder structure.
Currently it gives me something like
Array([0]->path/filename [1]->path/filename) Array([0]->path/filename [1]->path/filename..)
(one for each folder)
function o99_list_all_files_in_dir($dir) //need to ocheck for server compatibility (unix,linux,win)
{
$root = scandir($dir);
foreach($root as $value)
{
if($value === '.' || $value === '..') {continue;}
if(is_file("$dir/$value")) {$result[]="$dir/$value";continue;}
//if(is_file("$dir/$value")) {$result["$dir"]="$value";continue;}
foreach(k99_list_all_files_in_dir("$dir/$value") as $value)
{
$result[]=$value;
//$result["$dir"]=$value;
}
}
//print_r($result);
return $result;
}
Few questions :
1 - I need both the path and the filename pair so I thought to get an array like so :
results([path] -> [filename] [anotherpath] -> [anotherfilename]).
but if I try to construct another array (switch uncomment and comment lines) the function will give me only the 1st file in each dir.
2 - Later on , I am using this function in order to have both the path and filename seperated , So I tried this :
$result = o99_list_all_files_in_dir($upload_dir);
foreach ($result as $image) {
reset($image);
while (list($key, $val) = each($image)) {
// echo "$key => $val\n";
}
$filename = pathinfo($image);// I need the path here ...
...
... but obviously it is not working (otherwise I would not be here :-)
3 - Bonus question : How can I filter files from the results (like thumbs.db for example) or decide how to ignore or not certain extensions ??
EDIT I
4 - !important (forgot before) - what do I need to be careful about when dealing with unknows server paths (Linux, Win, Unix) ...will this function work on all ?
Try this code:
function scanFileNameRecursivly($path = '', &$name = array() )
{
$path = $path == ''? dirname(__FILE__) : $path;
$lists = #scandir($path);
if(!empty($lists))
{
foreach($lists as $f)
{
if(is_dir($path.DIRECTORY_SEPARATOR.$f) && $f != ".." && $f != ".")
{
scanFileNameRecursivly($path.DIRECTORY_SEPARATOR.$f, &$name);
}
else
{
$name[] = $path.DIRECTORY_SEPARATOR.$f;
}
}
}
return $name;
}
$path = "abs path to your directory";
$file_names = scanFileNameRecursivly($path);
echo "<pre>";
var_dump($file_names);
echo "</pre>";

Get all array keys that is not equal to X

I have several files uploaded with a form that is processed by a PHP script. There are several "categories" that I need to have handles separate ways. In other words, I need some of the files in the $_FILES array to be stored someplace, and some others stored in other places.
So what I need is all files (array keys) that are not $_FILES['filename_form'] to be stored / used separably.
The reason why I need this is because the amount of files being uploaded are dynamic, but always either $_FILES['filename_type1'] or $_FILES['filename_type2_*] where * is a number that increments when more files are input from the form (dynamically)
Might be a very simple solution, either I'm too tired or maybe I've been staring too much at the code, but all I know is I need a solution before tomorrow morning, so it's time sensitive =P
Appreciate all the help I can get.
Thank you!
$files = array();
$filenames = array();
foreach($_FILES as $name => $fileInfo)
{
if($name != 'filename_form')
{
$files[$name] = $fileInfo;
$filenames[] = $name;
}
}
How about:
foreach ( $_FILES as $key => $value )
if ( preg_match ( '/type2/', $key ) )
// do something with the type2
else if ( preg_match ( '/type1/', $key ) )
// do something with these
<?php
foreach ($_FILES as $key => $value) {
$a = explode('_', $key);
$defaultDir = 'myDefaultDirOrPathOrWhatever';
if ($a[1] == 'type2') {
$defaultDir = 'myOtherDirWhenMultipleFiles';
$incrementPassed = $a[2];
}
if (isset($incrementPassed)) unset($incrementPassed);
}
Here is an alternate way
$keys = array_keys($thearray);
$filteredArray = array_filter($keys, 'fiterKeys');
function filterKeys($item) {
if($item != 'valuetocheck') return true;
else return false;
}
$type1_files = array(); // Array of files of first type
$type2_files = array(); // Array of files of second type
$underfined_files = array(); // Array of files of unnormal type (who knows :-P)
foreach($_FILES as $name => $value){
if($name == 'type1'){
$type1_files[] = $value;
}
elseif($name == 'type2'){
$type2_files[] = $value;
}
else{
$undefined_files[] = $value;
}
}
After foreach you'll have your files devided into arrays, which you can process later as you wish
<?php
$files = array();
foreach ($_FILES as $filename => $fileinfo) {
if (strpos($filename, 'form') !== false) {
$files[$name] = $fileinfo;
unset($_FILES[$name]);
}
}
?>
Fastest method I can think of, should be faster then any of the previous answers.

how can recursion function return accumulative array(array_merge) (php)

function file_list($path){
$final_result=array();
if ($handle = opendir($path)) {
while (false !== ($file = readdir($handle))) {
if ($file != "." && $file != "..") {
if (is_dir($path."/".$file)) {
//echo $path."/".$file."\n";//directory
return file_list($path."/".$file);
} else {
//echo $path."/".$file."\n"; //all file
if(stripos($path."/".$file,"playlist.data"))
{
//echo $path."/".$file."\n"; //file contains "list.data"
$content = file_get_contents($path."/".$file);
preg_match_all("/([0-9]*).txt,0/",$content, $matches);
$result=array_unique($matches[1]);
$final_result=array_merge($final_result,$result);
$final_result=array_unique($final_result);
sort($final_result);
return($final_result);
}
}
}
}
}
}
print_r(file_list($argv[1]));
list.data file like this:
1.txt
3.txt
another list.data file like this:
2.txt
4.txt
so the result should be array like this:
Array(
[0]=>1
[1]=>2
[2]=>3
[3]=>4
)
I was aim to search the specified directory of the file system recursively,when I found file name called "list.data", I read this file and using regex to filter and array to $result. since I have more than one "list.data", I wannted to merge every $result to $final_result. but this script output nothing.
can anybody tell me does something wrong with file_list function.
i am execute this php script in CLI mode like this:
php.exe script.php "d:/test/listdir"
This is a paraphrased pseudo-code version showing the recursive merging logic:
function file_list($path) {
$result = array();
foreach ($path as $file) {
if (is_dir($file)) {
$result = array_merge($result, file_list($file));
} else {
$result[] = ...
}
}
return $result;
}
The function always returns an array, even if it's empty. Going through a directory, you add your results into the $result array. If you encounter a subdirectory, you let file_list go through it, merging the results into your current $result array (because file_list returns an array of results). Finally, after all entries in the directory have been handled, you return the list of results to the caller (which may be file_list itself).
If you feel like experimenting, look into the RecursiveDirectoryIterator, which would allow you to flatten the logic in your function, making it non-recursive.
Best way to do what you're trying to do: let PHP recurse for you.
$iter = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator(
$path, FilesystemIterator::CURRENT_AS_FILEINFO ) );
$out = array();
foreach( $iter as $file )
{
if( $file->getBasename() == 'list.data' )
{
$listdata = file_get_contents( $file->getPathname() );
// do something with list.data
$out = array_merge( $listDataOutput, $out );
}
}

Categories