Php bir dosya tanıtıcısından olarak bir dize erişmek için bir yolu var mı?

5 Cevap php

Ben str_getcsv bana uygun değil demektir PHP 5.2.6 sınırlı Ben bir sunucuda değilim. I ") () () (başarıyla fopen ile açılmış bir dosya için geçerli bir dosya işaretçisi, popen veya fsockopen." Gerektirir yerine fgetcsv kullanıyorum üzerinde işletmek.

Benim sorum şudur: Bir dosya tanıtıcısı olarak bir dize erişmek için bir yol var?

Benim diğer seçenek bir metin dosyasına dize yazmak ve ardından fopen() üzerinden erişmek ve daha sonra fgetcsv kullanmak için, ama ben gibi, doğrudan yapmak bir yolu var umuyorum perl'de.

5 Cevap

Eğer bu fonksiyonu önermektedir str_getcsv , you'll find this note from daniel için manuel sayfada kullanıcı notları, bir göz atacak olursak (quoting):

<?php
if (!function_exists('str_getcsv')) {
    function str_getcsv($input, $delimiter = ",", $enclosure = '"', $escape = "\\") {
        $fiveMBs = 5 * 1024 * 1024;
        $fp = fopen("php://temp/maxmemory:$fiveMBs", 'r+');
        fputs($fp, $input);
        rewind($fp);

        $data = fgetcsv($fp, 1000, $delimiter, $enclosure); //  $escape only got added in 5.3.0

        fclose($fp);
        return $data;
    }
}
?>

Sizin için sorduk tam olarak ne yapıyor gibi görünüyor: bunun üzerine fgetcsv kullanmak için, bellekte geçici bir dosya tanıtıcısına işaret hangi bir akım kullanır.


See
PHP input/output streams for the documentation about, amongst others, the php://temp stream wrapper.


Of course, you should test that it works OK for you -- but, at least, this should give you an idea of how to achieve this ;-)

Genel soruyu yanıtlamak için, evet bir dosya akışı gibi bir değişken davranabilirsiniz.

http://www.php.net/manual/en/function.stream-context-create.php

Aşağıdaki (yani ben ne kadar üretim hazır için kefil olamaz) PHP kılavuzda birkaç farklı yorumlardan bir kopyalama ve yapıştırma:

<?php
class VariableStream {
    private $position;
    private $varname;
    public function stream_open($path, $mode, $options, &$opened_path) {
        $url = parse_url($path);
        $this->varname = $url["host"];
        $this->position = 0;
        return true;
    }
    public function stream_read($count) {
        $p=&$this->position;
        $ret = substr($GLOBALS[$this->varname], $p, $count);
        $p += strlen($ret);
        return $ret;
    }
    public function stream_write($data){
        $v=&$GLOBALS[$this->varname];
        $l=strlen($data);
        $p=&$this->position;
        $v = substr($v, 0, $p) . $data . substr($v, $p += $l);
        return $l;
    }
    public function stream_tell() {
        return $this->position;
    }
    public function stream_eof() {
        return $this->position >= strlen($GLOBALS[$this->varname]);
    }
    public function stream_seek($offset, $whence) {
        $l=strlen(&$GLOBALS[$this->varname]);
        $p=&$this->position;
        switch ($whence) {
            case SEEK_SET: $newPos = $offset; break;
            case SEEK_CUR: $newPos = $p + $offset; break;
            case SEEK_END: $newPos = $l + $offset; break;
            default: return false;
        }
        $ret = ($newPos >=0 && $newPos <=$l);
        if ($ret) $p=$newPos;
        return $ret;
    }
}

stream_wrapper_register("var", "VariableStream");
$csv = "foo,bar\ntest,1,2,3\n";

$row = 1;
if (($handle = fopen("var://csv", "r")) !== FALSE) {
    while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
        $num = count($data);
        echo "<p> $num fields in line $row: <br /></p>\n";
        $row++;
        for ($c=0; $c < $num; $c++) {
            echo $data[$c] . "<br />\n";
        }
    }
    fclose($handle);
}
?>

Tabii ki, özel bir örnek için, kullanılabilir basit akış yöntem vardır.

Ben kimsenin bu çözüm yanıtladı dehşete değilim:

<?php

$string = "I tried, honestly!";
$fp     = fopen('data://text/plain,' . $string,'r');

echo stream_get_contents($fp);

#fputcsv($fp, .......);

?>

Ve bellek aç mükemmel bir çözüm:

<?php

class StringStream
{
    private   $Variable = NULL;
    protected $fp       = 0;

    final public function __construct(&$String, $Mode = 'r')
    {
        $this->$Variable = &$String;

        switch($Mode)
        {
            case 'r':
            case 'r+':
                $this->fp = fopen('php://memory','r+');
                fwrite($this->fp, @strval($String));
                rewind($this->fp);
                break;

            case 'a':
            case 'a+':
                $this->fp = fopen('php://memory','r+');
                fwrite($this->fp, @strval($String));
                break;

            default:
                $this->fp = fopen('php://memory',$Mode);
        }
    }

    final public function flush()
    {
        # Update variable
        $this->Variable = stream_get_contents($this->fp);
    }

    final public function __destruct()
    {
        # Update variable on destruction;
        $this->Variable = stream_get_contents($this->fp);
    }

    public function __get($name)
    {
        switch($name)
        {
            case 'fp': return $fp;
            default:   trigger error('Undefined property: ('.$name.').');
        }

        return NULL;
    }
}

$string = 'Some bad-ass string';
$stream = new StringStream($string);

echo stream_get_contents($stream->fp);
#fputcsv($stream->fp, .......);

>

Eğer stream sonra ne konum elde etmek için bu tür php://memory olarak kolları kullanabilirsiniz. Sadece açık, fwrite, geri sarma ve fgetcsv kullanmak gerekir.

Ne yazık ki, bu mümkün değildir. Bir dosyadan bir akım var gibi eğer bir dize tedavi edemez. Sen gerçekten Önce bir dosyaya dize yazmak zorunda, ve sonra fopen kullanılarak dedi dosyayı açacak.

Ve şimdi bariz bir kısmı, yükseltme kabul var?