Okay guys so I am a bit lost as to how to adjust my code. Up to now, I have my code to read any Json file in a directory, parse it and put it in a table - works great since I was only using 1 JSON file per table row.
What I need to do now is the following, each IP address I have gives me 3 JSON files now that are placed into a folder with the IP address as its name. In my main directory I will have many folder each with 3 JSON files in it.
I want to read each file in every folder, place the info I parse in a table and then move on to the next folder as a new row and do the same.
FOR REFERENCE::
Current file layout:
FOLDER-->JSON
-->JSON
-->JSON
New file layout:
FOLDER-->IPADDRESS-->JSONFILE1
-->JSONFILE2
-->JSONFILE3
-->IPADDRESS2-->JSONFILE1
--JSONFILE2
-->JSONFILE3
Current code for reading any JSON file in a directory:
$dir = "my dir";
if (is_dir($dir)) {
if ($dh = opendir($dir)) {
foreach(glob("*_name.json") as $filename) {
$data = file_get_contents($filename);
$testing = json_decode($data, true);
echo "<tr>";
echo "<td>{$filename }</td>";
foreach($testing[0] as $row) {
// code for parsing here ...
}
}
}
}
here you go using RecursiveIteratorIterator Class
function Get_Files()
{
$dir = "my_dir";
$init = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir));
$files = array();
foreach ($init as $file) {
if ($file->isDir()) {
continue;
}
$files[] = $file->getPathname();
}
return $files;
}
foreach (Get_Files() as $file) {
$data = file_get_contents($file);
$testing = json_decode($data, true);
echo "<tr>";
echo "<td>{$file}</td></tr>";
}
output:
my_dir\192.168.0.1\JSONFILE1.json
my_dir\192.168.0.1\JSONFILE2.json
Related
Pls sir, how can I loop through a directory and get the sub-directory name and all the files names so that I can generate a directory try, am trying to build a file manager in php.
I have tried:
$dir = new DirectoryIterator(dirname(FILE));
foreach ($dir as $fileinfo) {
if (!$fileinfo->isDot()) {
var_dump($fileinfo->getFilename());
}
}
You can scan a directory and display the name of files in it using the PHP Code below
<?php
$dir = 'dir/';
$files = scandir($dir);
$totFiles = sizeof($files);
for($i=2;$i<$totFiles;$i++){
$name = explode(".",$files[$i]);
echo "
$name[0]
";
}
?>
A little stuck on this and hoping for some help. I'm trying to get the last modified dir from a path in a string. I know there is a function called "is_dir" and I've done some research but can't seem to get anything to work.
I don't have any code i'm sorry.
<?php
$path = '../../images/';
// echo out the last modified dir from inside the "images" folder
?>
For example: The path variable above has 5 sub folders inside the "images" dir currently right now. I want to echo out "sub5" - which is the last modified folder.
You can use scandir() instead of is_dir() function to do it.
Here is an example.
function GetFilesAndFolder($Directory) {
/*Which file want to be escaped, Just add to this array*/
$EscapedFiles = [
'.',
'..'
];
$FilesAndFolders = [];
/*Scan Files and Directory*/
$FilesAndDirectoryList = scandir($Directory);
foreach ($FilesAndDirectoryList as $SingleFile) {
if (in_array($SingleFile, $EscapedFiles)){
continue;
}
/*Store the Files with Modification Time to an Array*/
$FilesAndFolders[$SingleFile] = filemtime($Directory . '/' . $SingleFile);
}
/*Sort the result as your needs*/
arsort($FilesAndFolders);
$FilesAndFolders = array_keys($FilesAndFolders);
return ($FilesAndFolders) ? $FilesAndFolders : false;
}
$data = GetFilesAndFolder('../../images/');
var_dump($data);
From above example the last modified Files or Folders will show as Ascending order.
You can also separate your files and folder by checking is_dir() function and store the result in 2 different arrays like $FilesArray=[] and $FolderArray=[].
Details about filemtime() scandir() arsort()
Here's one way you can accomplish this:
<?php
// Get an array of all files in the current directory.
// Edit to use whatever location you need
$dir = scandir(__DIR__);
$newest_file = null;
$mdate = null;
// Loop over files in directory and if it is a subdirectory and
// its modified time is greater than $mdate, set that as the current
// file.
foreach ($dir as $file) {
// Skip current directory and parent directory
if ($file == '.' || $file == '..') {
continue;
}
if (is_dir(__DIR__.'/'.$file)) {
if (filemtime(__DIR__.'/'.$file) > $mdate) {
$newest_file = __DIR__.'/'.$file;
$mdate = filemtime(__DIR__.'/'.$file);
}
}
}
echo $newest_file;
This will work too just like the other answers. Thanks everyone for the help!
<?php
// get the last created/modified directory
$path = "images/";
$latest_ctime = 0;
$latest_dir = '';
$d = dir($path);
while (false !== ($entry = $d->read())) {
$filepath = "{$path}/{$entry}";
if(is_dir($filepath) && filectime($filepath) > $latest_ctime) {
$latest_ctime = filectime($filepath);
$latest_dir = $entry;
}
} //end loop
echo $latest_dir;
?>
I've a function which scan through the provided dir and returns all the files and sub directory inside the parent dir.
public function show_image(){
$dir=FCPATH.'uploads/';
$files = scandir($dir);
$ret= array();
$result=array();
foreach($files as $file)
{
if($file == "." || $file == "..")
continue;
$filePath=$dir."/".$file;
$details = array();
$details['name']=$file;
$details['path']=$filePath;
$details['size']=filesize($filePath);
$ret[] = $details;
}
echo json_encode($ret);
//echo json_encode($result);
}
Basically I'm using Ajax, so what I'm doing is printing both folders and files inside that dir. But the problem here is that I really want to filter the subdir and file which this function isn't currently doing.
I want to have the folder printed out at the very beginning whereas other files after the folders.
The $ret consists the data in ascending order. In the view I've following Ajax onSucess function.
onSuccess:function(files,data,xhr,pd)
{
var src = '<?php echo base_url("uploads"); ?>'+'/'+data.file_name;
var html = '<div class="col-sm-3 text-center"><div class="mid-folder">';
html+= '<div class="folder-content"><img src="'+src+'" class="img-container" style="max-height:100%; max-width:100%;"/></div>'
html+= '<h3 class="title-folder">'+data.file_name.substr(0,10)+".."+' </h3> </div>';
$('.hello').append(html);
$('.ajax-file-upload-statusbar').fadeOut(1000, function(){
$('.ajax-file-upload-statusbar').show(1000).html('Your file successfully uploaded');
});
$('.ajax-file-upload-statusbar').hide('slow');
}
What should I be doing, so that I could display the folder and files in different way. Basically a logic/way by which I can filter which object inside the $ret should be treated as dir and which as file and display it thoroughly.
I'd go with separering files and directories on the server side, and then sending a json object with to arrays. One with directories and one with files.
$ret= array();
$result=array();
foreach($files as $file){
if($file == "." || $file == "..")
continue;
$filePath=$dir."/".$file;
$details = array();
$details['name']=$file;
$details['path']=$filePath;
$details['size']=filesize($filePath);
if(is_dir($filePath) {
$ret['directories'][] = $details;
}
else {
$ret['files'][] = $details;
}
}
Next, make two loops in the ajax success callback function. One for data.directories and one for data.files.
I have a zip file containing one folder, that contains more folders and files, like this:
myfile.zip
-firstlevel
--folder1
--folder2
--folder3
--file1
--file2
Now, I want to extract this file using PHPs ZipArchive, but without the "firstlevel" folder. At the moment, the results look like this:
destination/firstlevel/folder1
destination/firstlevel/folder2
...
The result I'd like to have would look like this:
destination/folder1
destination/folder2
...
I've tried extractTo, which produces the first mentioned result, and copy(), as suggested here, but this doesn't seem to work at all.
My current code is here:
if($zip->open('myfile.zip') === true) {
$firstlevel = $zip->getNameIndex(0);
for($i = 0; $i < $zip->numFiles; $i++) {
$entry = $zip->getNameIndex($i);
$pos = strpos($entry, $firstlevel);
if ($pos !== false) {
$file = substr($entry, strlen($firstlevel));
if(strlen($file) > 0){
$files[] = $file;
}
}
}
//attempt 1 (extractTo):
//$zip->extractTo('./test', $files);
//attempt 2 (copy):
foreach($files as $filename){
copy('zip://'.$firstlevel.'/'.$filename, 'test/'.$filename);
}
}
How can I achieve the result I'm aiming for?
Take a look at my Quick Unzipper script. I wrote this for personal use a while back when uploading large zip files to a server. It was a backup, and 1,000s of files take forever with FTP so using a zip file was faster. I use Git and everything, but there wasn't another option for me. I place this php file in the directory I want the files to go, and put the zip file in the same directory. For my script, they all have to operate in the same directory. It was an easy way to secure it for my needs, as everything I needed was in the same dir.
Quick Unzipper: https://github.com/incomepitbull/QuickUnzipper/blob/master/unzip.php
I linked the file because I am not showcasing the repo, just the code that makes the unzip tick. With modern versions of PHP, there should't be anything that isn't included on your setup. So you shouldn't need to do any server config changes to use this.
Here is the PHP Doc for the ZipArchive class it uses: http://php.net/manual/en/class.ziparchive.php
There isn't any included way to do what you want, which is a shame. So I would unzip the file to a temp directory, then use another function to copy the contents to where you want. So when using ZipArchive, you will need to return the first item to get the folder name if it is unknown. If the folder is known, ie: the same pesky folder name every time, then you could hard code the name.
I have made it return the first item from the index. So if you ALWAYS have a zip with 1 folder inside it, and everything in that folder, this would work. However, if you have a zip file without everything consolidated inside 1 folder, it would fail. The code I have added will take care of your question. You will need to add further logic to handle alternate cases.
Also, You will still be left with the old directory from when we extract it to the temp directory for "processing". So I included code to delete it too.
NOTE: The code uses a lot of if's to show the processing steps, and print a message for testing purposes. You would need to modify it to your needs.
<?php
public function copyDirectoryContents($source, $destination, $create=false)
{
if ( ! is_dir($source) ) {
return false;
}
if ( ! is_dir($destination) && $create === true ) {
#mkdir($destination);
}
if ( is_dir($destination) ) {
$files = array_diff(scandir($source), array('.','..'));
foreach ($files as $file)
{
if ( is_dir($file) ) {
copyDirectoryContents("$source/$file", "$destination/$file");
} else {
#copy("$source/$file", "$destination/$file");
}
}
return true;
}
return false;
}
public function removeDirectory($directory, $options=array())
{
if(!isset($options['traverseSymlinks']))
$options['traverseSymlinks']=false;
$files = array_diff(scandir($directory), array('.','..'));
foreach ($files as $file)
{
if (is_dir("$directory/$file"))
{
if(!$options['traverseSymlinks'] && is_link(rtrim($file,DIRECTORY_SEPARATOR))) {
unlink("$directory/$file");
} else {
removeDirectory("$directory/$file",$options);
}
} else {
unlink("$directory/$file");
}
}
return rmdir($directory);
}
$file = dirname(__FILE__) . '/file.zip'; // full path to zip file needing extracted
$temp = dirname(__FILE__) . '/zip-temp'; // full path to temp dir to process extractions
$path = dirname(__FILE__) . '/extracted'; // full path to final destination to put the files (not the folder)
$firstDir = null; // holds the name of the first directory
$zip = new ZipArchive;
$res = $zip->open($file);
if ($res === TRUE) {
$firstDir = $zip->getNameIndex(0);
$zip->extractTo($temp);
$zip->close();
$status = "<strong>Success:</strong> '$file' extracted to '$temp'.";
} else {
$status = "<strong>Error:</strong> Could not extract '$file'.";
}
echo $status . '<br />';
if ( empty($firstDir) ) {
echo 'Error: first directory was empty!';
} else {
$firstDir = realpath($temp . '/' . $firstDir);
echo "First Directory: $firstDir <br />";
if ( is_dir($firstDir) ) {
if ( copyDirectoryContents($firstDir, $path) ) {
echo 'Directory contents copied!<br />';
if ( removeDirectory($directory) ) {
echo 'Temp directory deleted!<br />';
echo 'Done!<br />';
} else {
echo 'Error deleting temp directory!<br />';
}
} else {
echo 'Error copying directory contents!<br />';
}
} else {
echo 'Error: Could not find first directory';
}
}
I`m trying to create a function that reads a directory and returns all file's working directories in an array, but it is not working. I don`t know why the code doesn`t work, can you help me?
$postsDirectory = "../posts/";
function listFiles() {
$results = array();
$handler = opendir($postsDirectory);
while ($file = readdir($handler)) {
if ($file != "." && $file != "..") {
$results[] = getcwd($file);
}
}
closedir($handler);
return $results;
}
getcwd() returns the working directory for the script that is being executed. It doesn't take any parameters, and it has nothing to do with other files on the file system (nor does the idea of a "working directory" make sense for an arbitrary file). I assume that what you actually want is a list of all directories within a given directory.
I would use a RecursiveDirectoryIterator for this:
$it = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($postsDirectory),
FilesystemIterator::SKIP_DOTS
);
$results = array();
while($it->valid()) {
if($it->isDir()) {
$results[] = $it->getSubPath();
}
$it->next();
}