My goal is to move the first file containing -3-sml in the filename from temp to b2. What my code does is move every file to b2. Why is that and what to change?
$name = "";
$dname = "";
$dir = new DirectoryIterator('temp/');
foreach ($dir as $fileinfo)
{
if (!$fileinfo->isDot())
{
if (substr($fileinfo->getFilename(),'-3-sml') !== false)
{
rename("temp/".$fileinfo->getFilename(), "b2/".$fileinfo->getFilename());
$name = $fileinfo->getFilename();
$dname = "http://domain.com/b2/".$fileinfo->getFilename();
break;
}
}
}
EDIT: I tried
if (substr($fileinfo->getFilename(),'-3-sml') !== false)
{
echo $fileinfo->getFilename()."<br>";
continue;
rename("temp/".$fileinfo->getFilename(), "b2/".$fileinfo->getFilename());
$name = $fileinfo->getFilename();
$dname = "http://oneitis.mygrabrede.de/b2/".$fileinfo->getFilename();
break;
}
and it seems that substr($fileinfo->getFilename(),'-3-sml') !== false doesn't filter anything, so every filename goes through. Why?
EDIT: Solution is: it has to be strpos not substr.
If you need to move only the first matching file, you can use glob, and access the first item on the array, i.e.:
$origin_path = "/somepath/temp";
$dest_path = "/somepath/b2";
$files = glob("$origin_path/*-3-sml*");
$fileName = basename($files[0]);
if(!is_dir("$dest_path")){
mkdir("$dest_path", 0777);
rename($files[0],"$dest_path/$fileName" );
}else{
rename($files[0],"$dest_path/$fileName" );
}
If you need to search inside multiple sub-folders, use this recursive glob function:
function rglob($pattern='*', $flags = 0, $path='')
{
$paths=glob($path.'*', GLOB_MARK|GLOB_ONLYDIR|GLOB_NOSORT);
$files=glob($path.$pattern, $flags);
foreach ($paths as $path) { $files=array_merge($files,rglob($pattern, $flags, $path)); }
return $files;
}
and change from
$files = glob("$origin_path/*-3-sml*");
to
$files = rglob("$origin_path/*-3-sml*");
Change substr() to strpos()
Substr for find out substring
Strpos will return position of specific string
Related
$file = glob("submission/".$iid."/".$yr."/".$sem."/".$sec."/Word/".$sid.".*");
if ($file!=="")
{
return $path."/". $file;
break;
}
the sid is the student submitted file starting with the student id .I want tyo find the exact file from inside the folder 'word' .The file is like 211000110-Word.docx
glob() returns an array that you need to further loop through and match the individual values against the value you are looking for.
$files = glob("submission/".$iid."/".$yr."/".$sem."/".$sec."/Word/*.docx");
$result = false;
foreach($files as $file) {
if($file == "$sid-Word.docx"){
$result = $file;
break;
}
}
Turning this into a re-usable function would be a good idea:
function get_student_file($sid) {
$files = glob("submission/".$iid."/".$yr."/".$sem."/".$sec."/Word/*.docx");
$result = false;
foreach($files as $file) {
if($file == "$sid-Word.docx"){
$result = $file;
break;
}
}
unset($files);
return $result;
}
I am yet to work on a very large project which has too many files. I am trying to find out few vaiables where it is present and list all the file names which contains the specific word or variable or string.
What I have tried so far!
$path = realpath(__DIR__); // Path to your textfiles
$fileList = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($path), \RecursiveIteratorIterator::SELF_FIRST);
foreach ($fileList as $item) {
if ($item->isFile() && stripos($item->getPathName(), 'php') !== false) {
$file_contents = file_get_contents($item->getPathName());
$file_contents = strpos($file_contents,"wordtofind");
echo $file_contents;
}
}
I use the same code for replacing text which I found it on stackoverflow. But I need to find out few strings before replacing specific words in specific files. Hence this has become most important task to me.
How can I further code and get the file names?
Edit:
I want to search for a specific word, for example: word_to_find
And there are more than 200 files in a folder called abc.
When I run that code, searching for the word, then it should search in all 200 files and list all the file names which contains word_to_find word.
Then I would know, in which all files, the specific word exists and then I can work on.
Output would be:
123.php
111.php
199.php
I created you a nice function. This will return filenames (Not any paths, yield $item->getPathName() instead if you want the path, or probably better yet, just yield $item, which will return the SplFileInfo class which you can then use any of the helper functions to get info about that file.):
function findStringInPath($needle, $path = __DIR__) {
//$path = realpath(__DIR__); // Path to your textfiles
$fileList = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($path), \RecursiveIteratorIterator::SELF_FIRST);
foreach ($fileList as $item) {
if ($item->isFile() && strtolower($item->getExtension()) === 'php') {
$file_contents = file_get_contents($item->getPathName());
if ( strpos($file_contents, $needle) !== false )
yield $item->getFileName();
}
}
}
foreach ( findStringInPath('stringtofind') as $file ) {
echo $file . '<br />';
}
?>
For older PHP versions:
<?php
function findStringInPath($needle, $path = __DIR__) {
//$path = realpath(__DIR__); // Path to your textfiles
$fileList = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($path), \RecursiveIteratorIterator::SELF_FIRST);
$ret = array();
foreach ($fileList as $item) {
if ($item->isFile() && strtolower($item->getExtension()) === 'php') {
$file_contents = file_get_contents($item->getPathName());
if ( strpos($file_contents, $needle) !== false )
$ret[] = $item->getFileName();
}
}
return $ret;
}
foreach ( findStringInPath('stringtofind') as $file ) {
echo $file . '<br />';
}
?>
I have a recursive directory iterator looking like this:
function ReadFolderDirectory($dir,$listDir= array())
{
$listDir = array();
if($handler = opendir($dir))
{
while (($sub = readdir($handler)) !== FALSE)
{
if ($sub != "." && $sub != ".." && $sub != "Thumb.db")
{
if(is_file($dir."/".$sub))
{
$listDir[] = $sub;
}elseif(is_dir($dir."/".$sub))
{
$listDir[$sub] = ReadFolderDirectory($dir."/".$sub);
}
}
}
closedir($handler);
}
return $listDir;
}
And I use it like this
$path = dirname(__FILE__);
$path = $path.'/uploadedImages/';
$dir = new DirectoryIterator($path);
$filesArray = ReadFolderDirectory($dir);
echo json_encode($filesArray);
Now when I try to set the starting point of the directory iteration, as you see I have added /uploadedImages/ to the path, but it seems to disregard that.
No matter if that is there or not, it always starts from the same directory as the php file is in, thus including also the index.php, ._index,php, and listing of course the folder uploadedImages itself.
Any thoughts what I am missing?
There is an error in your code, you have just to remove this code line :
$dir = new DirectoryIterator($path);
Explanation
opendir(String $pathToDir) // expects a String, but you pass an Object as a parameter
I've created this code to cycle through the folders in the current directory and echo out a link to the folder, it all works fine. How would I go about using the $blacklist array as an array to hold the directory names of directories I dont want to show?
$blacklist = array('dropdown');
$results = array();
$dir = opendir("./");
while($file = readdir($dir)) {
if($file != "." && $file != "..") {
$results[] = $file;
}
}
closedir($dir);
foreach($results as $file) {
if($blocked != true) {
$fileUrl = $file;
$fileExplodedName = explode("_", $file);
$fileName = "";
$fileNameCount = count($fileExplodedName);
echo "<a href='".$fileUrl."'>";
$i = 1;
foreach($fileExplodedName as $name) {
$fileName .= $name." ";
}
echo trim($fileName);
echo "</a><br/>";
}
}
array_diff is the best tool for this job -- it's the shortest to write, very clear to read, and I would expect also the fastest.
$filesToShow = array_diff($results, $blacklist);
foreach($filesToShow as $file) {
// display the file
}
Use in_array for this.
$blocked = in_array($file, $blacklist);
Note that this is rather expensive. The runtime complexity of in_array is O(n) so don't make a large blacklist. This is actually faster, but with more "clumsy" code:
$blacklist = array('dropdown' => true);
/* ... */
$blocked = isset($blacklist[$file]);
The runtime complexity of the block check is then reduced to O(1) since the array (hashmap) is constant time on key lookup.
I want to use a function to recursively scan a folder, and assign the contents of each scan to an array.
It's simple enough to recurse through each successive index in the array using either next() or foreach - but how to dynamically add a layer of depth to the array (without hard coding it into the function) is giving me problems. Here's some pseudo:
function myScanner($start){
static $files = array();
$files = scandir($start);
//do some filtering here to omit unwanted types
$next = next($files);
//recurse scan
//PROBLEM: how to increment position in array to store results
//$next_position = $files[][][].... ad infinitum
//myScanner($start.DIRECTORY_SEPARATOR.$next);
}
any ideas?
Try something like this:
// $array is a pointer to your array
// $start is a directory to start the scan
function myScanner($start, &$array){
// opening $start directory handle
$handle = opendir($start);
// now we try to read the directory contents
while (false !== ($file = readdir($handle))) {
// filtering . and .. "folders"
if ($file != "." && $file != "..") {
// a variable to test if this file is a directory
$dirtest = $start . DIRECTORY_SEPARATOR . $file;
// check it
if (is_dir($dirtest)) {
// if it is the directory then run the function again
// DIRECTORY_SEPARATOR here to not mix files and directories with the same name
myScanner($dirtest, $array[$file . DIRECTORY_SEPARATOR]);
} else {
// else we just add this file to an array
$array[$file] = '';
}
}
}
// closing directory handle
closedir($handle);
}
// test it
$mytree = array();
myScanner('/var/www', $mytree);
print "<pre>";
print_r($mytree);
print "</pre>";
Try to use this function (and edit it for your demands):
function getDirTree($dir,$p=true) {
$d = dir($dir);$x=array();
while (false !== ($r = $d->read())) {
if($r!="."&&$r!=".."&&(($p==false&&is_dir($dir.$r))||$p==true)) {
$x[$r] = (is_dir($dir.$r)?array():(is_file($dir.$r)?true:false));
}
}
foreach ($x as $key => $value) {
if (is_dir($dir.$key."/")) {
$x[$key] = getDirTree($dir.$key."/",$p);
}
}
ksort($x);
return $x;
}
It returns sorted array of directories.