Asked  9 Months ago    Answers:  5   Viewed   60 times

I want to create a file tree, and for this purpose I need to convert an array of files and directories to a multidimensional file tree array. For example:

array
(
   'file.txt',
   'dir1/',
   'dir1/dir2/',
   'dir1/dir2/dir3/',
   'dir1/file.txt',
)

to

array
(
   'file.txt',
   'dir1' => 
   array
   (
       'dir2' => 
       array
       (
           'dir3' =>
           array(),
       ),
       'file.txt',
    )
)

I've tried several functions to accomplish this, but non of them worked. The problem I've encountered for example that there is no easy way to convert an array ('test','test','test'),'test' to $array['test']['test']['test'] = 'test'.

 Answers

26

Here's a shorter recursive one:

function dir_tree($dir) {    
    $files = array_map('basename', glob("$dir/*"));
    foreach($files as $file) {
        if(is_dir("$dir/$file")) {
            $return[$file] = dir_tree("$dir/$file");
        } else {
            $return[] = $file;
        }
    }
    return $return;
}
Wednesday, March 31, 2021
 
phpmeh
answered 9 Months ago
42
function set_val(array &$arr, $path,$val)
{
   $loc = &$arr;
   foreach(explode('.', $path) as $step)
   {
     $loc = &$loc[$step];
   }
   return $loc = $val;
}
Wednesday, March 31, 2021
 
laurent
answered 9 Months ago
39

When you set cell values individually, you have the option of setting the datatype explicitly, but when you use the fromArray() method, you don't have this option.

However, by default, PHP uses a default value binder to identify datatypes from the values passed, and set the cell datatype accordingly. This default behaviour is defined in a class /PHPExcel/Cell/DefaultValueBinder.php.

So you can create your own value binder, as described in the PHPExcel Documentation, that would set every value as a string datatype.

Something like:

class PHPExcel_Cell_MyColumnValueBinder extends PHPExcel_Cell_DefaultValueBinder implements PHPExcel_Cell_IValueBinder
{
    protected $stringColumns = [];

    public function __construct(array $stringColumnList = []) {
        // Accept a list of columns that will always be set as strings
        $this->stringColumns = $stringColumnList;
    }

    public function bindValue(PHPExcel_Cell $cell, $value = null)
    {
        // If the cell is one of our columns to set as a string...
        if (in_array($cell->getColumn(), $this->stringColumns)) {
            // ... then we cast it to a string and explicitly set it as a string
            $cell->setValueExplicit((string) $value, PHPExcel_Cell_DataType::TYPE_STRING);
            return true;
        }
        // Otherwise, use the default behaviour
        return parent::bindValue($cell, $value);
    }
}

// Instantiate our custom binder, with a list of columns, and tell PHPExcel to use it
PHPExcel_Cell::setValueBinder(new PHPExcel_Cell_MyColumnValueBinder(['A', 'B', 'C', 'E', 'F']));

$objPHPExcel = new PHPExcel();
$objPHPExcel->getActiveSheet()->fromArray($dataArray,null,"A2");
Friday, May 28, 2021
 
Wilk
answered 7 Months ago
62

alternatively, if I assume that's $field_array contains sequentially key fields from root to sub key, you can loop your $field_array within $data_array loop

function summarize($data_array, $fields_array, $process_array){
    $return_array = array();
    foreach ($data_array as $row){
        $temp = array();
        foreach($fields_array as $key=>$field){
            $temp = $key==0?$row[$field]:$temp[$field];
        }
        if(!empty($temp)) $return_array[] = $temp;
    }
    return $return_array;
}

and this is my array, will summarize with these function

$array = array(
    array("multi"=>array("dimensional"=>array("array"=>"foo1"))),
    array("multi"=>array("dimensional"=>array("array"=>"foo2"))),
    array("multi"=>array("dimensional"=>array("array"=>"foo3"))),
    array("multi"=>array("dimensional"=>array("array"=>"foo4"))),
    array("multi"=>array("dimensional"=>array("array"=>"foo5"))),
    array("multi"=>array("dimensional"=>array("array"=>"foo6"))),
    array("multi"=>array("dimensional"=>array("array"=>"foo7"))),
    array("multi"=>array("dimensional"=>array("array"=>"foo8"))),
    array("multi"=>array("dimensional"=>array("array"=>"foo9")))
);
print_r(summarize($array,array("multi","dimensional","array"),NULL));

Ouput

Array ( [0] => foo1 [1] => foo2 [2] => foo3 [3] => foo4 [4] => foo5 [5] => foo6 [6] => foo7 [7] => foo8 [8] => foo9 ) 
Saturday, May 29, 2021
 
AlterPHP
answered 7 Months ago
98

Just add them dynamically by iterating over the number of ids:

$meta_box = array
(
    'id' => 'my-meta-box',
    'title' => 'Custom Input Fields',
    'page' => 'page',
    'context' => 'normal',
    'priority' => 'high',
    'fields' => array ()
);


$dynamicNumber = 2;
$idPrefix = 'textarea';
assert('$dynamicNumber > 0');
$dynamicIds = range(1, $dynamicNumber);

$fields = &$meta_box['fields'];
foreach($dynamicIds as $id)
{
    $fields[] = array( //this array must be created dynamic 
                      'name' => 'Textarea',
                      'desc' => 'Enter big text here',
                      'id' => sprintf('%s%d', $idPrefix, $id), //id is textarea + number
                      'type' => 'textarea',
                      'std' => 'Default value'
                  );
}
unset($fields);

Demo

Friday, September 3, 2021
 
shahalpk
answered 3 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :
 
Share