PHP condition is being output randomly? - php

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('.');

Related

can i use || and && together?

im trying to open a log file and see if a text does not exist, if it doesnt exist then continue, but at the same time i want to check its the log file has not been sent per mail already.
public function start() {
$pattern = $this->config["twp_pattern"] ?? '*.log';
$pathLog = (isset($this->config["twp_path"])) ? trim($this->config["twp_path"], '/') : 'var/log';
$lastRun = (isset($this->config['twp_last_run'])) ? str_replace('T', ' ', $this->config['twp_last_run']) : false;
$path = getcwd() . '/' . $pathLog . '/' . $pattern;
$this->now = new \DateTime();
foreach (glob($path) as $log) {
$open = fopen($log, 'r') or die ('File opening failed');
$content = fread($open,filesize($log));
var_dump($content);
fclose($log);
if (!$lastRun || filectime($log) < strtotime($lastRun) && $this->checkIfAlreadyExists($content) === false) {
continue;
}
$logs[] = $log;
}
if (!empty($logs)) {
$success =$this->sendMail($logs);
}
if($success === false){
return false;
}
$this->setLastRun();
return true;
}
public function checkIfAlreadyExists($content){
if (!preg_match_all('/already exists/', $content)) {
echo "is not there";
return false;
}else{
echo "is there";
return true;
}
}
my problem is even tho email has been sent, it will send it again when i run
function start()
if i remove the && $this->checkIfAlreadyExists($content) === false, it will not longer send logs per mail that has already been sent. can anyone spot my mistake ? Thanks
Fixed by changing my if statement
if ((!$lastRun || filectime($log) < strtotime($lastRun)) || ($this->checkIfAlreadyExists($content))) {
continue;
}
Thanks for your time and the help ! <3

read files from an array in php

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
}
}

Only first elseif in if/elseif/else statement is working

Only the elseif (isset($foo['read'])) on line 37 is working, the if and first elseif work, when I try to call the second elseif, it returns the first elseif statements output. I have even swapped the two elseif statements and it still only returned the first elseif statement output when calling the second elseif statement.
<?php
$nh = "true";
$foo = file_get_contents("php://input");
//$stuff = json_decode($foo, true);
function savetxt($sttext)
{
$filename = 'test.txt';
$somecontent = $sttext;
if (is_writable($filename)) {
if (!$handle = fopen($filename, 'a')) {
echo "Cannot open file ($filename)";
exit;
}
if (fwrite($handle, $somecontent) === FALSE) {
echo "Cannot write to file ($filename)";
exit;
}
echo "Success, wrote ($somecontent) to file ($filename)";
fclose($handle);
}
else {
echo "The file $filename is not writable";
}
}
if (strpos($foo, 'write:') !== false) {
echo 'Attempting to write!';
$stext = substr($foo, 6);
savetxt($stext);
}
elseif ($foo == "read"){
echo file_get_contents( "test.txt" );
}
elseif ($foo == "test){
echo 'Working!';
}
else {
echo 'Didn't get test.';
}
?>
try this(you must replace else if with elseif)
else if ($foo && $foo=='read')
and
else if ($foo && $foo=='test')
and at end
else if (!$foo || $foo=='')

php deleting a specific folder and all its contents

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);
}
}

PHP Repeating Print Statement

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 !=?

Categories