2013-03-13 34 views
17

JSON dizesini alıp CSV biçimine dönüştüren (fputcsv kullanarak) kısa bir PHP betiği oluşturmaya çalışıyorum ve bu CSV'yi indirilmiş bir .csv dosyası olarak kullanılabilir hale getiriyorum. Düşüncem, cronjobs hakkında endişelenmenize veya disk alanı tükenmeden endişelenmek için tmpfile() kullanmaktı, ancak sihrin gerçekleşmesi mümkün görünmüyor.Geçici bir dosya nasıl karşıdan yüklenir

İşte the PHP docs of readfile dönüştürülmüş bir örnektir benim girişimi var:

$tmp = tmpfile(); 
$jsonArray = json_decode($_POST['json']); 
fputcsv($tmp, $jsonArray); 

header('Content-Description: File Transfer'); 
header('Content-Type: text/csv'); 
header('Content-Disposition: attachment; filename='.basename($tmp)); 
header('Content-Transfer-Encoding: binary'); 
header('Expires: 0'); 
header('Cache-Control: must-revalidate'); 
header('Pragma: public'); 
header('Content-Length: ' . filesize($tmp)); 

ob_clean(); 
flush(); 
readfile($tmp); 

ben yanlış Content-Disposition ve Content-Transfer-Encoding başlıklarını gibi hissediyorum, ama bunları düzeltmek için nasıl emin değilim. Örneğin, basename($tmp) hiçbir şey döndürmüyor ve ben emin değilim text/csv ikili kodlama olarak aktarır. Aynı şekilde, echo filesize($tmp) da boş. Denediğimi yapmanın bir yolu var mı?

[Düzenle]

** Aşağıda kabul ettim cevabın sonucunda yazdığı çalışma kod şudur: * varsayılan olarak

$jsonArray = json_decode($_POST['json'], true); 
$tmpName = tempnam(sys_get_temp_dir(), 'data'); 
$file = fopen($tmpName, 'w'); 

fputcsv($file, $jsonArray); 
fclose($file); 

header('Content-Description: File Transfer'); 
header('Content-Type: text/csv'); 
header('Content-Disposition: attachment; filename=data.csv'); 
header('Content-Transfer-Encoding: binary'); 
header('Expires: 0'); 
header('Cache-Control: must-revalidate'); 
header('Pragma: public'); 
header('Content-Length: ' . filesize($tmpName)); 

ob_clean(); 
flush(); 
readfile($tmpName); 

unlink($tmpName); 
+0

Bu soruna yönelik bir javascript çözümü için, http://stackoverflow.com/questions/4130849/convert-json-format-to-csv-format-for-ms-excel adresine bakın. – Impirator

+0

'json_decode', herhangi bir şans ile null’ı döndürüyor mu? – Jon

+0

Yani dosya sadece indirilmek istemiyor musunuz? ve tarayıcıda açıldı? sorun bu mu? – Anton

cevap

5

Not olduğunu Dosya tanıtıcısı, ancak tüm işlevler bir dosya yol (yani bir dize), bir tanıtıcıya ihtiyaç duymaz - özellikle basename, filesize ve readfile. Yani bu fonksiyon çağrılarının hiçbiri doğru şekilde çalışmayacaktır. Ayrıca basename, bir dosya uzantısı da geri döndürmez. @Joshua Burns, söylediği gibi sadece fputcsv emin Bir dizide bir geçiyoruz yapmak veya assoc parametresini kullanın, ne istersen yani

'Content-Disposition: attachment; filename=data.csv' 

diyoruz.

+0

Bu, sorunu çözmek için gereken her şeydi. Çalışan kodu, kullanıcıların düzeltmeyi görebilmesi için soruya düzenleyeceğim. Teşekkür ederim! – Impirator

3

json_decode() nesneler ziyade diziler içine unsurları çevirir. fputcsv(), geçirilen verilerin bir dizi olmasını bekler.

$jsonArray = json_decode($_POST['json']); 

için:

$jsonArray = json_decode($_POST['json'], True); 

Ve bu sorunu çözmezse olmadığını görmek

değişiyorum öneriyoruz.

Bu gibi sorunların üstesinden gelmeye çalışırken ben çok display_errors etkinleştirilmesi ve görmek E_ALL için error_reporting ayarı öneriyoruz eğer orada üzerinde eksik hata çeşit: tmpfile() bir döndüren

<?php 
error_reporting(E_ALL); 
ini_set('display_errors', '1'); 

// Rest of your code here 
0

Öncelikle, dışarı bu dizeyi kontrol i bunu değiştirecek:

header('Content-Disposition: attachment; filename="'.basename($tmp).'"'); 

i tarayıcı uyumluluğu :)

0

Bir problem tmpfile() bir dosya tanıtıcısı döndürür olmasıdır ile, bir kere onunla sorun vardı filesize parametresi olarak bir dosya adı alırken.
Aşağıdaki satır: Herhangi çıkış gerçekleşmeden önce yürütülen tüm çağrılar Üstbilgiye

header('Content-Length: 0'); 

kontrol edin():

muhtemelen
header('Content-Length: ' . filesize($tmp)); 

olarak değerlendirilir alır.

İlgili konular