Michał Sosnowski

Michał Sosnowski grafik/webmaster

Temat: PHPImageWorkshop

Czy ktoś korzystał z tego skryptu??
[url="http://phpimageworkshop.com/"]http://phpimageworkshop.com/[/url]

Próbuje go okiełznać, ale co chwila napotykam problemy.. klasa jest ładowana korzystając z autoload i prosta manipulacja obrazkiem wygląda tak :
use PHPImageWorkshop\ImageWorkshop;
$image = ImageWorkshop :: initFromPath('butterfly.png');
$image -> resizeInPixel(250, null, true);
$image -> save('news/', 'new.png', true, null, 8);


deklaracja metody initFromPath wygląda tak :
public static function initFromPath($path)


a wyjątki są zrzucane w ten sposób :
 throw new ImageWorkshopException('Not an image file (jpeg/png/gif) at "'.$path.'"', static::ERROR_NOT_AN_IMAGE_FILE);


No i z tymi błędami mam problem :

Otóż podanie nieistniejącego pliku graficzne skutkuje wywaleniem błędu : Fatal error: Uncaught PHPImageWorkshop\Exception\ImageWorkshopBaseException: [2]: No such file found at "butterflysdf.png" thrown in i przerwaniem ładowania skryptu.. Ja jednakowoż nie chciałbym, aby skrypt się zatrzymywał i chciałbym ten błąd wyświetlić w widoku w przyjaźniejszej formie.. Więc próbuje w try i catch gdzie przy catch robię :
catch(ImageWorkshopException $e) {
$this -> error = 'Błąd : '.$e -> getMessage();
}


ale tu okazuje się, że nie mogę użyć $this bo metoda jest static. Próbuje usunąć static z deklaracji, try i catch działa ale wtedy nie mogę użyć czegoś takiego :
$image = ImageWorkshop :: initFromPath('butterfly.png');


no to robie zwyczajny obiekt :
$image = new ImageWorkshop;


ale to przestaje mi widzieć inne klasy PHPImageWorkshop

W jaki sposób najmniej inwazyjny przechwycić błędy i wyświetlić w widoku bez przerywania skryptu??
Kamil S.

Kamil S. Backend Engineer and
Symfony Developer

Temat: PHPImageWorkshop

W tym przypadku statyczność IMageWorkshop nie powinna mieć znaczenia
try {
$image = ImageWorkshop :: initFromPath('butterfly.png');
$image -> resizeInPixel(250, null, true);
$image -> save('news/', 'new.png', true, null, 8);
} catch(ImageWorkshopException $e) {
$image = null;
$this -> error = 'Błąd : '.$e -> getMessage();
}
Michał Sosnowski

Michał Sosnowski grafik/webmaster

Temat: PHPImageWorkshop

Logicznie patrząc na powyższy kod jestem sam zdziwiony, że nie działa jakbyśmy chcieli.. Dalej wyrzuca mi błąd w takiej formie :
Fatal error: Uncaught PHPImageWorkshop\Exception\ImageWorkshopBaseException: [2]: No such file found at "butterflysdf.png" thrown in [....]\library\classes\PHPImageWorkshop\ImageWorkshop.php on line 96

Temat: PHPImageWorkshop

Michał S.:
catch(ImageWorkshopException $e) {
$this -> error = 'Błąd : '.$e -> getMessage();
}



catch(ImageWorkshopException $e) {
echo $e;
}

zmienna typu ImageWorkshopException potraktowana jako string zawiera przyjazny komunikat błędu.
Piotr Mroczek

Piotr Mroczek Programista PHP

Temat: PHPImageWorkshop

moim zdaniem nie łapie Ci tego wyjątku, bo nie masz go w swoim zasięgu.
stawiam, że wyjątek ImageWorkshopException leży gdzieś w namespace ie PHPImageWorkshop i zapewne musisz
go przywołać za pomocą derektywy use.

daj znać czy pomogło :)
Michał Sosnowski

Michał Sosnowski grafik/webmaster

Temat: PHPImageWorkshop

A mógłbyś pokazać jak to zrobić?? główna klasa ImageWorkshop.php na zdefiniowany namespace tak :
namespace PHPImageWorkshop;

use PHPImageWorkshop\Core\ImageWorkshopLayer as ImageWorkshopLayer;
use PHPImageWorkshop\Core\ImageWorkshopLib as ImageWorkshopLib;
use PHPImageWorkshop\Exception\ImageWorkshopException as ImageWorkshopException;
Michał Sosnowski

Michał Sosnowski grafik/webmaster

Temat: PHPImageWorkshop

Jest mam dzięki za pomoc ;)

use PHPImageWorkshop\ImageWorkshop;
use PHPImageWorkshop\Exception\ImageWorkshopException as ImageWorkshopException;
try {
$image = ImageWorkshop :: initFromPath('butterfly.png');
$image -> resizeInPixel(250, null, true);
$image -> save('news/', 'new.png', true, null, 8);
} catch(ImageWorkshopException $e) {

$image_error = 'Błąd : '.$e -> getMessage();
}

echo $image_error;
Michał Sosnowski

Michał Sosnowski grafik/webmaster

Temat: PHPImageWorkshop

A tak poza tematem.. czy w metodzie static można jakoś uzyć try i catch i przesłać błąd na zewnątrz?? wiadomo że $this -> error nie zadziała...
Piotr Mroczek

Piotr Mroczek Programista PHP

Temat: PHPImageWorkshop

nie bardzo rozumiem twoje pytanie.
jeżeli przechwyciłeś wyjątek w swoim kodzie to już masz dostęp do informacji o błędzie.
niestety $this odwołuje się do instancji obiektu wewnątrz którego jest wywołany.

przy wowołania statycznych nie tworzymy obiektu przez operator new
Michał Sosnowski

Michał Sosnowski grafik/webmaster

Temat: PHPImageWorkshop

no tak.. ale nie lepiej by było try i catch umieścić w klasie i blad wychwytywać za pomocą $this -> error??

teraz muszę za każdym użyciem ImageWorshop pamiętać , żeby w kodzie skryptu użytć try i catch ;/
Kamil S.

Kamil S. Backend Engineer and
Symfony Developer

Temat: PHPImageWorkshop

No troszkę na tym to polega że cały blok kodu ładujesz w try i wyłapujesz błąd wysoko i nie musisz martwić się o to czy kolejne fragmenty bloku mogą działać czy nie. Np całą procedurę dajesz w try i w razie problemu wyświetlasz, zwracasz błąd:

try {
$instancja = Klasa::konstruktor('parametr');{
$instancja->metoda();
$instancja->metoda();
} catch (Wyjatek $e) {
// wyswietlasz blad
}

.. lub:

$instancja = Klasa::konstruktor('parametr');
if(false !== $instancja->error) {
$instancja->metoda();
$instancja->metoda();
} else {
// wyswietlasz blad
}


jak dla mnie pierwszy sposób jest lepszy bo mam pewność że wszystko się wykona i w zmiennej $instancja jest to co potrzeba.
Jeśli bardzo chcesz przechwytywania po swojemu to nie powinieneś przerabiać vandorów, bo jak wyjdzie update to co ? Lepiej całość swojej logiki biznesowej dotyczącej tego tematu i korzystającej z liba wywalić do jakiejś klaski:


class MojLib
{
private $error;

public function getCos(parametr)
{
$instancja = null;

try {
$instancja = Klasa::konstruktor('parametr');{
$instancja->metoda();
$instancja->metoda();
} catch (Wyjatek $e) {
$this->error = $e->message;
}

return $instancja;
}

public function getError()
{
return $this->error;
}
}


a potem u siebie:

$lib = new MojLib;
$instancja = $lib->getCos(parametr);

// ogarniasz blad jak chcesz
if(null === $instancja) {
print $instancja->getError();
}
Ten post został edytowany przez Autora dnia 16.10.13 o godzinie 17:41
Michał Sosnowski

Michał Sosnowski grafik/webmaster

Temat: PHPImageWorkshop

Ok .. dziękuje za wskazówki i przykład.. przyda się ;) a teraz pomyślę, pokombinuję, i zobaczę co wybrać ;)
Piotr Mroczek

Piotr Mroczek Programista PHP

Temat: PHPImageWorkshop

osobiscie skłaniałbym się do tego co Kamil napisał, ale przesłoniłbym klase ImageWorkshop, a w sumie przeslonil metode initFromPath i tam juz sobie zaimplementowal oblsuge tego bledu tak jak chcesz.

obojetnie jaka drogę wybierzesz, to zgadzam się z Kamilem, że bibliotek nie powinno sie modyfikowac tak "po prostu" bo:

1. aktualizacje
2. ktos w przyszloscie moze przejac projekt po Tobie i bedzie mial problem, a trzeba promowac dobre praktyki ;)

daj znać jak to sobie dalej rozwiązałeś jeśli możesz, bo jestem ostatnio zwolennikiem różnych punktów widzenia na problemy tego typu ;)

miłego wieczoru.

konto usunięte

Temat: PHPImageWorkshop

Michał S.:
no tak.. ale nie lepiej by było try i catch umieścić w klasie i blad wychwytywać za pomocą $this -> error??

teraz muszę za każdym użyciem ImageWorshop pamiętać , żeby w kodzie skryptu użytć try i catch ;/

Proponuję inny koncept.
Wyjątek który zostaje wyrzucony oznacza, że doprowadziłeś do sytuacji w której dalsze działanie programu nie jest możliwe - próbujesz otworzyć nieistniejący plik.
Zamiast przechwytywać wyjątek, proponuję przed przekazaniem nazwy pliku do biblioteki sprawdzić czy plik istnieje i w razie czego powiadomić użytkownika nim zajdzie za daleko.
Czyli:


use PHPImageWorkshop\ImageWorkshop;
use PHPImageWorkshop\Exception\ImageWorkshopException;

$source = 'butterfly.png';
$target = 'new.png';

if(!is_file($source)) {
throw new \InvalidArgumentException(sprintf('Plik zrodlowy %s nie istnieje, sprawdz sciezke', $source));
}

if(is_file($target)) {
throw new \InvalidArgumentException(sprintf('Plik docelowy %s istnieje, sprawdz sciezke', $target));
}

$image = ImageWorkshop :: initFromPath($source);
$image -> resizeInPixel(250, null, true);
$image -> save('news/',$target, true, null, 8);


I teraz "poziom wyżej" możesz sobie łapać wyjątki i odpowiednio na nie reagować.Ten post został edytowany przez Autora dnia 17.10.13 o godzinie 21:57
Kamil S.

Kamil S. Backend Engineer and
Symfony Developer

Temat: PHPImageWorkshop

Ale ImageWorkshop robi dokładnie to samo, sprawdza czy plik istnieje i rzuca wyjątkiem... więc to chyba dublowanie logiki :( Jest sobie kontroler i zostaje zatrzymany wyjątkiem a tu właśnie chodziło by tego uniknąć. Michałowi chodziło o to by nie zatrzymywać całego skryptu i iść dalej z informacją o błędzie dlatego przechwycenie wyjątku w kontrolerze tak wysoko jak się da lub opakowanie IWS w swój lib który przechwyci wyjątek z vendora gdzieś głębiej w sobie i odda null jeśli zadzieje się coś złego.
Michał W.:
Michał S.:
no tak.. ale nie lepiej by było try i catch umieścić w klasie i blad wychwytywać za pomocą $this -> error??

teraz muszę za każdym użyciem ImageWorshop pamiętać , żeby w kodzie skryptu użytć try i catch ;/

Proponuję inny koncept.
Wyjątek który zostaje wyrzucony oznacza, że doprowadziłeś do sytuacji w której dalsze działanie programu nie jest możliwe - próbujesz otworzyć nieistniejący plik.
Zamiast przechwytywać wyjątek, proponuję przed przekazaniem nazwy pliku do biblioteki sprawdzić czy plik istnieje i w razie czego powiadomić użytkownika nim zajdzie za daleko.
Czyli:


use PHPImageWorkshop\ImageWorkshop;
use PHPImageWorkshop\Exception\ImageWorkshopException;

$source = 'butterfly.png';
$target = 'new.png';

if(!is_file($source)) {
throw new \InvalidArgumentException(sprintf('Plik zrodlowy %s nie istnieje, sprawdz sciezke', $source));
}

if(is_file($target)) {
throw new \InvalidArgumentException(sprintf('Plik docelowy %s istnieje, sprawdz sciezke', $target));
}

$image = ImageWorkshop :: initFromPath($source);
$image -> resizeInPixel(250, null, true);
$image -> save('news/',$target, true, null, 8);


I teraz "poziom wyżej" możesz sobie łapać wyjątki i odpowiednio na nie reagować.Ten post został edytowany przez Autora dnia 18.10.13 o godzinie 01:33

konto usunięte

Temat: PHPImageWorkshop

Kamil S.:
Ale ImageWorkshop robi dokładnie to samo, sprawdza czy plik istnieje i rzuca wyjątkiem... więc to chyba dublowanie logiki :(
Ale to nie ma znaczenia, bo co miał IWS zrobić, tępo otwierać nieistniejący plik?

Nie, to nie jest dublowanie logiki ( hłe hłe logiki, dwa ify :D ), warunki uruchomienia IWS (czy innej jeśli się biblioteka znudzi) zostały zapisane przed wywołaniem, teraz Michał może napisane przeze mnie wyjątki zamienić na die('...'), albo opakować to w funkcję i robić return false.
Jest sobie kontroler i zostaje zatrzymany wyjątkiem a tu właśnie chodziło by tego uniknąć.
Nie wiem czy ma kontroler, Ty pierwszy o tym wspomniałeś.
Michałowi chodziło o to by nie zatrzymywać całego skryptu i iść dalej z informacją o błędzie dlatego przechwycenie wyjątku w kontrolerze tak wysoko jak się da lub opakowanie IWS w swój lib który przechwyci wyjątek z vendora gdzieś głębiej w sobie i odda null jeśli zadzieje się coś złego.
Wiem do czego służy try-catch.
Pytał, bo trafił na sytuację z którą nie wiedział jak sobie poradzić.
Teraz wie dzięki Wam jak sobie z nią poradzić i napisałem jak do niej nie dopuszczać.

A ty co obyś wybrał? :D
Kamil S.

Kamil S. Backend Engineer and
Symfony Developer

Temat: PHPImageWorkshop

Troszkę się jednak nie zgodzę bo IWS sprawdza czy plik istnieje zamiast go tępo otwierać, rzuca wtedy wyjątkiem, więc po co sprawdzać przed nim to raz jeszcze?
Nie trzeba się bać wyjątków, oni nie muszą zatrzymywać aplikacji, takie bardziej biznesowe mogą służyć do tego by z jakiegoś głębokiego miejsca poinformować że coś się nie udało bez przekazywanie sobie return'ów z nullami czy czymś podobnym. Tutaj IWS mówi logice wyżej że coś poszło nie tak, ogarniasz to jak Ci się podoba.
Ja cały kod dot. operacji na IWS (odczyt, resize i zapis zdjęcia) zrobił bym między try i przechwycił wyjątki jeśli coś się stanie ... dlaczego ? bo wtedy mam pewność że całość się wykonała i mogę działać dalej, nie tylko odczyt z dysku, resize też może się wysypać przez brak liba gdzieś, zapis może się wysypać bo prawa nie takie albo dysku będzie za mało. IWS ogarnia wszystko i odpowiednio potrafi o tym poinformować właśnie wyjątkiem. Hipotetycznie fajnie przykład:

try {
$instancja = Klasa::get(cos);
$instancja->resize();
$instancja->zapisz();
} catch(WyjatekOdczyt $e) {
echo 'blad odczytu';
} catch(WyjatekZapis $e) {
echo 'blad zapisu';
} catch(Wyjatek $e) {
echo 'cos innego się wysypało';
}


I teraz, lib wywala biznesowymi wyjątkami a ja je sobie ogrywam, robiąc to na returnach i ifach był by makaron. Gdy blok się wykona mam pewność że wszystko jest poprawne i jadę dalej.

konto usunięte

Temat: PHPImageWorkshop

Możesz się bardzo nie zgodzić :)
Ja bym zasłonił IWS jakimś adapterem by uniezależnić się od implementacji. Ale ja bym nie ma tutaj znaczenia, ani Ty ani ja nie piszemy za Michała :)
Cholera wie jak duży skrypt pisze Michał, może całą logikę da się zamknąć w jednego try/catch?
Może mu Twoje try/catch starczy?
Może wygodniej będzie mu robić returny?
A może nie powinien używać biblioteki do prostego resize? :)Ten post został edytowany przez Autora dnia 18.10.13 o godzinie 12:54
Piotr Mroczek

Piotr Mroczek Programista PHP

Temat: PHPImageWorkshop

też właśnie zastanawiałem się nad tym adapterem, pytanie tylko na ile operacje na grafikach da się zunifikować do wspólnego interfejsu, tak by to miało rączki i nóżki i niosło korzyść ;)

konto usunięte

Temat: PHPImageWorkshop

Zaprojektuj sobie interface, określ jakie operacje będą ci potrzebne, jakie parametry powinny przyjmować.
Napisz testy do interfejsu - opcjonalne :)
Napisz implementacje interfejsu dla IWS, GD2.



Wyślij zaproszenie do