Image upload storage strategies

后端 未结 7 623
天命终不由人
天命终不由人 2020-12-04 07:01

When a user uploads an image to my site, the image goes through this process;

  • user uploads pic
  • store pic metadata in db, giving the image a unique id
7条回答
  •  遥遥无期
    2020-12-04 07:16

    I got soultion im using for a long time. It's quite old code, and can be further optimised, but it still serves good as it is.

    It's a immutable function creating directory structure based on:

    1. Number that identifies image (FILE ID):

    it's recommended that this numer is unique for base directory, like primary key for database table, but it's not required.

    1. The base directory

    2. The maximum desired number of files and first level subdirectories. This promised can be kept only if every FILE ID is unique.

    Example of usage:

    Using explicitly FILE ID:

    $fileName = 'my_image_05464hdfgf.jpg';
    $fileId = 65347;
    $baseDir = '/home/my_site/www/images/';
    $baseURL = 'http://my_site.com/images/';
    
    $clusteredDir = \DirCluster::getClusterDir( $fileId );
    $targetDir = $baseDir . $clusteredDir;
    $targetPath = $targetDir . $fileName;
    $targetURL = $baseURL . $clusteredDir  . $fileName;
    

    Using file name, number = crc32( filename )

    $fileName = 'my_image_05464hdfgf.jpg';
    $baseDir = '/home/my_site/www/images/';
    $baseURL = 'http://my_site.com/images/';
    
    $clusteredDir = \DirCluster::getClusterDir( $fileName );
    $targetDir = $baseDir . $clusteredDir;
    $targetURL = $baseURL . $clusteredDir  . $fileName;
    

    Code:

    class DirCluster {
    
    
    /**
    * @param mixed $fileId       - numeric FILE ID or file name
    * @param int $maxFiles       - max files in one dir
    * @param int $maxDirs        - max 1st lvl subdirs in one dir
    * @param boolean $createDirs - create dirs?
    * @param string $path        - base path used when creatign dirs
    * @return boolean|string
    */
    public static function getClusterDir($fileId, $maxFiles = 100, $maxDirs = 10,
    $createDirs = false, $path = "") {
    
    // Value for return
    $rt = '';
    
    // If $fileId is not numerci - lets create crc32
    if (!is_numeric($fileId)) {
        $fileId = crc32($fileId);
    }
    
    if ($fileId < 0) {
      $fileId = abs($fileId);
    }
    
    if ($createDirs) {
    
        if (!file_exists($path))
        {
            // Check out the rights - 0775 may be not the best for you
            if (!mkdir($path, 0775)) { 
              return false;
            }
            @chmod($path, 0775);
        }
    }
    
    if ( $fileId <= 0 || $fileId <= $maxFiles ) { 
      return $rt;
    }
    
    // Rest from dividing
    $restId = $fileId%$maxFiles;
    
    $formattedFileId = $fileId - $restId;
    
    // How many directories is needed to place file
    $howMuchDirs = $formattedFileId / $maxFiles;
    
    while ($howMuchDirs > $maxDirs)
    {
        $r = $howMuchDirs%$maxDirs;
        $howMuchDirs -= $r;
        $howMuchDirs = $howMuchDirs/$maxDirs;
        $rt .= $r . '/'; // DIRECTORY_SEPARATOR = /
    
        if ($createDirs)
        {
            $prt = $path.$rt;
            if (!file_exists($prt))
            {
                mkdir($prt);
                @chmod($prt, 0775);
            }
        }
    }
    
    $rt .= $howMuchDirs-1;
    if ($createDirs)
    {
        $prt = $path.$rt;
        if (!file_exists($prt))
        {
            mkdir($prt);
            @chmod($prt, 0775);
        }
    }
    
    $rt .= '/'; // DIRECTORY_SEPARATOR
    
    return $rt;
    
    
    }
    
    }
    

提交回复
热议问题