Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: przechwycenie wyjątku przy tworzeniu pliku
Forum PHP.pl > Forum > PHP
damianooo
Witam,

Mam problem z zapisem pliku w miejscu sieciowym na serwerze i chciałbym teraz poprzez przechwycenie wyjątku dowiedzieć się jaki jest problem, tzn. : czy jest problem z uprawnieniami , czy z błędną ścieżką czy może jeszcze coś innego ...

zrobiłem tak :

  1. try
  2. {
  3. $dane = "jakiś tam tekst\n";
  4. $file = "/zap/hurt/test.txt";
  5. $fp = fopen($file, "a");
  6. flock($fp, 2);
  7. fwrite($fp, $dane);
  8. flock($fp, 3);
  9. fclose($fp);
  10. }
  11. catch( Exception $e )
  12. {
  13. $danes = "Komunikat: ".$e->getMessage().". Plik: ".$e->getFile().". Wiersz: ".$e->getLine()."\r\n";
  14. $files = "info_log.txt";
  15. $fps = fopen($files, "a");
  16. flock($fps, 2);
  17. fwrite($fps, $danes);
  18. flock($fps, 3);
  19. fclose($fps);
  20. }


jednak nie uzyskuję żadnej informacji w pliku info_log.txt , a plik test.txt nie zostaje utworzony

Proszę o pomoc czy dobrze próbuję przechwycić wyjątek czy może powinienem to zrobić w inny sposób ...

dziękuję
Crozin
Standardowa biblioteka PHP praktycznie w ogóle nie wykorzystuje wyjątków. Będziesz musiał to samemu sprawdzić (is_writable itp.) i ręcznie rzucić wyjątek. Ewentualnie możesz poszukać jakieś biblioteki-nakładki na funkcje f*(), która robiłaby to już za Ciebie.
damianooo
ale to jak? proponujesz tak:

  1. $filename = '/zap/hurt/test.txt';
  2. if (is_writable($filename)) {
  3. echo 'The file is writable';
  4. } else {
  5. echo 'The file is not writable';
  6. }



zrobiłem tak i tylko zauważyłem że długo się skrypt wykonywał, tak jakby próbował parę razy wykonać tą operację zapisu albo jakby nie mógł znaleźć ścieżki do zapisu ..


czy czegoś mi tu brakuje ?

bo myślałem że jakieś warningi dostanę czy coś ... ale nic ...

Ilware
spróbuj utworzyć plik, i nadać mu uprawnienia readonly,wywołaj następnie sam zapis i zobaczysz jaki błąd dostaniesz.
damianooo
ok zrobiłem najpierw tak:

  1. $nazwa_pliku = '/zap/hurt/test.txt';
  2. if (file_exists($nazwa_pliku)) {
  3. echo "Plik $nazwa_pliku istnieje";
  4. } else {
  5. echo "Plik $nazwa_pliku nie istnieje";
  6. }


i dostałem tak:

"Plik /zap/hurt/test.txt nie istnieje"

następnie zrobiłem tak:

  1. $filename = '/zap/hurt/test.txt';
  2. if (is_writable($filename)) {
  3. echo 'The file is writable';
  4. } else {
  5. echo 'The file is not writable';
  6. }


i otrzymałem tak:

"The file is not writable"


a więc wyraźnie widać że nie może znaleźć katalogu i nie może zapisać tam tego pliku ...

wniosek ? nie mam uprawnień ? katalog na pewno istnieje ponieważ admin twierdzi że go utworzył ...

skoro tak dużo się dowiedziałem ... można jeszcze coś wymyśleć aby sprawdzić dlaczego są problemy .? ... czy pewne że nie mam uprawnień questionmark.gif?

proszę o propozycje

dzięki
Crozin
No widzisz, niestety PHP od 7 lat (od czasu wprowadzenia wyjątków) nie doczekało się żadnych istotnych zmian w jego bibliotece standardowej i nadal jest na tym z poziomu roku 1999 (chyba). Nie pojawiła się też żadna wiodąca biblioteka zastępująca standardową, tak więc nadal jest się zdanym samym na siebie.

I tak, niestety będziesz musiał zrobić coś w stylu:
  1. $path = '...';
  2.  
  3. try {
  4. if (!file_exists($path)) {
  5. throw ...;
  6. }
  7.  
  8. if (!is_writable($path)) {
  9. throw ...;
  10. }
  11.  
  12. if (($fh = fopen(...)) === false) {
  13. throw ...;
  14. }
  15.  
  16. if (!fwrite(...)) {
  17. throw ...;
  18. }
  19.  
  20. if (!fclose(...)) {
  21. throw ...;
  22. }
  23. } catch (MyIOException $mioe) {
  24. ...
  25. }
Oczywiście jeżeli w wyjątkach chciałbyś przemycić coś więcej niż tylko "nie udało się zapisać", np. konkretny powód takiej niemożliwości, musiałbyś kombinować ze zmienną $php_errormsg, bo API funkcji f*() nie udostępnia żadnego normalnego sposobu do dobrania się do treści błędu - ewentualnie użyć error_handlera, ale to mocno ograniczające podejście.

Oczywiście radziłbym napisać jakąś nakładę na powyższy kod, bo coś Cię trafi, jeżeli będziesz za każdym razem pisać taką obsługę błędów - pomijając fakt, że przy takiej formie niewiele się z wyjątków zyskuje.
damianooo
apropo tego co napisał CROZIN ... chyba szkoda zachodu .... zrobiłem tak jak wcześniej napisałem .. powiedz mi co z tego wynika .. jeśli nie działa is_writeable oraz is_exists no to czy na pewno jest już peewne że nie mam uprawnień ? ... co może być jeszcze ?

wychodzi na to że muszę męczyć admina w firmie , bo to on pewnie stoi za tym i powinien wszystko sprawdzić jeszcze dokładnie
melkorm
a nie lepiej po prostu skorzystać z splFileObject ?
damianooo
melkorm ...

czyli że tak:

  1. $file = new SplFileObject("/zap/hurt/test.txt", "w");
  2. if ($file->flock(LOCK_EX)) { // do an exclusive lock
  3. $file->ftruncate(0); // truncate file
  4. $file->fwrite("Write something here\n");
  5. $file->flock(LOCK_UN); // release the lock
  6. } else {
  7. echo "Couldn't get the lock!";
  8. }


albo tak:

  1. <?php
  2. $file = new SplFileObject("/zap/hurt/test.txt", "w");
  3. $written = $file->fwrite("12345");
  4. echo "Wrote $written bytes to file";
  5. ?>



tylko czy coś więcej informacji wyłuskam wprost z serwera questionmark.gif?
Crozin
Cytat
a nie lepiej po prostu skorzystać z splFileObject ?
Już myślałem, że właśnie popisałem się nieznajomością tak starej części SPL-a, która dawałaby namiastkę sensownego API ale... deweloperzy PHP jak zwykle dali dupy i nie potrafili wprowadzić normalnej obsługi błędów. Czyli na dobrą sprawę pozostaje się z dokładnie tym samym problemem co przy funkcjach f*().
melkorm
Fakt - sam wyjątek jest tylko rzucany przy tworzeniu obiektu, właśnie zobaczyłem że dla fwrite zwraca NULL w przypadku błędu, eh.

Czyli kontrolować na poziomie klasy możesz tylko tworzenie obiektu, czyli:
Cytat
Throws a RuntimeException if the filename cannot be opened.


PS. Zawsze można dopisać jakąś sensowną nakładkę.
by_ikar
Nie no to co chcesz osiągnąć można osiągnąć, chociażby w ten sposób:

  1. <?php
  2.  
  3. if(is_readable($path))
  4. {
  5. if(is_writable($path))
  6. {
  7. file_put_contents($path, $dane);
  8. } else
  9. {
  10. throw new RuntimeException(sprintf('Brak uprawnień zapisu dla pliku: %s ', $path));
  11. }
  12. } else
  13. {
  14. throw new RuntimeException(sprintf('Podana ścieżka %s nie istnie, lub nie posiadasz uprawnień odczytu.', $path));
  15. }


Możesz jeszcze dodatkowo do tego dołożyć zamiast is_readable sprawdzanie czy to plik, czy to katalog, w sumie co chcesz. Męczące jest robienie tego często tam gdzie się chce coś zapisać/odczytać i fajnie by było gdyby php rzucało w takich przypadkach wyjątki jeżeli masz zdefiniowanego swojego handlera wyjątków, no ale jak już wyżej napisano, tak nie jest wink.gif

Nie mniej, dokładnie więcej informacji się nie dowiesz, to że nie możesz zapisać tych danych to raczej najprawdopodobniej problem z uprawnieniami zapisu.
damianooo
ok admin naprawił swój błąd ...

a żeby w php nie było fajnej obsługi wyjątków to skandal smile.gif .. delikatnie mówiąc .. pozostaje czekać na nową wersję PHPa - pewnie tam już to będzie ...

dzięki wszystkim za usiłowanie pomocy ...

za pomoc najbardziej dziękuję CROZINowi ... bo w sumie wystarczyło sprawdzić tylko is_writable lub file_exists aby wiedzieć czemu nie chce się plik utworzyć w podanym katalogu

temat zamknięty

pozdrawiam
melkorm
Obsługa wyjątków jest, tylko że 99% metod została stworzona gdy jeszcze obsługi wyjątków i w ogóle OOP w PHP nie było.
I nie zapowiada się by cokolwiek w tej materii się zmieniło.

Ewentualnym rozwiązaniem jest set_error_handler.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.