Php может записать файл, но не может его отключить, возможно ли это в Windows?

У меня есть следующая функция, которую я использую, чтобы проверить, доступен ли каталог для записи или нет.

/**
 * check if the path is writable. if the path is a folder it creates a test file.
 *
 * @param string $path
 * @return boolean
 */
public static function is_writable( $path ) {
    //will work in despite of Windows ACLs bug
    //NOTE: use a trailing slash for folders!!!
    //see http://bugs.php.net/bug.php?id=27609
    //see http://bugs.php.net/bug.php?id=30931
    if ( $path{strlen($path)-1} === DIRECTORY_SEPARATOR ) {// recursively return a temporary file path
        return self::is_writable( $path . uniqid( mt_rand() ) . '.tmp' );
    } else if ( is_dir( $path ) ) {
        return self::is_writable( $path . DIRECTORY_SEPARATOR . uniqid( mt_rand() ) . '.tmp' );
    }
    $file_already_exists = file_exists( $path );
    // check tmp file for read/write capabilities
    $f = @fopen( $path, 'a');
    if ( $f === false ) {
        return false;
    }
    if ( ! $file_already_exists ) {
        unlink( $path );
    }
    return true;
}

Это всегда работало нормально, до недавнего времени я всегда получал предупреждение, так как unlink() не имеет разрешения на удаление файла. Но временный файл создается нормально, поэтому я могу писать в каталог.

Предупреждение: unlink (C:\Program Files (x86)\Zend\Apache2\htdocs\wordpress\wp-content\plugins\all-in-one-event-calendar-premium\cache\152006398050813468bb6ec.tmp) [function.unlink] : Доступ запрещен в C:\Program Files (x86)\Zend\Apache2\htdocs\wordpress\wp-content\plugins\all-in-one-event-calendar-premium\lib\utility\class-ai1ec-filesystem-utility .php в строке 35

Как это возможно? Я пытался указать 777 в тестируемом каталоге, но все равно получаю предупреждение! Я на Windows 7 с сервером Zend


person Nicola Peluchetti    schedule 19.10.2012    source источник
comment
добавьте все разрешения в вашу папку wordpress (не в php, а в свойствах папки), иногда win7 возится с разрешением, когда вы пытаетесь прочитать/записать/удалить файл в Program Files...   -  person SmasherHell    schedule 19.10.2012
comment
chmod() не имеет смысла в Windows. Вместо этого вам нужно перейти к папке в проводнике, щелкнуть правой кнопкой мыши -> свойства -> вкладка безопасности -> найти пользователя Zend server, который работает, как в списке -> убедиться, что у него есть разрешения modify и write.   -  person DaveRandom    schedule 19.10.2012
comment
@DaveRandom я использовал powershell, и chmod поддерживается, я попробую это, но это раздражает, потому что, если у кого-то еще возникнет эта проблема (я работаю над плагином wordpress), он получит предупреждение.   -  person Nicola Peluchetti    schedule 19.10.2012
comment
@DaveRandom в httpd.conf пользователь и группа настроены как демон, но я не вижу этого пользователя на вкладке безопасности папки   -  person Nicola Peluchetti    schedule 19.10.2012
comment
@NicolaPeluchetti Это настройки * nix. Загляните в Панель управления -> Администрирование -> Службы, найдите службу Apache и посмотрите, под каким пользователем она настроена для работы. Часто это будет СИСТЕМА   -  person DaveRandom    schedule 19.10.2012
comment
@DaveRandom служба запускается локальной системной учетной записью, а СИСТЕМА имеет разрешение как на изменение, так и на запись.   -  person Nicola Peluchetti    schedule 19.10.2012
comment
Подозреваю, что UAC сует свой нос не туда, куда следует. Я рекомендую вам настроить конфигурацию Apache так, чтобы корень документа находился вне Program Files, и я подозреваю, что проблема исчезнет. Это также, как правило, лучшая практика ИМХО.   -  person DaveRandom    schedule 19.10.2012
comment
@DaveRandom, ты знаешь действительно странную вещь? Я переключился на другую ветку, и она этого не делает. Это связано с PHP. Единственная разница между двумя версиями заключается в том, что здесь метод статический.   -  person Nicola Peluchetti    schedule 19.10.2012
comment
@NicolaPeluchetti Попробуйте добавить fclose(), я только что заметил, что вы оставили указатель файла открытым, может быть, это причина? Также рассмотрите возможность использования touch(), если все, что вы хотите сделать, это определить, можете ли вы для создания файла.   -  person DaveRandom    schedule 19.10.2012
comment
@DaveRandom Да, я тоже заметил, и это было причиной! Добавьте это как ответ, и я приму это :)   -  person Nicola Peluchetti    schedule 19.10.2012


Ответы (4)


Попробуйте добавить вызов fclose(), вы оставили указатель файла открытым после создания файла.

Также рассмотрите возможность использования touch(), если все, что вы хотите сделать, это определить, можете ли вы создайте файл.

person DaveRandom    schedule 19.10.2012

Ваш файл не существует, когда вы пытаетесь отменить связь. Смотри сюда:

if ( ! $file_already_exists ) { //TRUE if file does not exist.
    unlink( $path );
}

Это работает, когда file_exist имеет значение FALSE

person Vladimir Gordienko    schedule 19.10.2012
comment
Это очень похоже на копирование/вставку предыдущего ответа и не является проблемой. - person DaveRandom; 19.10.2012

C:\Program Files (x86) — защищенный системный каталог. Попробуйте перетащить туда файлы с помощью проводника — вам нужно будет получить необходимые права, кивнув подсказку UAC.

Если вы хотите, чтобы скрипт PHP записывал или удалял в этой части файловой системы, вам нужно запустить его из административной строки (откройте меню «Пуск», введите «cmd» в поле поиска, щелкните правой кнопкой мыши на cmd команду и выберите «запуск от имени администратора»).

Из этого приглашения вызовите свой PHP-скрипт, и он будет иметь все права на запись в эту папку или удаление вещей и, как правило, сеет хаос в вашей системе везде, где скрипт сочтет нужным;)

Как уже упоминалось, chmod() не имеет смысла в Windows и ничего не делает. Это только для *nix.

person hashchange    schedule 19.10.2012

Обычно c:\ Windows 7 требует записи администратора для добавления/удаления любого файла. Либо дайте apache uaser admin записывает/дайте папку htdocs 777 разрешение/переместите apache docrot за пределы c:\

person Debugger    schedule 19.10.2012