2011-12-27 9 views
9

Ho un vero e proprio scratcher qui.PHP non riconoscerà i propri file temporanei caricati

Questa è la mia configurazione di sistema:

  • Windows Server 2008 R2
  • PHP 5.3.8 installato come modulo FastCGI
  • IIS 7,5

Questo è il mio problema:

Ho un semplice modulo per il caricamento di file. Come sappiamo, quando PHP accetta un caricamento di file, il file riceve un nome temporaneo e viene inserito in una directory temporanea prima di essere elaborato. Nel mio caso, PHP inserisce il file nella directory temporanea (che si trova in E: \ Inetpub_IIS \ tmp, accanto a E: \ Inetpub_IIS \ wwwroot) ma immediatamente "dimentica" che il file esiste fino a quando non viene visualizzato il garbage collector, che elimina il file temporaneo. Più specificamente, il file temporaneo viene creato nella directory temporanea sul server, ma quando chiamo sha1_file() su quel file, la funzione non restituisce nulla. anche file_exists() fallisce. Questo mi fa pensare che PHP non riesce a trovare il file. Il log di ProcMon di seguito mostra che PHP sta cercando nel posto giusto.

Ecco il mio registro 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 

Come si può vedere, ProcMon mostra chiaramente il file temporaneo viene creato, scritto e poi chiuse. Verso la fine è possibile visualizzare le chiamate "QueryDirectory", che coincidono con le mie chiamate di script, che tentano di ottenere l'hash SHA1 del file, tra le altre cose.

Questo è il mio script:

Il modulo di upload di file ha un oggetto Flash e alcune DIV per l'oggetto Flash per costruire la forma, niente di più. Il file di caricamento temporaneo viene creato sul server nella sua interezza quindi dubito seriamente che il mio modulo sia il problema.

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

Il contenuto di "logfile.txt":

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

La chiamata "sonno" esiste per darmi il tempo di controllare la directory temporanea per il file prima che scompaia.

Dozzine di ricerche su Google mi hanno portato a cose riguardanti le autorizzazioni o a soluzioni che comportano moduli di caricamento non riusciti che non riescono a caricare nulla. I file vengono creati sul server, quindi ovviamente il modulo funziona. Inoltre, ho provato a dare a IUSR, IIS_ISURS e DefaultAppPool l'accesso completo alla directory temporanea ea tutti E: \ Inetpub_IIS per vedere se questo avesse qualcosa a che fare con le autorizzazioni associate, ma questo non ha cambiato nulla. Qualcuno può offrire qualche consiglio su cosa sta succedendo qui?

EDIT: l'ho capito.

DaveRandom e io pensavamo che fosse un problema di autorizzazioni di qualche tipo, il che era vero. Tuttavia, stavamo entrambi pensando alle autorizzazioni di Windows, quando il problema era in realtà un problema di autorizzazione/configurazione di PHP. Il fraseggio di "work backwards" di Dave mi ha fatto pensare di spostarmi all'indietro attraverso l'albero delle directory e testare le autorizzazioni che alla fine hanno prodotto la seguente soluzione.

Quello che ho fatto:

ho scritto un breve script:

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

Questo restituito FALSE. Apparentemente la directory non era leggibile, come suggeriva Dave.

Ho provato la directory E: \ Inetpub_IIS \ wwwroot, che ha restituito TRUE. Hmm. Ho poi realizzato che avevo trascurato di controllare il php_error.log tutto il giorno. Ecco cosa ho trovato:

[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 

I google "restrizione open_basedir in vigore" e ha avuto la mia risposta. Nel file php.ini, open_basedir è stato fissato a:

open_basedir = E:\Inetpub_IIS\wwwroot 

l'ho cambiato a:

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

Dopo aver riavviato il server l'applicazione ha iniziato a lavorare come previsto.

Speriamo che questa documentazione sia sufficiente per qualcun altro che potrebbe avere lo stesso problema.

Moral (s) della storia:

  • controllare le impostazioni open_basedir.
  • Abilitare, impostare e ricordare di controllare il registro degli errori php.
  • Non fissare lo stesso problema per 7 ore di fila senza interruzioni. Penso di aver quasi avuto un ictus.
+0

[php man] (http://www.php.net/manual/en/features.file-upload.php) vedere la sezione dei codici di errore per facilitare il debug, anche cercare [print_r] (http: //www.php.net/print_r)() funzione in modo da poter eseguire print_r ($ _ FILES); – goat

+0

UPLOAD_ERR_OK viene restituito. Ecco alcuni output di print_r: 'Array ([the_uploaded_file] => Array ([nome] => picture.jpg [tipo] => immagine/jpeg [nome_tmp] => E: \ Inetpub_IIS \ tmp \ php34DD.tmp [errore] = > 0 [size] => 391387)) ' – TPC

+0

So che sei stato in questa strada, ma sembra probabile che questo sia legato alle autorizzazioni - in particolare (anche se sarebbe bizzarro) che qualcosa abbia accesso in scrittura alla directory - o i file che si stanno creando e che non possono leggerli/loro. Prova ad assegnare il controllo completo al gruppo 'Everyone' e vedi se questo risolve il problema, se funziona a ritroso da lì. – DaveRandom

risposta

4

Come promesso, ecco la mia risposta. Questo era copia/incollato dalla modifica OP.

L'ho capito.

DaveRandom e io pensavamo entrambi che fosse un problema di autorizzazioni di qualche tipo, il che era vero. Tuttavia, stavamo entrambi pensando alle autorizzazioni di Windows, quando il problema era in realtà un problema di autorizzazione/configurazione di PHP. Il fraseggio di "work backwards" di Dave mi ha fatto pensare di spostarmi all'indietro attraverso l'albero delle directory e testare le autorizzazioni che alla fine hanno prodotto la seguente soluzione.

Quello che ho fatto:

ho scritto un breve script:

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

Questo restituito FALSE. Apparentemente la directory non era leggibile, come suggeriva Dave.

Ho provato la directory E: \ Inetpub_IIS \ wwwroot, che ha restituito TRUE. Hmm. Ho poi realizzato che avevo trascurato di controllare il php_error.log tutto il giorno. Ecco cosa ho trovato:

[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 

I Googled "restrizione open_basedir in effetti" e ha avuto la mia risposta. Nel php.file ini, open_basedir è stato fissato a:

open_basedir = E:\Inetpub_IIS\wwwroot 

l'ho cambiato a:

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

Dopo aver riavviato il server l'applicazione ha iniziato a lavorare come previsto.

Speriamo che questa documentazione sia sufficiente per qualcun altro che potrebbe avere lo stesso problema.

Moral (s) della storia:

  • controllare le impostazioni open_basedir.
  • Abilitare, impostare e ricordare di controllare il registro degli errori php.
  • Non fissare lo stesso problema per 7 ore di fila. Penso di aver quasi avuto un ictus.
+0

Vorrei sottolineare che sebbene questo risolvesse il problema immediato, non spiegava perché PHP fosse in grado di scrivere nella directory ma non era in grado di leggerlo. Non so se questo è accaduto, un bug legittimo o un problema di configurazione. Ma qualunque cosa, ora funziona. – TPC

+0

Risposta ben documentata. – xbonez

Problemi correlati