Skip to main content
update formatting
Source Link

I'm using some simple files for caching and some basic user data. I was first just using file_put_contensfile_put_contents() and file_get_contents(), but realized this could quickly go wrong when traffic starts increasing.

I've been trying to figure out how to do it properly with flock(), correct file modes, etc, and come up with the following functions. Have I understood things correctly? Will this be safe in most normal use-cases, with small-to-medium web site usage?

class File
{

    public static function read($path, $default = NULL)
    {
        $fp = @fopen($path, 'r');
        if( ! $fp)
            return $default;

        flock($fp, LOCK_SH);
        $data = fread($fp, filesize($path));
        flock($fp, LOCK_UN);
        fclose($fp);

        return $data;
    }


    public static function write($path, $data)
    {
        self::check(dirname($path));

        $fp = fopen($path, 'c');
        flock($fp, LOCK_EX);
        ftruncate($fp, 0);
        fwrite($fp, $data);
        fflush($fp);
        flock($fp, LOCK_UN);
        fclose($fp);

        return $data;
    }



    public static function check($dir)
    {
        if( ! is_dir($dir))
        {
            // https://en.wikipedia.org/wiki/Chmod#System_call
            @mkdir($dir, 06750, true);
            @chmod($dir, 06750);
        }
        return $dir;
    }
}

Some particular things:

  • Should using LOCK_SH in read allow for multiple simultaneous reads?
    (which will be the bulk of what's happening since writes will happen quite seldom)
  • Will using LOCK_EX in write make sure nobody else is reading or writing while the file is changed?
  • Will using the directory permission mask 06750 makes sure that
    1. any files created in that directory will get the same permissions as the directory, and
    2. the directory/file will only be writable by the web server user and readable by its group?

I'm using some simple files for caching and some basic user data. I was first just using file_put_contens and file_get_contents, but realized this could quickly go wrong when traffic starts increasing.

I've been trying to figure out how to do it properly with flock, correct file modes, etc, and come up with the following functions. Have I understood things correctly? Will this be safe in most normal use-cases, with small-to-medium web site usage?

class File
{

    public static function read($path, $default = NULL)
    {
        $fp = @fopen($path, 'r');
        if( ! $fp)
            return $default;

        flock($fp, LOCK_SH);
        $data = fread($fp, filesize($path));
        flock($fp, LOCK_UN);
        fclose($fp);

        return $data;
    }


    public static function write($path, $data)
    {
        self::check(dirname($path));

        $fp = fopen($path, 'c');
        flock($fp, LOCK_EX);
        ftruncate($fp, 0);
        fwrite($fp, $data);
        fflush($fp);
        flock($fp, LOCK_UN);
        fclose($fp);

        return $data;
    }



    public static function check($dir)
    {
        if( ! is_dir($dir))
        {
            // https://en.wikipedia.org/wiki/Chmod#System_call
            @mkdir($dir, 06750, true);
            @chmod($dir, 06750);
        }
        return $dir;
    }
}

Some particular things:

  • Should using LOCK_SH in read allow for multiple simultaneous reads?
    (which will be the bulk of what's happening since writes will happen quite seldom)
  • Will using LOCK_EX in write make sure nobody else is reading or writing while the file is changed?
  • Will using the directory permission mask 06750 makes sure that
    1. any files created in that directory will get the same permissions as the directory, and
    2. the directory/file will only be writable by the web server user and readable by its group?

I'm using some simple files for caching and some basic user data. I was first just using file_put_contents() and file_get_contents(), but realized this could quickly go wrong when traffic starts increasing.

I've been trying to figure out how to do it properly with flock(), correct file modes, etc, and come up with the following functions. Have I understood things correctly? Will this be safe in most normal use-cases, with small-to-medium web site usage?

class File
{

    public static function read($path, $default = NULL)
    {
        $fp = @fopen($path, 'r');
        if( ! $fp)
            return $default;

        flock($fp, LOCK_SH);
        $data = fread($fp, filesize($path));
        flock($fp, LOCK_UN);
        fclose($fp);

        return $data;
    }


    public static function write($path, $data)
    {
        self::check(dirname($path));

        $fp = fopen($path, 'c');
        flock($fp, LOCK_EX);
        ftruncate($fp, 0);
        fwrite($fp, $data);
        fflush($fp);
        flock($fp, LOCK_UN);
        fclose($fp);

        return $data;
    }



    public static function check($dir)
    {
        if( ! is_dir($dir))
        {
            // https://en.wikipedia.org/wiki/Chmod#System_call
            @mkdir($dir, 06750, true);
            @chmod($dir, 06750);
        }
        return $dir;
    }
}

Some particular things:

  • Should using LOCK_SH in read allow for multiple simultaneous reads?
    (which will be the bulk of what's happening since writes will happen quite seldom)
  • Will using LOCK_EX in write make sure nobody else is reading or writing while the file is changed?
  • Will using the directory permission mask 06750 makes sure that
    1. any files created in that directory will get the same permissions as the directory, and
    2. the directory/file will only be writable by the web server user and readable by its group?
edited body; edited tags
Source Link

I'm using some simple files for caching and some basic user data. I was first just using file_put_contens and file_get_contents, but realized this could quickly go wrong when traffic starts increasing.

I've been trying to figure out how to do it properly with flock, correct file modes, etc, and come up with the following functions. Have I understood things correctly? Will this be safe in most normal use-cases, with small to medium-to-medium web site usage?

class File
{

    public static function read($path, $default = NULL)
    {
        $fp = @fopen($path, 'r');
        if( ! $fp)
            return $default;

        flock($fp, LOCK_SH);
        $data = fread($fp, filesize($path));
        flock($fp, LOCK_UN);
        fclose($fp);

        return $data;
    }


    public static function write($path, $data)
    {
        self::check(dirname($path));

        $fp = fopen($path, 'c');
        flock($fp, LOCK_EX);
        ftruncate($fp, 0);
        fwrite($fp, $data);
        fflush($fp);
        flock($fp, LOCK_UN);
        fclose($fp);

        return $data;
    }



    public static function check($dir)
    {
        if( ! is_dir($dir))
        {
            // https://en.wikipedia.org/wiki/Chmod#System_call
            @mkdir($dir, 06750, true);
            @chmod($dir, 06750);
        }
        return $dir;
    }
}

Some particular things:

  • Should using LOCK_SH in read allow for multiple simultaneous reads?
    (which will be the bulk of what's happening since writes will happen quite seldom)
  • Will using LOCK_EX in write make sure nobody else is reading or writing while the file is changed?
  • Will using the directory permission mask 06750 makes sure that
    1. any files created in that directory will get the same permissions as the directory, and
    2. the directory/file will only be writable by the web server user and readable by its group?

I'm using some simple files for caching and some basic user data. I was first just using file_put_contens and file_get_contents, but realized this could quickly go wrong when traffic starts increasing.

I've been trying to figure out how to do it properly with flock, correct file modes, etc, and come up with the following functions. Have I understood things correctly? Will this be safe in most normal use-cases, with small to medium web site usage?

class File
{

    public static function read($path, $default = NULL)
    {
        $fp = @fopen($path, 'r');
        if( ! $fp)
            return $default;

        flock($fp, LOCK_SH);
        $data = fread($fp, filesize($path));
        flock($fp, LOCK_UN);
        fclose($fp);

        return $data;
    }


    public static function write($path, $data)
    {
        self::check(dirname($path));

        $fp = fopen($path, 'c');
        flock($fp, LOCK_EX);
        ftruncate($fp, 0);
        fwrite($fp, $data);
        fflush($fp);
        flock($fp, LOCK_UN);
        fclose($fp);

        return $data;
    }



    public static function check($dir)
    {
        if( ! is_dir($dir))
        {
            // https://en.wikipedia.org/wiki/Chmod#System_call
            @mkdir($dir, 06750, true);
            @chmod($dir, 06750);
        }
        return $dir;
    }
}

Some particular things:

  • Should using LOCK_SH in read allow for multiple simultaneous reads?
    (which will be the bulk of what's happening since writes will happen quite seldom)
  • Will using LOCK_EX in write make sure nobody else is reading or writing while the file is changed?
  • Will using the directory permission mask 06750 makes sure that
    1. any files created in that directory will get the same permissions as the directory, and
    2. the directory/file will only be writable by the web server user and readable by its group?

I'm using some simple files for caching and some basic user data. I was first just using file_put_contens and file_get_contents, but realized this could quickly go wrong when traffic starts increasing.

I've been trying to figure out how to do it properly with flock, correct file modes, etc, and come up with the following functions. Have I understood things correctly? Will this be safe in most normal use-cases, with small-to-medium web site usage?

class File
{

    public static function read($path, $default = NULL)
    {
        $fp = @fopen($path, 'r');
        if( ! $fp)
            return $default;

        flock($fp, LOCK_SH);
        $data = fread($fp, filesize($path));
        flock($fp, LOCK_UN);
        fclose($fp);

        return $data;
    }


    public static function write($path, $data)
    {
        self::check(dirname($path));

        $fp = fopen($path, 'c');
        flock($fp, LOCK_EX);
        ftruncate($fp, 0);
        fwrite($fp, $data);
        fflush($fp);
        flock($fp, LOCK_UN);
        fclose($fp);

        return $data;
    }



    public static function check($dir)
    {
        if( ! is_dir($dir))
        {
            // https://en.wikipedia.org/wiki/Chmod#System_call
            @mkdir($dir, 06750, true);
            @chmod($dir, 06750);
        }
        return $dir;
    }
}

Some particular things:

  • Should using LOCK_SH in read allow for multiple simultaneous reads?
    (which will be the bulk of what's happening since writes will happen quite seldom)
  • Will using LOCK_EX in write make sure nobody else is reading or writing while the file is changed?
  • Will using the directory permission mask 06750 makes sure that
    1. any files created in that directory will get the same permissions as the directory, and
    2. the directory/file will only be writable by the web server user and readable by its group?
Tweeted twitter.com/StackCodeReview/status/956250438466142208
edited tags
Link
Jamal
  • 34.9k
  • 13
  • 133
  • 237
Bumped by Community user
added 22 characters in body; edited title
Source Link
Jamal
  • 34.9k
  • 13
  • 133
  • 237
Loading
added 544 characters in body
Source Link
Svish
  • 298
  • 1
  • 2
  • 8
Loading
Source Link
Svish
  • 298
  • 1
  • 2
  • 8
Loading