The code below needs to read the directory uploads/ but he always tells me that the directory is not empty, even when it totally is empty.
<?php
$dir = "uploads/";
echo (count(glob("$dir/*")) === 0) ? 'Empty' : 'Not empty';
?>
Is there a error in this code or anything or am I just going crazy?
UPDATED CODE
<?php
echo (count(glob("uploads/*")) === 0) ? 'Empty' : 'Not empty';
?>
FULL PAGE CODE UPDATE
<?php
if (array_key_exists('error', $_GET)) {
echo '<div class="galleryError">That image could not be found, we're sorry!</div>';
} elseif (array_key_exists('unknownerror', $_GET)) {
echo '<div class="galleryError">There went something wrong</div>';
} else {
echo '';
}
if ($handle = opendir('uploads/')) {
while (false !== ($entry = readdir($handle))) {
if ($entry != "." && $entry != "..") {
echo "<div class='imgbox'><a href='fullscreen.php?token=$entry'><img src='$submap$gallery$entry' class='boximg'></a><p class='boxname'>$entry<br /><a href='?view&token=$entry'><small>View this image</small></a></p></div>";
}
}
closedir($handle);
}
// all the above is working but then we have this lonely code over here which refuses to work.
echo (count(glob("uploads/*")) == 0) ? 'Empty' : 'Not empty';
?>
glob is silently failing. I couldn't tell you why, with file system access it's usually permissions related but there could be other factors - it even says in the documentation that the functionality is partially dependent on your server environment...
On some systems it is impossible to distinguish between empty match and an error.
When there's a glob error it returns false - and count(false) === 1 (also documented) so it's no surprise folks get into confusing situations when they ignore these checks. If you really don't care about errors you can utilise the short-hand ternary operator to make an inline false-check, ensuring an array is always passed to count so it will behave as expected:
$isEmpty = count(glob("uploads/*")?:[]) === 0;
This still doesn't get around the fact that the directory is not being read though - have you tried printing the output of glob when you do have files in the directory? I'd imagine that's borked too. What does the following print? :
var_dump(is_readable('./uploads'));
Does the output of the following match your expected working directory? :
echo realpath('uploads');
FYI use var_dump when debugging, not print_r as suggested in the comments - it will give you more detail about the variables / types / structures / references etc. that you actually need.
In summary - things to consider:
What OS is running on the server? What mode is PHP running in? Is it running under SuPHP / FastCGI or similar context. What user owns the ./uploads directory, what permissions are set on it?
Related
Note: The file number is just so I can refer to each file easier
I am testing some code in which I have a file called first.txt (file 1) and and file called tom-first.php (file 2), file 2 file checks for the file 1's existence and sets a variable, then in my index.php(file 3), I require file 2 and if the variable is 1, I redirect to startup.php(file 4). File 4 deletes a text file called text.txt
My error is when I run the code, no matter what happens, test.txt is always deleted
tom-first.php
<?php
if (file_exists('first.txt')) {
$first = '1';
} else {
$first = '0';
}
echo $first;
?>
index.php
<?php
require 'tom-first.php';
if($first = '1')
{
header("Location: startup.php");
}
else
{
echo 'HI';
}
?>
Startup.php
<?php
unlink('text.txt')
?>
First.txt is Empty
I feel like the error is to do with setting variables on file 2 although echoing out $first shows the right number.
Any help is appreciated, even a completely different method of this would be useful, I am basically trying to make a system where it has a setup that runs on first time use.
You have a typo in index.php file.
Equality comparison operator in PHP is '==', not '='.
Your if statement below assigns value '1' to $first variable and always evaluates to '1'.
index.php
<?php
require 'tom-first.php';
if($first = '1') // this should be $first == '1'
{
header("Location: startup.php");
}
else
{
echo 'HI';
}
?>
With = you make an assignment (you assign a value to a variable). But == is a comparison operator. In your case you're evaluating 1 which is always TRUE. Another thing is, why so verbose and so many files if you can just write:
$first = file_exists('first.txt') ? 1 : 0;
and then the rest. Or even better...
if (file_exists('first.txt') {
unlink('first.txt');
// and do some other stuff
}
echo 'whatever';
But... :)
If you have to do something like this, it very much smells.
Why would you check for the presence of a file only to delete it right away?
I'd like to be able to search a directory for a file that starts with a specific string, for example:
- foo
- 1_foo.jpg
- 2_bar.png
How would I check directory foo for files that begin with "1_"?
I've tried using file_exists and preg_match like so:
if (file_exists("foo/" . preg_match("/^1_/", "foo/*"))) echo "File exists.";
but this doesn't work.
Sounds like you need the glob() function. The glob() function searches for all the pathnames matching pattern according to the rules used by the libc glob() function, which is similar to the rules used by common shells.
<?php
foreach (glob('1_*.*') as $filename) {
echo "$filename\n";
}
?>
The above example will output something similar to:
1_foo.png
1_bar.png
1_something.png
Sorry, but the filesystem doesn't understand wildcards or regular expressions. To accomplish what you want, you have to open the directory and read its contents, getting a list of all the files in that directory. Then you use standard string utilities to see which filenames match your criteria.
I think PHP's scandir is what you want as a starting point. You can also use glob but that actually forks a shell to get the file list (which in turn will do the C equivalent of scandir()).
You can use the glob() function
<?php
$list = glob('1_*.*');
var_dump($list);
I was having some trouble checking a directory and files and I gather some scripts here and there and this worked for me (Hope it helps u too):
if ($handle = opendir('path/to/folder/'))
{
while ( false !== ($entry = readdir($handle)) ) {
if ( $entry != "." && $entry != ".." ) {
// echo "$entry<br>";
if (preg_match("/^filename[0-9]_[0-9].jpg/", $entry))
{
// $found_it = TRUE;
}
}
}
closedir($handle);
}
I am working on my 404 error doc, and I was thinking instead of just giving a sitemap, one could suggest to the user the website he might have looked for based on what actually exists on the server.
Example: if the person typed in "www.example.com/foldr/site.html", the 404 page could output:
Did you mean "www.example.com/folder/site.html"?
For this, I wrote the following code which works for me very well. My question now is: is it "safe" to use this? As basically someone could detect all files on the server by trying all kind of combinations. Or a hacker could even use a script that loops through and lists all types of valid URLs.
Should I limit the directories this script can detect and propose? With an array of "OK"-locations, or by file type?
Had anyone else already got an idea like this?
PHP:
// get incorrect URL that was entered
$script = explode("/",$_SERVER['SCRIPT_NAME']);
$query = $_SERVER['QUERY_STRING'];
// create vars
$match = array();
$matched = "../";
// loop through the given URL folder by folder to find the suggested location
foreach ($script as $dir) {
if (!$dir) {
continue;
}
if ($handle = opendir($matched)) {
while (false !== ($entry = readdir($handle))) {
if ($entry != "." && $entry != "..") {
similar_text($dir, $entry, $perc);
if ($perc > 80) {
$match[$entry] = $perc;
}
}
}
closedir($handle);
if ($match) {
arsort($match);
reset($match);
$matched .= key($match)."/";
} else {
$matched = false;
break;
}
$match = array();
}
}
// trim and echo the result that had the highest match
$matched = trim(ltrim(rtrim($matched,"/"),"."));
echo "proposed URL: ".$_SERVER["SERVER_NAME"].$matched;
Yup, you can see it as this:
Imagine a house with only glass walls on the outside, but it's night. You're a thief (hacker) and you want to check the house for worthfull loot (files with passwords, db connections etc).
If you don't protect (certain) files, you would be putting the lights on in every part of the house. The thief would look through the windows and see that you have loot - now the only the he would have to do is get in and take it.
If you do protect the files, the thief won't even be able to know that there was any loot in the house, and thus would the thief have a higher chance of moving on to the next house.
I am using readdir in the following code to get a list of all file names of images in a directory.
while (false !== ($entry = readdir($frameDir))){
$shapeName = explode('.',$entry);
if (!empty($shapeName[0]) && $shapeName[0] != '.' && $shapeName[0] != '..' && $shapeName[0] != '/'){
$shapeName = $shapeName[0];
$shapes['frames'][] = $shapeName;
}
After this code the script appends the '.png' to make it a valid file name.
As you can see I've tried to eliminate any chances of a blank file name being passed. Though when I run the script I end up getting a blank directory "/shapes/frame/.png" . This only happens for this particular directory. When I use the code on another of the three directories I get results as expected, and the code is the same logic as what is used above.
while (false !== ($entry = readdir($frameDotDir))){
$shapeName = explode('.',$entry);
if (!empty($shapeName[0]) && $shapeName[0] != '.' && $shapeName[0] != '..' && $shapeName[0] != '/'){
$shapeName = $shapeName[0];
$shapes['frame_dots'][] = $entry;
}
}
When checking the filesystem on the server, I can't find any files with blank names.
I am wondering what could be causing my script to be reading blank file names from the diretory.
File names cannot be empty (and will not). You did something wrong in your code. It should look like:
while ($entry = readdir($frameDir)){
// skip files which names starting with a dot
// like '.', '..' or hidden files
if (strpos($entry, '.') !== 0) {
$shapes['frame_dots'][] = $entry;
}
}
You see, less is more ;)
Why don't you use glob() instead of readdir().Just give it a pattern and it will let you process the filenames with much ease instead of doing the one by one scanning work. And in your case, there is no way it will return an empty file name. Also, have a look on glob flags in the documentation, you will be amazed of it's simplicity.
glob("*.png");
Output:
Array ( [0] => shape.png, [1] => shape2.png )
I was having the same problem with blank filenames usind readdir() it turn out to be that the directory name was wrong, turns out linux is case sensitive, in code the directory name starts with "I" and in linux the directory started with "i".
I guess the error was due to not handling opendir() errors. Check your code.
I already saw this question, but it didn't work for me.
What I need to do is to check whether a file exists, in PHP, without knowing the extension.
I use this code:
<?php
if (count(glob("/database/".$_REQUEST['thetitle'].".*")) == 0) {
echo 'true';
} else {
echo 'false';
}
?>
EDIT:
Maybe it's relevant saying that the script is located in
[root]/functions/validatefilename.php
and the database in
[root]/database/
But it always returns false, no matter what the filename ($_REQUEST['thetitle']) is.
try:
count(glob("./database/".$_REQUEST['thetitle'].".*"))
Looks to me like it works fine except that you should be specifying the full path:
if (count(glob( "/path/to/" . "database/" .$_REQUEST['thetitle']. ".*")) == 0) {