2016-05-31 12 views
5

Sto provando a creare un file "virtuale" senza utilizzare né memoria né file temporaneo. Il file "virtuale" deve passare un controllo effettuato con file_exists() senza generare alcun errore o avviso se utilizzato con require o include.Come creare un file falso/"virtuale"?

consente di implementare i propri gestori di protocollo e flussi per l'uso con all the other filesystem functions (come fopen(), fread() ecc).

... dove file_exists() è uno di questi. The docs page stati:

A partire da PHP 5.0.0, questa funzione può essere utilizzata anche con alcuni wrapper URL. Fare riferimento a Supported Protocols and Wrappers per determinare quali wrapper supportano la famiglia di funzionalità stat().

Il mio tentativo non era quello di costruire una consuetudine, file di involucro virtuale

class VirtualFileWrapper 
{ 
    public $context; 

    public function stream_open($path, $mode, $options, &$opened_path) 
    { 
     return TRUE; 
    } 

    public function stream_stat() 
    { 
     var_dump(__METHOD__); 
     $data = [ 
      'dev'  => 0, 
      'ino'  => getmyinode(), 
      'mode' => 'r', 
      'nlink' => 0, 
      'uid'  => getmyuid(), 
      'gid'  => getmygid(), 
      'rdev' => 0, 
      'size' => 0, 
      'atime' => time(), 
      'mtime' => getlastmod(), 
      'ctime' => FALSE, 
      'blksize' => 0, 
      'blocks' => 0, 
     ]; 
     return array_merge(array_values($data), $data); 
    } 
} 

stream_wrapper_register('virtual', 'VirtualFileWrapper'); 

$file = fopen("virtual://foo", 'r+'); 

// Executes VirtualFileWrapper::stream_stat() 
fstat($file); 

// Executes no VirtualFileWrapper method 
file_exists($file); 

Mentre la funzione fstat() esegue il metodo, file_exists() non esegue alcun metodo di classe flusso.

Come posso far funzionare un wrapper stream virtuale (con file_exists())?


Sono pienamente consapevole che tempnam(__DIR__, '') passerà entrambi:

  • var_dump(tempnam(__DIR__, '')); Returns true
  • require tempnam(__DIR__, ''); Nessun errore

ma io non voglio usare un file temporaneo in quanto non vi potrebbe essere un modo migliore (prestazioni saggio).

+1

Non è possibile. file_exists() si aspetta una stringa come argomento. È possibile passare in un oggetto che implementa il metodo magico __toString(), ma in questo caso file_exists eseguirà 'stat()' quella stringa e non riuscirà, perché il file non esiste realmente. –

+0

@MarcB In realtà [** Drupal ** ha funzionato] (http://drupal.stackexchange.com/a/24233/55237). Non riuscivo proprio a capire come la roba di 'vfsStream' sia solo quella incasinata nella fonte. – kaiser

+0

Perché stai provando a realizzare con questo? Penso che creare un file falso sia una pratica molto strana. – Jehy

risposta

5

Sembra che sia necessario implementare un metodo pubblico url_stat() su VirtualFileWrapper per consentire il superamento del controllo file_exists().

per mettere a tacere gli avvertimenti e gli errori da include e require, è necessario implementare stream_read() e stream_eof() metodi:

class VirtualFileWrapper 
{ 
    public $context; 

    public function stream_open($path, $mode, $options, &$opened_path) 
    { 
     return TRUE; 
    } 

    public function stream_stat() 
    { 
     var_dump(__METHOD__); 
     return []; 
    } 

    public function url_stat() 
    { 
     return array (
      0 => 0, 
      1 => 0, 
      2 => 0, 
      3 => 0, 
      4 => 0, 
      5 => 0, 
      6 => 0, 
      7 => 0, 
      8 => 0, 
      9 => 0, 
      10 => 0, 
      11 => 0, 
      12 => 0, 
      'dev' => 0, 
      'ino' => 0, 
      'mode' => 0, 
      'nlink' => 0, 
      'uid' => 0, 
      'gid' => 0, 
      'rdev' => 0, 
      'size' => 0, 
      'atime' => 0, 
      'mtime' => 0, 
      'ctime' => 0, 
      'blksize' => 0, 
      'blocks' => 0 
     ); 
    } 

    public function stream_read(){ 
     return ''; 
    } 

    public function stream_eof(){ 
     return ''; 
    } 

} 

stream_wrapper_register('virtual', 'VirtualFileWrapper'); 

$file = fopen("virtual://foo", 'r+'); 

// Executes VirtualFileWrapper::stream_stat() 
fstat($file); 

// Executes no VirtualFileWrapper method 
file_exists("virtual://foo"); 

//Still no errors :-)! 
require "virtual://foo"; 
include "virtual://foo"; 

Fare attenzione a passare file_exists() una stringa, piuttosto che la risorsa si è creato con fopen().

+0

Vorrei poter fornire maggiori dettagli - Non ho idea del perché funzioni, Ill tornare e modificare se capisco. – HPierce

+0

Dopo aver provato questo per ore, sono davvero felice che tu sia saltato in: Il mio esempio era vicino a non diverso dal tuo, a parte il fatto che ho restituito 'stat()' dentro 'url_stat() '. Sembra che ho bisogno di imparare a leggere: P Il [valore 'return'] (http://php.net/manual/en/streamwrapper.url-stat.php) afferma chiaramente che. Grazie mille! A proposito, un'altra cosa strana è che sia 'require' che 'include' viene chiamato _twice_ nel mio test locale. – kaiser