PHP Empty folder not deleting with rmdir command - php

My code is as below:
<?php
header("Location: ../");
unlink("index.php");
unlink("style.css");
unlink("success.php");
unlink("fail.php");
unlink("remove.php");
unlink("README.md");
unlink(".gitignore");
unlink(".git");
rmdir("../Humble-Installer");
die();
But every time I run it I receive the following error:
[17-Nov-2014 19:47:37 Pacific/Auckland] PHP Warning: unlink(.git): Operation not permitted in /Users/user/Humble/admin/Humble-Installer/remove.php on line 10
[17-Nov-2014 19:47:37 Pacific/Auckland] PHP Warning: rmdir(../Humble-Installer): Directory not empty in /Users/user/Humble/admin/Humble-Installer/remove.php on line 11
I have no idea, the directory is empty but will not delete... even if I remove the unlink(."git"); it still throws an error?
Cheers.

You can use this simple function to delete folder recursively:
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);
}
}
Notes:
unlink is for a file, .git is a directory, so it won't remove, use rmdir. If you want to do it recursively, use function I wrote above.
Update
If you want to use RecursiveIteratorIterator, you can use this function:
/**
* Remove directory recursively.
*
* #param string $dirPath Directory you want to remove.
*/
function recursive_rmdir($dirPath)
{
foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dirPath, FilesystemIterator::SKIP_DOTS), RecursiveIteratorIterator::CHILD_FIRST) as $path) {
$pathName = $path->getPathname();
echo $pathName."\n";
($path->isDir() and ($path->isLink() === false)) ? rmdir($pathName) : unlink($pathName);
}
}

simplest function using glob
function removeDirectory($directory)
{
$files=glob($directory.'/*');
foreach ($files as $file)
{
if(is_dir($file))
{
removeDirectory($file);
continue;
}
unlink($file);
}
rmdir($directory);
}
this function will delete all the files and folders inside the given directory and at the end directory it self.

Related

Call function again if array

I got a router in my MVC, it works fine but I think it can be shortened twice because anything beside of if (is_array($path)) and after else is the same
Currently I just copied code when condition is_array returns true and use foreach to loop through $path. When condition is_array is false it just use else statement.
public function run()
{
// Get string of query
$uri = $this->getURI();
// Check availability of query in routes.php
foreach ($this->routes as $uriPattern => $path) {
// Compare $uriPattern and $uri
if (preg_match("~$uriPattern~", $uri)) {
if (is_array($path)) {
foreach ($path as $p) {
//***logic here***
}
} else {
//***same logic here but for a string***
}
Currently my code is bigger than it should because 50% of it just a copy af itself. Can you suggest what would be a more elegant way to split array and loop though paths? I thought about recursion but kinda don't know how to apply it in this case.
Thanks
public function run()
{
$uri = $this->getURI();
foreach ($this->routes as $uriPattern => $path) {
if (preg_match("~$uriPattern~", $uri)) {
if (!is_array($path)) {
$path = [$path];
}
foreach ($path as $p) {
do_logic($p);
}
}
}
}

How to configure Twig to find templates?

I am using Twig with Slim, and am getting the following error:
Warning: file_get_contents(application/templates/config.html): failed
to open stream: No such file or directory in
/var/www/testing/vendor/twig/twig/lib/Twig/Loader/Filesystem.php on
line 131
The script below is located in /var/www/testing/html/index.php, and I have verified that the template exists at /var/www/testing/application/templates/config.html.
$container['view'] = function ($c) {
$view = new \Slim\Views\Twig('../application/templates', [
//'cache' => 'path/to/cache' // See auto_reload option
'debug' => true,
'strict_variables'=> true
]);
$view->addExtension(new \Slim\Views\TwigExtension(
$c['router'],
$c['request']->getUri()
));
$view->addExtension(new \Twig_Extension_Debug());
return $view;
};
$app->get('/config', function (Request $request, Response $response) {
return $this->view->render($response, 'config.html',[]);
});
Line 131 is shown below and returns config.html.
public function getSource($name)
{
return file_get_contents($this->findTemplate($name));
}
I have used this same script in another similar server (however, maybe different PHP version and php.ini and httpd.conf may be different), and do not have this issue?
Obviously, I have configured something incorrectly. How should I configure Twig to find templates?
Yes, that's a problem (bug?) I've encountered last week, and #geggleto solved it.
This is because of Twig update from v1.26.1 from 1.24.2.
This is how Twig grabbed in 1.24.2 (method Twig_Loader_Filesystem::normalizeName):
protected function normalizeName($name)
{
return preg_replace('#/{2,}#', '/', str_replace('\\', '/', (string) $name));
}
And this is how it grabs file in 1.26.1:
private function normalizePath($path)
{
$parts = explode('/', str_replace('\\', '/', $path));
$isPhar = strpos($path, 'phar://') === 0;
$new = array();
foreach ($parts as $i => $part) {
if ('..' === $part) {
array_pop($new);
} elseif ('.' !== $part && ('' !== $part || 0 === $i || $isPhar && $i < 3)) {
$new[] = $part;
}
}
return implode('/', $new);
}
See that array_pop($new); line? That's the one that ruins use of relative path.
#geggleto suggested to use absolute path instead of relative, and it worked:
\Slim\Views\Twig(__DIR__.'/../application/templates')
To sum up: this happens because of Twig new version.

OOP problems with instance variables

I've got some problems with a piece of code in my two classes 'File' and 'Folder'. I've created a page which shows me the content of my server space. Therefore I've wrote the class Folder which contains information about it self like 'name', 'path' and 'children'. The children property contains an Array of 'Files' or 'Folders' within this folder. So it's a kind of recursive class. To get the whole structure of a wanted directory I've wrote some recursive backtracking algorithms that are giving me an array of objects for all children in the same structure as my folder on the server. The second algorithm is taking that array and searches an special folder. If it finds this folder the method will return the root path to it and if the folder isn't a subfolder of this directory the algorithm will return false. I've tested all of that methods for the 'Folder' object and it works just fine but now I've detected an error by using my script more intensive.
/**
* find an subfolder within the given directory (Recursive)
*/
public function findFolder($name) {
// is this object the object you wanted
if ($this->name == $name) {
return $this->getPath();
}
// getting array
$this->bindChildren();
$result = $this->getChildren();
// backtracking part
foreach($result as $r) {
// skip all 'Files'
if(get_class($r) == 'File') {
continue;
} else {
if($search_res = $r->findFolder($name)) {
return $search_res;
}
}
}
// loop runned out
return false;
}
/**
* stores all children of this folder
*/
public function bindChildren() {
$this->resetContent();
$this->dirSearch();
}
/**
* resets children array
*/
private function resetContent() {
$this->children = array();
}
/**
* storing children of this folder
*/
private function dirSearch() {
$dh = opendir($this->path);
while($file = readdir($dh)) {
if($file !== "" && $file !== "." && $file !== "..") {
if(!is_dir($this->path.$file)) {
$this->children[] = new File($this->path.$file);
} else {
$this->children[] = new Folder($this->path.$file.'/');
}
}
}
}
In my website I first create a new folder object and then I'm starting to find a subfolder of 'doc' which is call 'test' for example. The folder 'test' is in '/var/www/media/username/doc/test4/test/' located
$folder = new Folder('/var/www/media/username/doc/');
$dir = $folder->findFolder('test');
If I print out $dir it returns a link as I wanted because the folder 'test' is a subfolder of 'docs' but the returned link is not correct. it should be '/var/www/media/username/doc/test4/test' but the result is '/var/www/media/username/doc/test' I've tried to debugg a bit and found out that the folders list which contains all children is keeping the objects with the right links but in the findFolder method in the first if condition the object $this doesn't have the correct path. I don't know why but the the
// backtracking part
foreach($result as $r) {
seems to change the object properties. I hope someone can help me and thanks in advance
Don't reinvent the wheel. PHP already has a class for that purpose named RecursiveDirectoryIterator.
http://php.net/manual/en/class.recursivedirectoryiterator.php

find recursive specific file

I'm trying to find all the files that called "testunit.php".
In addition i want to cut the first 23 chars of the string.
I tried this but this is not working.I get all the files.
$it = new RecursiveDirectoryIterator($parent);
$display = Array ( 'testunit.php');
foreach (new RecursiveIteratorIterator($it) as $file=>$cur) {
{
if ( In_Array ( $cur, $display ) == true )
$file = substr($cur, 23)
fwrite($fh,"<file>$file</file>");
}
Thank you!
see if glob helps you
Try
class TestUnitIterator extends FilterIterator
{
public function accept()
{
return (FALSE !== strpos(
$this->getInnerIterator()->current(),
'testunit.php'
));
}
public function current()
{
return sprintf(
'<file>%s</file>',
substr($this->getInnerIterator()->current(), 23)
);
}
}
Usage (codepad (abridged example)):
$iterator = new TestUnitIterator(
new RecursiveIteratorIterator(
new RecursiveDirectoryIterator(
'/path/to/iterate/over',
FilesystemIterator::CURRENT_AS_PATHNAME
)
)
);
foreach ($iterator as $file) {
echo $file, PHP_EOL;
}
Disclaimer: I wasn't in the mood to mock the filesystem or setup the required test files, so the above might need a little tweaking to work with the filesystem. I only tested with an ArrayIterator but there shouldn't be much to do if the above produces errors.

listing all jpg files in dir and subdirs

How can I list all jpg files in a given directory and its subdirectories in PHP5 ?
I thought I could write a glob pattern for that but I can't figure it out.
thanx, b.
You can use a RecursiveDirectoryIterator with a filter:
class ImagesFilter extends FilterIterator
{
public function accept()
{
$file = $this->getInnerIterator()->current();
return preg_match('/\.jpe?g$/i', $file->getFilename());
}
}
$it = new RecursiveDirectoryIterator('/var/images');
$it = new ImagesFilter($it);
foreach ($it as $file)
{
// Use $file here...
}
$file is an SplFileInfo object.
without doing it for you. recursion is the answer here. a function that looks in a dir and gets a list of all files. filters out only th jpg's then calls its self if i finds any sub dirs
Wish I had time to do more & test, but this could be used as a starting point: it should (untested) return an array containing all the jpg/jpeg files in the specified directory.
function load_jpgs($dir){
$return = array();
if(is_dir($dir)){
if($handle = opendir($dir)){
while(readdir($handle)){
echo $file.'<hr>';
if(preg_match('/\.jpg$/',$file) || preg_match('/\.jpeg$/',$file)){
$return[] = $file;
}
}
closedir($handle);
return $return;
}
}
return false;
}

Categories