У меня есть настоящий головной убор.
Это конфигурация моей системы:
- Windows Server 2008 R2
- Установлен PHP 5.3.8как модуль FastCGI
- IIS 7.5
Это моя проблема:
У меня есть простая форма загрузки файла.Как мы знаем, когда 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"
После перезапуска сервера приложение начало работать должным образом.
Надеюсь, этого будет достаточно для тех, у кого такая же проблема.
Мораль (и) истории:
- Проверьте настройку open_basedir.
- Включите, установите и не забудьте проверить свой журнал ошибок php.
- Не смотрите на эту проблему в течение 7 часов подряд без перерыва.Я думаю, что у меня почти был инсульт.