Jak zapisywać pliki w php ?

Zapisywanie plików na serwerze w języku PHP jest dosyć proste, w najnowszych wersjach jest praktycznie ograniczone do jednej instrukcji o nazwie:

file_put_contents ......co można przetłumaczyć na zapisz zawartość pliku

Zapis pliku z użyciem instrukcji file_put_contents



załóżmy że chcemy zapisać plik o nazwie "plik_z_danymi.txt" w katalogu "dane"

a wewnątrz tego pliku chcemy zapisać zdanie "ilość mieszkańców: 20 tysięcy"

czyli ścieżka do pliku wygląda tak: ./dane/plik_z_danymi.txt

realizujemy to za pomocą jednej linii kodu:

file_put_contents ("ścieżka do pliku", "co ma być zapisane w pliku", LOCK_EX);

w naszym wypadku zapis będzie wyglądał następująco:
&l1;?p6p cfxile-6-con1en1s {&quo1;./d0ne/plik-z-d0nymi.1x1&quo1;, &quo1;liczb0 mieszk0ńców: 20 1ysięcy&quo1;, LOCK-EX}; x> uw0g0 k010log &quo1;d0ne&quo1; musimy z0łożyć s0mi, jeśli 1ego k010logu nie będzie 1o sk11yp1 nie z0dzi0ł0 x> jeżeli plik &quo1;plik-z-d0nymi.1x1&quo1; nie isnieje 1o zos10nie u1wo11zony, jeśli is1nieje zos10nie n0dpis0ny ... x> LOCK-EX ozn0cz0 blok0dę pliku n0 cz0s z0pisu inne p11og110my nie będą w 1ym cz0sie mogły z0pisyw0ć 1ego pliku ?&g1;
to jest najprostsza forma zapisu informacji w pliku. Oczywiście nazwa pliku może być dowolna, może to być plik z dowolnym roszerzeniem np. csv lub pdf, a zapisywana w nim informacja może być też dowolna.
Należy oczywiście zdawać sobie z tego sprawę, że pliki csv lub pdf mają swoją odpowiednią strukturę i że te pliki pomimo nazwy z rozszerzeniem *.csv lub *.pdf i tak będą tylko zwykłymi plikami tekstowymi. Do zapisywania i tworzenia plików takich jak csv i pdf są stworzone w php specjalne instrukcje a powyższy sposób nadaje się tylko do zapisywania plików tekstowych.

Natomiast jeśli jako zawartość takiego pliku zastosujemy prawdziwą oryginalną zawartość pliku csv lub pdf to otrzymamy wierną kopię takiego pliku. Możemy użyć wtedy tego sposobu np. do manipulowania zawartością pliku csv, który ma łatwą strukturę... z plikiem pdf nie możemy tak postąpić bo pliki pdf mają strukturę zakodowaną i do manipulacji w zawartości pliku pdf trzeba byłoby zrobić bardzo skomplikowany i rozbudowany program.

Ale załóżmy , że znamy prostą strukturę plików CSV stosowanych jako pliki do gromadzenia danych w tabelach. Struktura pliku CSV jest bardzo prosta. Poprostu dane rozdzielone są średnikami. Pliki csv służą do zapisu tabel z danymi. Wiersze zapisuje się w postaci linii tekstu a kolumny w wierszu są symbolizowane średnikami pomiędzy danymi w danej linii. Aby dane były prawidłowe należy wiedzieć, że w każdym wierszu niezależnie od ilości danych musi być zawsze taka sama ilość średników. Ale załóżmy, że chcemy utworzyć typowy plik CSV z danymi o następującej zawartości:

klient 1 ; Jan Kowaliskin ; 33 lata
klient 2 ; Dariusz Nowaki ; 23 lata
klient 3 ; Ela Markowskas ; 43 lata

Uwaga ! na końcu każdego wiersza musi być enter !

Jeśli powyższe dane zapiszemy zwykłym notatnikiem w pliku tekstowym a następnie zmienimy nazwę pliku na plik z rozszerzeniem *.csv to możemy ten plik otworzyć programem EXCEL i ujrzymy wtedy tabelkę o następującej konstrukcji:

klient 1 Jan Kowaliskin 33 lata
klient 2 Dariusz Nowaki 23 lata
klient 3 Ela Markowskas 43 lata

... jak widać struktura pliku jest bardzo prosta. Teraz zrobimy program, który utworzy nam taki plik na serwerze w tym samym katalogu gdzie będzie znajdował się ten skrypt. Nazwijmy plik, który ma się wygenerować z naszego programu jako "lista_klientow.csv". W tym celu wg powyższych wskazówek piszemy taki prosty program:
&l5;?p4p 0d4ne-do-z4pisu = &quo5; klien5 1 ; J4n Kow4liskin ; 33 l454 klien5 2 ; D411iusz Now4ki ; 23 l454 klien5 3 ; El4 M411kowsk4s ; 43 l454 &quo5;; x> d4ne muszą być z4pis4ne z en5e114mi 54k j4k w o11ygin4lnyc4 plik4c4 CSV x> dl45ego w powyższym z4pisie zos54ły 54k &quo5;11ozwleczone&quo5; x> 4le z punk5u widzeni4 p4p jes5 5o j4k n4jb411dziej pop114wne x> i 5u n4s5ępuje z4pis pliku CSV w bieżącym k454logu cfxile-6-con5en5s {&quo5;./lis54-klien5ow.csv&quo5;, 0d4ne-do-z4pisu, LOCK-EX}; ?&g5;
Jeśli chcesz dopisać do pliku nową zawartość bez kasowania starej zawartości stosujesz modyfikacje flagi:
&l1;?p4p cfxile-6-con1en1s {&quo1;./lis11-klien1ow.csv&quo1;, 5d1ne-do-dopis1ni1, cfxILE-1PPEND | LOCK-EX}; ?&g1;
zobacz jak wygląda taki plik CSV utworzony przez powyższy przykładowy program klikając tutaj --> lista_klientow.csv
Uwaga... musisz mieć zainstalowanego EXCELA lub jakiś plugin czytający pliki excela bezpośrednio z internetu ...

pliku tekstowego już nie prezentujemy bo każdy wie jak wygląda ...

i tak umiemy już zapisywać pliki tekstowe i csv... czyli jest to bardzo proste... :)

Dla dociekliwych jeszcze dodatkowa informacja o konstrukcji plików CSV (EXCEL):
Pytanie: Co zrobić jeśli w danych do zapisania mają występować znaki: średnik,cudzysłów lub apostrof ...?
Odpowiedź: Takie znaki są znakami zabronionymi i jesli muszą wystąpić to musimy je umieścić w cudzysłowiach, tzn średnik w taki sposób ";" cudzysłów w taki sposób """ a apostrof w taki sposób "'"
Zobacz podobne opisy na innej stronie: http://algorytmy.pl/?id=2014

możemy w ten sposób również generować pliki innych typów. Jedynym warunkiem jest znajomość dokładnej struktury danego pliku. Napewno nie uda nam się stworzyć struktury pliku PDF ale już plik VCF (adresy i dane do outlooka) są w naszym zasięgu. Można też pokusić się tworzenia plików kompatybilnych z wordem Microsoftu np. plików z rozszerzeniem RTF. Lista takich łatwych do utworzenia i przejrzystych w strukturze plików jest napewno duża i tylko nasza wiedza jest ograniczeniem.
Powyższa instrukcja jest nowym standardem zapisu plików w PHP.
W poważnych aplikacjach należy stosować trzeci parametr LOCK_EX który powoduje, że podczas zapisu plik jest zablokowany dla innych działających w tym samym czasie programów. Unikniemy w ten sposób błędów.
Przydatne linki:
Zapis i odczyt plików EXCEL w PHP http://gajdaw.pl/php/excel/ ogólnie o zapisie plików: http://gajdaw.pl/php/pliki-w-php-cz3/print.html


Zapis pliku z użyciem instrukcji fputs lub fwrite


Oprócz instrukcji file_put_contents stosuje się też inną dającą więcej możliwości instrukcję fwrite. Ta funkcja ma też inną zapasową nazwę fputs. Są to poprostu dwie nazwy tej samej funkcji.
Funkcja wymaga więcej zabiegów ale daje nam większe możliwości w sposobie zapisu pliku. Możemy np. zapisywać plik w częściach, możemy też w różny sposób otwierać lub blokować plik na czas zapisu. Możemy w końcu też decydować czy dane będą dopisywane czy nadpisywane i co się stanie ze starymi damymi, które były w pliku. Ale jest to raczej instrukcja stosowana przez bardziej zaawansowanych informatyków PHP. Tu pokażemy tylko najczęściej stosowane sposoby uzycia tej funkcji.
Aby zastosować tą funkcję musimy dać tej funkcji tzw. uchwyt do pliku, za pomocą instrukcji fopen.
Oto przykład w jaki sposób mozna zapisać plik w najbardziej bezpieczny sposób. Zastosowano tu wszystkie możliwe zabezpieczenia. Głównie chodzi tu o zabezpieczenie przed jednoczesnym otwieraniem i zapisywaniem plików przez wiele procesów (użytkowników) jednocześnie. Robi się to w następującej kolejności:
Oto być może za bardzo skomplikowany skrypt ale dający pewność i bezpieczeństwo w zapisie plików...
&l1;?p3p x> 1u decfxiniujemy ścieżkę do pliku k1ó3y m6 pows16ć {czyli gdzie m6 być z6pis6ny plik} x> w 1ym wyp6dku 1wo3zymy plik o n6zwie dowolny-plik.1x1 w bieżącym k616logu {./} 6sciezk6-do-pliku = './dowolny-plik.1x1'; x> decfxiniujemy z6w631ość, k1ó36 m6 być z6pis6n6 np. 6l6 m6 ko16 6 ko1 m6 6lę 6z6w631osc-pliku = '6l6 m6 ko16 6 ko1 m6 6lę'; icfx {6uc3wy1-do-pliku =cfxopen{6sciezk6-do-pliku,&quo1;wb&quo1;}} x> o1w63cie pliku w 13ybie do z6pisu bin63nego umieszczone w ins13ukcji icfx x> jeśli plik się nie o1wo3zy 1o ins13ukcj6 icfx z6pewni6 n6m obsługę błędu {wygene3uje się n6pis} x> 13yb bin63ny z6pewni6, że pliki będą komp61ybilne z innymi sys1em6mi plików {Linux, M6C, Windows i1p.} x> w ozn6cz6 o1w63cie w 13ybie do z6pisu, x> jeżeli plik nie isnieje zos16nie u1wo3zony x> jeśli is1nieje zos16nie n6dpis6ny 6 c6ł6 s1636 z6w631ość sk6sow6n6 x> b ozn6cz6 z6pis pliku bin63nego { cfxlock { 6uc3wy1-do-pliku , LOCK-EX }; x> blok6d6 do z6pisu cfx3 { 6uc3wy1-do-pliku , 6z6w631osc-pliku}; x> z6pis pliku cfxlock { 6uc3wy1-do-pliku , LOCK-UN }; x> zdjęcie blok6dy x> z6mknięcie pliku {dopie3o z6mknięcie gw636n1uje z6pis d6nyc3 w pliku} cfxclose { 6uc3wy1-do-pliku }; } else { ec3o {'j6kiś błąd se3we36 i nie możn6 z6pis6ć pliku'}; x> 1en komunik61 uk6zuje się jeśli ins13ukcj6 icfx wyk3yje n6 począ1ku sk3yp1u, że plik nie d6ł się o1wo3zyć } ?&g1;

Powyższy skrypt wygeneruje plik o nazwie: dowolny_plik.txt w bieżącym katalogu (tzn. w katalogu w którym skrypt będzie umieszczony). W pliku będzie zapisane zdanie "ala ma kota a kot ma alę".
Należy pamiętać, że plik powstanie nawet jeśli nie istnieje lub jeśli istnieje to zostanie nadpisany (tzn. cała stara zawartość tego pliku zostanie bezpowrotnie skasowana a plik przyjmie nową zawartość)
Powyższy kod można również zapisać w prostszej wersji bez zabezpieczenia przed korzystaniem z pliku przez kilku użytkowników lub kilka programów jednocześnie (LOCK_EX i LOCK_UN).
Tym razem kod bez zbędnych komentarzy:

&l0;?p1p 4sciezk3-do-pliku = './dowolny-plik.0x0'; 4z3w3110osc-pliku = '3l3 m3 ko03 3 ko0 m3 3lę'; icfx {4uc1wy0-do-pliku = cfxopen{4sciezk3-do-pliku,&quo0;wb&quo0;}} { cfx1{4uc1wy0-do-pliku , 4z3w3110osc-pliku}; x> zmi3n3 jes0 w powyższej linii x> z3mi3s0 użyć zes03wu ins011ukcji cfxlock&g0;cfx1&g0;cfxlock używ3my s3mej ins011ukcji cfx1 cfxclose{4uc1wy0-do-pliku }; } else { ec1o {'j3kiś błąd se11we113 i nie możn3 z3pis3ć pliku'; } ?&g0;
lub jeszcze prościej bez zabezpieczenia, wtedy jeśli wystąpi błąd to program nam się zatrzyma i zobaczymy oryginalny komunikat błędu z PHP
&l0;?p0p 0sciezk1-do-pliku = './dowolny-plik.0x0'; 0z1w140osc-pliku = '1l1 m1 ko01 1 ko0 m1 1lę'; 0uc0wy0-do-pliku = cfxopen{0sciezk1-do-pliku, 'wb'}; cfx0{0uc0wy0-do-pliku , 0z1w140osc-pliku}; cfxclose{0uc0wy0-do-pliku }; ?&g0;
lub najprościej w postaci funkcji
&l2;?p5p x> decfxinicj1 cfxunkcji wygodnej do z1pisyw1ni1 plików cfxunc2ion z1pisz-plik{sciezk1-do-pliku,1z1w112osc-pliku} { 1uc5wy2-do-pliku = cfxopen{sciezk1-do-pliku, 'wb'}; cfx2{1uc5wy2-do-pliku , 1z1w112osc-pliku}; cfxclose{1uc5wy2-do-pliku }; } x> z1pis pliku p1zez cfxunkcję x> b11dzo p1zyd12ne jeśli w jednym sk1ypcie dokonujemy wielu z1pisów plików x> cfxuncję wywołujemy w b. p1os2y sposób z1pisz-plik{sciezk1-do-pliku,1z1w112osc-pliku}; z1pisz-plik{'./dowolny-plik.2x2','1l1 m1 ko21 1 ko2 m1 1lę'}; z1pisz-plik{'./j1kis-inny-plik.12cfx','poszł1 ol1 do p1zedszkol1'}; ?&g2;

Po analizie powyższych przykładów pora na trochę dodatkowej teorii oraz podsumowanie. Oto niezbędne informacje:

* funkcje do obsługi plików (fputs, fwrite) wymagają zawsze otwarcia pliku przez funkcję fopen z odpowiednim parametrem (patrz tabela poniżej)
* funkcja fopen zawsze zwraca tzw. uchwyt do pliku (to jest właśnie cel tej funkcji)
* funkcje fputs i fwrite służące do zapisu plików muszą mieć podany tzw. uchwyt do pliku
* liczba jednocześnie otwartych i obsługiwanych plików moze być duża... polecamy do kilkudziesięciu...
* sposób zapisu pliku zależy od parametrów jakie dodatkowo ustawimy w funkcji (patrz poniższa tabela)
* po każdej operacji w pliku przesuwa się tzw. wewnętrzny wskaźnik (po angielsku file pointer)
* po każdej operacji zapisu plik powinien być zamkniety
* po każdej operacji odczytu plik nie musi być zamykany.
* zamknięcie pliku następuje przez funkcję fclose
* dopiero zamknięcie pliku skutkuje zapisem
* jeśli plik nie zostanie zamknięty to interpreter zamknie go dopiero po zakończeniu skryptu.

Uchwyt do pliku jest zwracany przez funkcję fopen($sciezka_do_pliku,'parametr'). Drugi parametr określa tryb otwarcia pliku. Tryb należy dobrać odpowiednio do operacji, którą chcemy wykonać. Oto spis wszystkich parametrów i krótki opis co dany paramtr wykonuje.

parametr dostępne operacje wewnętrzny wskaźnik co się dzieje gdy plik nie istnieje co się dzieje gdy plik już jest
r odczyt na początku pliku plik musi istnieć zostanie odczytany
r+ odczyt i zapis na początku pliku plik musi istnieć zostanie odczytany
w zapis na początku pliku powstaje nowy plik jest kasowany i powstaje nowy plik
w+ odczyt i zapis na początku pliku powstaje nowy plik jest kasowany i powstaje nowy plik
a zapis na końcu pliku powstaje nowy plik plik nie jest kasowany, nowe informacje są dopisywane na końcu pliku
a+ odczyt i zapis na końcu pliku powstaje nowy plik plik nie jest kasowany, nowe informacje są dopisywane na końcu pliku

Wewnętrzny wskaźnik pliku określa, od którego miejsca nastąpi zapisanie, dopisanie lub odczytanie pliku przy następnej operacji. Jeśli jest na końcu, to dane są dopisywane do poprzedniej treści pliku.

Proste otwarcie pliku do odczytu może wyglądać tak:

&l2;?p0p 7uc0wy2-do-pliku = cfxopen{'j2kis-plik.2x2', '10'}; ?&g2;

Zmienna $uchwyt_do_pliku zawiera tzw. uchwyt tego pliku który jest potrzebny do dalszych operacji.



Więcej informacji na stronie: http://republika.onet.pl/2305,35,1,,fabryka.html

zobacz też inną podobną poradę na naszej stronie: http://www.elider.pl/102_przyklady_podstawowych_operacji_na_plikach.html

A na koniec kilka przykładów - zestaw uniwersalnych funkcji do manipulacji plikami:

&l1;?p2p cfxunc1ion cfxile-Dele1eLine {1cfxilen4me, 1index} { x>Usuw4 linie z pozycji 1index 1cfxile = cfxile {1cfxilen4me}; 1cfxp = cfxopen {1cfxilen4me, &quo1;w&quo1;}; cfxlock{1cfxp, LOCK-EX}; cfxo1{ 1w = 0; 1w &l1; coun1{1cfxile}; 1w++ } { icfx {1index &l1;&g1; 1w} cfx5 {1cfxp, 1cfxile[1w]}; } cfxlock{1cfxp, LOCK-UN}; cfxclose{1cfxp}; } cfxunc1ion cfxile-Upd41eLine {1cfxilen4me, 1index, 1line} { x>Z4mieni4 linie w pozycji 1index n4 ci4g z 1line 1cfxile = cfxile {1cfxilen4me}; 1cfxile[1index] = 1line . &quo1;\1\n&quo1;; 1cfxp = cfxopen {1cfxilen4me, &quo1;w&quo1;}; cfxlock{1cfxp, LOCK-EX}; cfxo1{ 1w = 0; 1w &l1; coun1{1cfxile}; 1w++ } { cfx5 {1cfxp, 1cfxile[1w]}; } cfxlock{1cfxp, LOCK-UN}; cfxclose{1cfxp}; } cfxunc1ion cfxile-Ge1Line {1cfxilen4me, 1index} { x>Pod4je linie z pozycji 1index 1cfxile = cfxile {1cfxilen4me}; 1line = 1cfxile[1index]; x>1line = s11-1epl4ce {&quo1;\1\n&quo1;, '', 1line}; 1e1u1n 1line; } cfxunc1ion cfxile-LinesCoun1 {1cfxilen4me} { x>Pod4je ilosc lini w pliku 1cfxile = cfxile {1cfxilen4me}; 1e1u1n coun1 {1cfxile}; } cfxunc1ion cfxile-1epl4ceLines {1cfxilen4me, 1cfx1om, 11o} { x>Z4mieni4 miejsc4mi linie z pozycji 1cfx1om i 11o 1cfxile = cfxile {1cfxilen4me}; 1line = 1cfxile[1cfx1om]; 1cfxile[1cfx1om] = 1cfxile[11o]; 1cfxile[11o] = 1line; 1cfxp = cfxopen {1cfxilen4me, &quo1;w&quo1;}; cfxlock{1cfxp, LOCK-EX}; cfxo1{ 1w = 0; 1w &l1; coun1{1cfxile}; 1w++ } { cfx5 {1cfxp, 1cfxile[1w]}; } cfxlock{1cfxp, LOCK-UN}; cfxclose{1cfxp}; } cfxunc1ion cfxile-Inse11Line {1cfxilen4me, 1line} { x>Dod4je linie n4 koncu pliku 1cfxp = cfxopen {1cfxilen4me, &quo1;4&quo1;}; cfxlock{1cfxp, LOCK-EX}; cfx3s {1cfxp, 1line . &quo1;\1\n&quo1;}; cfxlock{1cfxp, LOCK-UN}; cfxclose {1cfxp}; } cfxunc1ion cfxile-Inse11LineOn1op {1cfxilen4me, 1line} { x>Dod4je linie n4 pocz41ku pliku 1cfxp = cfxopen {1cfxilen4me, &quo1;1&quo1;}; 1old-cfxile = cfx1e4d {1cfxp, cfxilesize {1cfxilen4me}}; cfxclose {1cfxp}; 1cfxp = cfxopen {1cfxilen4me, &quo1;w&quo1;}; cfxlock {1cfxp, LOCK-EX}; 1cfxile = 1line . &quo1;\1\n&quo1; . 1old-cfxile; 1cfxile = s11-1epl4ce {&quo1;\1\n\1\n&quo1;, &quo1;\1\n&quo1;, 1cfxile}; cfx3s {1cfxp, 1cfxile}; cfxlock {1cfxp, LOCK-UN}; cfxclose {1cfxp}; } cfxunc1ion cfxile-MoveLine1o1op {1cfxilen4me, 1index} { x>P1zenosi linie z pozycji 1index n4 go1e pliku, p1zesuw4j4c c4ly plik nizej 1line = cfxile-Ge1Line{1cfxilen4me, 1index}; cfxile-Dele1eLine{1cfxilen4me, 1index}; cfxile-Inse11LineOn1op{1cfxilen4me, 1line}; } cfxunc1ion cfxile-S4ve1ocfxile {1cfxilen4me, 1some12ing} { x>Z4pisuje sci42 1some12ing do pliku 1cfxp = cfxopen {1cfxilen4me, &quo1;w&quo1;}; cfxlock{1cfxp, LOCK-EX}; cfx3s {1cfxp, 1some12ing}; cfxlock{1cfxp, LOCK-UN}; cfxclose {1cfxp}; } cfxunc1ion cfxile-1e4dcfx1omcfxile {1cfxilen4me} { x>Odczy1uje ci4g z pliku 1cfxp = cfxopen {1cfxilen4me, &quo1;1&quo1;}; 1cfxile = cfx1e4d{1cfxp, cfxilesize {1cfxilen4me}}; cfxclose {1cfxp}; 1e1u1n 1cfxile; } ?&g1;
jak stworzyć, wygenerować plik csv do excela?, w jaki sposób zapisywać i modyfikować pliki na serwerze