PHP readdir to find xml - php

I inherited a piece of code that has suddenly stopped working. I've isolated the code down to it appears this function is no longer reading the directory and locating the xml file found in it for later processing. I've uploaded versions of the xml file with uppercase and lowercase .xml/.XML extension with the same result: NO XML FILE FOUND
I've verified that the print_r is in fact reading the correct directory where the xml file resides. There are other files in the directory but that has been the case for years. Did something change recently in PHP to stop this code from working?
function GetXMLFile($path) {
$path .= "/";
print_r($path);
$filename = "";
if ($handle = opendir($path)) {
while (false !== ($file = readdir($handle))) {
if ($file != "." && $file != "..") {
if (GetFileExtention($path . strtolower($file)) =="XML") {
$filename = $file;
}
}
}
closedir($handle);
}
return $filename;
}
Later in the code the function is called that is producing the NO XML error. I've confirmed the $config['xml_dir'] variable below matches the print_r directory location above as well.
$cur_xml_file = GetXMLFile($config['xml_dir']);
if ($cur_xml_file == "") {
echo "NO XML FILE FOUND";
exit(0);
}

No, nothing has changed in PHP recently that would cause the code you show to stop functioning. If it doesn't work anymore, the error is somewhere else.
Then again, that's a lot of code to find a file. Why don't you just do change it to
function GetXMLFile($path) {
$all_xml_files = glob("$path/*.{xml,XML}", GLOB_BRACE);
return !empty($all_xml_files) ? realpath($all_xml_files[0]) : "";
}
That will return the absolute path of the first file with an .XML or .xml extension in the given $path or an empty string if no files are found or an error occured.
See if the error goes away when you change it to that.

Related

Using phpseclib to check if file already exists

I'm trying to create a script that will send across files from one server to another. My script successfully does that as well as checks if the file has something in it or not. My next step is to check whether the file already exists on the server; if the file already exists it does not send and if it does not exist, it does send.
I've tried a few different things and can't seem to get my head around it. How can I get it to check whether the file already exists or not? Any help would be appreciated!
(I had a look at some similar questions but couldn't find anything specific to my issue.)
require('constants.php');
$files = $sftp->nlist('out/');
foreach($files as $file) {
if(basename((string) $file)) {
if(strpos($file,".") > 1) { //Checks if file
$filesize = $sftp->size('out/'.$file); //gets filesize
if($filesize > 1){
if (file_exists('import/'.$file)){
echo $file.' already exists';
}
else {
$sftp->get('out/'.$file, 'import/'.$file); //Sends file over
//$sftp->delete('out/'.$file); //Deletes file from out folder
}
else {
echo $file. ' is empty.</br>';
}
}
}
}
}
EDIT: To try and get this to work, I wrote the following if statement to see if it was finding the file test.php;
if (file_exists('test.txt')){
echo 'True';
} else {
echo 'False';
}
This returned true (a good start) but as soon as I put this into my code, I just get a 500 Internal Server Error (extremely unhelpful). I cannot turn on errors as it is on a server that multiple people use.
I also tried changing the file_exists line to;
if (file_exists('test.txt'))
in the hopes that would work but still didn't work.
Just to clarify, I'm sending the files from the remote server to my local server.
There is a closing curly brace missing right before the second else keyword.
Please try to use a code editor with proper syntax highlighting and code formatting to spot such mistakes on the fly while you are still editing the PHP file.
The corrected and formatted code:
require('constants.php');
$files = $sftp->nlist('out/');
foreach ($files as $file) {
if (basename((string)$file)) {
if (strpos($file, ".") > 1) { //Checks if file
$filesize = $sftp->size('out/' . $file); //gets filesize
if ($filesize > 1) {
if (file_exists('import/' . $file)) {
echo $file . ' already exists';
} else {
$sftp->get('out/' . $file, 'import/' . $file); //Sends file over
}
} else {
echo $file . ' is empty.</br>';
}
}
}
}
Your code checks the file exist in your local server not in remote server.
if (file_exists('import/'.$file)){
echo $file.' already exists';
}
You need to check in remote server using sftp object like
if($sftp->file_exists('import/'.$file)){
echo $file.' already exists';
}
Edit:
Add clearstatcache() before checking file_exists() function as the results of the function get cached.
Refer: file_exists

Trying to include files within subdirectories in php but it is showing errors

I am trying to recursively loop through a bunch of subdirectories and include the files within them instead of 'hardcoding' them in, the problem is if I do hardcode the include path it displays correctly but using the below code I keep getting 'failed to open stream: No such file or directory'. I have tried many different approaches and keep getting similar errors. If anybody has a suggestion of what or where I am going wrong I would appreciate it.
include path would be like: (/core/edit_object/border/border_radius.php);
filesInDir('core/edit_object');
function filesInDir($tdir) {
$dirs = scandir($tdir);
foreach($dirs as $file) {
if (($file == '.') || ($file == '..') || ($file == '.DS_Store')) {
} else if (is_dir($tdir.'/'.$file)) {
filesInDir($tdir.'/'.$file);
} else {
//echo '/'.$tdir.'/'.$file."<br>";
include '/'.$tdir.'/'.$file;
}
}
}
Decided I would try a different approach, I found after running the code below that it was returning what I was after although with many many include errors as in my original post. I found after turning off error reporting in php.ini it ran perfectly. Thank to the posters above with their help and suggestions.
$dir = new RecursiveDirectoryIterator('test');
foreach (new RecursiveIteratorIterator($dir) as $filename => $file) {
$search = array('.DS_Store');
$file = str_replace($search, '', $file);
include $file;
}

delete_dir() from Codeigniter doesn't work

I get this error message when I try to delete a directory:
"Unable to delete the file" using PHP Codeigniter's delete_dir('/path/to/my/dir/'). No additional info provided.
There is no problem with the ftp conn (works with everything else), no problem with the file permission (delete_file() works jsut fine)..no problem with the code, the path is also valid. I'm all out of ideas and open for suggestions.
You can use unlink() to remove php directory.
function removedir($dir1) {
if (is_dir($dir1)) {
//scan
$files = scandir($dir1);
//loop through all the files
foreach ($files as $file) {
if ($file != "." && $file != "..") {
if (filetype($dir1."/".$file) == "dir1")
rrmdir($dir1."/".$file);
else
unlink($dir1."/".$file);
}
}
reset($files);
rmdir($dir);
}
}

Cannot open zip file in Windows Explorer which generated by PHP Zip Archive

When I trying to open my zip file which is generated by PHP Zip Archive, there is an alert showing
"Windows cannot open the folder. The Compressed (zipped) Folder
'filename' is invalid." error opening in Windows Explorer.
But I can open the file through 7-zip. In some reason, I have to ensure the zip file can open by Windows Explorer. Is there any problem when I generated the zip file? Please help!
function create_a_zip($files = array(),$dest = '',$root_folder,$overwrite = false) {
if(file_exists($dest) && !$overwrite) {
return false;
}
$valid_files = array();
if(is_array($files)) {
foreach($files as $file) {
if(file_exists($file)) {
$valid_files[] = $file;
}
}
}
if(count($valid_files)) {
$zip = new ZipArchive();
if($zip->open($dest,$overwrite ? ZIPARCHIVE::OVERWRITE : ZIPARCHIVE::CREATE) !== true) {
return false;
}
foreach($valid_files as $valid_file) {
if(is_dir($valid_file) === true){
foreach(glob($valid_file . '/*') as $file){
$zip->addFile($file, $root_folder . $file);
}
}else if (is_file($valid_file) === true){
$zip->addFile($valid_file, $root_folder . $valid_file);
}
}
$zip->close();
return file_exists($dest);
}
else
{
return false;
}
}
For me, the solution was to use ob_end_clean() before outputting zip file contents (as noted by #Ywis in the comments)...
ob_end_clean();
readfile($zipfilename); // outputs zip file's content
... even if you don't output any characters before that.
I think the problem originates from:
$zip->addFile($file,$file);
Unless you have your php script in the same directory as the files you want to add to zip, you will need to include the file path. The 2nd parameter in addFile is the name of the file inside the zip, so if your $file var includes the path, that’s where the issue probably coming from. Try to change the code to :
$filenameonly = preg_replace("/(.*)\/?([^\/]+)/","$2",$file);
$zip->addFile($file,$filenameonly );
which will strip out the file path (if any) and leave you only the file name for the 2nd variable in addFile.
If this will solve your problem you will know for sure that the problem was in your filenames and can pinpoint it easily.
Just send as parameter to absolute path for example $abspath. Then use it in
$filenameonly = str_replace($abspath,"",$file);
$zip->addFile($file, $filenameonly);
It works 100% even in Window 8 and even your files you zip are in folders.
Instead of using str_replace string function, you can use built-in file-system functions.
$zip->addFile(realpath($file), pathinfo($file, PATHINFO_BASENAME));
Windows zip does not recognize paths begining with "/"
Just remove the first "/" in the filepath.
Like this:
if ( substr($root_folder,0,1) == '/' ) {
$root_folder = substr($root_folder,1);
}
$zip->addFile($file, $root_folder . $file);

PHP - check if file is finished encoding

I have a .bat file that encodes an mp3 file on the server side, and I also have a php function that checks if the file exists, and then adds it as an HTML list item. The problem I'm running into - sometimes the mp3 file isn't done encoding on the server side. If somebody were to try downloading the file while it's in the process of encoding it will crash the browser.
Can I check to make sure the filesize is finished increasing before listing the item?
Here's the function that checks if the file exists:
function ListDir($dir_handle,$path) {
global $listing;
echo "<ul>";
while (false !== ($file = readdir($dir_handle))) {
$dir =$path . $file;
if(is_dir($dir) && $file != '.' && $file !='..' && filesize($file) {
$handle = #opendir($dir) or die("Unable to open file $file");
echo "<li>".$dir;
ListDir($handle, $dir);
echo "</li>";
} elseif($file != '.' && $file !='..' && $file !='.htaccess') {
$new_string = ereg_replace("[^A-Za-z.]", "", $file);
echo '<li>'.str_replace('wav', 'mp3', $new_string).'</li>';
}
}
echo "</ul>";
closedir($dir_handle);
}
Have the bat encode, then move to a final location for a "finished" state, if it doesn't exist there - it's not done. This is similar to drew010's answer except it utilizes the same file, from a working directory to a production directory.
This also prevents it being accessible by any resources until it's ready which could potentially cause problems.
You can't really know the final filesize, so have your bat file create a file like mp3filename.work or something and then have the bat file delete it when the encoding finishes, so if the .work file doesn't exist, then the encoding is done.

Categories