【问题标题】:PHP image upload and write to databasePHP图像上传并写入数据库
【发布时间】:2013-05-06 17:35:00
【问题描述】:

我对 PHP 很陌生,并尝试将图像上传到服务器,然后使用表单和 php 使用下面的代码和表单将其写入数据库,但它似乎不起作用,如果我把所有表格中的照片内容与其他变量和内容(例如写出文章标题和内容)完美配合,谁能告诉我哪里出错了?在此先感谢各位。

<?php

session_start();

include_once('../php/connection.php');

if (isset($_SESSION['logged_in'])) {
    if (isset($_POST['title'], $_POST['content'], $_FILES['photo1'])) {
        $title = $_POST['title'];
        $content = nl2br($_POST ['content']);
        $photo1=($_FILES['photo1']);
        $target = "../lifestlye";
        $target = $target . basename( $_FILES['photo1']);


        $query =$pdo->prepare('INSERT INTO article (article_title, article_content, photo_1) VALUES (?,?,?)');

        $query->bindValue(1, $title);
        $query->bindValue(2, $content);
        $query->bindValue(3, $photo1);

        $query->execute();
        move_uploaded_file($_FILES['photo1'], $target);
{

}


        header('Location: index.php');
    }

    ?>




 <form action="add.php" method="post" autocomplete="off"/>


    <dl class="field four columns centered">
                    <dd><label for="title">Article Title</label></dd>
                    <dt class="text"><input type="text" name="title" id="title"/>
                    </dt>
                    </dl>
                    <dl class="field nine columns centered">
                <dd><label for="content">Content</label></dd>
                <dt class="textarea">
                <textarea name="content" id="message"></textarea></dt>
                </dl>
                <p class="blacktext">Photo</p>
                <input type="file" name="photo1">
                <input type="submit" id="add article"/>
                </form>

【问题讨论】:

标签: php mysql forms phpmyadmin


【解决方案1】:

试试这个代码:

<?php

session_start();

include_once('../php/connection.php');

if (isset($_SESSION['logged_in'])) {

    if (isset($_POST['title'], $_POST['content'], $_FILES['photo1'])) {

        $title    = $_POST['title'];
        $content  = nl2br($_POST['content']);
        $name     = $_FILES['photo1']['name'];
        $tmp_name = $_FILES['photo1']['tmp_name'];

        $target = '../lifestlye/'.$name;

        if (move_uploaded_file($tmp_name,$target)) {

            $stmt = $pdo->prepare('INSERT INTO article (article_title, article_content, photo_1) VALUES (?,?,?)');
            $stmt->execute(array($title,$content,$name));
            header('Location: index.php');
            exit();

        }

    }

}

【讨论】:

  • 除了尝试将它放在服务器上时完美运行我收到此错误,是因为我没有正确定义目录吗?警告:move_uploaded_file(../lifestlye/Shop.png) [function.move-uploaded-file]:无法打开流:/home/content/55/10880055/html/admin/add.php 中没有这样的文件或目录在第 19 行警告:move_uploaded_file() [function.move-uploaded-file]:无法将 '/tmp/php7JHFaJ' 移动到 /home/content/55/10880055/html/ 中的 '../lifestlye/Shop.png'第 19 行的 admin/add.php
  • 嗯,../lifestyle/ 是指./lifestyle/?或者这个目录的权限不是777
  • 拼写错误对不起!非常感谢,现在效果很好。最后一个问题,如果我想上传多个文件,例如 photo2,我可以制作另一个 $name 和 $tmp_name 并将其添加到移动 _upload 我不能吗?例如(move_upload_file($tmp_name,$tmp_name2,$target)?
  • 没有。将文件作为数组接收就足够了。示例:&lt;input name="photos[]" type="file" /&gt;。请参考:stackoverflow.com/a/16499251/1846562
【解决方案2】:

你做得太简单了。您需要阅读手册页:http://www.php.net/manual/en/features.file-upload.post-method.php

首先,将此作为参数添加到您的表单中:enctype="multipart/form-data"

然后,了解 $_FILES['photo1'] 将是一个数组,而 $_FILES['photo1']['tmp_name'] 将包含一个临时文件名,即上传的文件。然后您可以将文件移动到新位置,或者读取它并将其作为 BLOB 放入数据库(但为什么要将二进制数据保留在数据库中?)

【讨论】:

    【解决方案3】:
    1. 您应该使用绝对路径来移动文件。如果您想在当前目录中执行某些操作,请使用 __DIR__ 或 dirname(__FILE__),具体取决于您的 php 版本。如果可用,第一个是首选。
    2. 您应该进行错误检查 - 阅读 php.net 手册中的 $_FILES 数组以了解需要注意的事项。
    3. 检查 move_uploaded_file 的返回值、错误、通知 - 写入权限也可能有问题(目标目录/文件必须可被网络服务器写入)
    4. 您应该考虑生成文件名,否则如果 2 个人上传同名文件,第二个将覆盖第一个。然后开始讨论竞态条件和 php 本身不可能执行原子锁的乐趣(使用 mysql get lock 是迄今为止我想出的最好的方法,因为信号量和文件锁定在 php 的 Web 上下文中很烂)
    5. 您应该添加一些安全检查,例如str_replace("\0", "", $filename) 用于避免 nul 中毒(根据您的系统和文件系统,您可能应该过滤/检查其他内容)
    6. 这只是一个提示,但实际上:如果您在 php/安全方面没有足够的经验,请不要对用户输入进行任何操作,尤其是文件上传,公开(例如公开可用的网址)。否则你会在很短的时间内看到你的服务器崩溃、被接管……。 PHP 本身已经非常不安全,添加 mysql 和文件上传并不能真正让它变得更好。无法保证您从 $_FILES 获得的文件名是安全的 - 攻击者可以发送任何文件名(我自己只需几行脚本就可以轻松完成,而且我不是真正的黑客)。

    此外,basename 不会过滤文件名,它只会为您提供最后一个 '.' 之前的内容。

    编辑:+ Palantir 编写的所有内容,以使其正常工作(抱歉,我跳过了一些内容)

    【讨论】:

    • @palantir 谢谢大家,基本上这是我为博客制作的cms,文件上传基本上是为页面顶部的幻灯片插件上传图片。我想在上传后将数据写入数据库的原因是我可以使用生成的文件名将其动态输入到幻灯片中,例如" 你会说这是最好的方法吗?对不起,如果这没有意义,就像我说的那样对 php 很陌生。
    • 这完全没问题/标准,但是在过去的 2 年里我自己在 php+mysql 上构建了一个新的 cms,我只能强调它在这种情况下的重要性:1。阅读安全性(nul 字节中毒,utf8,...) 2. 阅读竞争条件(例如,这样你就没有 2 个文件最终成为一个) 3. 永远不要相信任何用户输入(更好的是:永远不要相信任何类型的输入),因此总是验证、清理、过滤……
    • 这东西好像不喜欢 alt+enter ;) 无论如何,您还应该确保无论您将文件上传到何处,都没有机会 1. 您覆盖现有文件(我例如,可以将 '../index.php' 作为文件名传递,您只需附加它!) 2. 上传的文件不能直接访问,或者至少服务器不会执行它们(考虑上传一些后门。 php 文件,然后在我的浏览器中打开 /whatever-upload-dir/backdoor.php)
    • 感谢格里芬,我正在阅读有关安全性的大量信息,并且我通过使用 pdo 之类的东西来防止注入,但显然它是我必须看很多的东西。暂时,要修复上传问题,是否只是修复文件路径的情况,给它一个临时文件名 '$_FILES['photo1']['tmp_name']' 并添加 enctype="multipart/form -data”到表格?
    • tmp_name 应该已经存在,这就是您应该使用 move_upload_file 的内容 - 我认为如果您查看该功能的 php.net 手册,您会发现上传时缺少什么工作。那个,+ form enctype。
    猜你喜欢
    • 2016-09-07
    • 2013-07-29
    • 1970-01-01
    • 2013-05-06
    • 1970-01-01
    • 1970-01-01
    • 2018-07-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多