I've been struggling quite a bit with this. I have a folder with a list of files and a basic naming order - abc-def-xyz.php
I'm trying to create an index page to list all of the files automatically in groups. So:
abc-def-xyz.php
abc-def-xzz.php
abb-def-xyz.php
Would show in the php index page as:
abc
def
xyz
xzz
abb
def
xyz
I can get to the point of exploding the file names and removing the extension, then i'm just lost. Any advice would be much appreciated. Thank you!
Array
(
[0] => Array (this is applyOnline-alert-warning.php)
(
[0] => applyOnline
[1] => alert
[2] => warning
)
[1] => Array
(
[0] => applyOnline
[1] => collectionOrDelivery
)
)
Using the methodology from this answer How to write getter/setter to access multi-level array by key names?:
$array = array();
foreach($files as $file) {
$temp = &$array;
foreach(explode('-', $file) as $key) {
$temp =& $temp[pathinfo($key, PATHINFO_FILENAME)];
}
$temp = $file;
}
Yields an array where the key names can be used:
Array
(
[abc] => Array
(
[def] => Array
(
[xyz] => abc-def-xyz.php
[xzz] => abc-def-xzz.php
)
)
[abb] => Array
(
[def] => Array
(
[xyz] => abb-def-xyz.php
)
)
)
Related
With this code
$files = scandir('audio');
$files = array_slice($files, 2);
$files = array_combine(range(1, count($files)), $files);
echo "<pre>";
print_r($files);
echo "</pre>";
I am able to scan a dir and list its files in an array like so..
Array
(
[1] => audio1.mp3
[2] => audio2.mp3
[3] => audio3.mp3
)
What I'd like to do is insert an increasing value number for each file it finds that I can later reference so the array becomes
Array
(
[1] => Array
(
[0] => 1
[1] => audio1.mp3
)
[2] => Array
(
[0] => 2
[1] => audio2.mp3
)
[3] => Array
(
[0] => 3
[1] => audio3.mp3
)
)
I haven't a clue where to start with this one so can't say what I've tried, any help appreciated.
PS: this is in a bid for me to solve the issue I'm having in this question Problem when using echo'd ++$value in javascript as part of a html5 audio player page because if these values are in the array I won't have to increase them with ++ on the echo side.
foreach($files as $key=>$f) {
$files[$key] = array($key, $f);
}
I would like to replace a value within the path array and I'm quite stuck for a while. So here is what I got.
My array:
// $myArr
Array
(
[0] => stdClass Object
(
[doc] => stdClass Object
(
[path] => Array
(
[0] => Bob
[1] => pictures
[2] => food
)
)
)
[1] => stdClass Object
(
[doc] => stdClass Object
(
[path] => Array
(
[0] => Alice
[1] => pictures
[2] => vacations
[3] => rome
)
)
)
)
PHP code:
for ($i=0; $i < count($myArr) ; $i++) {
$search = array($old_name); // pictures
$replace = array($new_name); // test
$result = str_replace($search, $replace, $myArr[$i]->doc->path);
}
Result:
It only changes one array and gives me a hint on my str_replace line. Both, $search and $replace are of type array and I know that I need to access elements in an array via array notation -> $item['price'] for example. That is not what is wrong here right?
Notice: Trying to get property of non-object in ...
Array
(
[0] => Bob
[1] => test
[2] => food
)
1) Do you see why he only modifies the last object so to speak?
2) Why is he giving me a Notice whereas I don't violate type conventions in my opinion?
Your code is working fine on my end, however..
I think the problem is in your $result variable. With every iteration, you are overwriting the last written value in the array.
You have to either use that $result variable directly, or replace $result by $myArr[$i]->doc->path. That way you can use the $myArr with the rewritten values.
I don't know what to do to get this done what would like to do. I tried multiple approaches, e.g. I used array_map, array_walk, nested foreach loops with get_object_vars and I worked with json_decode/encode and so on. I always come a little bit further but never reach my goal and I would like to get some guidance from you
Basically when you see the array below, how would you proceed when you want to change some value in the path array for multiple values in the array itself?
My questions:
1) Is it right that I must convert both nested objects to an array first or is this not nesessary to do this? I mean I always get some type conversion error which tells me that I either have everything as an object or array. Is this right?
2) If this mistery is solved, which php array function is the appropriate one to change values in an array(/object)? As I have written above, I tried so many and I don't see the trees in the woods anymore. Which one do you suggest to me to use in a foreach loop?
Array
(
[0] => stdClass Object
(
[doc] => stdClass Object
(
[path] => Array
(
[0] => Bob
[1] => pictures
[2] => food
)
)
)
[1] => stdClass Object
(
[doc] => stdClass Object
(
[path] => Array
(
[0] => Alice
[1] => pictures
[2] => vacations
[3] => rome
)
)
)
)
I would suggest that,
you create an array with keys as new path and value as old path (
path to be replaced).
Loop you path array and check if it is available in above defined array.
If available replace it with key of above defined array.
For example
// array defined as point 1
$change_path_array= array('pics'=>'pictures','meal'=>'food');
// $array is your array.
foreach ($array as $value) {
// loop you path array
for($i=0;$i<count($value->doc->path);$i++){
// check if the value is in defined array
if(in_array($value->doc->path[$i],$change_path_array)){
// get the key and replace it.
$value->doc->path[$i] = array_search($value->doc->path[$i], $change_path_array);
}
}
}
Out Put: picture is replaced with pics and food with meal
Array
(
[0] => stdClass Object
(
[doc] => stdClass Object
(
[path] => Array
(
[0] => Bob
[1] => pics
[2] => meal
)
)
)
[1] => stdClass Object
(
[doc] => stdClass Object
(
[path] => Array
(
[0] => Alice
[1] => pics
[2] => vacations
[3] => rome
)
)
)
)
You can modify the code to check casesensitive.
Example of changing all pictures to photos:
$doc1 = new \stdClass;
$doc1->doc = new \stdClass;
$doc1->doc->path = array('Bob', 'pictures', 'food');
$doc2 = new \stdClass;
$doc2->doc = new \stdClass;
$doc2->doc->path = array('Alice', 'pictures', 'vacations', 'rome');
$documents = array($doc1, $doc2);
/* change all 'pictures' to 'photos' */
foreach ($documents as &$doc) {
foreach ($doc->doc->path as &$element) {
if ($element == 'pictures') {
$element = 'photos';
}
unset($element);
}
unset($doc);
}
print_r($documents);
You can do it like this:
for($i = 0; $i < count($arr); $i++){
$path_array = $arr[$i]->doc->path;
// do your modifications for [i]th path element
// in your case replace all 'Bob's with 'Joe's
$path_array = array_map(function($paths){
if($paths == 'Bob') return 'Joe';
return $paths;
}, $paths_array);
$arr[$i]->doc->path = $path_array;
}
I get a response from an API call that looks like the following
Array
(
[_id] => aasdasdasdasdasd
[created] => 2017-01-16T14:11:54.616Z
[options] => Array
(
[title] => 1
[data] => Array
(
[0] => Array
(
[labelName] => Date
[labelValues] => Array
(
[0] => March 2016
)
)
[1] => Array
(
[labelName] => Title
[labelValues] => Array
(
[0] => Food
)
)
[2] => Array
(
[labelName] => Product
[labelValues] => Array
(
[0] => Rice
)
)
)
)
)
I then process the response by doing the following
$results = array();
foreach ($output['options']['data'] as $data) {
if (isset($data['labelValues'][0])) {
$results[$data['labelName']] = $data['labelValues'][0];
}
}
This leaves me with something along the lines of this
Array
(
[Date] => March 2016
[Title] => Food
[Product] => Rice
)
Putting it into an array was not my intention, it was mainly done to help me better understand the looping required to process the original data.
My main intention is to create directories from these values. The main directory will be the Date, within this should be the Title and within this should be Product. So for the above, the directory structure should be something like 2016 > Food > Rice.
In order to achieve this, I have come up with the following
foreach ($output['options']['data'] as $data) {
if (isset($data['labelValues'][0])) {
if($data['labelName'] == 'Date') {
if (preg_match('/\b\d{4}\b/', $data['labelValues'][0], $matches)) {
$results[$data['labelName']] = $matches[0];
if (!file_exists($matches[0])) {
mkdir($matches[0], 0777, true);
}
}
}
}
}
The above works well and creates the date folder for me. Where I am struggling is how I now create the Title folder within the Date folder, and then the Product within the Title.
How would I go about achieving this?
Many thanks
I like your created array:
$array = array
(
[Date] => March 2016
[Title] => Food
[Product] => Rice
)
Simply implode the path:
mkdir(implode('/', $array), 0777, true);
This will create all of the directories, March 2016/Food/Rice
I've got an array, called $data which needs to be updated with data from an ajax call.
There are two variables sent via an ajax call (with example inputs):
sectionDetails:
[111][0][2][0][service_providers][]
serviceProvider:
Google
The serviceProvider is the data, and the sectionDetails is the array in which the serviceProvider should be in, in the $data array.
What I need is the $data array to end up as:
$data = Array
(
[111] => Array
(
[0] => Array
(
[2] => Array
(
[0] => Array
(
[service_providers] => Array
(
[0] = Google
)
)
)
)
)
)
This way, I can dynamically input data into any cell and then later I can update specific arrays (e.g. $data[111][0][2][0][service_providers][0] = "Yahoo";
The $_POST['sectionDetails'] is however a string which is where the issue is.
Is there a way to change this string to an array that can then be appended to the main $data array (and in the case of an existing value in the same section, update the value)?
Hope that makes sense.
If you create a function like this:
function setToPath(&$data, $path, $value){
//$temp will take us deeper into the nested path
$temp = &$data;
//notice this preg_split logic is specific to your path syntax
$exploded = preg_split("/\]\[/", rtrim(ltrim($path,"["),"]"));
// Where $path = '[111][0][2][0][service_providers][]';
// $exploded =
// Array
// (
// [0] => 111
// [1] => 0
// [2] => 2
// [3] => 0
// [4] => service_providers
// [5] =>
// )
foreach($exploded as $key) {
if ($key != null) {
$temp = &$temp[$key];
} else if(!is_array($temp)) {
//if there's no key, i.e. '[]' create a new array
$temp = array();
}
}
//if the last index was '[]', this means push into the array
if($key == null) {
array_push($temp,$value);
} else {
$temp = $value;
}
unset($temp);
}
You can use it like this:
setToPath($data, $_POST['sectionDetails'], $_POST['serviceProvider']);
print_r($data) will return:
Array
(
[111] => Array
(
[0] => Array
(
[2] => Array
(
[0] => Array
(
[service_providers] => Array
(
[0] => Google
)
)
)
)
)
)
Being very careful and depending on the situation, you could use eval:
eval("\$data$sectionDetails = '$serviceProvider';");
print_r($data) will return:
Array
(
[111] => Array
(
[0] => Array
(
[2] => Array
(
[0] => Array
(
[service_providers] => Array
(
[0] => Google
)
)
)
)
)
)
Caution
The eval() language construct is very dangerous because it allows execution of arbitrary PHP code. Its use thus is discouraged. If you have carefully verified that there is no other option than to use this construct, pay special attention not to pass any user provided data into it without properly validating it beforehand.