I'm having an issue with a PHP print statement that repeats the output continuously for about 40 or 50 times, then stops. I thought it was supposed to print only one line. I'm still somewhat new to PHP, so I don't understand what I'm doing wrong. The code in question is located at the bottom of the snippet.
Thanks in advance.....
<?php
$query = $_POST['query'];
find_files('.');
function find_files($seed) {
if(! is_dir($seed)) return false;
$files = array();
$dirs = array($seed);
while(NULL !== ($dir = array_pop($dirs))) {
if($dh = opendir($dir)) {
while( false !== ($file = readdir($dh))) {
if($file == '.' || $file == '..') continue;
$path = $dir . '/' . $file;
if(is_dir($path)) {
$dirs[] = $path;
} else {
if(preg_match('/^.*\.(php[\d]?|js|txt)$/i', $path)) {
check_files($path);
}
}
}
closedir($dh);
}
}
}
function check_files($this_file) {
$query = $_POST['query'];
$str_to_find = $query;
if ((isset($str_to_find)) && (empty($str_to_find))) {
print '<p>Your search produced no results</p>';
} else {
if(!($content = file_get_contents($this_file))) {
echo("<p>Could not check $this_file</p>\n");
} else {
if(stristr($content, $str_to_find)) {
echo("<p>$this_file -> contains $str_to_find</p>\n");
}
}
unset($content);
}
}
?>
'Your search produced no results' will be printed out once for every file that your loop sees. You should do the check before you call find_files():
if (!isset($str_to_find) || empty($str_to_find)) {
print '<p>Your search produced no results</p>';
} else {
find_files('.');
}
You can then remove that bit of code from check_files().
You have the print statement inside of the check_files() function, which is being called from inside your while... loop. So, yes, it's going to be executed each time that loop executes and the conditions match.
By !== you maybe meant !=?
Related
I'm trying to open a directory, read just files with a .txt format and then display the contents. I've coded it out, but it doesn't do anything, although it doesn't register any errors either. Any help?
$dir = 'information';
If (is_dir($dir)) {
$handle = opendir($dir);
} else {
echo "<p>There is a system error</p>";
}
$entry=array();
while(false!==($file = readdir($handle))) {
if ( !strcmp($file, ".") || !strcmp($file, "..")) {
}
else if(substr($file, -4) == '.txt') {
$entry[] = $file;
}
foreach ($entry as $txt_file) {
if(is_file($txt_file) && is_writable($txt_file)) {
$file_open = fopen($txt_file, 'r');
while (!feof($file_open)) {
echo"<p>$file_open</p>";
}
}
}
}
Help is quite simple.
Instead
$dir = 'information';
If (is_dir($dir)) {
$handle = opendir($dir);
} else {
echo "<p>There is a system error</p>";
}
write (I am sorry for re-formatting of new lines)
$dir = 'information';
if(is_dir($dir))
{
$handle = opendir($dir);
}
else
{
echo "<p>There is a system error</p>";
}
because if has to be written only smallcaps, thus not If.
And the second part rewrite to (again, you may use your own formatting of new lines)
$entry=array();
$file = readdir($handle);
while($file !== false)
{
if(!strcmp($file, ".") || !strcmp($file, ".."))
{
}
elseif(substr($file, -4) == '.txt')
{
$entry[] = $file;
}
foreach ($entry as $txt_file)
{
if(is_file($txt_file) && is_writable($txt_file))
{
$file_open = fopen($txt_file, 'r');
while(!feof($file_open))
{
echo"<p>$file_open</p>";
}
}
}
}
because PHP has elseif, not else if like JavaScript. Also I separated $file = readdir($handle) for possible source of error.
Code part
if(!strcmp($file, ".") || !strcmp($file, ".."))
{
}
elseif(substr($file, -4) == '.txt')
{
$entry[] = $file;
}
should be shortened only to
if(substr($file, -4) == '.txt')
{
$entry[] = $file;
}
because when if part is empty, then it is not neccessary.
That is all I can do for you at this time.
Instead of iterating the directory with readdir, consider using glob() instead. It allows you to specify a pattern and it returns all files that match it.
Secondly, your while loop has an error: you conditionally add the file name to the list of files, but then you always print every file name using a foreach loop. On the first loop it will print the first file. On the second loop it will print the first and second files, etc. You should separate your while and foreach loops to fix that issue (i.e. unnest them).
Using glob, the modified code will look like:
$file_list = glob('/path/to/files/*.txt');
foreach ($file_list as $file_name) {
if (is_file($file_name) && is_writable($file_name)) {
// Do something with $file_name
}
}
I'm using php to delete folders containing images of posts that where deleted. I'm using the code below which I found online and does a good job.
I want to know how can I delete only a specific folder in a folder when there are other folders in it.
When I using the code below, how is it possible to do this?
Using: /dev/images/norman/8 -> Will not delete folder 8
Using: /dev/images/norman/ -> Will delete all folders
Eg:
/dev/images/norman/8 -> I need to delete only this folder
/dev/images/norman/9
/dev/images/norman/10
/dev/images/norman/11
/dev/images/norman/12
<?php
$path = $_SERVER['DOCUMENT_ROOT'].'/dev/images/norman/8';
emptyDir($path);
function emptyDir($path) {
// INITIALIZE THE DEBUG STRING
$debugStr = '';
$debugStr .= "Deleting Contents Of: $path<br /><br />";
// PARSE THE FOLDER
if ($handle = opendir($path)) {
while (false !== ($file = readdir($handle))) {
if ($file != "." && $file != "..") {
// IF IT"S A FILE THEN DELETE IT
if(is_file($path."/".$file)) {
if(unlink($path."/".$file)) {
$debugStr .= "Deleted File: ".$file."<br />";
}
} else {
// IT IS A DIRECTORY
// CRAWL THROUGH THE DIRECTORY AND DELETE IT'S CONTENTS
if($handle2 = opendir($path."/".$file)) {
while (false !== ($file2 = readdir($handle2))) {
if ($file2 != "." && $file2 != "..") {
if(unlink($path."/".$file."/".$file2)) {
$debugStr .= "Deleted File: $file/$file2<br />";
}
}
}
}
if(rmdir($path."/".$file)) {
$debugStr .= "Directory: ".$file."<br />";
}
}
}
}
}
echo $debugStr;
}
?>
<?php
delete_directory($dirname) {
if (is_dir($dirname))
$dir_handle = opendir($dirname);
if (!$dir_handle)
return false;
while($file = readdir($dir_handle)) {
if ($file != "." && $file != "..") {
if (!is_dir($dirname."/".$file))
unlink($dirname."/".$file);
else
delete_directory($dirname.'/'.$file);
}
}
closedir($dir_handle);
rmdir($dirname);
return true;
}
?>
if you are using, version 5.1 and above,
<?php
function deleteDir($dir) {
$iterator = new RecursiveDirectoryIterator($dir);
foreach (new RecursiveIteratorIterator($iterator, RecursiveIteratorIterator::CHILD_FIRST) as $file)
{
if ($file->isDir()) {
rmdir($file->getPathname());
} else {
unlink($file->getPathname());
}
}
rmdir($dir);
}
deleteDir("temporary");
?>
You want to hear about rmdir.
if(is_file($path."/".$file)) {
if(unlink($path."/".$file)) {
$debugStr .= "Deleted File: ".$file."<br />";
}
} else {
if(rmdir($path."/".$file)) {
$debugStr .= "Deleted Directory: ".$file."<br />";
}
}
EDIT: as rmdir can only handle empty dirs, you may use this solution as reported in rmdir's page comments:
function rrmdir($dir) {
foreach(glob($dir . '/*') as $file) {
if(is_dir($file))
rrmdir($file);
else
unlink($file);
}
rmdir($dir);
}
It just recursively deletes everything in $dir, then gets rid of directory itself.
I added an $exclude param to your function, this param it's an array with the names of directories you want to exclude from being deleted, like so:
$path = $_SERVER['DOCUMENT_ROOT'].'/dev/images/norman/';
emptyDir($path); //will delete all under /norman/
emptyDir($path, array('8')); //will delete all under /norman/ except dir 8
emptyDir($path, array('8','10')); //will delete all under /norman/ except dir 8 and 10
function emptyDir($path,$exclude=false) {
// INITIALIZE THE DEBUG STRING
$debugStr = '';
$debugStr .= "Deleting Contents Of: $path<br /><br />";
if (!$exclude) {
$exclude = array();
}
// PARSE THE FOLDER
if ($handle = opendir($path)) {
while (false !== ($file = readdir($handle))) {
if ($file != "." && $file != "..") {
// IF IT"S A FILE THEN DELETE IT
if(is_file($path."/".$file)) {
if(unlink($path."/".$file)) {
$debugStr .= "Deleted File: ".$file."<br />";
}
} else if (!in_array($file, $exclude)) {
// IT IS A DIRECTORY
// CRAWL THROUGH THE DIRECTORY AND DELETE IT'S CONTENTS
if($handle2 = opendir($path."/".$file)) {
while (false !== ($file2 = readdir($handle2))) {
if ($file2 != "." && $file2 != "..") {
if(unlink($path."/".$file."/".$file2)) {
$debugStr .= "Deleted File: $file/$file2<br />";
}
}
}
}
if(rmdir($path."/".$file)) {
$debugStr .= "Directory: ".$file."<br />";
}
}
}
}
}
echo $debugStr;
}
You can use system commands ex. exec("rm -rf {$dirPath}"); or if you want to do it by PHP you have to go recursive, loops won't do it right.
public function deleteDir($path) {
if ($handle = opendir($path)) {
while (false !== ($file = readdir($handle))) {
if ($file != "." && $file != "..") {
// IF IT"S A FILE THEN DELETE IT
if(is_file($path."/".$file)) {
if(unlink($path."/".$file)) {
$debugStr .= "Deleted File: ".$file."<br />";
}
} else {
deleteDir($path."/".$file."/");
rmdir($path."/".$file);
}
}
}
}
}
When I using the code below, how is it possible to do this? Using:
/dev/images/norman/8 -> Will not delete folder 8 Using:
/dev/images/norman/ -> Will delete all folders
I think your problem is that you're missing "/" at the end of "/dev/images/norman/8"
$path='./ggg';
rrmdir($path);
function rrmdir($dir) {
if (is_dir($dir)) {
$objects = scandir($dir);
foreach ($objects as $object) {
if ($object != "." && $object != "..") {
if (filetype($dir."/".$object) == "dir") rrmdir($dir."/".$object); else unlink($dir."/".$object);
}
}
reset($objects);
rmdir($dir);
}
}
I have a huge ammount of photos that need sorting through. I need to know the dimensions of each photo in order to know or it needs re-sizing. As a programmer I'm convinced there must be a quicker way of doing this.
I got quite far. The following code reads the dir and all the sub dirs. But the moment I try to extract the dimensions the loop halts at 8% of all the pictures that need checking. Could it be PHP is not allowed to do more calculations? What is going on!?
This is how far I got:
checkDir('dir2Check');
function checkDir($dir, $level = 0) {
if ($handle = opendir($dir)) {
while (false !== ($entry = readdir($handle))) {
if (!preg_match('/\./i', $entry)) {
echo echoEntry("DIR\\", $entry, $level);
checkDir($dir.'/'.$entry, $level+1);
} else {
if ($entry != "." && $entry != ".." && $entry != ".DS_Store") {
// if I comment the next line. It loops through all the files in the directory
checkFile($entry, $dir.'/'.$entry, $level);
// this line echoes so I can check or it really read all the files in case I comment the proceeding line
//echo echoEntry("FILE", $entry, $level);
}
}
}
$level--;
closedir($handle);
}
}
// Checks the file type and lets me know what is happening
function checkFile($fileName, $fullPath, $level) {
if (preg_match('/\.gif$/i', $fullPath)) {
$info = getImgInfo(imagecreatefromgif($fullPath));
} else if (preg_match('/\.png$/i', $fullPath)) {
$info = getImgInfo(imagecreatefrompng($fullPath));
} else if (preg_match('/\.jpe?g$/i', $fullPath)){
$info = getImgInfo(imagecreatefromjpeg($fullPath));
} else {
echo "XXX____file is not an image [$fileName]<br />";
}
if ($info) {
echo echoEntry("FILE", $fileName, $level, $info);
}
}
// get's the info I need from the image and frees up the cache
function getImgInfo($srcImg) {
$width = imagesx($srcImg);
$height = imagesy($srcImg);
$info = "Dimensions:".$width."X".$height;
imagedestroy($srcImg);
return $info;
}
// this file formats the findings of my dir-reader in a readable way
function echoEntry($type, $entry, $level, $info = false) {
$output = $type;
$i = -1;
while ($i < $level) {
$output .= "____";
$i++;
}
$output .= $entry;
if ($info) {
$output .= "IMG_INFO[".$info."]";
}
return $output."<br />";
}
The following does similar to what you do, only it's using php's DirectoryIterator which in my humble opinion is cleaner and more OOP-y
<?php
function walkDir($path = null) {
if(empty($path)) {
$d = new DirectoryIterator(dirname(__FILE__));
} else {
$d = new DirectoryIterator($path);
}
foreach($d as $f) {
if(
$f->isFile() &&
preg_match("/(\.gif|\.png|\.jpe?g)$/", $f->getFilename())
) {
list($w, $h) = getimagesize($f->getPathname());
echo $f->getFilename() . " Dimensions: " . $w . ' ' . $h . "\n";
} elseif($f->isDir() && $f->getFilename() != '.' && $f->getFilename() != '..') {
walkDir($f->getPathname());
}
}
}
walkDir();
You can simply use getimagesize()
list($width, $height) = getimagesize($imgFile);
I'm having an issue with one of my conditional statements. The code below is a single text search where the user can enter a string and check a set of files within a directory. The code is working great, although I'm just having a small output glitch.
The 2nd conditional below (just before find_files function) is displaying one echo statement in the middle of my search results. In other words, my results are displaying perfectly, although that 2nd conditional statement appears once within the search results.
Even more weird is that the conditional does works when it's supposed to (i.e. when I enter a string and the string "is not found" within the files), so I'm confused. And I know the conditional is not included in a loop, so why would it display at all during the search?
This is the one last glitch I need to work out and this will work great. Any help would be appreciated.
<?php
$query = $_POST['query'];
if ((isset($query)) && (empty($query))) {
echo "<p style=\"color:darkgray; font-family:arial\">Your search produced no results</p>";
}
elseif ((isset($query)) && (!find_files('.'))) {
echo "<p style=\"color:darkgray; font-family:arial\">Your search produced no results</p>";
}
find_files('.');
function find_files($seed) {
if(! is_dir($seed)) return false;
$files = array();
$dirs = array($seed);
while(NULL !== ($dir = array_pop($dirs)))
{
if($dh = opendir($dir))
{
while( false !== ($file = readdir($dh)))
{
if($file == '.' || $file == '..') continue;
$path = $dir . '/' . $file;
if(is_dir($path)) { $dirs[] = $path; }
else { if(preg_match('/^.*\.(php[\d]?|js|txt)$/i', $path)) { check_files($path); }}
}
closedir($dh);
}
}
}
function check_files($this_file)
{
$query = $_POST['query'];
$str_to_find = $query;
if(!($content = file_get_contents($this_file))) { echo("<p style=\"color:darkgray; font-
family:arial\">Could not check $this_file</p>\n"); }
else { if(stristr($content, $str_to_find)) { echo("<p style=\"color:darkgray; font-
family:arial\">$this_file -> contains $str_to_find</p>\n"); }}
unset($content);
}
?>
Simply adding return, won't help. this modified code works and displays no error me
if (!isset($_REQUEST['query']))
{
//Ask for query here :)
//echo "<p style=\"color:darkgray; font-family:arial\">No query specified.</p>";
exit;
}
$query = isset($_REQUEST['query']) ? $_REQUEST['query'] : '';
if (empty($query))
{
echo "<p style=\"color:darkgray; font-family:arial\">Your search produced no results</p>";
exit;
}
$filesFound = find_files('.');
if (!$filesFound)
{
echo "<p style=\"color:darkgray; font-family:arial\">Your search produced no results</p>";
}
function find_files($seed)
{
if (!is_dir($seed)) return false;
$found = false;
$dirs = array($seed);
while (NULL !== ($dir = array_pop($dirs)))
{
if ($dh = opendir($dir))
{
while (false !== ($file = readdir($dh)))
{
if ($file == '.' || $file == '..') continue;
$path = $dir . '/' . $file;
if (is_dir($path))
{
$dirs[] = $path;
}
else
{
if (preg_match('/^.*\.(php[\d]?|js|txt)$/i', $path))
{
if (!$found)
{
$found = check_files($path);
}
}
}
}
closedir($dh);
}
}
return $found;
}
function check_files($this_file)
{
$query = $_REQUEST['query'];
$str_to_find = $query;
if (($content = file_get_contents($this_file)) === false)
{
echo("<p style=\"color:darkgray; font-family:arial\">Could not check $this_file</p>\n");
return false;
}
else
{
if (stristr($content, $str_to_find))
{
echo("<p style=\"color:darkgray; font-family:arial\">$this_file -> contains $str_to_find</p>\n");
return true;
}
}
}
In your second condition, you are checking to see if the condition: !find_files('.') matches. In order to check that condition, PHP is actually running the function at that time to get its return value, which it then checks for the condition.
On top of that, the find_files() function returns false when it is provided with incorrect input, but does not send a return value when it is successful. That means it does not provide the conditional statement with a value that evaluates to positive, so !find_files('.') evaluates to true, and the echo statement runs.
To fix this, you should just add a return true; as the very last line of your find_files() function.
But I'd also recommend fixing the fact that you're running the function twice. Use something like:
if ((isset($query)) && (empty($query))) {
echo "<p style=\"color:darkgray; font-family:arial\">Your search produced no results</p>";
}
else {
$success = find_files('.');
if ((isset($query)) && (!$success)) {
echo "<p style=\"color:darkgray; font-family:arial\">Your search produced no results</p>";
}
}
Instead of:
if ((isset($query)) && (empty($query))) {
echo "<p style=\"color:darkgray; font-family:arial\">Your search produced no results</p>";
}
elseif ((isset($query)) && (!find_files('.'))) {
echo "<p style=\"color:darkgray; font-family:arial\">Your search produced no results</p>";
}
find_files('.');
I wanna check if there any image on a folder from my server. I have this little function in PHP but is not working and I don't know why:
$path = 'folder/'.$id;
function check($path) {
if ($handle = opendir($path)) {
$array = array();
while (false !== ($file = readdir($handle))) {
if ($file != "." && $file != ".." && count > 2) {
echo "folder not empty";
} else {
echo "folder empty";
}
}
}
closedir($handle);
}
Any help will be appreciated, thanks in advance.
It does not work because count is coming from nowhere. Try this instead:
$path = 'folder/'.$id;
function check($path) {
$files = glob($path.'/*');
echo empty($files) ? "$path is empty" : "$path is not empty";
}
Try this function: http://www.php.net/glob
Try This:
$path = 'folder/'.$id;
function check($path) {
if (is_dir($path)) {
$contents = scandir($path);
if(count($contents) > 2) {
echo "folder not empty";
} else {
echo "folder empty";
}
}
closedir($handle);
}
It counts the contents of the path. If there are more than two items, then its not empty. The two items we are ignoring are "." and "..".
Step 1: $query = select * from your_table where id=$id;
Step 2: $path=$query['path_column'];
Step 3: if($path!=null&&file_exit($path)&&$dir=opendir($path)){
while (($file = readdir($dir )) !== false)
{
if ($file == '.' || $file == '..')
{
continue;
}
if($file) // file get
{
$allowedExts = array("jpg");
$extension = pathinfo($file, PATHINFO_EXTENSION);
if(in_array($extension, $allowedExts))
$file[]=$file;
}
$data[file_name'] = $file;
}
closedir($dir);
}