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 内にあります。

4

3 に答える 3

1

削除を試みる前に、fileExists()句をIFステートメントに追加できます。コードからは、ファイルシステムでの実際のルックアップに基づくのではなく、DBから返されるものに基づいてファイルが存在すると想定しているように見えます。

また、ファイルのアクセス許可や大文字と小文字の問題が発生していないことを確認します(* 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>

アップロード後にファイルをコピーすると (指定されたスニペットの直後にコードが続くと仮定します)、そこにあるファイルはすべて上書きされます。ファイルが同じ名前の場合、既存のファイルが上書きされるだけなので、削除する必要さえないかもしれません。

もう 1 つ注意してください -非常に重要なこと- あなたのクエリ:

    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=fooURL に追加すると、既存の tableName 変数の代わりに取得される可能性があります。おそらく のようにスコープを指定することをお勧めします#variables.tableName#。または、SQL テーブル名を動的にしないでください (本当に必要な場合を除きます)。

于 2012-05-15T17:46:37.323 に答える
1

一部の人が示唆しているように、ファイルのアクセス許可が問題だとは思いません。アクセス許可エラーには、アクセス許可に関する何かが記載されています。したがって、エラーは真実を伝えていると思います-ファイルが実際に「存在しない」ということです。大文字と小文字の区別を慎重に確認してください (/Pics と /pics など)。提案されているように Fileexists を使用します (2 番目のエラーはおそらく構文エラーです。

テスト サイトで完全な堅牢なデバッグを有効にすると、より多くの情報が得られます。あなたはそれを行って、このグループのためにそれを切り詰めたかもしれません.

よく使われていないポンド記号もあります

<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) を追加してみてください - OS にファイルハンドルを解放する時間を与えます。最近では、非常に多くの異なる種類のストレージがあるため、基礎となる I/O メカニズムと、それが OS とコードにどのように戻ってくるかを知るのは困難です。

お役に立てれば。

于 2012-05-15T23:04:29.637 に答える