I'm trying to use RecursiveIteratorIterator and RecursiveDirectoryIterator.
I want get all file inside my c:\ folder. But i don't know why i can't get the result but a blank page.
$it = new RecursiveIteratorIterator(new RecursiveDirectoryIterator('c:/' ));
foreach( $it as $file ) {
$all[] = $file->getRealPath();
}
print_r($all);
but if i use this code, it's work
foreach( $it as $key=>$file )
{
echo $key."=>".$file."\n";
}
Most likely because your PHP interpreter does not have access to that folder.
It's because PHPs StdObj-class cannot be used as an array because it's an associative array. This is wrong by the words but I cannot describe it better. The PHP object gets casted or something like that.
If $data is an object then this is required if you want to access $value as an object.
foreach($data as $property => $value){
echo $value->r;
}
Edit: This is a good question btw, I've spent a couple of hours myself figuring this out.
Related
There is this library https://github.com/halaxa/json-machine (PHP) that allows me to read huge JSON files without loading the entire file to memory. It works great and the way I read the JSON is like this:
$temp = \JsonMachine\JsonMachine::fromFile("teste.json");
foreach ($temp as $key => $value) {
echo $value;
}
The problem is that I cant use foreach, I need to only read the JSON as I need. For example, I tried the code below everytime I need to retrieve an element from the array:
echo next($temp);
However it returns and empty string. If I use var_dump(current($temp)) it returns this:
object(JsonMachine\StreamBytes)#2 (1) { ["stream":"JsonMachine\StreamBytes":private]=> resource(10) of type (stream) }
Using the foreach loop works perfectly, but I cant use it, I need to retrieve the elements as I need. How can I do that?
This class already provides a generator, you should be able to do something like this:
$temp = \JsonMachine\JsonMachine::fromFile("teste.json");
$iterator = $temp->getIterator();
$firstItem = $iterator->current();
$iterator->next();
$secondItem = $iterator->current();
$iterator->next();
$thirdItem = $iterator->current();
[Edit] Looks like JsonMachine::getIterator() returns a chained generator, so just change that second line to this:
$iterator = $temp->getIterator()->getIterator();
I need to recursively traverse a certain directory and list all of the files inside of it I have found an example on the PHP website however after further searching I am not able to find a solution to my problem. The problem is that it prints out the entire path but I only want to echo out the first containing folder of the file. So for example as it sits now I get this output:
/var/www/example.com/public_html/images/6.Blah/_Original/DSC_0174.jpg
But I want it to echo:
_Original/DSC_0174.jpg
or
/_Original/DSC_0174.jpg
Here is the code I am using:
<?php
$path = realpath('/etc');
$objects = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path), RecursiveIteratorIterator::SELF_FIRST);
foreach($objects as $name => $object){
echo "$name\n";
}
?>
This is a formatting issue, you can approach it in many different ways. One way will be to split the string into an array and grab the last two elements.
foreach($objects as $name => $object){
$pieces = explode("/",$name);
$length = count($pieces);
$result = $pieces[$length-2]."/".$pieces[$length-1];
}
Here is a fairly big object dumped using print_r.
https://docs.google.com/document/d/175RLhWlMQcyhGR6ffGSsoJGS3RyloEqo4EEHCL2H2vg/edit?usp=sharing
I am trying to change the values of the uploaded_files.
Towards the end of that object you'll see something like
[uploaded_files] => Array
(
[attachment] => /home2/magician/public_html/development/testing/wp-content/uploads/wpcf7_uploads/Central-Coast-Montessori-logo.jpg
[attachment2] => /home2/magician/public_html/development/testing/wp-content/uploads/wpcf7_uploads/Andrew.jpg )
My code
// move the attachments to wpcf7ev temp folder
foreach ($cf7ev_object['uploaded_files'] as $key => $uploaded_file_path) {
$new_filepath = WPCF7EV_UPLOADS_DIR . '/' . basename($uploaded_file_path);
wpcf7ev_debug("New file path is {$new_filepath}");
rename($uploaded_file_path, $new_filepath);
wpcf7ev_debug("'{$key}'is the KEY for {$uploaded_file_path}");
wpcf7ev_debug($cf7ev_object['uploaded_files']);
$cf7ev_object['uploaded_files'][$key] = $new_filepath; // this is not updating
}
To loop through it I have been using
foreach ($cf7ev_object->uploaded_files as $key => $uploaded_file_path) {
and this has worked.
But shouldn't it be
foreach ($cf7ev_object['uploaded_files'] as $key => $uploaded_file_path) {
? As '->' is for accessing methods?
And specifically I want to update the values of those uploaded_files, so to do that I need to do
$cf7ev_object['uploaded_files'][$key] = $new_filepath; // this is not updating
? But this doesn't seem to be working.
I think I need to be clear on how to access values in an object.
Thanks.
First of all, regarding the single arrow "->" that is how you reference an objects values. But I won't get into that. Since you say it works, $cf7ev_object is obviously an object.
You say you want to "access the values in the object".
var_dump($cf7ev_object);
This will spit out what is in that object. I gather you are a bit of a newbie, so I will try to help you out best I can with the limited data you provided (you may want to expand your question.
Looping is not a one-shot deal. You can have nested loops and nested loops inside of those. However, it is a resource hog if you're not careful. Here is an exercise that might help you.
$new_array = array();
foreach($cf7ev_object->uploaded_files as $key => $value) {
$new_value = $value;//do something to the $value here
$new_array[$key] = $new_value;
}
//take a look at your work now:
print_r($new_array);
I hope this helps. Note: your google doc is restricted, public can't see it.. And your question is too vague. Let me know if I can help more.
If you want to change the object array values instantly you just set it equal to the above loop result:
$cf7ev_object->uploaded_files = $new_array;
This is my CodeIgniter code to find the directory structure of a folder in my own server, but it is only going one level deep. I want to list all the subdirectories in the given $path. What is the error in this code?
function finddir($path)
{
$this->load->helper('directory');
$dir=directory_map($path,1);
//echo"$path";
foreach ($dir as $key => $subdir)
{
//echo $subdir."<br/>";
if(is_dir($subdir))
{
echo "<h3>$subdir</h3>";
$this->finddir($subdir);
}
else
{
echo "$subdir<br>";
}
}
}
The output goes only one level deep. Since I'm using recursion, I want it to go into deeper levels.
Try the RecursiveDirectoryIterator for this
function finddir($path)
{
$objects = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path), RecursiveIteratorIterator::SELF_FIRST);
foreach($objects as $name => $object){
echo "$name\n";
}
}
It makes more sense to make two functions so that you're not regenerating the array within a recursive function. This way it's generated once, and you are recursively getting values from just that one array. Unless the directory class is broken, you shouldn't need to check if it's a directory. If it's an array, it's a directory:
function finddir($path){
$this->load->helper('directory');
$dir=directory_map($path);
$this->recursive($dir);
}
function recursive($arr) {
foreach ($arr as $key => $val) {
if (is_array($val)){
echo "<h3>$key</h3>";
echo "<ul>\n";
$this->recursive($val);
echo "</ul>\n";
} else {
echo "<li>".$val."</li>\n";
}
}
}
Your break tags <br/> don't show the structure well, so I changed it to use nested lists.
I just noticed that you are pasing a value of 1 to the directory_map() function. That limits it to just one level, so you probably want to leave that out if you want to goes all the way with the recursion:
$dir=directory_map($path);
Why are you doint it this way?
The directory_map('source directory') returns you an array with sub-arrays (and sub-sub-arrays if applicable based on path).
You get the complete tree - just loop over array and print/use as needed, Use is_array($subdir) to test if its directory or file leaf.
instead of $dir=directory_map($path,1) remove number 1 so it displays this way $dir=directory_map($path) since that number will only return the first level directory only.
I am maintaining an OO PHP application that loads everything to $this array. When I do a var dump on $this to find out how to access a value, I get dozens of pages of output. Hunting down the array elements that I need is very time consuming
For example, if I want to find where Customer Territory is stored, I have to figure out the heirarchy of the array using print_r or var_dump and staring [edit: and searching] ]at the output until I figure out the path.
for example:
$this->Billing->Cst->Record['Territory']
Is there a better way to do this, or some tools/techniques that I can use. For instance, is there there quick way to find the path to variable ['Territory'] throughout the array directly?
Krumo is a graphical "var_dump" tool that may make navigation a tiny bit easier. Check out the "examples" section on the project page.
For searching in multi-dimensional arrays, this SO question may help you.
You could probably do ctr+F on the output instead of staring at it?
Just start with ctr+F: "Customer", "Territory" and all other names related to whatever you're searching.
function findInTree($var, $words) {
$words = explode(' ', strtolower($words));
$path = array();
$depth = 0;
$iterator = new RecursiveIteratorIterator(new RecursiveArrayIterator($var), RecursiveIteratorIterator::SELF_FIRST);
foreach ($iterator as $key => $value) {
if ($iterator->getDepth() < $depth) {
unset($path[$depth]);
}
$depth = $iterator->getDepth();
$path[$depth] = $key;
if (is_string($key) && in_array(strtolower($key), $words)) {
echo '<pre>', implode(' -> ', $path), '</pre>';
}
}
}
findInTree($this, 'Customer Territory');
This function will walk through your object and look for any of the given words as a key.
FirePHP/Firebug can give you a detailed structural view of $this and its properties.