У меня тут настоящая головная боль.
Это моя конфигурация системы:
Это моя проблема:
У меня есть простая загрузка файла форма. Как мы знаем, когда PHP принимает загрузку файла, файлу присваивается временное имя и он помещается во временный каталог перед обработкой. В моем случае PHP помещает файл во временный каталог (который оказывается E: \ Inetpub_IIS \ tmp, рядом с E: \ Inetpub_IIS \ wwwroot), но затем сразу же «забывает», что файл существует, пока не появится сборщик мусора, который удаляет временный файл. В частности, временный файл создается во временном каталоге на сервере, но когда я вызываю sha1_file () для этого файла, функция ничего не возвращает. file_exists () также не работает. Это заставляет меня думать, что PHP не может найти файл. Журнал ProcMon ниже показывает, что PHP ищет правильное место.
Вот мой журнал ProcMon:
2:43:14.9175650 PM php-cgi.exe 5020 CreateFile E:\Inetpub_IIS\tmp\php3F86.tmp SUCCESS Desired Access: Generic Read, Disposition: Create, Options: Synchronous IO Non-Alert, Non-Directory File, Attributes: N, ShareMode: None, AllocationSize: 0, Impersonating: NT AUTHORITY\IUSR, OpenResult: Created
2:43:14.9182596 PM php-cgi.exe 5020 CloseFile E:\Inetpub_IIS\tmp\php3F86.tmp SUCCESS
2:43:14.9184424 PM php-cgi.exe 5020 QueryOpen E:\Inetpub_IIS\tmp\php3F86.tmp SUCCESS CreationTime: 12/27/2011 2:43:14 PM, LastAccessTime: 12/27/2011 2:43:14 PM, LastWriteTime: 12/27/2011 2:43:14 PM, ChangeTime: 12/27/2011 2:43:14 PM, AllocationSize: 0, EndOfFile: 0, FileAttributes: A
2:43:14.9185907 PM php-cgi.exe 5020 CreateFile E:\Inetpub_IIS\tmp\php3F86.tmp SUCCESS Desired Access: Write Attributes, Synchronize, Disposition: Open, Options: Synchronous IO Non-Alert, Open Reparse Point, Attributes: n/a, ShareMode: Read, Write, Delete, AllocationSize: n/a, Impersonating: NT AUTHORITY\IUSR, OpenResult: Opened
2:43:14.9187896 PM php-cgi.exe 5020 SetBasicInformationFile E:\Inetpub_IIS\tmp\php3F86.tmp SUCCESS CreationTime: 0, LastAccessTime: 0, LastWriteTime: 0, ChangeTime: 0, FileAttributes: AN
2:43:14.9188368 PM php-cgi.exe 5020 CloseFile E:\Inetpub_IIS\tmp\php3F86.tmp SUCCESS
2:43:14.9190234 PM php-cgi.exe 5020 CreateFile E:\Inetpub_IIS\tmp\php3F86.tmp SUCCESS Desired Access: Generic Read/Write, Disposition: OverwriteIf, Options: Synchronous IO Non-Alert, Non-Directory File, Attributes: N, ShareMode: Read, Write, AllocationSize: 0, Impersonating: NT AUTHORITY\IUSR, OpenResult: Overwritten
2:43:14.9193771 PM php-cgi.exe 5020 WriteFile E:\Inetpub_IIS\tmp\php3F86.tmp SUCCESS Offset: 0, Length: 5,119, Priority: Normal
2:43:14.9489663 PM php-cgi.exe 5020 WriteFile E:\Inetpub_IIS\tmp\php3F86.tmp SUCCESS Offset: 5,119, Length: 5,119, Priority: Normal
2:43:14.9730524 PM php-cgi.exe 5020 WriteFile E:\Inetpub_IIS\tmp\php3F86.tmp SUCCESS Offset: 10,238, Length: 5,119
2:43:15.0054693 PM php-cgi.exe 5020 WriteFile E:\Inetpub_IIS\tmp\php3F86.tmp SUCCESS Offset: 15,357, Length: 5,119, Priority: Normal
2:43:15.0309328 PM php-cgi.exe 5020 WriteFile E:\Inetpub_IIS\tmp\php3F86.tmp SUCCESS Offset: 20,476, Length: 5,119
2:43:15.0633978 PM php-cgi.exe 5020 WriteFile E:\Inetpub_IIS\tmp\php3F86.tmp SUCCESS Offset: 25,595, Length: 5,119
2:43:15.0879028 PM php-cgi.exe 5020 WriteFile E:\Inetpub_IIS\tmp\php3F86.tmp SUCCESS Offset: 30,714, Length: 5,119, Priority: Normal
...
2:43:17.1849721 PM php-cgi.exe 5020 WriteFile E:\Inetpub_IIS\tmp\php3F86.tmp SUCCESS Offset: 383,925, Length: 5,119
2:43:17.1851664 PM php-cgi.exe 5020 WriteFile E:\Inetpub_IIS\tmp\php3F86.tmp SUCCESS Offset: 389,044, Length: 2,343
2:43:17.1852283 PM php-cgi.exe 5020 CloseFile E:\Inetpub_IIS\tmp\php3F86.tmp SUCCESS
2:43:17.5070914 PM php-cgi.exe 5020 QueryDirectory E:\Inetpub_IIS\tmp\php3F86.tmp SUCCESS Filter: php3F86.tmp, 1: php3F86.tmp
2:43:17.5083973 PM php-cgi.exe 5020 QueryDirectory E:\Inetpub_IIS\tmp\php3F86.tmp SUCCESS Filter: php3F86.tmp, 1: php3F86.tmp
2:43:17.5112593 PM php-cgi.exe 5020 QueryDirectory E:\Inetpub_IIS\tmp\php3F86.tmp SUCCESS Filter: php3F86.tmp, 1: php3F86.tmp
2:43:17.5120519 PM php-cgi.exe 5020 QueryDirectory E:\Inetpub_IIS\tmp\php3F86.tmp SUCCESS Filter: php3F86.tmp, 1: php3F86.tmp
2:43:27.5512956 PM php-cgi.exe 5020 CreateFile E:\Inetpub_IIS\tmp\php3F86.tmp SUCCESS Desired Access: Read Attributes, Delete, Disposition: Open, Options: Non-Directory File, Open Reparse Point, Attributes: n/a, ShareMode: Read, Write, Delete, AllocationSize: n/a, OpenResult: Opened
2:43:27.5515084 PM php-cgi.exe 5020 QueryAttributeTagFile E:\Inetpub_IIS\tmp\php3F86.tmp SUCCESS Attributes: A, ReparseTag: 0x0
2:43:27.5515406 PM php-cgi.exe 5020 SetDispositionInformationFile E:\Inetpub_IIS\tmp\php3F86.tmp SUCCESS Delete: True
2:43:27.5515879 PM php-cgi.exe 5020 CloseFile E:\Inetpub_IIS\tmp\php3F86.tmp SUCCESS
Как видите, ProcMon четко показывает, что временный файл создается, записывается и затем закрывается. Ближе к концу вы можете увидеть вызовы «QueryDirectory», которые совпадают с вызовами моих скриптов, которые, помимо прочего, пытаются получить хэш SHA1 файла.
Это мой сценарий:
Форма загрузки файла содержит объект Flash и несколько DIV для объекта Flash для создания формы, не более того.Временный файл загрузки создается на сервере полностью, поэтому я очень серьезно сомневаюсь, что проблема в моей форме.
<?php
// *******************************************************************
// exhibit-upload.php
//
// *******************************************************************
// Reset same session ID because Adobe Flash is a flaming pile
session_id($_POST['sessionid']);
ob_start("ob_gzhandler");
require_once('inc-common.php');
$logFile = "logfile.txt";
$logHandle = fopen($logFile, 'w');
fwrite($logHandle, '$_FILES error: ' . $_FILES['error'] . "\n");
if(!empty($_FILES))
{
// Get temp file
$sFileTemp = $_FILES['Filedata']['tmp_name'];
$sFileName = $objMySQL->sanitize($_FILES['Filedata']['name']);
fwrite($logHandle, "Permanent Filename: " . $sFileName . "\n");
$aFileBits = explode('.', $_FILES['Filedata']['name']);
$sFileExt = $aFileBits[count($aFileBits) - 1];
// Get SHA1 hash
$sFileHash = sha1_file($sFileTemp);
fwrite($logHandle, "Temp File Exists: " . file_exists($sFileTemp) . "\n");
fwrite($logHandle, "Temp File Name: " . $sFileTemp . "\n");
fwrite($logHandle, "File Hash: " . $sFileHash . "\n");
sleep(10);
exit();
}
?>
Содержимое "logfile.txt":
$_FILES error:
Permanent Filename: picture.jpg
Temp File Exists:
Temp File Name: E:\Inetpub_IIS\tmp\php3F86.tmp
File Hash:
Вызов "сна" дает мне время проверить временный каталог на наличие файла, прежде чем он исчезнет.
Десятки поисков в Google привели меня к вещам, касающимся разрешений, или к решениям, которые связаны с неработающими формами загрузки, которые вообще не могут загружать что-либо. Файлы создаются на сервере, поэтому очевидно, что форма работает. Кроме того, я попытался предоставить IUSR, IIS_ISURS и DefaultAppPool полный доступ к временному каталогу и всему E: \ Inetpub_IIS, чтобы узнать, связано ли это с соответствующими разрешениями, но это ничего не изменило. Может ли кто-нибудь дать совет о том, что здесь происходит?
РЕДАКТИРОВАТЬ: Я понял это.
DaveRandom и я думали, что это проблема с правами доступа определенного типа, и это было правдой. Однако мы оба думали о разрешениях Windows, когда на самом деле проблема заключалась в разрешении / конфигурации PHP. Фраза Дейва «работать в обратном направлении» заставила меня задуматься о перемещении назад по дереву каталогов и проверке разрешений, что в конечном итоге привело к следующему решению.
Что я сделал:
Я написал очень короткий сценарий:
<?php
//phpinfo();
echo "Readable: " . is_readable('E:\Inetpub_IIS\tmp');
?>
Это вернуло ЛОЖЬ. Очевидно, каталог не читался, как предположил Дэйв.
Я попробовал каталог E: \ Inetpub_IIS \ wwwroot, который вернул TRUE. Хм. Затем я понял, что не проверял php_error.log весь день. Вот что я обнаружил:
[27-Dec-2011 16:51:43] PHP Warning: is_readable(): open_basedir restriction in effect. File(E:\Inetpub_IIS\tmp) is not within the allowed path(s): (E:\Inetpub_IIS\wwwroot) in E:\Inetpub_IIS\wwwroot\ipl\info.php on line 3
Я погуглил "действует ограничение open_basedir" и получил ответ. В файле php.ini для open_basedir было установлено значение:
open_basedir = E:\Inetpub_IIS\wwwroot
Я изменил это на:
open_basedir = "E:\Inetpub_IIS\wwwroot;E:\Inetpub_IIS\tmp"
После перезапуска сервера приложение начало работать, как задумано.
Надеюсь, этой документации достаточно для кого-то, у кого может быть такая же проблема.
Мораль (и) истории: