1

我有一个页面,用户可以在其中更新包含 4 个图像和其他一些字段的页面。已经为每个文件输入上传了一张图片,当他们上传新图片时,我想拍摄新图片,然后上传它,如果上传成功,请删除旧图片。但是我收到了这个错误。

File /var/www/mywebsite.com/Pics/Sunset3.jpg specified in action delete does not exist. 

根据我的 ftp,这些文件确实存在于该目录中。这些文件甚至作为表单的一部分显示在页面上,以供用户参考已经存在的图像。我听说无法在同一页面上处理文件上传,您必须使用辅助文件,但这些图像是在上次访问该页面时上传的,因此它们不会在同一页面上上传和处理页。

这是我的代码。变量 tableName 是正确的,它是在代码前面定义的,加上数据库在上传尝试后反映了正确的值,它只是在删除时中断。

<cfquery name="getPreviousImage" datasource="#Application.datasourceName#">
        SELECT 
            image1, image2, image3, image4
        FROM 
            #tableName#
        WHERE 
            RecordID = '#form.ID#'
</cfquery> 

<cfset oldImage1 = getPreviousImage.image1>
<cfset oldImage2 = getPreviousImage.image2>
<cfset oldImage3 = getPreviousImage.image3>
<cfset oldImage4 = getPreviousImage.image4>

<cfset image1 = getPreviousImage.image1>
<cfset image2 = getPreviousImage.image2>
<cfset image3 = getPreviousImage.image3>
<cfset image4 = getPreviousImage.image4>

<cfif #form.image1# NEQ ""> 

    <cffile action="upload" destination="#Application.filePath#Pics/" filefield="image1" nameconflict="makeunique">
    <cfif isDefined ("cffile.serverFile")>
        <cfset image1Place = #cffile.serverFile#> 
    </cfif>

    <cfif #getPreviousImage.image1# NEQ "" AND #image1Place# NEQ "">
        <cffile action="delete" file="#Application.filePath#Pics/#oldImage1#">
    </cfif>
</cfif>

<cfif #form.image2# NEQ ""> 

    <cffile action="upload" destination="#Application.filePath#Pics/" filefield="image2" nameconflict="makeunique">
    <cfif isDefined ("cffile.serverFile")>
        <cfset image2Place = #cffile.serverFile#> 
    </cfif>

    <cfif #getPreviousImage.image2# NEQ "" AND #image2Place# NEQ "">
        <cffile action="delete" file="#Application.filePath#Pics/#oldImage2#">
    </cfif>
</cfif>

<cfif #form.image3# NEQ ""> 

    <cffile action="upload" destination="#Application.filePath#Pics/" filefield="image3" nameconflict="makeunique">
    <cfif isDefined ("cffile.serverFile")>
        <cfset image3Place = #cffile.serverFile#> 
    </cfif>

    <cfif #getPreviousImage.image3# NEQ "" AND #image3Place# NEQ "">
        <cffile action="delete" file="#Application.filePath#Pics/#oldImage3#">
    </cfif>
</cfif>

<cfif #form.image4# NEQ ""> 

    <cffile action="upload" destination="#Application.filePath#Pics/" filefield="image4" nameconflict="makeunique">
    <cfif isDefined ("cffile.serverFile")>
        <cfset image4Place = #cffile.serverFile#> 
    </cfif>

    <cfif #getPreviousImage.image4# NEQ "" AND #image4Place# NEQ "">
        <cffile action="delete" file="#Application.filePath#Pics/#oldImage4#">
    </cfif>
</cfif>


<cfquery name="UpdateInfo" datasource="#Application.datasourceName#">
    UPDATE 
        #tableName#
    SET                  
        title = <cfqueryparam value="#form.title#" cfsqltype="CF_SQL_VARCHAR" maxlength="250">,
        <cfif #image1Place# NEQ ""> 
            image1 =    <cfqueryparam value="#image1Place#" cfsqltype="CF_SQL_VARCHAR" maxlength="250">,
        </cfif>
        <cfif #image2Place# NEQ ""> 
            image2 =    <cfqueryparam value="#image2Place#" cfsqltype="CF_SQL_VARCHAR" maxlength="250">,
        </cfif>
        <cfif #image3Place# NEQ ""> 
            image3 =    <cfqueryparam value="#image3Place#" cfsqltype="CF_SQL_VARCHAR" maxlength="250">,
        </cfif>
        <cfif #image4Place# NEQ ""> 
            image4 =    <cfqueryparam value="#image4Place#" cfsqltype="CF_SQL_VARCHAR" maxlength="250">,
        </cfif>
        body = <cfqueryparam value="#form.body#" cfsqltype="CF_SQL_VARCHAR">
    WHERE RecordID = <cfqueryparam value="#form.ID#" cfsqltype="CF_SQL_INTEGER" maxlength="50">
</cfquery>

编辑:这是我实现 fileExist() 后的新错误。此外,我看到所有这些图像都建立在我的服务器上。在其他照片中,我最多可以看到 sunset10.jpg。如果我让这个 fileExist 工作,它所做的不仅仅是防止显示错误并且永远不会执行删除。因为这些文件确实存在,除非我指向错误的位置。

Invalid CFML construct found on line 107 at column 138.
ColdFusion was looking at the following text:

>

The CFML compiler was processing:

An expression beginning with #, on line 107, column 23.This message is usually caused     by a problem in the expressions structure.
A cfif tag beginning on line 107, column 18.
A cfif tag beginning on line 107, column 18.
A cfif tag beginning on line 107, column 18.

不幸的是,我无法打开强大的异常报告。此外,当我第一次导航到该页面时会显示此错误。在我有机会提交表格之前。同时,此代码位于 if 中,该 if 仅应在填写表格后执行。

4

3 回答 3

1

您可以在尝试删除之前将 fileExists() 子句添加到 IF 语句中。从您的代码看来,您假设文件的存在是基于从数据库返回的内容,而不是基于文件系统中的实际查找。

我还会确保您没有遇到文件权限或大小写问题(看起来您在 *nix 环境中)

于 2012-05-15T17:32:22.570 回答
1

不幸的是,我可能无法为您提供明确的答案。听起来您的服务器可能配置错误,但我无法确定。您的文件属性(好的,linux/unix 上的“模式”)也可能设置错误,因此 CF 可能无法查看或删除它。检查 cffile 命令的 mode="" 属性。

下面介绍如何解决抛出异常的问题。只需添加对 fileExists() 的检查。

<cfif getPreviousImage.image1 NEQ "" AND image1Place NEQ "" AND fileExists(application.filePath & "Pics/" & oldImage1>
    <cffile action="delete" file="#Application.filePath#Pics/#oldImage1#">
</cfif>

当您在上传后复制文件时(我假设代码紧跟在您给定的代码段之后),它将覆盖那里的任何文件。如果文件具有相同的名称,它只会覆盖任何现有文件,因此您甚至不需要删除。

还有一点 -非常重要的一点- 您的查询:

    SELECT 
        image1, image2, image3, image4
    FROM 
        #tableName#
    WHERE 
        RecordID = '#form.ID#'

你真的,真的需要把#form.ID# 放在cfqueryparam 中。你的数据库很容易被黑客入侵。这是您需要的:

    WHERE 
        RecordID = <cfqueryparam value="#form.ID#" cfsqltype="cf_sql_integer" />

另外,我希望#tableName#不是来自用户输入的东西。它没有作用域,因此如果有人添加&tablename=foo到 URL,它可能会被拾取,而不是您现有的 tableName 变量。我建议您指定范围,可能像#variables.tableName#. 或者更好的是,不要让 SQL 表名动态化(除非你真的必须这样做)。

于 2012-05-15T17:46:37.323 回答
1

我不认为文件权限是一些人建议的问题。权限错误会提到一些关于权限的内容。所以我会假设错误说的是实话——文件确实“不”存在。仔细检查是否区分大小写(例如 /Pics 与 /pics)。按照建议使用 Fileexists (您的第二个错误可能是语法错误。

在您的测试站点上打开完整的健壮调试,您将获得更多信息。你可能已经这样做了,并为这个小组削减了它。

你也有一些使用不当的英镑符号

<cfif #form.something# EQ "">

英镑符号实际上与输出而不是评估密切相关。所以这个更好

<cfif form.something EQ "">

最后 - 为了确保代码可以获取它试图删除的文件的句柄,您可能会考虑这样的命名锁:

<cfif trim(form.image4) IS NOT ""> 

    <cflock name="piclock_img4" timeout="25">
    <cffile action="upload" destination="#Application.filePath#Pics/" filefield="image4" nameconflict="makeunique">
    <cfif structkeyexists(cffile,"serverfile")>
        <cfset image4Place = cffile.serverFile> 
    </cfif>
    </cflock>

    <cflock name="piclock_img4" timeout="10">
    <cfif trim(getPreviousImage.image4) IS NOT "" AND trim(image4Place) IS NOT "">
        <cffile action="delete" file="#Application.filePath#Pics/#oldImage4#">
    </cfif>
    </cflock>
</cfif>

如果这不起作用,您可以尝试在它们之间添加一个 sleep(2000) - 让操作系统有时间释放文件句柄。现在有这么多不同类型的存储,很难知道底层的 I/O 机制以及它是如何回溯到操作系统和您的代码的。

希望这可以帮助。

于 2012-05-15T23:04:29.637 回答