what permissions do I need to use php to write to file?

diabolo

Community Advocate
Community Support
Messages
1,682
Reaction score
32
Points
48
Code:
Warning:  fopen(*****) [[URL="http://localhost/mcs/gallery/function.fopen"]function.fopen[/URL]]: failed to open stream: Permission denied in C:\xampp\htdocs\mcs\sources\functions\gallery.php on line 48
can't open file

PHP:
function createGalleryDirectory($name) {
   if(!is_dir($name)) {
      $path = ROOT.'gallery/'.$name;
      mkdir($path, 0777);
   }
}
 

Twinkie

Banned
Messages
1,389
Reaction score
12
Points
0
755 works fine with most files. The directory and the file must both have permissions set to allow local access. There is nothing wrong with the code you posted.
 

misson

Community Paragon
Community Support
Messages
2,572
Reaction score
72
Points
48
Remember that Windows doesn't use Unix style permissions. If you read the PHP.net documentation for mkdir, you'll see that the $mode argument is ignored. Make sure whichever user the Apache process runs as has write access to ROOT . 'gallery/'. You can use procexp to figure out what user httpd runs as. If you run WinXP home, use Reinhard Tchorz's security tab patch to enable the security tab.

What's the definition for ROOT? If it's missing a trailing path separator, that will probably cause the permission denied error. Edit: the reason being the script will try to create a directory within the wrong parent directory, which may have too restrictive permissions.

Lastly, use 'file_exists()' rather than 'is_dir' as the former will return true for existing directories while the latter will return false if $path is a file that's not a directory.
 
Last edited:

Twinkie

Banned
Messages
1,389
Reaction score
12
Points
0
is_dir seem appropriate since he is trying to create a directory, not a file, so it is natuaral he should try to ignore them. Its more concise. Anyway, misson brought up a good point. What operating system are you using?
 
Last edited:

diabolo

Community Advocate
Community Support
Messages
1,682
Reaction score
32
Points
48
right now it is running off xampp on my windows xp

so if I upload it to x10 server's which has linux, it should work?
 

misson

Community Paragon
Community Support
Messages
2,572
Reaction score
72
Points
48
is_dir seem appropriate since he is trying to create a directory, not a file, so it is natuaral he should try to ignore them. Its more concise. Anyway, misson brought up a good point. What operating system are you using?
Except that if he tries to create a directory with the same name as a non-directory file, is_dir() will return false and the mkdir will fail. Directories are a special kind of file, as are symbolic links and junction points; file_exists is very appropriate.

so if I upload it to x10 server's which has linux, it should work?
Maybe. Permissions will always be an issue. They just need to be handled a little differently depending on the OS. First check that the directory is being created where you thing it's being created (print $path), then check the permissions on the directories in the path to see whether or not the web server user has write access.

Do you have an answer for my question about ROOT?
 

diabolo

Community Advocate
Community Support
Messages
1,682
Reaction score
32
Points
48
Do you have an answer for my question about ROOT?

o sorry, i was at a another computer and just scanned the post.
but I know the root is defined and working because it can make the directory, it just can not write a file to it.
Edit:
actually it was because I had an error in my path for the fopen function. but now I have a different problem

PHP:
   $dir_handle = @opendir($url) or die("Unable to open $url");
   $count = "0";
   while ($file = readdir($dir_handle)) {
      if (!is_dir($url.'/'.$file) && ($file="*.jpg" || $file="*.gif" || $file="*.png") && $file!="picture0.*") {
         $galleryEventFile[$count] = $file;
         $count++;
      }
   }
   closedir($dir_handle);

$count is not being changed.
i believe it has to do something with this line, but im not sure
PHP:
if (!is_dir($url.'/'.$file) && ($file="*.jpg" || $file="*.gif" || $file="*.png") && $file!="picture0.*")
 
Last edited:

misson

Community Paragon
Community Support
Messages
2,572
Reaction score
72
Points
48
You need to use glob to expand file patterns or (e.g.) substr to extract the file extension. $file="*.jpg" is just a string comparison; '*' is not magical in any way.
 

diabolo

Community Advocate
Community Support
Messages
1,682
Reaction score
32
Points
48
sorry i should have updated the script once I realized it was wrong.
PHP:
   $dir_handle = @opendir($url) or die("Unable to open $url");
   $count = 0;
   while ($file = readdir($dir_handle)) {
      $extension = pathinfo($file, PATHINFO_EXTENSION);
      $allowedExtensions = array('jpg', 'png', 'gif');
      if (!is_dir($url.'/'.$file) && in_array(strtolower($pathinfo), $allowedExtensions) && !preg_match('/picture0./i', $file)) {
         $galleryEventFile[$count] = $file;
         $count++;
      }
   }
   closedir($dir_handle);
 

Twinkie

Banned
Messages
1,389
Reaction score
12
Points
0
Are you sure according to your debug information that it is entering the if statement appropriately? I don't see anything wrong with that, but I can't tell if it is executing properly. I need some additional info.

I use a function that writes to a file when ever is is called with some info about its surrounding variables (if there is a better way to do this, I am open to ideas). If you want it, I could post it for you.

Also on line 6, misson is right about the file_exists in that small possibility (damn him he is always right).
 
Last edited:

misson

Community Paragon
Community Support
Messages
2,572
Reaction score
72
Points
48
PHP:
      if (!is_dir($url.'/'.$file) && in_array(strtolower($pathinfo), $allowedExtensions) && !preg_match('/picture0./i', $file)) {
In this line, you're checking for $pathinfo in $allowedExtensions, whereas the file extension is stored in $extension.

Efficiency notes: you're reassigning $allowedExtensions each time through the loop even though it's loop invariant. Move it outside the loop and either make it a static variable or a default argument.

in_array() has to scan the array (in formal terms, it's O(n)). Array lookup is much more efficent. Use the power of associative arrays by making the extensions array-keys.

It won't affect performance, but $count is unnecessary. If you don't specify an index to the [] operator when assigning, PHP will assign to the maximum index + 1.

PHP:
function exception_error_handler($errno, $errstr, $errfile, $errline ) {
    throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
}
set_error_handler("exception_error_handler");

...

function readGallery($url, $allowedExtensions = array('jpg' => 1, 'png' => 1, 'gif' => 1)) {
    $galleryEventFile = array();
    if ($dir_handle = opendir($url)) {
        while ($file = readdir($dir_handle)) { 
            $extension = pathinfo($file, PATHINFO_EXTENSION); 
            if (!is_dir($url.'/'.$file) 
                && array_key_exists(strtolower($extension), $allowedExtensions) 
                && !preg_match('/picture0./i', $file))
            {
                $galleryEventFile[] = $file; 
            }
        }
        closedir($dir_handle);
    }
    return $galleryEventFile;
}
 

diabolo

Community Advocate
Community Support
Messages
1,682
Reaction score
32
Points
48
thank you for making it more efficient Mission. but i still have a problem with the $count and I have debugged it down to this.
PHP:
function createGalleryEventFile($year, $title, $url, $allowedExtensions = array('jpg' => 1, 'png' => 1, 'gif' => 1)) {
   $count = 0;
   if ($dir_handle = opendir($url)) { 
      while ($file = readdir($dir_handle)) {
         $extension = pathinfo($file, PATHINFO_EXTENSION);
         //if (!is_dir($url.'/'.$file)
           // && in_array(strtolower($extension), $allowedExtensions)
            //&& !preg_match('/picture0./i', $file)) {
            $galleryEventFile[$count] = $file;
            $count++;
         //}
      }
   }
   closedir($dir_handle);
$count returns 9 in this example.
attached is an image of the files in the directory

and for some reason my Enter key is not working on x10Forums. Had to cut + paste a line break into here. fyi. and apparently its not working for all text-boxes in FF.
 

Attachments

  • dir.jpg
    dir.jpg
    59.6 KB · Views: 15

misson

Community Paragon
Community Support
Messages
2,572
Reaction score
72
Points
48
Two additional entries returned by readdir are "." and "..". Try var_dump or print_r to see what the other entry is. Also print $url to make sure the scripts in the right directory.

You could install XAMPP or WAMP along with the XDebug extension, Eclipse and its PDT extension. This will let you debug web pages.

As for Firefox, check your extensions. I have a vague recollection of an extension being involved with a similar problem on another site. Start Firefox in safe mode to temporarily disable all extensions.
 

diabolo

Community Advocate
Community Support
Messages
1,682
Reaction score
32
Points
48
I added print_r($file)
this is what it returned:

...1.jpg1.thumb.jpg2.jpg3.jpg4.jpgpicture0.jpgThumbs.db...1.jpg1.thumb.jpgpicture0.jpgThumbs.db...1.jpg1.thumb.jpgpicture0.jpgThumbs.db
the other 9th file is Thumbs.db.

so does anybody know how to made the if statement so that it only excepts "1.jpg, 2.jpg, 3.jpg, 4,jpg"


after more debugging I pinpointed it down to this:

PHP:
function createGalleryEventFile($year, $title, $url, $allowedExtensions = array('jpg' => 1, 'png' => 1, 'gif' => 1)) {
   $count = 0;
   if ($dir_handle = opendir($url)) { 
      while ($file = readdir($dir_handle)) {
         $extension = pathinfo($file, PATHINFO_EXTENSION);
         if (!is_dir($url.'/'.$file)
            //&& in_array(strtolower($extension), $allowedExtensions)
            && !preg_match('/picture0./i', $file)) {
            $galleryEventFile[$count] = $file;
            print_r($file);
            $count++;
         }
      }
   }
   closedir($dir_handle);
}
presents this:
Code:
1.jpg1.thumb.jpg2.jpg3.jpg4.jpgThumbs.db1.jpg1.thumb.jpgThumbs.db1.jpg1.thumb.jpgThumbs.db

so I need to fix the script for allowed fileTypes and figure out why for some reason it reads the files over again
 
Last edited:

misson

Community Paragon
Community Support
Messages
2,572
Reaction score
72
Points
48
When I test createGalleryEventFile(), there aren't repeated entries. Rather than calling print_r on $filewithin the loop, call it on $galleryEventFile outside the loop. The point of print_r is to print arrays.
 
Top