CakePHP: home.pl – Internal Server Error 500

UWAGA!

 

Artykuł ten jest nieaktualny! Rozwiązanie problemu jest niepoprawne, prawidłowe rozwiązanie znajduje się w artykule: CakePHP: IdeaCache – Internal Server Error 500

 

Natknąłem się dzisiaj na błąd podczas przenoszenia serwisu opartego na CakePHP na serwer firmy home.pl. Nigdy nie podobała mi się ta firma, ale do tej pory nie stwarzała mi specjalnych kłopotów.

Po wgraniu strony na nowy serwer, ustawilem debug na wartość 2 celem odswieżenia wewnetrznego cache’a CakePHP. Po pomyślnym otworzeniu strony ustawilem debug na wartość 0. Po ponownym otwarciu strony wyskoczył mi błąd Internal Server Error 500. Po przeszukaniu internetu, doszedłem do tego, że należy dodać do pliku .htaccess znajdującego się w nadrzędnym naszej aplikacji, tj. katalog zawierający katalogi app,cake,plugins,vendors; linię RewriteBase /podkatalog/. A zatem cały plik będzie wyglądał następująco

<ifmodule mod_rewrite.c="">
    RewriteEngine on
    RewriteBase /podkatalog/
    RewriteRule    ^$    webroot/    [L]
    RewriteRule    (.*) webroot/$1    [L]
 </ifmodule>

Z moich obserwacji wynika, że bez tej linijki CakePHP nie jest w stanie przeładować swoich wewnetrznych cache. Odpalamy naszą aplikację z debug ustawionym na 2, następnie zmieniamy na 0 i wszystko powinno ładnie chodzić. Co ciekawe mogę również usunąc dodaną linijkę kodu i wszystko będzie działać jak należy. Można wnioskować, że dodanie tej linijki jest konieczne jedynie dlatego, aby CakePHP mógł przeładować wewnętrzne cache. Mam nadzieję, że ktoś z podobnym problemem trafi na ten artykuł.

CakePHP: Usuwanie rekurencyjne (kaskadowe)

Jeżeli chcemy skasować rekord z bazy danych, wraz z wszystkimi powiązaniami rekordami z innych modeli wystarczy ustawić odpowiednie parametry w modelu(dla danego powiązania dependent = true a następnie wywołać metodę delete() na modelu. Nazwijmy to usuwanie rekurencyjne, lub usuwanie kaskadowe. Załóżmy, że mamy model User, który posiada powiązanie hasOne z modelem Account, hasAndBelongsToMany z modelem Tag, oraz powiązanie hasMany z modelem Photo. Dodatkowo model Account posiada powiązanie hasMany z modelem Information. Pomijam powiązanie belongsTo, gdyż nie wyobrażam sobie sytuacji, że chcemy usunąć model z takim powiązaniem. Nasze modele wyglądają następująco.

class User extends AppModel {
  var $hasOne = array('Account');
  var $hasMany = array('Photo');
  var $hasAndBelongsToMany = array('Tag');
}
 
class Account extends AppModel {
  var $hasMany = array('Information');
}

Wywołując w kontrolerze users $this->User->delete($id); skasujemy rekord z modelu User oraz wszystkie rekordy z tabeli tags_users, czyli z tabeli łączącej model User z modelem Tag. Dzieje się tak dlatego, że relacje HABTM są domyślnie zależne od siebie. Co zrobić aby skasować powiązanie rekordy z modeli Account, Photo, Information? Wystarczy określić, że modele są zależne od siebie. Nasze modele wyglądają teraz następująco.

class User extends AppModel {
  var $hasOne = array('Account' => array('dependent' => true));
  var $hasMany = array('Photo' => array('dependent' => true));
  var $hasAndBelongsToMany = array('Tag');
}
 
class Account extends AppModel {
  var $hasMany = array('Information' => array('dependent' => true));
}

Tak określone modele tworzą zależności pomiędzy modelami. Kasując użytkownika kasujemy wszystkie jego zdjecia, konto, oraz informacje należące do konta. Bardzo prosta i przydatna procedura.

PHP: zmienne zmiennych – zmienne dynamiczne

Spotkałem się ostatnio z problemem dostępu do zmiennej w PHP, której nazwa nie jest znana do chwili uruchomienia skryptu. Rozwiązanie okazuje się banalne. Dla przykładu załóżmy że chcemy wyświetlić zmienną o nazwie $nieznana_nazwa. Należy skorzystać z następującej składni.

$name = 'nieznana_nazwa';
echo ${$name};

Jest to równoznaczne z napisaniem echo $nieznana_nazwa. Sytuacja kiedy nie znamy nazwy zmiennej nie wydaje się częsta, istnieje prawdopodobnie milion innych sposobów aby to obejść, np. skorzystać z tablicy. Ten sposób wydaje się ciekawy, dlatego nie chciałbym o nim zapomnieć. 😉