how to protect url string which is created by GET in php - php

for a filemanagement i want to make an anchor for scanning a specific directory.
I use this echo for it:
echo "<div class='urldir'>"
."<a href='?dir=".dirname($dir).'/'.basename($dir).'/'.$file."'>open dir</a>"
."</div>";
The dirname and basename give me the the right path to the directory.
this is the normal "root" directory for the users:
$dir = 'uploads/sfm/'.$UserID;
When i user created a folder in his root, he must be able to see the files in that folder.To change the directory and show all the files in that directory, i use this
$actual_link = "http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
$strArr = explode("=",$actual_link);
$CurrentPath = $strArr[1];
if(isset($_GET['dir'])) {
$dir = $CurrentPath;
}
So i read the dir from the url and the variable $dir changes
The problem: the url shows me a string like this:
sfm?dir=uploads/sfm/c4ca4238a0b923820dcc509a6f75849b/folder
When i type now in the url:
sfm?dir=uploads/
he shows me the files in uploads folder. This must be protected!
Nobody should be able to see this.
And also this must be protected from view:
sfm?dir=uploads/sfm/
How can i achieve that?
By the way: the hash in the url is because i have the var $UserID md5 hashed
md5($UserID)

$protectedDirectories = array(
array( 'uploads', 'sfm', $userId )
);
$directory = str_replace('\\','',$_GET['dir']);
$directory = trim($directory,'/');
$directory = preg_replace('#[\/]{1,}#','/',$directory);
$stats = false; // True = Protected , False = Cannot enter this directory.
$seperate = explode('/',$directory);
$cntSeperate = count( $seperate );
foreach($protectedDirectories as $pattern ){
if( count( $pattern ) > $cntSeperate ){
continue;
}
$innerStats = true;
foreach( $pattern as $key => $val ){
if( $seperate[ $key ] !== $val ){
$innerStats = false;
break;
}
}
if( $innerStats == false ){
continue;
}
$stats = true;
break;
}
if( $stats == true ){
// Access Granted
}else{
// Access Not Granted
}
Now you can dynamically use your directory access grants. Each array means a pattern. Each array's value is a directory inside directories ( For example : array('uploads', 'sfm') means uploads/sfm )

A sample solution is to grab the md5 directory using a regular expression.
Something like this:
$res = preg_match('/uploads\/sfm\/([a-f0-9]{32}).*/', $dir, $matches);
if (!$res || $matches[1] != md5($UserID)) {
// user requested a directory he has no access to. Take additional
// actions, e.g. return HTTP status 403
exit('No access here');
}

Related

PHP File count inside a folder

I'm using bootstrap tables and rows to count how much files are in a folder, but the destination is pointing to a different server the code below does not work.
As i'm using localhost (xampp) trying to do this don't know if its possible.
<?php
// integer starts at 0 before counting
$i = 0;
$dir = 'uploads/'; <!--\\189.207.00.122\folder1\folder2\folder3\test-->
if ($handle = opendir($dir)) {
while (($file = readdir($handle)) !== false){
if (!in_array($file, array('.', '..')) && !is_dir($dir.$file))
$i++;
}
}
// prints out how many were in the directory
echo "There were $i files";
?>
Here is a handy little function you might want to try out. Just pass the path to the Directory as the first argument to it and you'd get your result.
NOTE: This Function is RECURSIVE, which means: it will traverse all sub-directories... to disable this behaviour, simply comment out or delete the following lines towards the end of the Funciton:
<?php
}else if(is_dir($temp_file_or_dir) && !preg_match('/^\..*/', $val) ){
getFilesInFolder($temp_file_or_dir);
}
THE CODE:
<?php
$folder = dirname(__FILE__).'/uploads'; // ASSUMES YOUR uploads DIRECTORY
// IS IN THE SAME DIRECTORY AS index.php
// (/htdocs/php/pages)
// OR
$folder = dirname(__FILE__).'/../uploads'; // ASSUMES YOUR uploads DIRECTORY
// IS ONE DIRECTORY ABOVE
// THE CURRENT DIRECTORY (/htdocs/php)
// THIS IS MOST LIKELY RIGHT
// OR
$folder = dirname(__FILE__).'/../../uploads';// ASSUMES YOUR uploads DIRECTORY
// IS TWO DIRECTORIES ABOVE
// THE CURRENT DIRECTORY (/htdocs)
// MAKE SURE THE FOLDER IN QUESTION HAS THE RIGHT PERMISSIONS
// OR RATHER CHANGE PERMISSIONS ON THE FOLDER TO BE ABLE TO WORK WITH IT
chmod($folder, 0777);
var_dump(getFilesInFolder($folder));
// IF YOU PASS false AS THE THE 2ND ARGUMENT TO THIS FUNCTION
// YOU'D GET AN ARRAY OF ALL FILES IN THE $path2Folder DIRECTORY
// AS WELL AS IN SUB-DIRECTORIES WITHIN IT...
function getFilesInFolder($path2Folder, $countOnly=true){
$files_in_dir = scandir($path2Folder);
$returnable = array();
foreach($files_in_dir as $key=>$val){
$temp_file_or_dir = $path2Folder . DIRECTORY_SEPARATOR . $val;
if(is_file($temp_file_or_dir) && !preg_match("#^\..*#", $temp_file_or_dir)){
$arrRX = array('#\.{2,4}$#', '#\.#');
$arrReplace = array("", "_");
$returnVal = preg_replace($arrRX, $arrReplace, $val);
$returnable[$returnVal] = $temp_file_or_dir;
}else if(is_dir($temp_file_or_dir) && !preg_match('/^\..*/', $val) ){
getFilesInFolder($temp_file_or_dir);
}
}
return ($countOnly) ? count($returnable) : $returnable;
}
Use $_SERVER['DOCUMENT_ROOT'] to get your root directory.
$dir = $_SERVER['DOCUMENT_ROOT'].'/uploads/';

Exploring a file structure using php using scandir()

I am new to php and trying to learn how to navigate a local file structure in for the format:
-Folder
-SubFolder
-SubSubFolder
-SubSubFolder
-SubFolder
-SubSubFolder
...
From another stackoverflow question I have been able to use this code using scandir():
<?php
$scan = scandir('Folder');
foreach($scan as $file)
{
if (!is_dir($file))
{
$str = "Folder/".$file;
echo $str;
}
}
?>
This allows me to generate a list of strings of all the 'SubFolder' in my folder directory.
What I am trying to do is list all the 'SubSubFolder' in each 'SubFolder', so that I can create a string of the 'SubSubFolder' name in combination with its 'SubFolder' parent and add it to an array.
<?php
$scan = scandir('Folder');
foreach($scan as $file)
{
if (!is_dir($file))
{
$str = "Folder/".$file;
//echo $str;
$scan2 = scandir($str);
foreach($scan2 as $file){
if (!is_dir($file))
{
echo "Folder/SubFolder/".$file;
}
}
}
}
?>
This however isn't working, and I wasn't sure if it was because I cannot do consecutive scandir() or if I cannot use $file again.
There is probably a better solution, but hopefully the following will be of some help.
<?php
function getDirectory( $path = '.', $level = 0 ){
$ignore = array( 'cgi-bin', '.', '..' );
// Directories to ignore when listing output. Many hosts
// will deny PHP access to the cgi-bin.
$dh = #opendir( $path );
// Open the directory to the handle $dh
while( false !== ( $file = readdir( $dh ) ) ){
// Loop through the directory
if( !in_array( $file, $ignore ) ){
// Check that this file is not to be ignored
$spaces = str_repeat( ' ', ( $level * 4 ) );
// Just to add spacing to the list, to better
// show the directory tree.
if( is_dir( "$path/$file" ) ){
// Its a directory, so we need to keep reading down...
echo "<strong>$spaces -$file</strong><br />";
getDirectory( "$path/$file", ($level+1) );
// Re-call this same function but on a new directory.
// this is what makes function recursive.
} else {
//To list folders names only and not the files within comment out the following line.
echo "$spaces $file<br />.";
// Just print out the filename
}
}
}
closedir( $dh );
// Close the directory handle
}
getDirectory( "folder" );
// Get the current directory
?>

Duplicate files in php

I am wondering how I can create a function that states:
if a file of name Setup.php exist twice in a folder and/or it's associated sub folders, return a message. if a file with the extension .css exists more then once in a folder or any of its sub folders, return a message
This function would have to be recursive, due to sub folders. and its fine to hard code 'Setup.php' or '.css' as they are the only things looked for.
What I currently have is a bit messy but does the trick (refactoring will come after I figure out this issue)
protected function _get_files($folder_name, $type){
$actual_dir_to_use = array();
$array_of_files[] = null;
$temp_array = null;
$path_info[] = null;
$array_of_folders = array_filter(glob(CUSTOM . '/' .$folder_name. '/*'), 'is_dir');
foreach($array_of_folders as $folders){
$array_of_files = $this->_fileHandling->dir_tree($folders);
if(isset($array_of_files) && !empty($array_of_files)){
foreach($array_of_files as $files){
$path_info = pathinfo($files);
if($type == 'css'){
if($path_info['extension'] == 'css'){
$actual_dir_to_use[] = $folders;
}
}
if($type == 'php'){
if($path_info['filename'] == 'Setup' && $path_info['extension'] == 'php'){
$temp_array[] = $folders;
$actual_dir_to_use[] = $folders;
}
}
}
}
$array_of_files = array();
$path_info = array();
}
return $actual_dir_to_use;
}
if you pass in say, packages and php into the function I will look through the packages folder and return all the sub-folder names, (eg: path/to/apples, path/to/bananas, path/to/fruit, path/to/cat, path/to/dog) that contain Setup with an extension of php.
The problem is if apples/ contains more then one Setup.php then I get: path/to/apples, path/to/apples, path/to/bananas, path/to/fruit, path/to/cat, path/to/dog
So I need to modify this function, or write a separate one, that sates the above sudo code.
problem? I don't know where to begin. So I am here asking for help.
You can find the class ipDirLiterator here - deleting all files in except the one running the delete code.
i hope you got it.
<?php
$directory = dirname( __FILE__ )."/test/";
$actual_dir_to_use = array();
$to_find = "php";
$literator = new ipDirLiterator( $directory, array( "file" => "file_literator", "dir" => "dir_literator" ) );
$literator->literate();
function file_literator( $file ) {
global $actual_dir_to_use, $to_find;
// use print_r( $file ) to see what all are inside $file
$filename = $file["filename"]; // the file name
$filepath = $file["pathname"]; // absolute path to file
$folder = $file["path"]; // the folder where the current file contains
$extens = strtolower( $file["extension"] );
if ( $to_find === "php" && $filename === "Setup.php" ) {
$actual_dir_to_use[] = $folder;
}
if ( $to_find === "css" && $extens === "css" ) {
$actual_dir_to_use[] = $folder;
}
}
function dir_literator( $file ) {}
print_r( $actual_dir_to_use );
// or check
if ( count( $actual_dir_to_use ) > 1 ) {
// here multiple files
}
?>
Q: Is this a homework assignment?
Assuming "no", then:
1) No, the function doesn't need to be recursive
2) Under Linux, you could find matching files like this: find /somefolder -name somefile -print
3) Similarly, you can detect if a match occurs zero, once or more than once in the path like this:
find /somefolder -name somefile -print|wc -l

problem with folder handling with php

Friends,
I have a problem............
Help me please........
Am getting the image url from my client, i want to store those images in my local folder.
if those images are in less, i will save them manually
But they are greater than 5000 images.........
Please give some code to down load all the images with PHP
you could try file_get_contents for this. just loop over the array of files and use file_get_contents('url'); to retrieve the files into a string and then file_put_contents('new file name'); to write the files again.
You may download file using file_get_contents() PHP function, and then write it on your local computer, for example, with fwrite() function.
The only opened question is, where to get list of files supposed to be downloaded - you did not specify it in your question.
Code draft:
$filesList = // obtain URLs list somehow
$targetDir = // specify target dir
foreach ($filesList: $fileUrl) {
$urlParts = explode("/", $fileUrl);
$name = $urlParts[count($urlParts - 1)];
$contents = file_get_contents($fileUrl);
$handle = fopen($targetDir.$filename, 'a');
fwrite($handle, $contents);
fclose($handle);
}
I'm not sure that this is what you want. Given a folder's (where PHP has the authority to get the folder's contents) URL and a URL you want to write to, this will copy all of the files:
function copyFilesLocally( $source, $target_folder, $index = 5000 )
{
copyFiles( glob( $source ), $target_folder, $index );
}
function copyFiles( array $files, $target_folder, $index )
{
if( count( $files ) > $index )
{
foreach( $files as $file )
{
copy( $file, $target_folder . filename( $file ) );
}
}
}
If you're looking to a remote server, try this:
function copyRemoteFiles( $directory, $target_folder, $exclutionFunction, $index = 5000)
{
$dom = new DOMDocument();
$dom->loadHTML( file_get_contents( $directory ) );
// This is a list of all links which is what is served up by Apache
// when listing a directory without an index.
$list = $dom->getElementsByTagName( "a" );
$images = array();
foreach( $list as $item )
{
$curr = $item->attributes->getNamedItem( "href" )->nodeValue;
if( $exclutionFunction( $curr ) )
$images[] = "$directory/$curr";
}
copyFiles( $images, $target_folder, $index );
}
function exclude_non_dots( $curr )
{
return strpos( $curr, "." ) != FALSE;
}
copyRemoteFiles( "http://example.com", "/var/www/images", "exclude_non_dots" );

PHP dynamically populating an array

I have an array that lists folders in a directory. Until now, I've been hardcoding the folder names, but rather than do that, I thought I could easily create a script to parse the directory and just assign each folder name to the array. That way, I could easily add folders and not have to touch the script again...
The subject array creates an options list pulldown menu listing each folder...
Currently, the array is hardcoded like so...
"options" => array("folder one" => "folder1", "folder two" => "folder2")),
But I'm trying to make it dynamic based on whatever folders it finds in the given directory.
Here's the script I'm using to parse the directory and return the foldernames to the array. It works fine.
function getDirectory( $path = '.', $level = 0 )
{
// Directories to ignore when listing output.
$ignore = array( '.', '..' );
// Open the directory to the handle $dh
$dh = #opendir( $path );
// Loop through the directory
while( false !== ( $file = readdir( $dh ) ) )
{
// Check that this file is not to be ignored
if( !in_array( $file, $ignore ) )
{
// Show directories only
if(is_dir( "$path/$file" ) )
{
// Re-call this same function but on a new directory.
// this is what makes function recursive.
//echo $file." => ".$file. ", ";
// need to return the folders in the form expected by the array. Probably could just add the items directly to the array?
$mydir2=$mydir2.'"'.$file.'" => "'.$file. '", ';
getDirectory( "$path/$file", ($level+1) );
}
}
}
return $mydir2;
// Close the directory handle
closedir( $dh );
}
And here's my first take at getting those folders into the array...
$mydir = getDirectory('/images/');
"options" => array($mydir)),
But obviously, that doesn't work correctly since its not feeding the array properly I just get a string in my options list... I'm sure this is an easy conversion step I'm missing...
Why not just look at php.net? It has several examples on recursive dir listing.
Here is one example:
<?php
public static function getTreeFolders($sRootPath = UPLOAD_PATH_PROJECT, $iDepth = 0) {
$iDepth++;
$aDirs = array();
$oDir = dir($sRootPath);
while(($sDir = $oDir->read()) !== false) {
if($sDir != '.' && $sDir != '..' && is_dir($sRootPath.$sDir)) {
$aDirs[$iDepth]['sName'][] = $sDir;
$aDirs[$iDepth]['aSub'][] = self::getTreeFolders($sRootPath.$sDir.'/',$iDepth);
}
}
$oDir->close();
return empty($aDirs) ? false : $aDirs;
}
?>
You want to create an array, not a string.
// Replace
$mydir2=$mydir2.'"'.$file.'" => "'.$file. '", ';
// With
$mydir2[$file] = $file;
Also, close $dh before returning. Now, closedir is never called.
Here is a simple function that will return an array of available directories, but it is not recursive in that it has a limited depth. I like it because it is so simple:
<?php
function get_dirs( $path = '.' ){
return glob(
'{' .
$path . '/*,' . # Current Dir
$path . '/*/*,' . # One Level Down
$path . '/*/*/*' . # Two Levels Down, etc.
'}', GLOB_BRACE + GLOB_ONLYDIR );
}
?>
You can use it like this:
$dirs = get_dirs( WP_CONTENT_DIR . 'themes/clickbump_wp2/images' );
If you're using PHP5+ you might like scandir(), which is a built-in function that seems to do pretty much what you're after. Note that it lists all the entries in a folder - files, folders, . and .. included.

Categories