Is it possible to find a file on C:/ (windows) using php script? If yes, is there any manual of sample code/workaround.
Edit : The webserver are on same PC as C:/ Directory in.
Thank you
If you're looking for a recursive search you might be interested in the spl's RecursiveDirectoryIterator.
<?php
$path = 'C:/';
$file = 'issetup.exe';
$rdi = new RecursiveDirectoryIterator($path);
$rit = new RecursiveIteratorIterator($rdi);
foreach( $rit as $path=>$info ) {
if ( $file===$info->getFilename() ) {
echo $path, "\n";
break;
}
}
As long as you only want to look in one directory, then yes, coding it using the PHP functions is quicker. But if you want to search recursively through the tree for a particular filename then it'll probably be a lot quicker to shell out:
$cmd="dir $fname /s"
chdir("C:/");
$found=explode("\n",`$cmd`);
But I believe that these days NT has file indexing built in to the OS - so there must be hooks exposed somewhere for an even faster search.
C.
I use scandir for this purpose, like so:
$path = $_SERVER['DOCUMENT_ROOT'];
$files = scandir($path);
echo '<pre>';
if (count($files) > 2) {
// first 2 entries are '.' and '..'
$files = array_slice($files, 2);
print_r($files);
}
echo '</pre>';
Go read up on http://php.net/manual/en/function.scandir.php
And for help on manululating the resulting array: http://php.net/manual/en/ref.array.php
If you are talking about the server on whcih PHP is installed, it should be infinitely possible with the PHP file command, as long as you are accessing areas of the HDD that share permissions with the webserver. The first example on PHP.net says as much ...
http://php.net/manual/en/function.file.php
If you are talking about your user's machine, they can select a file to upload using a <input id="uploader" name="uploader" type="file"> form element, but you cannot browse it using any server side language, because it is exactly that.
Unless you're talking about the C: drive on the server, or a command-line version of PHP running on your Windows machine, PHP as a server side language, doesn't have access to your C: drive.
If you are referring to the C: drive on the server, then the readdir function (as haim evgi suggested) should work for you.
Remember to read the warning on the readdir reference page, and remember to open the directory first. The function reference provides sample code.
I assume you want to run from the actual PHP interpreter (ie as a local script), you can use SPL(php 5)
see here and here for just 2 examples. More examples if you read the PHP manual and lots of others on the web if you search hard enough.
Related
This question already has an answer here:
Security vulnerabilities with file_get_contents() using variable location
(1 answer)
Closed 3 years ago.
Is it possible to read any file (not only those with the extension .html) from the server in the following script?
<?php
echo file_get_contents($_GET['display'].'.html');
?>
I know about wrappers (php://, file://, etc.) but achieved not too much.
I'm eager to hear all the possible vectors of attack.
The PHP configuration is default:
allow_url_fopen On, and let's assume the version is >= 7.0, so null character %00 doesn't work.
No, that will only ever read files ending in '.html', but that doesn't necessarily mean that it's secure! Generally, the more that you can sanitise and restrict the input, the better.
Also, for anyone planning to use file_get_contents like this, it's always good to remember that when serving from file_get_contents, you can serve files that are not normally accessible - either due to server configuration, e.g. .htaccess, or file permissions.
As #David said, this will only get files ending in '.html', but its not a good practice, if you have html folder and you want the user to get only files from that folder , you shouldn't do that, by using this method a hacker can access any .html file in your server, not just the ones you want him to see.
My suggestion is that if you have a specific folder that you want user to be able to get files from, scan the directory and check for the file name.
Here's an example:
<?php
$paths = scandir('/html');
$file = isset($_GET['display']) : $_GET['display'] ? null;
if(!$file)
{
die('no display provided');
}
$html = '';
foreach($paths as $path) {
if($path !== '.' && $path !== '..' && $path === $file.'.html') {
$html = file_get_contents($path);
}
}
echo $html;
?>
Exploidale as proxy:
http://example.com/script.php?display=https://hackme.com/passwords%3Extension%3D
echo file_get_contents("https://hackme.com/passwords?Extension=.html")
Your IP will be logged on hackme.com machine and return some passwords (when lucky).
In windows, I open a dir, read the files, and for each file, run stat to determine the size, etc.
The problem is that when I run stat on a folder SHORTCUT, it comes back as a FOLDER, and I can't see anywhere in the mode bitmask that might indicate this. This has been true for all of the folder shortcuts in c:\Documents and Settings\myUserName\.
For these shortcuts, is_file returns false, is_dir returns true and is_link isn't supported in XP.
Here's an excerpt from my code (it has been trimmed down, so there may be bugs) :
if(($h=#opendir($root))!==false){
while (false !== ($file = readdir($h))){
if(!($file=="." || $file=="..")){
if( $stat = #lstat($root . $file) ){
$ary[0] = $file;
$ary[1] = $root;
$ary[2] = Date("m/d/y H:i:s", $stat['mtime']);
if($stat['mode'] & 040000){
$ary[3]="dir";
$ary[4]=0;
}else{
$ary[3] ="file";
$ary[4] = $stat['size'];
}
echo(json_encode($ary));
}
}
}
}
A workaround for this will be appreciated...
EDIT: Winterblood's solution almost worked
First off - my bad - it's a win7 machine.
Thanks Winterblood for the quick turnaround - this worked for several of the shortcuts, and the PHP manual says just that... However,
c:\users\myUserName\AppData\Local\Application Data
(and others) are still coming back as directories, while winSCP correctly sees them as shortcuts. As a matter of fact, the 'mode' is 040777, which is exactly the same as many real folders.
Any other suggestions?
PHP's stat() function "follows" shortcuts/symlinks, reporting details on the linked file/folder, not the actual link itself.
For getting stat details on the link itself use lstat().
More information in the PHP documentation on lstat.
I've got two servers. One for the files and one for the website.
I figured out how to upload the files to that server but now I need to show the thumbnails on the website.
Is there a way to go through the folder /files on the file server and display a list of those files on the website using PHP?
I searched for a while now but can't find the answer.
I tried using scanddir([URL]) but that didn't work.
I'm embarrassed to say this but I found my answer at another post:
PHP directory list from remote server
function get_text($filename) {
$fp_load = fopen("$filename", "rb");
if ( $fp_load ) {
while ( !feof($fp_load) ) {
$content .= fgets($fp_load, 8192);
}
fclose($fp_load);
return $content;
}
}
$matches = array();
preg_match_all("/(a href\=\")([^\?\"]*)(\")/i", get_text('http://www.xxxxx.com/my/cool/remote/dir'), $matches);
foreach($matches[2] as $match) {
echo $match . '<br>';
}
scandir will not work any other server but your own. If you want to be able to do such a thing your best bet to have them still on separate servers would be to have a php file on the website, and a php file on the file server. The php file on your website could get file data of the other server via the file server php file printing data to the screen, and the webserver one reading in that data. Example:
Webserver:
<?php
$filedata = file_get_contents("url to file handler php");
?>
Fileserver:
<?php
echo "info you want webserver to read";
?>
This can also be customized for your doing with post and get requests.
I used the following method:
I created a script which goes through all the files at the file server.
$fileList = glob($dir."*.*");
This is only possible if the script is actually on the fileserver. It would be rather strange to go through files at another server without having access to it.
There is a way to do this without having access (read my other answer) but this is very slow and not coming in handy.
I know I said that I didn't have access, but I had. I just wanted to know all the possibilities.
I'm looking for a solution to detect changes in folder(s) using php. The application may run on both platforms(linux and windows). I may use different methods for each platform as long as results are the same.
What I desire is :
If a file/folder is added to a directory, I want my app to detect this new file and read its attributes (size,filetime etc)
If a existing file/folder is saved/contents changed/deleted, I need to detect this file is changed
It would be better if I can monitor a base folder outside webroot of apache (such as c:\tmp, or d:\music on windows or /home/ertunc on linux)
I read something on inotify but I'm not sure it meets my needs.
Monitoring the filesystem for changes is a task that should be solved outside PHP. It's not really built to do stuff like this.
There are ready-made tools on both platforms that can monitor file changes that could call a PHP file to do the further processing.
For Linux:
How to efficiently monitor a directory for changes on linux? (looks best at a quick glance)
Monitor Directory for Changes
For Windows:
How to monitor a folder for changes, and execute a command if it does, on Windows?
The second answer in How can I monitor a Windows directory for changes?
So if you are checking compared to the last time you checked rather than just being updated as soon as it changes you could do the following.
You could create an MD5 of a directory, storew this MD5 then compare the new MD5 with the old to see if things have changed.
The function below taken from http://php.net/manual/en/function.md5-file.php would do this for you.
function MD5_DIR($dir)
{
if (!is_dir($dir))
{
return false;
}
$filemd5s = array();
$d = dir($dir);
while (false !== ($entry = $d->read()))
{
if ($entry != '.' && $entry != '..')
{
if (is_dir($dir.'/'.$entry))
{
$filemd5s[] = MD5_DIR($dir.'/'.$entry);
}
else
{
$filemd5s[] = md5_file($dir.'/'.$entry);
}
}
}
$d->close();
return md5(implode('', $filemd5s));
}
This is rather inefficient though, since as you probably know, there is no point checking the entire contents of a directory if the first bit is different.
I would
scan all folders/files and create an array of them,
save this somewhere
run this scan again later [to check if the array still looks the same].
As you have the entire data structure from "time 1" and "now", you can clearly see what has changed. To crawl through the directories, check this: http://www.evoluted.net/thinktank/web-development/php-directory-listing-script and this http://phpmaster.com/list-files-and-directories-with-php/
I have millions of file in a Folder its difficult to read with script so i need to store file in separate folder. just like
Move File to A-D and E-G and H-L and M-P and Q-T and U-W and X-Z with there starting character..
I try to use FTP but million so file did not show in directory correctly (took very long time to display and for moving, some time FTP stuck), also try cpanel etc. but no luck.
if there is a solution with PHP script please let me know, its help me alot.
Well, you could use DirectoryIterator and move the files based on the filename. I'd still rather recommend a more direct approach with SSH or similar (there are things PHP wasn't meant to do - like non-website things); this approach is Remote Client --request--> Web Server --access--> File System.
Other than that, something like
$dirname = dirname(__FILE__);
$iterator = new DirectoryIterator($dirname);
foreach ($iterator as $fileinfo) {
if ($fileinfo->isFile() && $fileinfo->isWritable()) {
$fname = $fileinfo->getFilename();
rename($dirname. DIRECTORY_SEPARATOR .$fname, $dirname. DIRECTORY_SEPARATOR .ucfirst(substr($fname, 0, 1)). DIRECTORY_SEPARATOR .$fname);
}
}
Should move the files into a subdirectory with the same letter as the first character in the filename. If you want to move based on category groups of characters, just put the rename() call into a switch statement.