Проблема с удалением cffile coldfusion

У меня есть страница, на которой пользователь может обновить страницу с 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(). Кроме того, я вижу, что все эти изображения накапливаются на моем сервере. Я примерно до заката10.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, который должен выполняться только после заполнения формы.


person d.lanza38    schedule 15.05.2012    source источник


Ответы (3)


Вы можете добавить предложение fileExists() в свой оператор IF перед попыткой удаления. Судя по вашему коду, вы предполагаете, что файл существует на основе того, что возвращается из БД, а не на основе фактического поиска в файловой системе.

Я также хотел бы убедиться, что вы не сталкиваетесь с правами доступа к файлам или проблемами с регистром (похоже, вы находитесь в среде * nix)

person oarevalo    schedule 15.05.2012
comment
Ах, права доступа к файлам, вероятно, моя проблема. Я обычно не использую coldfusion, поэтому ошибка, похоже, мало описывала, поэтому я не подумал об этом, но это также потому, что на сервере отключен, я думаю, робаст. Я также реализую fileexist на этой странице. Спасибо. - person d.lanza38; 15.05.2012
comment
Я не думаю, что разрешение файла было проблемой, у меня есть папка моего веб-сайта с чтением и выполнением, а папка Pics с чтением/записью/выполнением. Кроме того, загрузка также работает нормально, это просто удаление. Я также пытался реализовать fileExists, но это просто вызывает еще одну ошибку. Я опубликую это в своем первоначальном вопросе. - person d.lanza38; 15.05.2012

К сожалению, у меня может не быть окончательного ответа для вас. Похоже, ваш сервер может быть неправильно настроен, но я не могу точно сказать. Также возможно, что атрибуты вашего файла (хорошо, «режим» в linux/unix) установлены неправильно, поэтому, возможно, CF не может его увидеть или удалить. Проверьте атрибут mode="" в командах cffile.

Вот как решить проблему создания исключений. Просто добавьте проверку для 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 динамическими (если только вам это не нужно).

person Nathan Strutz    schedule 15.05.2012
comment
Спасибо за ваш ответ. Я переключил имя таблицы на статическое значение, это было соглашение бывшего программиста, и он сказал, что сделал это таким образом из соображений безопасности, мой отказ от использования coldfusion. Я предположил, что на это есть причина, и сохранил его в этом коде. Я также попытался использовать fileExists(), как вы предложили, изменив некоторые регистры, чтобы они подходили, и я получаю новую ошибку. Когда я удаляю существующий файл, ошибка исчезает или, по крайней мере, переходит к следующему экземпляру fileExist (для изображения2). Я опубликую ошибку в своем первоначальном вопросе. Кроме того, мои разрешения кажутся правильными. Я говорил о своей установке выше. - person d.lanza38; 15.05.2012

Я не думаю, что права доступа к файлам являются проблемой, как некоторые предполагают. Ошибки разрешения будут упоминать что-то о разрешениях. Поэтому я бы предположил, что ошибка говорит правду - что файл действительно «не» существует. внимательно проверьте чувствительность к регистру (например, /Pics vs. /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>

ЕСЛИ это не сработает, вы можете попробовать добавить спящий режим (2000) между ними, чтобы дать ОС время освободить дескриптор файла. В наши дни с таким количеством различных типов хранилищ трудно понять лежащий в основе механизм ввода-вывода и то, как он передается обратно в ОС и ваш код.

Надеюсь это поможет.

person Mark A Kruger    schedule 15.05.2012