如何将图像从 Vue.js 传递到 PHP,以将其作为 BLOB 保存到数据库中?

How do I pass an image from Vue.js to PHP to save it as a BLOB into a database?

提问人:541daw35d 提问时间:12/24/2021 最后编辑:541daw35d 更新时间:12/24/2021 访问量:679

问:

这听起来很简单,但请相信我,我无法找到可行的解决方案。我有一个Vue.js项目,它使用 PHP 作为后端从数据库检索/保存数据。我已经使用 Axios 设置了 AJAX,以提交页面上各个字段的内容。但是,我在图像文件上传时遇到了巨大的问题。目前,所有图像都作为 MEDIUMBLOB 存储在数据库中。我在 HTML 代码中创建了一个带有Vue.js事件侦听器的表单:<input>

    <div v-for="(gallery, i) in galleryMeta">
        <form @submit.prevent="editData('gallery', gallery.Id, i)">
            <div class="row no-gutters">
                <div class="col-xl-6 col-md-5 col-sm-4 col-12 pb-sm-0 pt-sm-0 d-flex align-items-center justify-content-md-start justify-content-sm-center">
                    <div class="d-flex flex-column py-3 pl-sm-0 pl-4">
                        <h6 class="font-normal text-brand-primary pb-1 pl-md-0 pl-sm-4">Title :</h6>
                        <div class="d-flex justify-content-md-start justify-content-sm-center">
                            <input type="text" class="border-radius" v-model="gallery.Title">
                        </div>
                    </div>
                </div>
                <div class="col-md-2 col-sm-3 col-12 pb-sm-0 d-flex align-items-center justify-content-sm-end justify-content-center">
                    <div class="d-flex flex-sm-column pr-lg-0 pr-sm-3">
                        <label class="btn btn-brand-primary font-bold py-2 my-sm-0 my-2" :for="'gallery-'+gallery.Id">EDIT</label>
                        <input type="file" :id="'gallery-'+gallery.Id" style="display: none;" accept="image/jpeg,image/png,image/webp" @change="pickData">
                        <button class="btn btn-brand-secondary font-bold px-lg-5 px-3 py-2 my-2 mx-sm-0 mx-2" @click="editData(gallery.Id, i)">UPLOAD</button>
                    </div>
                </div>
            </div>
        </form>
    </div>

简单地说,有一个是图像标题和两个按钮——一个用于选择文件,另一个用于上传文件(上传按钮运行最后一个方法,该方法应该使用 Axios 将数据传递给 PHP)。<input>

这是处理 AJAX 请求的Vue.js代码。该方法只是从事件中获取文件,并且应该处理文件及其标题的提交:pickDataeditData

methods:{
    pickData: function (){
        this.Image = event.target.files[0];
        },
    editData: function (Id, i){
        const formData = new FormData();
        formData.append('file', this.Image);
        axios.post('ajax.php', formData, {
            headers: {
                'Content-Type': 'multipart/form-data'
            }
        })
        axios.post('ajax.php',{
            request: 12,
            Id: Id,
            Title: this.galleryMeta[i].Title
        })
        .then(function(response) {
            console.log(response);
        })
        this.galleryMeta[i].File = this.Image
    }
}

然后我尝试从 PHP 中获取 AJAX 请求值。我首先对数据进行解码,因为它被编码为 JSON,并将其与正确的请求匹配:

$data = json_decode(file_get_contents("php://input"));
$request = $data->request;

这是用于处理请求的 if 语句:ajax.php

if($request == 12){
    $id = $data->Id;
    $title = $data->Title;
    $file = file_get_contents($_FILES['file']['tmp_name']);
    $stmt = $db -> prepare("REPLACE INTO images (id, title, file) VALUES(?, ?, ?);");
    $stmt -> bind_param('iss', $id, $title, $file);
    $stmt -> execute();
}

没什么花哨的,只需绑定 和 将其插入数据库即可。我希望该文件有点像 multipart/form-data 的 DOM,因为它在各种网站上被告知,您可以使用 PHP 直接指向该文件以检索 Axios JavaScript 请求中定义的文件。选择文件并单击“上传”按钮后,我在 Axios 的浏览器控制台中显示以下输出(顺便说一下,它也输出了两次,不确定这是否是正常行为,并且我已经确保没有任何其他具有相同编号的请求也可能被执行):IdTitle$_FILES['file']

Object { data: "<br />\n<b>Warning</b>:  Undefined array key \"file\" in <b>C:\\xampp\\htdocs\\COMPANY\\ajax.php</b> on line <b>28</b><br />\n<br />\n<b>Warning</b>:  Trying to access array offset on value of type null in <b>C:\\xampp\\htdocs\\COMPANY\\ajax.php</b> on line <b>28</b><br />\n<br />\n<b>Fatal error</b>:  Uncaught ValueError: Path cannot be empty in C:\\xampp\\htdocs\\COMPANY\\ajax.php:28\nStack trace:\n#0 C:\\xampp\\htdocs\\COMPANY\\ajax.php(28): file_get_contents('')\n#1 {main}\n  thrown in <b>C:\\xampp\\htdocs\\COMPANY\\ajax.php</b> on line <b>28</b><br />\n", status: 200, statusText: "OK", headers: {…}, config: {…}, request: XMLHttpRequest }

但是,当我将我的PHP代码编辑为此时:

if($request == 12){
    $id = $data->Id;
    $title = $data->Title;
    $file = file_get_contents($_FILES['file']['tmp_name']);
    $txt = fopen('response.txt', 'w');
    fwrite($txt, "$file");
    $stmt = $db -> prepare("REPLACE INTO images (id, title, file) VALUES(?, ?, ?);");
    $stmt -> bind_param('iss', $id, $title, $file);
    $stmt -> execute();
}

我收到同样的错误,但是内容确实被写入了 TXT 文件中,据我所知,这应该是不可能的,因为应该未定义,因为数组键应该是未定义的,对吧?我可以做些什么来查看哪些键已定义或可用?我知道你可以通过这样做来实现这一点,例如,这样做只是转储该文件的二进制内容表示(所以我试图将其保存到数据库中的一堆垃圾)。我已经复制了这个已写入的输出并手动将其插入到 HTML 中,并且图像确实呈现了,因此它确实是保存到 TXT 文件的实际文件。这是怎么回事?我怎样才能正确地将文件交给 PHP?主要部分是我需要能够正确地将其保存到数据库中,这不会发生此错误,并且查询无法正确执行。从技术上讲,我可以保存它并使用它,因为我一次总是只处理一个文件,但这是一个肮脏的黑客,我什至羞于提及它......感谢您的任何建议!$file'file'$_FILES$_POSTvar_dump($_POST)$_FILESrequest.txt<img>var_dump

JavaScript php ajax vue.js mysqli

评论

0赞 ADyson 12/24/2021
doing so with $_FILES just dumps the binary content representation for that file...好吧,这表明它已被填充,并且应该还显示其他字段。你还想从中知道什么?
0赞 ADyson 12/24/2021
which is also outputted twice ...嗯,那是因为你叫了两次。你跑了两次 axios.post。这可能也是它工作但仍然错误的原因

答: 暂无答案