php如何将文件服务器中的文件链接到数据库中的信息

php如何将文件服务器中的文件链接到数据库中的信息,php,mysql,file-upload,Php,Mysql,File Upload,我是PHP新手,我正在尝试将文件上传到文件服务器,并将文件信息上传到mysql数据库,我已经完成了文件服务器和数据库部分的上传,但我需要从我的文件服务器文件夹中检索特定文件的信息,如果我单击该文件,我正在尝试获取该逻辑。如果有任何固溶体,请帮助我。(如果我错了,请纠正我,我的想法是将文件路径与信息一起上载到数据库,这会给我解决方案吗?但文件名可以重复)我想我会写一个简短的(对我来说这是简短的)“回答”,这样我就可以总结我的观点了 创建文件存储系统时的一些“最佳做法”。文件存储是一个广泛的类别,因

我是PHP新手,我正在尝试将文件上传到文件服务器,并将文件信息上传到mysql数据库,我已经完成了文件服务器和数据库部分的上传,但我需要从我的文件服务器文件夹中检索特定文件的信息,如果我单击该文件,我正在尝试获取该逻辑。如果有任何固溶体,请帮助我。(如果我错了,请纠正我,我的想法是将文件路径与信息一起上载到数据库,这会给我解决方案吗?但文件名可以重复)

我想我会写一个简短的(对我来说这是简短的)“回答”,这样我就可以总结我的观点了

创建文件存储系统时的一些“最佳做法”。文件存储是一个广泛的类别,因此您的里程数可能会因某些类别而异。把它们当作我发现的建议很有效

文件名 不要使用最终用户指定的名称存储文件。他们可以也将使用各种让你生活痛苦的蹩脚角色。有些文件可能会像
单引号一样糟糕,在linux上,单引号基本上使文件无法读取,甚至无法(直接)删除文件。有些事情可能看起来很简单,比如
一个空格,但根据您使用它的位置和服务器上的操作系统,您可能会遇到
1%20two.txt
1+2.txt
1-2.txt
,这可能会或可能不会在您的链接中产生各种问题

最好的方法是创建一个散列,类似于
sha1
这可以简单到
{user\u id}{orgianl\u name}
用户名可以减少与其他用户文件名的冲突

我更喜欢这样做
文件\u散列('sha1',$contents)
如果有人多次上传同一个文件,那么您可以捕获到它(内容相同,散列相同)。但是,如果您希望拥有大型文件,您可能需要对其进行一些基准测试,以了解其性能类型。我主要处理小文件,所以它可以很好地工作。 -注意-使用时间戳,文件仍然可以保存,因为全名不同,但它使文件非常容易查看,并且可以在数据库中进行验证

不管你做什么,我都会在它前面加上时间戳
time().-'.$filename
。这是非常有用的信息,因为它是创建文件的绝对时间

至于用户给文件起的名字。只需将其存储在数据库记录中。通过这种方式,您可以向他们显示他们期望的名称,但使用您知道的名称对链接总是安全的

$filename='一些蹩脚的^fileane.jpg'

$ext = strrchr($filename, '.');

echo "\nExt: {$ext}\n";

$hash = sha1('some crapy^ fileane.jpg');

echo "Hash: {$hash}\n";

$time = time();

echo "Timestamp: {$time}\n";

$hashname = $time.'-'.$hash.$ext;

echo "Hashname: $hashname\n";
输出

Ext: .jpg
Hash: bb9d2c2c7c73bb8248537a701870e35742b41c02
Timestamp: 1511853063
Hashname: 1511853063-bb9d2c2c7c73bb8248537a701870e35742b41c02.jpg
你可以试试

路径从不存储文件的完整路径。数据库中所需的只是创建哈希名称所产生的哈希。存储文件的文件夹的“根”路径应该在PHP中完成。这有几个好处

  • 防止目录传输。因为你没有经过你周围道路的任何一部分,你不必担心有人在那里滑倒了一个
    \\\\\
    ,去了他们不应该去的地方。一个糟糕的例子是,有人通过上传一个名为
    .htpassword
    的文件(其中包含目录)来覆盖一个
    .htpassword
    文件
  • 具有更统一的外观链接、统一的大小、统一的设置 人物

  • 维修。路径改变,服务器改变。对您的系统更改的需求。如果您需要重新定位这些文件,但您在数据库中存储了这些文件的绝对完整路径,您可以使用
    symlinks
    将所有内容粘在一起,或者更新所有记录
这有一些例外。如果您想将它们存储在每月一次的文件夹中或按用户名存储。您可以将该部分路径保存在单独的字段中。但即使在这种情况下,您也可以根据记录中保存的数据动态构建它。我发现最好保存尽可能少的路径信息。它们生成一个配置或常量,您可以在需要放置文件路径的所有位置使用它

而且
路径
链接
非常不同,因此只保存名称就可以从任何PHP页面链接它,而无需从路径中减去数据。我总是发现添加到文件名比从路径中减去更容易

数据库(只是一些建议,用途可能有所不同) 与数据一样,问问自己,谁,什么,在哪里,什么时候

  • id-
    int
    主键自动递增
  • 用户id-
    int
    外键,谁上传的
  • 散列-
    char[40]*sha1*,唯一
    散列是什么
  • hashname-
    varchar
    {timestall}-{hash}.{ext}其中硬盘上的文件名
  • filename-
    varchar
    用户提供的原始名称,这样我们可以向他们显示他们期望的名称(如果这很重要)
  • 状态-
    枚举[公共、私有、已删除、挂起..等]
    文件的状态,根据您的使用情况,您可能需要查看文件,或者可能有些文件是私有的,只有用户才能看到,可能有些文件是公共的等等
  • 状态_日期-
    时间戳|日期时间
    状态更改的时间
  • 创建_date-
    时间戳|日期时间
    创建文件时,时间戳是首选的,因为它使某些事情变得更简单,但在这种情况下,它应该与hashname中使用的时间戳相同
  • type-
    varchar
    -mime类型,可用于在下载等时设置mime类型
如果您希望不同的用户上载同一个文件,并且使用
文件散列
,则可以将
散列
字段作为
用户id
h的组合唯一索引
http://www.example.com/download/ad87109bfff0765f4dd8cf4943b04d16a4070fea
1511848005-ad87109bfff0765f4dd8cf4943b04d16a4070fea.jpg
1511848005-ad87109bfff0765f4dd8cf4943b04d16a4070fea0234.jpg
$_FILES = [
 'fieldname' => [
        'name' => "MyFile.txt" // (comes from the browser, so treat as tainted)
        'type' => "text/plain" //  (not sure where it gets this from - assume the browser, so treat as tainted)
        'tmp_name' => "/tmp/php/php1h4j1o" // (could be anywhere on your system, depending on your config settings, but the user has no control, so this isn't tainted)
        'error' => "0" //UPLOAD_ERR_OK  (= 0)
        'size' => "123" //   (the size in bytes)
    ]
 ];
 $path = __DIR__.'/uploads/'; //for exmaple

$time = time();
$hash = hash_file('sha1',$_FILES['fielname']['tmp_name']);
$type = $_FILES['fielname']['type'];
$hashname = $time.'-'.$hash.strrchr($_FILES['fielname']['name'], '.');
$status = 'pending';

if(!move_uploaded_file ($_FILES['fielname']['tmp_name'], $path.$hashname  )){
     //failed
     //do somehing for errors.
     die();
}


//store record in db
$hash = $_GET['file'];

$stmt = $PDO->prepare("SELECT * FROM attachments WHERE hash = :hash LIMIT 1");  
$stmt->execute([":hash" => $hash]);

$row = $stmt->fetch(PDO::FETCH_ASSOC);

print_r($row);