2011-12-27 31 views
9

Tôi đã có một trình gỡ đầu thực sự ở đây.PHP sẽ không thừa nhận các tệp tạm thời được tải lên của riêng mình

Đây là cấu hình hệ thống của tôi:

  • Windows Server 2008 R2
  • PHP 5.3.8 cài đặt như một module FastCGI
  • IIS 7,5

Đây là vấn đề của tôi:

Tôi có một mẫu tải lên tệp đơn giản. Như chúng ta đã biết, khi PHP chấp nhận một tệp tải lên, tệp được cung cấp một tên tạm thời và được đặt trong một thư mục tạm thời trước khi nó được xử lý. Trong trường hợp của tôi, PHP đặt tệp trong thư mục tạm thời (xảy ra là E: \ Inetpub_IIS \ tmp, bên cạnh E: \ Inetpub_IIS \ wwwroot) nhưng sau đó ngay lập tức "quên" rằng tệp tồn tại cho đến khi trình thu thập rác xuất hiện, sẽ xóa tệp tạm thời. Cụ thể hơn, tệp tạm thời được tạo trong thư mục tạm thời trên máy chủ, nhưng khi tôi gọi sha1_file() trên tệp đó, hàm sẽ trả về không có gì. file_exists() cũng không thành công. Điều này làm cho tôi nghĩ rằng PHP không thể tìm thấy tập tin. Nhật ký ProcMon dưới đây cho thấy PHP đang tìm kiếm đúng vị trí.

Đây là log ProcMon tôi:

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 

Như bạn thấy, ProcMon rõ ràng cho thấy các tập tin tạm thời được tạo ra, bằng văn bản và sau đó đóng lại. Gần cuối, bạn có thể thấy các cuộc gọi "QueryDirectory", trùng với các cuộc gọi script của tôi, cố gắng lấy hàm băm SHA1 của tệp trong số những thứ khác.

Đây là kịch bản của tôi:

Các hình thức upload tập tin có một đối tượng Flash và một số DIV cho đối tượng Flash để xây dựng các hình thức, không có gì hơn. Tệp tải lên tạm thời đang được tạo trên toàn bộ máy chủ vì vậy tôi nghi ngờ rất nghiêm túc rằng biểu mẫu của tôi là vấn đề.

<?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(); 
} 
?> 

Nội dung của "logfile.txt":

$_FILES error: 
Permanent Filename: picture.jpg 
Temp File Exists: 
Temp File Name: E:\Inetpub_IIS\tmp\php3F86.tmp 
File Hash: 

Các "ngủ" gọi tồn tại để cho tôi thời gian để kiểm tra thư mục tạm thời cho các tập tin trước khi nó biến mất.

Hàng chục tìm kiếm trên Google đã dẫn tôi đến những điều liên quan đến quyền hoặc giải pháp liên quan đến các biểu mẫu tải lên bị hỏng mà không tải lên bất kỳ thứ gì. Các tệp đang được tạo trên máy chủ vì vậy rõ ràng biểu mẫu hoạt động. Ngoài ra, tôi đã thử cấp quyền truy cập đầy đủ cho IUSR, IIS_ISURS và DefaultAppPool vào thư mục tạm thời và tất cả E: \ Inetpub_IIS để xem điều này có liên quan gì đến quyền liên quan nhưng điều đó không thay đổi gì. Bất cứ ai có thể cung cấp một số lời khuyên về những gì đang xảy ra ở đây?

EDIT: Tôi đã tìm ra.

DaveRandom và cả hai đều nghĩ rằng đó là vấn đề về quyền của một số loại, điều đó đúng. Tuy nhiên, chúng tôi đều nghĩ đến quyền Windows, khi vấn đề thực sự là một vấn đề về quyền/cấu hình PHP. Dave "làm việc ngược" phrasing đã cho tôi nghĩ đến việc di chuyển ngược qua cây thư mục và kiểm tra quyền mà cuối cùng đã sản xuất các giải pháp sau đây.

Những gì tôi đã làm:

Tôi đã viết một kịch bản rất ngắn:

<?php 
    //phpinfo(); 
    echo "Readable: " . is_readable('E:\Inetpub_IIS\tmp'); 
?> 

này trở FALSE. Rõ ràng là thư mục không thể đọc được, như Dave đã gợi ý.

Tôi đã thử thư mục E: \ Inetpub_IIS \ wwwroot, trả về TRUE. Hmm. Sau đó tôi nhận ra rằng tôi đã bỏ quên để kiểm tra php_error.log cả ngày. Dưới đây là những gì tôi đã tìm thấy:

[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 

Tôi Googled "open_basedir restriction in effect" và có câu trả lời của tôi. Trong file php.ini, open_basedir được thiết lập để:

open_basedir = E:\Inetpub_IIS\wwwroot 

tôi đã thay đổi này để:

open_basedir = "E:\Inetpub_IIS\wwwroot;E:\Inetpub_IIS\tmp" 

Sau khi khởi động lại máy chủ ứng dụng bắt đầu làm việc như dự định.

Hy vọng rằng đó là đủ tài liệu cho người khác có thể gặp vấn đề tương tự.

đạo đức (s) của câu chuyện:

  • Kiểm tra cài đặt open_basedir của bạn.
  • Bật, đặt và nhớ kiểm tra nhật ký lỗi php của bạn.
  • Đừng nhìn chằm chằm vào cùng một vấn đề trong 7 giờ mà không cần nghỉ ngơi. Tôi nghĩ tôi gần như bị đột quỵ.
+0

[php man] (http://www.php.net/manual/en/features.file-upload.php) xem phần mã lỗi để giúp bạn gỡ lỗi, đồng thời tra cứu [print_r] (http: //www.php.net/print_r)() chức năng để bạn cxan làm print_r ($ _ FILES); – goat

+0

UPLOAD_ERR_OK được trả về. Đây là một số đầu ra print_r: 'Array ([the_uploaded_file] => Array ([name] => picture.jpg [type] => hình ảnh/jpeg [tmp_name] => E: \ Inetpub_IIS \ tmp \ php34DD.tmp [lỗi] = > 0 [size] => 391387)) ' – TPC

+0

Tôi biết bạn đã đi xuống con đường này, nhưng có vẻ như đây là quyền liên quan - cụ thể (mặc dù nó sẽ kỳ lạ) rằng một cái gì đó có quyền truy cập chỉ ghi vào thư mục - hoặc các tệp đang được tạo - và không thể đọc tệp/chúng. Hãy thử phân bổ toàn quyền kiểm soát cho nhóm 'Mọi người' và xem liệu có khắc phục được sự cố không, nếu nó hoạt động ngược từ đó. – DaveRandom

Trả lời

4

Như đã hứa, đây là câu trả lời của tôi. Điều này đã được sao chép/dán từ bản chỉnh sửa OP.

Tôi đã tìm ra.

DaveRandom và cả hai đều nghĩ rằng đó là vấn đề về quyền của một số loại, điều đó đúng. Tuy nhiên, chúng tôi đều nghĩ đến quyền Windows, khi vấn đề thực sự là một vấn đề về quyền/cấu hình PHP. Dave "làm việc ngược" phrasing đã cho tôi nghĩ đến việc di chuyển ngược qua cây thư mục và kiểm tra quyền mà cuối cùng đã sản xuất các giải pháp sau đây.

Những gì tôi đã làm:

Tôi đã viết một kịch bản rất ngắn:

<?php 
    //phpinfo(); 
    echo "Readable: " . is_readable('E:\Inetpub_IIS\tmp'); 
?> 

này trở FALSE. Rõ ràng là thư mục không thể đọc được, như Dave đã gợi ý.

Tôi đã thử thư mục E: \ Inetpub_IIS \ wwwroot, trả về TRUE. Hmm. Sau đó tôi nhận ra rằng tôi đã bỏ quên để kiểm tra php_error.log cả ngày. Dưới đây là những gì tôi đã tìm thấy:

[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 

Tôi Googled "open_basedir restriction in effect" và có câu trả lời của tôi. Trong php.tập tin ini, open_basedir được thiết lập để:

open_basedir = E:\Inetpub_IIS\wwwroot 

tôi đã thay đổi này để:

open_basedir = "E:\Inetpub_IIS\wwwroot;E:\Inetpub_IIS\tmp" 

Sau khi khởi động lại máy chủ ứng dụng bắt đầu làm việc như dự định.

Hy vọng rằng đó là đủ tài liệu cho người khác có thể gặp vấn đề tương tự.

đạo đức (s) của câu chuyện:

  • Kiểm tra cài đặt open_basedir của bạn.
  • Bật, đặt và nhớ kiểm tra nhật ký lỗi php của bạn.
  • Đừng nhìn chằm chằm vào cùng một vấn đề trong 7 giờ liền. Tôi nghĩ tôi gần như bị đột quỵ.
+0

Tôi muốn chỉ ra rằng mặc dù điều này giải quyết được vấn đề trước mắt, nhưng nó không giải thích tại sao PHP có thể ghi vào thư mục nhưng không thể đọc được từ nó. Tôi không biết liệu điều đó có xảy ra hay không, một lỗi hợp pháp hoặc một vấn đề về cấu hình. Nhưng bất cứ điều gì, nó hoạt động ngay bây giờ. – TPC

+0

Câu trả lời được viết rõ ràng. – xbonez

Các vấn đề liên quan